// To find the corresponding schema for a dconf path, e.g. /desktop/ibus/general/preload-engines: // $ gsettings list-schemas | grep desktop.ibus.general // org.freedesktop.ibus.general // org.freedesktop.ibus.general.hotkey // $ gsettings list-keys org.freedesktop.ibus.general | grep preload-engines // preload-engines protected virtual string[] GetMyKeyboards(IntPtr settingsGeneral) { // This is the proper path for the combined keyboard handling on Cinnamon with IBus. var sources = Unmanaged.g_settings_get_value(settingsGeneral, "preload-engines"); if (sources == IntPtr.Zero) { return(null); } var list = KeyboardRetrievingHelper.GetStringArrayFromGVariantArray(sources); Unmanaged.g_variant_unref(sources); // Call these only once per run of the program. if (CombinedIbusKeyboardSwitchingAdaptor.DefaultLayout == null) { LoadDefaultXkbSettings(); } if (CombinedIbusKeyboardSwitchingAdaptor.LatinLayouts == null) { LoadLatinLayouts(settingsGeneral); } return(list); }
/// <summary> /// Returns the list of keyboards or <c>null</c> if we can't get the combined keyboards /// list. /// </summary> private string[] GetMyKeyboards() { // This is the proper path for the combined keyboard handling, not the path // given in the IBus reference documentation. const string schema = "org.gnome.desktop.input-sources"; if (!KeyboardRetrievingHelper.SchemaIsInstalled(schema)) { return(null); } var settings = Unmanaged.g_settings_new(schema); if (settings == IntPtr.Zero) { return(null); } var sources = Unmanaged.g_settings_get_value(settings, "sources"); if (sources == IntPtr.Zero) { return(null); } var list = KeyboardRetrievingHelper.GetStringArrayFromGVariantListArray(sources); Unmanaged.g_variant_unref(sources); Unmanaged.g_object_unref(settings); return(list); }
/// <summary> /// Load a couple of settings from the GNOME settings system. /// </summary> private static void LoadLatinLayouts(IntPtr settingsGeneral) { IntPtr value = Unmanaged.g_settings_get_value(settingsGeneral, "xkb-latin-layouts"); CombinedIbusKeyboardSwitchingAdaptor.LatinLayouts = KeyboardRetrievingHelper.GetStringArrayFromGVariantArray(value); Unmanaged.g_variant_unref(value); CombinedIbusKeyboardSwitchingAdaptor.UseXmodmap = Unmanaged.g_settings_get_boolean( settingsGeneral, "use-xmodmap"); //Console.WriteLine("DEBUG use-xmodmap = {0}", _use_xmodmap); //Console.Write("DEBUG xkb-latin-layouts ="); //for (int i = 0; i < _latinLayouts.Length; ++i) // Console.Write(" '{0}'", _latinLayouts[i]); //Console.WriteLine(); }
/// <summary> /// Convert a GVariant handle that points to a list of lists of two strings into /// a C# string array. The original strings in the inner lists are separated by /// double semicolons in the output elements of the C# string array. /// </summary> /// <remarks> /// No check is made to verify that the input value actually points to a list of /// lists of two strings. /// </remarks> public static string[] GetStringArrayFromGVariantListArray(IntPtr value) { if (value == IntPtr.Zero) { return(new string[0]); } uint size = Unmanaged.g_variant_n_children(value); string[] list = new string[size]; for (uint i = 0; i < size; ++i) { IntPtr duple = Unmanaged.g_variant_get_child_value(value, i); var values = GetStringArrayFromGVariantArray(duple); Debug.Assert(values.Length == 2); list[i] = String.Format("{0};;{1}", values[0], values[1]); Unmanaged.g_variant_unref(duple); //Console.WriteLine("DEBUG GetStringArrayFromGVariantListArray(): list[{0}] = \"{1}\"", i, list[i]); } return(list); }
/// <summary> /// Convert a GVariant handle that points to a list of strings to a C# string array. /// Without leaking memory in the process! /// </summary> /// <remarks> /// No check is made to verify that the input value actually points to a list of strings. /// </remarks> public static string[] GetStringArrayFromGVariantArray(IntPtr value) { if (value == IntPtr.Zero) { return(new string[0]); } uint size = Unmanaged.g_variant_n_children(value); string[] list = new string[size]; for (uint i = 0; i < size; ++i) { IntPtr child = Unmanaged.g_variant_get_child_value(value, i); int length; // handle must not be freed -- it points into the actual GVariant memory for child! IntPtr handle = Unmanaged.g_variant_get_string(child, out length); var rawbytes = new byte[length]; Marshal.Copy(handle, rawbytes, 0, length); list[i] = Encoding.UTF8.GetString(rawbytes); Unmanaged.g_variant_unref(child); //Console.WriteLine("DEBUG GetStringArrayFromGVariant(): list[{0}] = \"{1}\" (length = {2})", i, list[i], length); } return(list); }