From 0b0e6bc987da4fd88a7854ebb12bde705e92c428 Mon Sep 17 00:00:00 2001 From: Perberos Date: Thu, 1 Dec 2011 21:51:44 -0300 Subject: moving from https://github.com/perberos/mate-desktop-environment --- capplets/keyboard/Makefile.am | 42 + capplets/keyboard/keyboard.desktop.in.in | 14 + .../mate-keyboard-properties-a11y-notifications.ui | 526 ++++++ capplets/keyboard/mate-keyboard-properties-a11y.c | 325 ++++ capplets/keyboard/mate-keyboard-properties-a11y.h | 32 + .../keyboard/mate-keyboard-properties-dialog.ui | 1857 ++++++++++++++++++++ .../mate-keyboard-properties-layout-chooser.ui | 315 ++++ .../mate-keyboard-properties-model-chooser.ui | 142 ++ .../mate-keyboard-properties-options-dialog.ui | 94 + capplets/keyboard/mate-keyboard-properties-xkb.c | 254 +++ capplets/keyboard/mate-keyboard-properties-xkb.h | 104 ++ capplets/keyboard/mate-keyboard-properties-xkblt.c | 475 +++++ .../keyboard/mate-keyboard-properties-xkbltadd.c | 561 ++++++ capplets/keyboard/mate-keyboard-properties-xkbmc.c | 347 ++++ capplets/keyboard/mate-keyboard-properties-xkbot.c | 516 ++++++ capplets/keyboard/mate-keyboard-properties-xkbpv.c | 136 ++ capplets/keyboard/mate-keyboard-properties.c | 265 +++ 17 files changed, 6005 insertions(+) create mode 100644 capplets/keyboard/Makefile.am create mode 100644 capplets/keyboard/keyboard.desktop.in.in create mode 100644 capplets/keyboard/mate-keyboard-properties-a11y-notifications.ui create mode 100644 capplets/keyboard/mate-keyboard-properties-a11y.c create mode 100644 capplets/keyboard/mate-keyboard-properties-a11y.h create mode 100644 capplets/keyboard/mate-keyboard-properties-dialog.ui create mode 100644 capplets/keyboard/mate-keyboard-properties-layout-chooser.ui create mode 100644 capplets/keyboard/mate-keyboard-properties-model-chooser.ui create mode 100644 capplets/keyboard/mate-keyboard-properties-options-dialog.ui create mode 100644 capplets/keyboard/mate-keyboard-properties-xkb.c create mode 100644 capplets/keyboard/mate-keyboard-properties-xkb.h create mode 100644 capplets/keyboard/mate-keyboard-properties-xkblt.c create mode 100644 capplets/keyboard/mate-keyboard-properties-xkbltadd.c create mode 100644 capplets/keyboard/mate-keyboard-properties-xkbmc.c create mode 100644 capplets/keyboard/mate-keyboard-properties-xkbot.c create mode 100644 capplets/keyboard/mate-keyboard-properties-xkbpv.c create mode 100644 capplets/keyboard/mate-keyboard-properties.c (limited to 'capplets/keyboard') diff --git a/capplets/keyboard/Makefile.am b/capplets/keyboard/Makefile.am new file mode 100644 index 00000000..5705b01f --- /dev/null +++ b/capplets/keyboard/Makefile.am @@ -0,0 +1,42 @@ +# This is used in MATECC_CAPPLETS_CFLAGS +cappletname = keyboard + +bin_PROGRAMS = mate-keyboard-properties + +mate_keyboard_properties_SOURCES = \ + mate-keyboard-properties.c \ + mate-keyboard-properties-a11y.c \ + mate-keyboard-properties-a11y.h \ + mate-keyboard-properties-xkb.c \ + mate-keyboard-properties-xkbmc.c \ + mate-keyboard-properties-xkblt.c \ + mate-keyboard-properties-xkbltadd.c \ + mate-keyboard-properties-xkbot.c \ + mate-keyboard-properties-xkbpv.c \ + mate-keyboard-properties-xkb.h + +mate_keyboard_properties_LDADD = $(MATECC_CAPPLETS_LIBS) $(LIBMATEKBDUI_LIBS) + +@INTLTOOL_DESKTOP_RULE@ + +uidir = $(pkgdatadir)/ui +dist_ui_DATA = mate-keyboard-properties-a11y-notifications.ui \ + mate-keyboard-properties-dialog.ui \ + mate-keyboard-properties-layout-chooser.ui \ + mate-keyboard-properties-model-chooser.ui \ + mate-keyboard-properties-options-dialog.ui + +desktopdir = $(datadir)/applications +Desktop_in_files = keyboard.desktop.in +desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop) + +INCLUDES = \ + $(MATECC_CAPPLETS_CFLAGS) \ + $(LIBMATEKBDUI_CFLAGS) \ + -DMATELOCALEDIR="\"$(datadir)/locale\"" \ + -DMATECC_DATA_DIR="\"$(pkgdatadir)\"" \ + -DMATECC_UI_DIR="\"$(uidir)\"" +CLEANFILES = $(MATECC_CAPPLETS_CLEANFILES) $(Desktop_in_files) $(desktop_DATA) +EXTRA_DIST = $(ui_DATA) + +-include $(top_srcdir)/git.mk diff --git a/capplets/keyboard/keyboard.desktop.in.in b/capplets/keyboard/keyboard.desktop.in.in new file mode 100644 index 00000000..fdfacfa6 --- /dev/null +++ b/capplets/keyboard/keyboard.desktop.in.in @@ -0,0 +1,14 @@ +[Desktop Entry] +_Name=Keyboard +_Comment=Set your keyboard preferences +Exec=mate-keyboard-properties +Icon=preferences-desktop-keyboard +Terminal=false +Type=Application +StartupNotify=true +Categories=MATE;GTK;Settings;HardwareSettings; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=mate-control-center +X-MATE-Bugzilla-Component=keyboard +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/capplets/keyboard/mate-keyboard-properties-a11y-notifications.ui b/capplets/keyboard/mate-keyboard-properties-a11y-notifications.ui new file mode 100644 index 00000000..3f33d991 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-a11y-notifications.ui @@ -0,0 +1,526 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Keyboard Accessibility Audio Feedback + center-on-parent + dialog + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + vertical + 18 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + General + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + Beep when _accessibility features are turned on or off + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + Beep when a _toggle key is pressed + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 1 + + + + + 1 + + + + + 1 + + + + + False + 0 + + + + + True + vertical + 6 + + + True + 0 + Visual cues for sounds + + + + + + 0 + + + + + True + + + True + + + + False + 0 + + + + + True + vertical + 6 + + + Show _visual feedback for the alert sound + True + True + False + True + True + + + 0 + + + + + True + + + True + + + + False + 0 + + + + + True + vertical + 6 + + + Flash _window titlebar + True + True + False + True + True + True + + + 0 + + + + + Flash entire _screen + True + True + False + True + True + True + visual_bell_titlebar + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Slow Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + Beep when a key is pr_essed + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + Beep when key is _accepted + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 1 + + + + + Beep when key is _rejected + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 2 + + + + + 1 + + + + + 1 + + + + + False + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Bounce Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + Beep when a key is reje_cted + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + 1 + + + + + 1 + + + + + False + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Sticky Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 6 + + + Beep when a _modifier key is pressed + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + 1 + + + + + 1 + + + + + False + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + end + + + gtk-help + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + False + False + 0 + + + + + gtk-close + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + False + False + 1 + + + + + False + end + 0 + + + + + + button11 + button12 + + + diff --git a/capplets/keyboard/mate-keyboard-properties-a11y.c b/capplets/keyboard/mate-keyboard-properties-a11y.c new file mode 100644 index 00000000..3405ffa7 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-a11y.c @@ -0,0 +1,325 @@ +/* -*- mode: c; style: linux -*- */ + +/* + * Copyright (C) 2007 The MATE Foundation + * Written by Denis Washington + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "mate-keyboard-properties-a11y.h" +#include +#include "mateconf-property-editor.h" +#include "capplet-util.h" + +#define CONFIG_ROOT "/desktop/mate/accessibility/keyboard" +#define NWID(s) GTK_WIDGET (gtk_builder_get_object (notifications_dialog, s)) + +static GtkBuilder *notifications_dialog = NULL; + +static void +stickykeys_enable_toggled_cb (GtkWidget *w, GtkBuilder *dialog) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)); + + gtk_widget_set_sensitive (WID ("stickykeys_two_key_off"), active); + if (notifications_dialog) + gtk_widget_set_sensitive (NWID ("stickykeys_notifications_box"), active); +} + +static void +slowkeys_enable_toggled_cb (GtkWidget *w, GtkBuilder *dialog) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)); + + gtk_widget_set_sensitive (WID ("slowkeys_delay_box"), active); + if (notifications_dialog) + gtk_widget_set_sensitive (NWID ("slowkeys_notifications_box"), active); +} + +static void +bouncekeys_enable_toggled_cb (GtkWidget *w, GtkBuilder *dialog) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)); + + gtk_widget_set_sensitive (WID ("bouncekeys_delay_box"), active); + if (notifications_dialog) + gtk_widget_set_sensitive (NWID ("bouncekeys_notifications_box"), active); +} + +static void +visual_bell_enable_toggled_cb (GtkWidget *w, GtkBuilder *dialog) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)); + + if (notifications_dialog) { + gtk_widget_set_sensitive (NWID ("visual_bell_titlebar"), active); + gtk_widget_set_sensitive (NWID ("visual_bell_fullscreen"), active); + } +} + +static MateConfEnumStringPair bell_flash_enums[] = { + { 0, "frame_flash" }, + { 1, "fullscreen" }, + { -1, NULL } +}; + +static MateConfValue * +bell_flash_from_widget (MateConfPropertyEditor *peditor, const MateConfValue *value) +{ + MateConfValue *new_value; + + new_value = mateconf_value_new (MATECONF_VALUE_STRING); + mateconf_value_set_string (new_value, + mateconf_enum_to_string (bell_flash_enums, mateconf_value_get_int (value))); + + return new_value; +} + +static MateConfValue * +bell_flash_to_widget (MateConfPropertyEditor *peditor, const MateConfValue *value) +{ + MateConfValue *new_value; + const gchar *str; + gint val = 2; + + str = (value && (value->type == MATECONF_VALUE_STRING)) ? mateconf_value_get_string (value) : NULL; + + new_value = mateconf_value_new (MATECONF_VALUE_INT); + if (value->type == MATECONF_VALUE_STRING) { + mateconf_string_to_enum (bell_flash_enums, + str, + &val); + } + mateconf_value_set_int (new_value, val); + + return new_value; +} + +static void +a11y_notifications_dialog_response_cb (GtkWidget *w, gint response) +{ + if (response == GTK_RESPONSE_HELP) { + + } + else { + gtk_widget_destroy (w); + } +} +static void +notifications_button_clicked_cb (GtkWidget *button, GtkBuilder *dialog) +{ + GtkWidget *w; + + notifications_dialog = gtk_builder_new (); + gtk_builder_add_from_file (notifications_dialog, MATECC_UI_DIR + "/mate-keyboard-properties-a11y-notifications.ui", + NULL); + + stickykeys_enable_toggled_cb (WID ("stickykeys_enable"), dialog); + slowkeys_enable_toggled_cb (WID ("slowkeys_enable"), dialog); + bouncekeys_enable_toggled_cb (WID ("bouncekeys_enable"), dialog); + + w = NWID ("feature_state_change_beep"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/feature_state_change_beep", + w, NULL); + + w = NWID ("togglekeys_enable"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/togglekeys_enable", + w, NULL); + + w = NWID ("stickykeys_modifier_beep"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/stickykeys_modifier_beep", + w, NULL); + + w = NWID ("slowkeys_beep_press"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/slowkeys_beep_press", + w, NULL); + + w = NWID ("slowkeys_beep_accept"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/slowkeys_beep_accept", + w, NULL); + + w = NWID ("slowkeys_beep_reject"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/slowkeys_beep_reject", + w, NULL); + + w = NWID ("bouncekeys_beep_reject"); + mateconf_peditor_new_boolean (NULL, + CONFIG_ROOT "/bouncekeys_beep_reject", + w, NULL); + + w = NWID ("visual_bell_enable"); + mateconf_peditor_new_boolean (NULL, + "/apps/marco/general/visual_bell", + w, NULL); + g_signal_connect (w, "toggled", + G_CALLBACK (visual_bell_enable_toggled_cb), dialog); + visual_bell_enable_toggled_cb (w, dialog); + + mateconf_peditor_new_select_radio (NULL, + "/apps/marco/general/visual_bell_type", + gtk_radio_button_get_group (GTK_RADIO_BUTTON (NWID ("visual_bell_titlebar"))), + "conv-to-widget-cb", bell_flash_to_widget, + "conv-from-widget-cb", bell_flash_from_widget, + NULL); + + w = NWID ("a11y_notifications_dialog"); + gtk_window_set_transient_for (GTK_WINDOW (w), + GTK_WINDOW (WID ("keyboard_dialog"))); + g_signal_connect (w, "response", + G_CALLBACK (a11y_notifications_dialog_response_cb), NULL); + + gtk_dialog_run (GTK_DIALOG (w)); + + g_object_unref (notifications_dialog); + notifications_dialog = NULL; +} + +static void +mousekeys_enable_toggled_cb (GtkWidget *w, GtkBuilder *dialog) +{ + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)); + gtk_widget_set_sensitive (WID ("mousekeys_table"), active); +} + +static MateConfValue * +mousekeys_accel_time_to_widget (MateConfPropertyEditor *peditor, const MateConfValue *value) +{ + GtkAdjustment *adjustment; + gdouble range_upper; + MateConfValue *new_value; + + adjustment = GTK_ADJUSTMENT (mateconf_property_editor_get_ui_control (peditor)); + g_object_get (adjustment, + "upper", &range_upper, + NULL); + + new_value = mateconf_value_new (MATECONF_VALUE_INT); + mateconf_value_set_int (new_value, MAX (0, ((int) range_upper) - mateconf_value_get_int (value))); + + return new_value; +} + +static MateConfValue * +mousekeys_accel_time_from_widget (MateConfPropertyEditor *peditor, const MateConfValue *value) +{ + GtkAdjustment *adjustment; + gdouble range_value, range_upper; + MateConfValue *new_value; + + adjustment = GTK_ADJUSTMENT (mateconf_property_editor_get_ui_control (peditor)); + g_object_get (adjustment, + "value", &range_value, + "upper", &range_upper, + NULL); + + new_value = mateconf_value_new (MATECONF_VALUE_INT); + mateconf_value_set_int (new_value, (int) range_upper - range_value); + + return new_value; +} + +void +setup_a11y_tabs (GtkBuilder *dialog, MateConfChangeSet *changeset) +{ + MateConfClient *client; + GtkWidget *w; + + client = mateconf_client_get_default (); + mateconf_client_add_dir (client, CONFIG_ROOT, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + g_object_unref (client); + + /* Accessibility tab */ + + w = WID ("master_enable"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/enable", + w, NULL); + + w = WID ("stickykeys_enable"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/stickykeys_enable", + w, NULL); + g_signal_connect (w, "toggled", + G_CALLBACK (stickykeys_enable_toggled_cb), dialog); + stickykeys_enable_toggled_cb (w, dialog); + + w = WID ("stickykeys_two_key_off"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/stickykeys_two_key_off", + w, NULL); + + w = WID ("slowkeys_enable"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/slowkeys_enable", + w, NULL); + g_signal_connect (w, "toggled", + G_CALLBACK (slowkeys_enable_toggled_cb), dialog); + slowkeys_enable_toggled_cb (w, dialog); + + w = WID ("bouncekeys_enable"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/bouncekeys_enable", + w, NULL); + g_signal_connect (w, "toggled", + G_CALLBACK (bouncekeys_enable_toggled_cb), dialog); + bouncekeys_enable_toggled_cb (w, dialog); + + mateconf_peditor_new_numeric_range (changeset, + CONFIG_ROOT "/slowkeys_delay", + WID ("slowkeys_delay_slide"), NULL); + mateconf_peditor_new_numeric_range (changeset, + CONFIG_ROOT "/bouncekeys_delay", + WID ("bouncekeys_delay_slide"), NULL); + + w = WID ("notifications_button"); + g_signal_connect (w, "clicked", + G_CALLBACK (notifications_button_clicked_cb), dialog); + + /* Mouse Keys tab */ + + w = WID ("mousekeys_enable"); + mateconf_peditor_new_boolean (changeset, + CONFIG_ROOT "/mousekeys_enable", + w, NULL); + g_signal_connect (w, "toggled", + G_CALLBACK (mousekeys_enable_toggled_cb), dialog); + mousekeys_enable_toggled_cb (w, dialog); + + mateconf_peditor_new_numeric_range (changeset, + CONFIG_ROOT "/mousekeys_accel_time", + WID ("mousekeys_accel_time_slide"), + "conv-to-widget-cb", mousekeys_accel_time_to_widget, + "conv-from-widget-cb", mousekeys_accel_time_from_widget, + NULL); + mateconf_peditor_new_numeric_range (changeset, + CONFIG_ROOT "/mousekeys_max_speed", + WID ("mousekeys_max_speed_slide"), NULL); + mateconf_peditor_new_numeric_range (changeset, + CONFIG_ROOT "/mousekeys_init_delay", + WID ("mousekeys_init_delay_slide"), NULL); +} diff --git a/capplets/keyboard/mate-keyboard-properties-a11y.h b/capplets/keyboard/mate-keyboard-properties-a11y.h new file mode 100644 index 00000000..35e5678d --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-a11y.h @@ -0,0 +1,32 @@ +/* -*- mode: c; style: linux -*- */ + +/* accessibility-keyboard.c + * Copyright (C) 2002 Ximian, Inc. + * + * Written by: Jody Goldberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __MATE_KEYBOARD_PROPERTY_A11Y_H +#define __MATE_KEYBOARD_PROPERTY_A11Y_H + +#include +#include + +extern void setup_a11y_tabs (GtkBuilder * dialog, MateConfChangeSet * changeset); + +#endif /* __MATE_KEYBOARD_PROPERTY_A11Y_H */ diff --git a/capplets/keyboard/mate-keyboard-properties-dialog.ui b/capplets/keyboard/mate-keyboard-properties-dialog.ui new file mode 100644 index 00000000..eb9e92f0 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-dialog.ui @@ -0,0 +1,1857 @@ + + + + + + 500 + 100 + 2000 + 10 + 10 + + + 1 + 1 + 100000 + 1 + 10 + + + 30 + 10 + 110 + 10 + 10 + + + 1000 + 100 + 2500 + 200 + 200 + + + 0.5 + 500 + 10 + 10 + + + 0.5 + 900 + 10 + 10 + + + 1800 + 3000 + 10 + 10 + + + 300 + 10 + 1000 + 10 + 10 + + + 300 + 10 + 2000 + 10 + 10 + + + 1 + 1 + 100000 + 1 + 10 + + + 5 + Keyboard Preferences + 450 + 430 + dialog + False + + + True + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + 12 + + + True + True + + + True + 12 + 18 + + + True + 6 + + + True + 0 + Repeat Keys + + + + + + False + False + 0 + + + + + True + + + True + + + + False + False + 0 + + + + + True + 6 + + + Key presses _repeat when key is held down + True + True + False + True + True + + + False + False + 0 + + + + + True + 12 + + + True + 6 + + + True + 0 + _Delay: + True + center + repeat_delay_scale + + + 0 + + + + + True + 0 + _Speed: + True + center + repeat_speed_scale + + + 1 + + + + + False + False + 0 + + + + + True + 6 + + + True + 1 + 10 + Short + + + + + + + 0 + + + + + True + 1 + 10 + Slow + + + + + + + 1 + + + + + False + False + 1 + + + + + True + 6 + + + True + True + adjustment1 + False + + + 0 + + + + + True + True + adjustment2 + False + + + Repeat keys speed + + + + + 1 + + + + + 2 + + + + + True + 6 + + + True + 0 + Long + + + + + + + 0 + + + + + True + 0 + Fast + + + + + + + 1 + + + + + False + False + 3 + + + + + False + 1 + + + + + 1 + + + + + 1 + + + + + False + 0 + + + + + True + 6 + + + True + 0 + Cursor Blinking + + + + + + False + False + 0 + + + + + True + + + True + + + + False + False + 0 + + + + + True + 6 + + + Cursor _blinks in text fields + True + True + False + True + True + + + False + False + 0 + + + + + True + 12 + + + True + 0 + S_peed: + True + center + cursor_blink_time_scale + + + False + False + 0 + + + + + True + 6 + + + True + 1 + 10 + Slow + + + + + + + False + False + 0 + + + + + True + True + discontinuous + adjustment3 + False + + + Cursor blinks speed + + + + + 1 + + + + + True + 0 + Fast + + + + + + + False + False + 2 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + False + 1 + + + + + + + True + General + center + + + False + + + + + True + 12 + 12 + + + True + 6 + + + True + True + automatic + automatic + in + + + True + True + List of keyboard layouts selected for usage + False + + + + + 0 + + + + + True + 6 + True + + + True + 6 + True + + + _Add... + True + True + True + Select a keyboard layout to be added to the list + True + + + 0 + + + + + gtk-remove + True + True + True + Remove the selected keyboard layout from the list + True + + + 1 + + + + + 0 + + + + + True + 6 + True + + + Move _Up + True + True + True + Move the selected keyboard layout up in the list + True + + + 0 + + + + + Move _Down + True + True + True + Move the selected keyboard layout down in the list + True + + + 1 + + + + + 1 + + + + + True + 6 + True + + + _Show... + True + True + True + Print a diagram of the selected keyboard layout + True + + + 0 + + + + + True + + + 1 + + + + + 2 + + + + + False + False + 1 + + + + + _Separate layout for each window + True + True + False + True + True + + + False + False + 2 + + + + + New windows u_se active window's layout + True + True + False + True + True + + + False + False + 3 + + + + + 0 + + + + + True + 12 + + + True + 0 + Keyboard _model: + True + xkb_model_pick + + + False + False + 0 + + + + + True + True + False + True + + + 1 + + + + + False + False + 1 + + + + + True + 6 + end + + + _Options... + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + View and edit keyboard layout options + True + + + False + False + 0 + + + + + Reset to De_faults + True + True + True + Replace the current keyboard layout settings with the +default settings + True + + + False + False + end + 1 + + + + + False + False + 2 + + + + + 1 + + + + + True + Layouts + + + 1 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + 18 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + _Accessibility features can be toggled with keyboard shortcuts + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + False + 0 + + + + + 1 + + + + + 1 + + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Sticky Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + _Simulate simultaneous keypresses + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + Disa_ble sticky keys if two keys are pressed together + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 1 + + + + + 1 + + + + + 1 + + + + + False + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Slow Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + _Only accept long keypresses + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + False + 0 + + + + + True + 12 + + + True + 0 + _Delay: + True + center + slowkeys_delay_slide + + + False + False + 0 + + + + + True + 6 + + + True + 1 + 10 + Short + + + + + + + False + False + 0 + + + + + True + True + discontinuous + adjustment4 + False + + + Cursor blinks speed + + + + + 1 + + + + + True + 0 + Long + + + + + + + False + False + 2 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + False + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Bounce Keys + + + + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + _Ignore fast duplicate keypresses + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + True + 12 + + + True + 0 + D_elay: + True + center + bouncekeys_delay_slide + + + False + False + 0 + + + + + True + 6 + + + True + 1 + 10 + Short + + + + + + + False + False + 0 + + + + + True + True + discontinuous + adjustment5 + False + + + Cursor blinks speed + + + + + 1 + + + + + True + 0 + Long + + + + + + + False + False + 2 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + False + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + end + + + Audio _Feedback... + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + False + False + 0 + + + + + False + 4 + + + + + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Accessibility + + + 2 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + _Pointer can be controlled using the keypad + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + False + 0 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + 3 + 4 + 12 + 6 + + + True + 1 + Slow + center + + + + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + 1 + Slow + center + + + + + + + 1 + 2 + GTK_FILL + + + + + + True + True + discontinuous + adjustment6 + False + right + + + 2 + 3 + GTK_FILL + + + + + True + True + discontinuous + adjustment7 + 0 + False + + + 2 + 3 + 1 + 2 + GTK_FILL + + + + + True + 0 + Fast + center + + + + + + + 3 + 4 + 1 + 2 + GTK_FILL + + + + + + True + 0 + Fast + center + + + + + + + 3 + 4 + GTK_FILL + + + + + + True + 0 + _Speed: + True + center + mousekeys_max_speed_slide + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + 0 + _Acceleration: + True + center + mousekeys_accel_time_slide + + + GTK_FILL + GTK_FILL + + + + + True + 0 + _Delay: + True + center + mousekeys_init_delay_slide + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + 1 + Short + center + + + + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + True + discontinuous + adjustment8 + 0 + False + + + 2 + 3 + 2 + 3 + GTK_FILL + + + + + True + 0 + Long + center + + + + + + + 3 + 4 + 2 + 3 + GTK_FILL + + + + + + 0 + + + + + 1 + + + + + 1 + + + + + False + 0 + + + + + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Mouse Keys + + + 3 + False + + + + + True + 12 + + + True + 12 + 18 + + + True + 6 + + + _Lock screen to enforce typing break + True + True + False + Lock screen after a certain duration to help prevent repetitive keyboard use injuries + True + True + + + False + False + 0 + + + + + True + + + True + + + + False + False + 0 + + + + + True + 6 + + + True + 12 + + + True + 6 + + + True + 0 + _Work interval lasts: + True + break_enabled_spin + + + 0 + + + + + True + 0 + _Break interval lasts: + True + break_interval_spin + + + 1 + + + + + False + False + 0 + + + + + True + 6 + + + True + 6 + + + True + True + Duration of work before forcing a break + adjustment9 + 1 + + + 0 + + + + + True + True + Duration of the break when typing is disallowed + adjustment10 + 1 + + + 1 + + + + + 0 + + + + + True + 6 + + + True + 0 + minutes + + + 0 + + + + + True + 0 + minutes + + + 1 + + + + + 1 + + + + + False + False + 1 + + + + + 0 + + + + + All_ow postponing of breaks + True + True + False + Check if breaks are allowed to be postponed + True + True + + + False + False + 1 + + + + + 1 + + + + + False + False + 1 + + + + + 0 + + + + + 0 + + + + + 4 + + + + + True + Typing Break + + + 4 + False + + + + + 0 + + + + + True + 12 + + + True + _Type to test settings: + True + test_entry + + + False + False + 0 + + + + + True + True + 256 + + + 1 + + + + + False + 1 + + + + + 1 + + + + + True + end + + + gtk-help + True + True + True + False + True + + + False + False + 0 + + + + + gtk-close + True + True + True + True + True + False + True + + + False + False + 1 + + + + + False + end + 0 + + + + + + helpbutton1 + button4 + + + diff --git a/capplets/keyboard/mate-keyboard-properties-layout-chooser.ui b/capplets/keyboard/mate-keyboard-properties-layout-chooser.ui new file mode 100644 index 00000000..2beb56d0 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-layout-chooser.ui @@ -0,0 +1,315 @@ + + + + + + True + 5 + Choose a Layout + 670 + 350 + dialog + False + + + True + vertical + 2 + + + True + 5 + vertical + 6 + + + True + True + + + True + 3 + 3 + 3 + 6 + + + True + 2 + 2 + 12 + 6 + + + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + _Variants: + True + xkb_country_variants_available + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + _Country: + True + xkb_countries_available + + + GTK_FILL + + + + + + + + + + True + By _country + True + + + False + + + + + True + 3 + 3 + 3 + 3 + + + True + 2 + 2 + 12 + 6 + + + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + _Variants: + True + xkb_country_variants_available + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + _Language: + True + xkb_countries_available + + + GTK_FILL + + + + + + + + 1 + + + + + True + By _language + True + + + 1 + False + + + + + False + False + 0 + + + + + True + vertical + 6 + + + True + 6 + + + True + 0 + Preview: + + + False + False + 0 + + + + + False + False + 0 + + + + + True + 0 + in + + + + + + 1 + + + + + 1 + + + + + 1 + + + + + True + end + + + gtk-print + True + True + True + False + True + + + False + False + 0 + True + + + + + gtk-cancel + True + True + True + False + True + + + False + False + 1 + + + + + gtk-add + True + True + True + False + True + + + False + False + 2 + + + + + False + end + 0 + + + + + + btnPrint + cancelbutton2 + btnOk1 + + + diff --git a/capplets/keyboard/mate-keyboard-properties-model-chooser.ui b/capplets/keyboard/mate-keyboard-properties-model-chooser.ui new file mode 100644 index 00000000..3fe7d4e1 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-model-chooser.ui @@ -0,0 +1,142 @@ + + + + + + True + 5 + Choose a Keyboard Model + True + 450 + 400 + dialog + False + + + True + vertical + 2 + + + True + 5 + vertical + 6 + + + True + 0 + _Vendors: + True + + + False + False + 0 + + + + + True + True + automatic + automatic + in + + + True + True + False + + + + + 1 + + + + + True + 0 + _Models: + True + + + False + False + 2 + + + + + True + True + automatic + automatic + in + + + True + True + False + + + + + 3 + + + + + 1 + + + + + True + end + + + gtk-cancel + True + True + True + False + True + + + False + False + 0 + + + + + gtk-ok + True + True + True + False + True + + + False + False + 1 + + + + + False + end + 0 + + + + + + cancelbutton1 + btnOk + + + diff --git a/capplets/keyboard/mate-keyboard-properties-options-dialog.ui b/capplets/keyboard/mate-keyboard-properties-options-dialog.ui new file mode 100644 index 00000000..f92c4cd2 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-options-dialog.ui @@ -0,0 +1,94 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Keyboard Layout Options + center-on-parent + 550 + 400 + dialog + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical + 2 + + + True + True + 5 + automatic + automatic + out + + + True + none + + + True + vertical + + + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + end + + + gtk-help + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + False + False + 0 + + + + + gtk-close + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + False + False + 1 + + + + + False + end + 0 + + + + + + button3 + button2 + + + diff --git a/capplets/keyboard/mate-keyboard-properties-xkb.c b/capplets/keyboard/mate-keyboard-properties-xkb.c new file mode 100644 index 00000000..3316b4d4 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkb.c @@ -0,0 +1,254 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkb.c + * Copyright (C) 2003-2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "capplet-util.h" +#include "mateconf-property-editor.h" + +#include "mate-keyboard-properties-xkb.h" + +#include + +XklEngine *engine; +XklConfigRegistry *config_registry; + +MatekbdKeyboardConfig initial_config; +MatekbdDesktopConfig desktop_config; + +MateConfClient *xkb_mateconf_client; + +char * +xci_desc_to_utf8 (XklConfigItem * ci) +{ + char *sd = g_strstrip (ci->description); + return sd[0] == 0 ? g_strdup (ci->name) : g_strdup (sd); +} + +static void +set_model_text (GtkWidget * picker, MateConfValue * value) +{ + XklConfigItem *ci = xkl_config_item_new (); + const char *model = NULL; + + if (value != NULL && value->type == MATECONF_VALUE_STRING) { + model = mateconf_value_get_string (value); + if (model != NULL && model[0] == '\0') + model = NULL; + } + + if (model == NULL) { + model = initial_config.model; + if (model == NULL) + model = ""; + } + + g_snprintf (ci->name, sizeof (ci->name), "%s", model); + + if (xkl_config_registry_find_model (config_registry, ci)) { + char *d; + + d = xci_desc_to_utf8 (ci); + gtk_button_set_label (GTK_BUTTON (picker), d); + g_free (d); + } else { + gtk_button_set_label (GTK_BUTTON (picker), _("Unknown")); + } + g_object_unref (G_OBJECT (ci)); +} + +static void +model_key_changed (MateConfClient * client, + guint cnxn_id, MateConfEntry * entry, GtkBuilder * dialog) +{ + set_model_text (WID ("xkb_model_pick"), + mateconf_entry_get_value (entry)); + + enable_disable_restoring (dialog); +} + +static void +setup_model_entry (GtkBuilder * dialog) +{ + MateConfValue *value; + + value = mateconf_client_get (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_MODEL, NULL); + set_model_text (WID ("xkb_model_pick"), value); + if (value != NULL) + mateconf_value_free (value); + + mateconf_client_notify_add (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_MODEL, + (MateConfClientNotifyFunc) model_key_changed, + dialog, NULL, NULL); +} + +static void +cleanup_xkb_tabs (GtkBuilder * dialog) +{ + matekbd_desktop_config_term (&desktop_config); + matekbd_keyboard_config_term (&initial_config); + g_object_unref (G_OBJECT (config_registry)); + config_registry = NULL; + g_object_unref (G_OBJECT (engine)); + engine = NULL; + g_object_unref (G_OBJECT (xkb_mateconf_client)); + xkb_mateconf_client = NULL; +} + +static void +reset_to_defaults (GtkWidget * button, GtkBuilder * dialog) +{ + MatekbdKeyboardConfig empty_kbd_config; + + matekbd_keyboard_config_init (&empty_kbd_config, xkb_mateconf_client, + engine); + matekbd_keyboard_config_save_to_mateconf (&empty_kbd_config); + matekbd_keyboard_config_term (&empty_kbd_config); + + mateconf_client_unset (xkb_mateconf_client, + MATEKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, NULL); + + /* all the rest is g-s-d's business */ +} + +static void +chk_separate_group_per_window_toggled (MateConfPropertyEditor * peditor, + const gchar * key, + const MateConfValue * value, + GtkBuilder * dialog) +{ + gtk_widget_set_sensitive (WID ("chk_new_windows_inherit_layout"), + mateconf_value_get_bool (value)); +} + +static void +chk_new_windows_inherit_layout_toggled (GtkWidget * + chk_new_windows_inherit_layout, + GtkBuilder * dialog) +{ + xkb_save_default_group (gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON + (chk_new_windows_inherit_layout)) ? -1 : + 0); +} + +void +setup_xkb_tabs (GtkBuilder * dialog, MateConfChangeSet * changeset) +{ + GObject *peditor; + GtkWidget *chk_new_windows_inherit_layout = + WID ("chk_new_windows_inherit_layout"); + + xkb_mateconf_client = mateconf_client_get_default (); + + engine = xkl_engine_get_instance (GDK_DISPLAY ()); + config_registry = xkl_config_registry_get_instance (engine); + + matekbd_desktop_config_init (&desktop_config, xkb_mateconf_client, + engine); + matekbd_desktop_config_load_from_mateconf (&desktop_config); + + xkl_config_registry_load (config_registry, + desktop_config.load_extra_items); + + matekbd_keyboard_config_init (&initial_config, xkb_mateconf_client, + engine); + matekbd_keyboard_config_load_from_x_initial (&initial_config, NULL); + + setup_model_entry (dialog); + + peditor = mateconf_peditor_new_boolean + (changeset, (gchar *) MATEKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, + WID ("chk_separate_group_per_window"), NULL); + + g_signal_connect (peditor, "value-changed", (GCallback) + chk_separate_group_per_window_toggled, dialog); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (strcmp (xkl_engine_get_backend_name (engine), "XKB")) +#endif + gtk_widget_hide (WID ("xkb_layouts_print")); + + xkb_layouts_prepare_selected_tree (dialog, changeset); + xkb_layouts_fill_selected_tree (dialog); + + gtk_widget_set_sensitive (chk_new_windows_inherit_layout, + gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON + (WID + ("chk_separate_group_per_window")))); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON + (chk_new_windows_inherit_layout), + xkb_get_default_group () < 0); + + xkb_layouts_register_buttons_handlers (dialog); + g_signal_connect (G_OBJECT (WID ("xkb_reset_to_defaults")), + "clicked", G_CALLBACK (reset_to_defaults), + dialog); + + g_signal_connect (G_OBJECT (chk_new_windows_inherit_layout), + "toggled", (GCallback) + chk_new_windows_inherit_layout_toggled, dialog); + + g_signal_connect_swapped (G_OBJECT (WID ("xkb_layout_options")), + "clicked", + G_CALLBACK (xkb_options_popup_dialog), + dialog); + + g_signal_connect_swapped (G_OBJECT (WID ("xkb_model_pick")), + "clicked", G_CALLBACK (choose_model), + dialog); + + xkb_layouts_register_mateconf_listener (dialog); + xkb_options_register_mateconf_listener (dialog); + + g_signal_connect (G_OBJECT (WID ("keyboard_dialog")), + "destroy", G_CALLBACK (cleanup_xkb_tabs), + dialog); + + enable_disable_restoring (dialog); +} + +void +enable_disable_restoring (GtkBuilder * dialog) +{ + MatekbdKeyboardConfig gswic; + gboolean enable; + + matekbd_keyboard_config_init (&gswic, xkb_mateconf_client, engine); + matekbd_keyboard_config_load_from_mateconf (&gswic, NULL); + + enable = !matekbd_keyboard_config_equals (&gswic, &initial_config); + + matekbd_keyboard_config_term (&gswic); + gtk_widget_set_sensitive (WID ("xkb_reset_to_defaults"), enable); +} diff --git a/capplets/keyboard/mate-keyboard-properties-xkb.h b/capplets/keyboard/mate-keyboard-properties-xkb.h new file mode 100644 index 00000000..19b673ba --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkb.h @@ -0,0 +1,104 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkb.h + * Copyright (C) 2003-2007 Sergey V Udaltsov + * + * Written by Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __MATE_KEYBOARD_PROPERTY_XKB_H +#define __MATE_KEYBOARD_PROPERTY_XKB_H + +#include + +#include "libmatekbd/matekbd-keyboard-config.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define CWID(s) GTK_WIDGET (gtk_builder_get_object (chooser_dialog, s)) +extern XklEngine *engine; +extern XklConfigRegistry *config_registry; +extern MateConfClient *xkb_mateconf_client; +extern MatekbdKeyboardConfig initial_config; + +extern void setup_xkb_tabs (GtkBuilder * dialog, + MateConfChangeSet * changeset); + +extern void xkb_layouts_fill_selected_tree (GtkBuilder * dialog); + +extern void xkb_layouts_register_buttons_handlers (GtkBuilder * dialog); + +extern void xkb_layouts_register_mateconf_listener (GtkBuilder * dialog); + +extern void xkb_options_register_mateconf_listener (GtkBuilder * dialog); + +extern void xkb_layouts_prepare_selected_tree (GtkBuilder * dialog, + MateConfChangeSet * changeset); + +extern void xkb_options_load_options (GtkBuilder * dialog); + +extern void xkb_options_popup_dialog (GtkBuilder * dialog); + +extern void clear_xkb_elements_list (GSList * list); + +extern char *xci_desc_to_utf8 (XklConfigItem * ci); + +extern gchar *xkb_layout_description_utf8 (const gchar * visible); + +extern void enable_disable_restoring (GtkBuilder * dialog); + +extern void preview_toggled (GtkBuilder * dialog, GtkWidget * button); + +extern void choose_model (GtkBuilder * dialog); + +extern void xkb_layout_choose (GtkBuilder * dialog); + +extern GSList *xkb_layouts_get_selected_list (void); + +extern GSList *xkb_options_get_selected_list (void); + +#define xkb_layouts_set_selected_list(list) \ + mateconf_client_set_list (mateconf_client_get_default (), \ + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, \ + MATECONF_VALUE_STRING, (list), NULL) + +#define xkb_options_set_selected_list(list) \ + mateconf_client_set_list (mateconf_client_get_default (), \ + MATEKBD_KEYBOARD_CONFIG_KEY_OPTIONS, \ + MATECONF_VALUE_STRING, (list), NULL) + +extern GtkWidget *xkb_layout_preview_create_widget (GtkBuilder * + chooser_dialog); + +extern void xkb_layout_preview_update (GtkBuilder * chooser_dialog); + +extern void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, + const gchar * id); + +extern gchar *xkb_layout_chooser_get_selected_id (GtkBuilder * + chooser_dialog); + +extern void xkb_save_default_group (gint group_no); + +extern gint xkb_get_default_group (void); + +#ifdef __cplusplus +} +#endif +#endif /* __MATE_KEYBOARD_PROPERTY_XKB_H */ diff --git a/capplets/keyboard/mate-keyboard-properties-xkblt.c b/capplets/keyboard/mate-keyboard-properties-xkblt.c new file mode 100644 index 00000000..41132647 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkblt.c @@ -0,0 +1,475 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkblt.c + * Copyright (C) 2003-2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include + +#include "capplet-util.h" +#include "mate-keyboard-properties-xkb.h" + + +#define SEL_LAYOUT_TREE_COL_DESCRIPTION 0 +#define SEL_LAYOUT_TREE_COL_ID 1 +#define SEL_LAYOUT_TREE_COL_ENABLED 2 + +static int idx2select = -1; +static int max_selected_layouts = -1; +static int default_group = -1; + +static GtkCellRenderer *text_renderer; + +static gboolean disable_buttons_sensibility_update = FALSE; + +void +clear_xkb_elements_list (GSList * list) +{ + while (list != NULL) { + GSList *p = list; + list = list->next; + g_free (p->data); + g_slist_free_1 (p); + } +} + +static gint +find_selected_layout_idx (GtkBuilder * dialog) +{ + GtkTreeSelection *selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW + (WID ("xkb_layouts_selected"))); + GtkTreeIter selected_iter; + GtkTreeModel *model; + GtkTreePath *path; + gint *indices; + gint rv; + + if (!gtk_tree_selection_get_selected + (selection, &model, &selected_iter)) + return -1; + + path = gtk_tree_model_get_path (model, &selected_iter); + if (path == NULL) + return -1; + + indices = gtk_tree_path_get_indices (path); + rv = indices[0]; + gtk_tree_path_free (path); + return rv; +} + +GSList * +xkb_layouts_get_selected_list (void) +{ + GSList *retval; + + retval = mateconf_client_get_list (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATECONF_VALUE_STRING, NULL); + if (retval == NULL) { + GSList *cur_layout; + + for (cur_layout = initial_config.layouts_variants; + cur_layout != NULL; cur_layout = cur_layout->next) + retval = + g_slist_prepend (retval, + g_strdup (cur_layout->data)); + + retval = g_slist_reverse (retval); + } + + return retval; +} + +gint +xkb_get_default_group () +{ + return mateconf_client_get_int (xkb_mateconf_client, + MATEKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, + NULL); +} + +void +xkb_save_default_group (gint default_group) +{ + if (default_group != xkb_get_default_group ()) + mateconf_client_set_int (xkb_mateconf_client, + MATEKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, + default_group, NULL); +} + +static void +xkb_layouts_enable_disable_buttons (GtkBuilder * dialog) +{ + GtkWidget *add_layout_btn = WID ("xkb_layouts_add"); + GtkWidget *show_layout_btn = WID ("xkb_layouts_show"); + GtkWidget *del_layout_btn = WID ("xkb_layouts_remove"); + GtkWidget *selected_layouts_tree = WID ("xkb_layouts_selected"); + GtkWidget *move_up_layout_btn = WID ("xkb_layouts_move_up"); + GtkWidget *move_down_layout_btn = WID ("xkb_layouts_move_down"); + + GtkTreeSelection *s_selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW + (selected_layouts_tree)); + const int n_selected_selected_layouts = + gtk_tree_selection_count_selected_rows (s_selection); + GtkTreeModel *selected_layouts_model = gtk_tree_view_get_model + (GTK_TREE_VIEW (selected_layouts_tree)); + const int n_selected_layouts = + gtk_tree_model_iter_n_children (selected_layouts_model, + NULL); + gint sidx = find_selected_layout_idx (dialog); + + if (disable_buttons_sensibility_update) + return; + + gtk_widget_set_sensitive (add_layout_btn, + (n_selected_layouts < + max_selected_layouts + || max_selected_layouts == 0)); + gtk_widget_set_sensitive (del_layout_btn, (n_selected_layouts > 1) + && (n_selected_selected_layouts > 0)); + gtk_widget_set_sensitive (show_layout_btn, + (n_selected_selected_layouts > 0)); + gtk_widget_set_sensitive (move_up_layout_btn, sidx > 0); + gtk_widget_set_sensitive (move_down_layout_btn, sidx >= 0 + && sidx < (n_selected_layouts - 1)); +} + +static void +xkb_layouts_dnd_data_get (GtkWidget * widget, GdkDragContext * dc, + GtkSelectionData * selection_data, guint info, + guint t, GtkBuilder * dialog) +{ + /* Storing the value into selection - + * while it is actually not used + */ + gint idx = find_selected_layout_idx (dialog); + gtk_selection_data_set (selection_data, + GDK_SELECTION_TYPE_INTEGER, 32, + (guchar *) & idx, sizeof (idx)); +} + +static void +xkb_layouts_dnd_data_received (GtkWidget * widget, GdkDragContext * dc, + gint x, gint y, + GtkSelectionData * selection_data, + guint info, guint t, GtkBuilder * dialog) +{ + gint sidx = find_selected_layout_idx (dialog); + GtkWidget *tree_view = WID ("xkb_layouts_selected"); + GtkTreePath *path = NULL; + GtkTreeViewDropPosition pos; + gint didx; + gchar *id; + GSList *layouts_list; + GSList *node2Remove; + + if (sidx == -1) + return; + + layouts_list = xkb_layouts_get_selected_list (); + node2Remove = g_slist_nth (layouts_list, sidx); + + id = (gchar *) node2Remove->data; + layouts_list = g_slist_delete_link (layouts_list, node2Remove); + + if (!gtk_tree_view_get_dest_row_at_pos + (GTK_TREE_VIEW (tree_view), x, y, &path, &pos)) { + /* Move to the very end */ + layouts_list = + g_slist_append (layouts_list, g_strdup (id)); + xkb_layouts_set_selected_list (layouts_list); + } else if (path != NULL) { + gint *indices = gtk_tree_path_get_indices (path); + didx = indices[0]; + gtk_tree_path_free (path); + /* Move to the new position */ + if (sidx != didx) { + layouts_list = + g_slist_insert (layouts_list, g_strdup (id), + didx); + xkb_layouts_set_selected_list (layouts_list); + } + } + g_free (id); + clear_xkb_elements_list (layouts_list); +} + +void +xkb_layouts_prepare_selected_tree (GtkBuilder * dialog, + MateConfChangeSet * changeset) +{ + GtkListStore *list_store = + gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_BOOLEAN); + GtkWidget *tree_view = WID ("xkb_layouts_selected"); + GtkTreeSelection *selection; + GtkTargetEntry self_drag_target = + { "xkb_layouts_selected", GTK_TARGET_SAME_WIDGET, 0 }; + GtkTreeViewColumn *desc_column; + + text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); + + desc_column = + gtk_tree_view_column_new_with_attributes (_("Layout"), + text_renderer, + "text", + SEL_LAYOUT_TREE_COL_DESCRIPTION, + "sensitive", + SEL_LAYOUT_TREE_COL_ENABLED, + NULL); + selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + + gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), + GTK_TREE_MODEL (list_store)); + + gtk_tree_view_column_set_sizing (desc_column, + GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_resizable (desc_column, TRUE); + gtk_tree_view_column_set_expand (desc_column, TRUE); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), + desc_column); + + g_signal_connect_swapped (G_OBJECT (selection), "changed", + G_CALLBACK + (xkb_layouts_enable_disable_buttons), + dialog); + max_selected_layouts = xkl_engine_get_max_num_groups (engine); + + /* Setting up DnD */ + gtk_drag_source_set (tree_view, GDK_BUTTON1_MASK, + &self_drag_target, 1, GDK_ACTION_MOVE); + gtk_drag_source_set_icon_name (tree_view, "input-keyboard"); + gtk_drag_dest_set (tree_view, GTK_DEST_DEFAULT_ALL, + &self_drag_target, 1, GDK_ACTION_MOVE); + + g_signal_connect (G_OBJECT (tree_view), "drag_data_get", + G_CALLBACK (xkb_layouts_dnd_data_get), dialog); + g_signal_connect (G_OBJECT (tree_view), "drag_data_received", + G_CALLBACK (xkb_layouts_dnd_data_received), + dialog); +} + +gchar * +xkb_layout_description_utf8 (const gchar * visible) +{ + char *l, *sl, *v, *sv; + if (matekbd_keyboard_config_get_descriptions + (config_registry, visible, &sl, &l, &sv, &v)) + visible = matekbd_keyboard_config_format_full_layout (l, v); + return g_strstrip (g_strdup (visible)); +} + +void +xkb_layouts_fill_selected_tree (GtkBuilder * dialog) +{ + GSList *layouts = xkb_layouts_get_selected_list (); + GSList *cur_layout; + GtkListStore *list_store = + GTK_LIST_STORE (gtk_tree_view_get_model + (GTK_TREE_VIEW + (WID ("xkb_layouts_selected")))); + int counter = 0; + + /* temporarily disable the buttons' status update */ + disable_buttons_sensibility_update = TRUE; + + gtk_list_store_clear (list_store); + + for (cur_layout = layouts; cur_layout != NULL; + cur_layout = cur_layout->next, counter++) { + GtkTreeIter iter; + const char *visible = (char *) cur_layout->data; + gchar *utf_visible = xkb_layout_description_utf8 (visible); + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + SEL_LAYOUT_TREE_COL_DESCRIPTION, + utf_visible, + SEL_LAYOUT_TREE_COL_ID, + cur_layout->data, + SEL_LAYOUT_TREE_COL_ENABLED, + counter < max_selected_layouts, -1); + g_free (utf_visible); + } + + clear_xkb_elements_list (layouts); + + /* enable the buttons' status update */ + disable_buttons_sensibility_update = FALSE; + + if (idx2select != -1) { + GtkTreeSelection *selection = + gtk_tree_view_get_selection ((GTK_TREE_VIEW + (WID + ("xkb_layouts_selected")))); + GtkTreePath *path = + gtk_tree_path_new_from_indices (idx2select, -1); + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); + idx2select = -1; + } else { + /* if there is nothing to select - just enable/disable the buttons, + otherwise it would be done by the selection change */ + xkb_layouts_enable_disable_buttons (dialog); + } +} + +static void +add_selected_layout (GtkWidget * button, GtkBuilder * dialog) +{ + xkb_layout_choose (dialog); +} + +static void +show_selected_layout (GtkWidget * button, GtkBuilder * dialog) +{ + gint idx = find_selected_layout_idx (dialog); + + if (idx != -1) { + GSList *layouts_list = xkb_layouts_get_selected_list (); + const gchar *id = g_slist_nth_data (layouts_list, idx); + char *descr = xkb_layout_description_utf8 (id); + GtkWidget *parent = WID ("keyboard_dialog"); + GtkWidget *popup = matekbd_keyboard_drawing_new_dialog (idx, descr); + gtk_widget_set_parent (popup, parent); + clear_xkb_elements_list (layouts_list); + g_free (descr); + } +} + +static void +remove_selected_layout (GtkWidget * button, GtkBuilder * dialog) +{ + gint idx = find_selected_layout_idx (dialog); + + if (idx != -1) { + GSList *layouts_list = xkb_layouts_get_selected_list (); + char *id = NULL; + GSList *node2Remove = g_slist_nth (layouts_list, idx); + + layouts_list = + g_slist_remove_link (layouts_list, node2Remove); + + id = (char *) node2Remove->data; + g_slist_free_1 (node2Remove); + g_free (id); + + if (default_group > idx) + xkb_save_default_group (default_group - 1); + else if (default_group == idx) + xkb_save_default_group (-1); + + xkb_layouts_set_selected_list (layouts_list); + clear_xkb_elements_list (layouts_list); + } +} + +static void +move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog) +{ + gint idx = find_selected_layout_idx (dialog); + + if (idx != -1) { + GSList *layouts_list = xkb_layouts_get_selected_list (); + GSList *node2Remove = g_slist_nth (layouts_list, idx); + + layouts_list = + g_slist_remove_link (layouts_list, node2Remove); + layouts_list = + g_slist_insert (layouts_list, node2Remove->data, + idx - 1); + g_slist_free_1 (node2Remove); + + idx2select = idx - 1; + xkb_layouts_set_selected_list (layouts_list); + clear_xkb_elements_list (layouts_list); + } +} + +static void +move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog) +{ + gint idx = find_selected_layout_idx (dialog); + + if (idx != -1) { + GSList *layouts_list = xkb_layouts_get_selected_list (); + GSList *node2Remove = g_slist_nth (layouts_list, idx); + + layouts_list = + g_slist_remove_link (layouts_list, node2Remove); + layouts_list = + g_slist_insert (layouts_list, node2Remove->data, + idx + 1); + g_slist_free_1 (node2Remove); + + idx2select = idx + 1; + xkb_layouts_set_selected_list (layouts_list); + clear_xkb_elements_list (layouts_list); + } +} + +void +xkb_layouts_register_buttons_handlers (GtkBuilder * dialog) +{ + g_signal_connect (G_OBJECT (WID ("xkb_layouts_add")), "clicked", + G_CALLBACK (add_selected_layout), dialog); + g_signal_connect (G_OBJECT (WID ("xkb_layouts_show")), "clicked", + G_CALLBACK (show_selected_layout), dialog); + g_signal_connect (G_OBJECT (WID ("xkb_layouts_remove")), "clicked", + G_CALLBACK (remove_selected_layout), dialog); + g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_up")), + "clicked", G_CALLBACK (move_up_selected_layout), + dialog); + g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_down")), + "clicked", + G_CALLBACK (move_down_selected_layout), dialog); +} + +static void +xkb_layouts_update_list (MateConfClient * client, + guint cnxn_id, MateConfEntry * entry, + GtkBuilder * dialog) +{ + xkb_layouts_fill_selected_tree (dialog); + enable_disable_restoring (dialog); +} + +void +xkb_layouts_register_mateconf_listener (GtkBuilder * dialog) +{ + mateconf_client_notify_add (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + (MateConfClientNotifyFunc) + xkb_layouts_update_list, dialog, NULL, + NULL); +} diff --git a/capplets/keyboard/mate-keyboard-properties-xkbltadd.c b/capplets/keyboard/mate-keyboard-properties-xkbltadd.c new file mode 100644 index 00000000..e73e59cc --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkbltadd.c @@ -0,0 +1,561 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkbltadd.c + * Copyright (C) 2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + +#include "capplet-util.h" +#include "mate-keyboard-properties-xkb.h" + +enum { + COMBO_BOX_MODEL_COL_SORT, + COMBO_BOX_MODEL_COL_VISIBLE, + COMBO_BOX_MODEL_COL_XKB_ID, + COMBO_BOX_MODEL_COL_REAL_ID +}; + +typedef void (*LayoutIterFunc) (XklConfigRegistry * config, + ConfigItemProcessFunc func, gpointer data); + +typedef struct { + GtkListStore *list_store; + const gchar *lang_id; +} AddVariantData; + +static void + + + + + + + + + +xkb_layout_chooser_available_layouts_fill (GtkBuilder * chooser_dialog, + const gchar cblid[], + const gchar cbvid[], + LayoutIterFunc layout_iterator, + ConfigItemProcessFunc + layout_handler, + GCallback combo_changed_notify); + +static void + + + + + + + + + +xkb_layout_chooser_available_language_variants_fill (GtkBuilder * + chooser_dialog); + +static void + + + + + + + + + +xkb_layout_chooser_available_country_variants_fill (GtkBuilder * + chooser_dialog); + +static void + xkb_layout_chooser_add_variant_to_available_country_variants + (XklConfigRegistry * config_registry, + XklConfigItem * parent_config_item, XklConfigItem * config_item, + AddVariantData * data) { + gchar *utf_variant_name = config_item ? + xkb_layout_description_utf8 (matekbd_keyboard_config_merge_items + (parent_config_item->name, + config_item->name)) : + xci_desc_to_utf8 (parent_config_item); + GtkTreeIter iter; + const gchar *xkb_id = + config_item ? + matekbd_keyboard_config_merge_items (parent_config_item->name, + config_item->name) : + parent_config_item->name; + + if (config_item && g_object_get_data + (G_OBJECT (config_item), XCI_PROP_EXTRA_ITEM)) { + gchar *buf = + g_strdup_printf ("%s", utf_variant_name); + gtk_list_store_insert_with_values (data->list_store, &iter, + -1, + COMBO_BOX_MODEL_COL_SORT, + utf_variant_name, + COMBO_BOX_MODEL_COL_VISIBLE, + buf, + COMBO_BOX_MODEL_COL_XKB_ID, + xkb_id, -1); + g_free (buf); + } else + gtk_list_store_insert_with_values (data->list_store, &iter, + -1, + COMBO_BOX_MODEL_COL_SORT, + utf_variant_name, + COMBO_BOX_MODEL_COL_VISIBLE, + utf_variant_name, + COMBO_BOX_MODEL_COL_XKB_ID, + xkb_id, -1); + g_free (utf_variant_name); +} + +static void + xkb_layout_chooser_add_variant_to_available_language_variants + (XklConfigRegistry * config_registry, + XklConfigItem * parent_config_item, XklConfigItem * config_item, + AddVariantData * data) { + xkb_layout_chooser_add_variant_to_available_country_variants + (config_registry, parent_config_item, config_item, data); +} + +static void +xkb_layout_chooser_add_language_to_available_languages (XklConfigRegistry * + config_registry, + XklConfigItem * + config_item, + GtkListStore * + list_store) +{ + gtk_list_store_insert_with_values (list_store, NULL, -1, + COMBO_BOX_MODEL_COL_SORT, + config_item->description, + COMBO_BOX_MODEL_COL_VISIBLE, + config_item->description, + COMBO_BOX_MODEL_COL_REAL_ID, + config_item->name, -1); +} + +static void +xkb_layout_chooser_add_country_to_available_countries (XklConfigRegistry * + config_registry, + XklConfigItem * + config_item, + GtkListStore * + list_store) +{ + gtk_list_store_insert_with_values (list_store, NULL, -1, + COMBO_BOX_MODEL_COL_SORT, + config_item->description, + COMBO_BOX_MODEL_COL_VISIBLE, + config_item->description, + COMBO_BOX_MODEL_COL_REAL_ID, + config_item->name, -1); +} + +static void +xkb_layout_chooser_enable_disable_buttons (GtkBuilder * chooser_dialog) +{ + GtkWidget *cbv = + CWID (gtk_notebook_get_current_page + (GTK_NOTEBOOK (CWID ("choosers_nb"))) ? + "xkb_language_variants_available" : + "xkb_country_variants_available"); + GtkTreeIter viter; + gboolean enable_ok = + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv), + &viter); + + gtk_dialog_set_response_sensitive (GTK_DIALOG + (CWID + ("xkb_layout_chooser")), + GTK_RESPONSE_OK, enable_ok); + gtk_widget_set_sensitive (CWID ("btnPrint"), enable_ok); +} + +static void +xkb_layout_chooser_available_variant_changed (GtkBuilder * chooser_dialog) +{ + xkb_layout_preview_update (chooser_dialog); + xkb_layout_chooser_enable_disable_buttons (chooser_dialog); +} + +static void +xkb_layout_chooser_available_language_changed (GtkBuilder * chooser_dialog) +{ + xkb_layout_chooser_available_language_variants_fill + (chooser_dialog); + xkb_layout_chooser_available_variant_changed (chooser_dialog); +} + +static void +xkb_layout_chooser_available_country_changed (GtkBuilder * chooser_dialog) +{ + xkb_layout_chooser_available_country_variants_fill + (chooser_dialog); + xkb_layout_chooser_available_variant_changed (chooser_dialog); +} + +static void +xkb_layout_chooser_page_changed (GtkWidget * notebook, GtkWidget * page, + gint page_num, + GtkBuilder * chooser_dialog) +{ + xkb_layout_chooser_available_variant_changed (chooser_dialog); +} + +static void +xkb_layout_chooser_available_language_variants_fill (GtkBuilder * + chooser_dialog) +{ + GtkWidget *cbl = CWID ("xkb_languages_available"); + GtkWidget *cbv = CWID ("xkb_language_variants_available"); + GtkListStore *list_store; + GtkTreeIter liter; + + list_store = gtk_list_store_new + (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING); + + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbl), &liter)) { + GtkTreeModel *lm = + gtk_combo_box_get_model (GTK_COMBO_BOX (cbl)); + gchar *lang_id; + AddVariantData data = { list_store, 0 }; + + /* Now the variants of the selected layout */ + gtk_tree_model_get (lm, &liter, + COMBO_BOX_MODEL_COL_REAL_ID, + &lang_id, -1); + data.lang_id = lang_id; + + xkl_config_registry_foreach_language_variant + (config_registry, lang_id, (TwoConfigItemsProcessFunc) + xkb_layout_chooser_add_variant_to_available_language_variants, + &data); + g_free (lang_id); + } + + /* Turn on sorting after filling the store, since that's faster */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE + (list_store), + COMBO_BOX_MODEL_COL_SORT, + GTK_SORT_ASCENDING); + + gtk_combo_box_set_model (GTK_COMBO_BOX (cbv), + GTK_TREE_MODEL (list_store)); + gtk_combo_box_set_active (GTK_COMBO_BOX (cbv), 0); +} + +static void +xkb_layout_chooser_available_country_variants_fill (GtkBuilder * + chooser_dialog) +{ + GtkWidget *cbl = CWID ("xkb_countries_available"); + GtkWidget *cbv = CWID ("xkb_country_variants_available"); + GtkListStore *list_store; + GtkTreeIter liter; + + list_store = gtk_list_store_new + (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING); + + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbl), &liter)) { + GtkTreeModel *lm = + gtk_combo_box_get_model (GTK_COMBO_BOX (cbl)); + gchar *country_id; + AddVariantData data = { list_store, 0 }; + + /* Now the variants of the selected layout */ + gtk_tree_model_get (lm, &liter, + COMBO_BOX_MODEL_COL_REAL_ID, + &country_id, -1); + xkl_config_registry_foreach_country_variant + (config_registry, country_id, + (TwoConfigItemsProcessFunc) + xkb_layout_chooser_add_variant_to_available_country_variants, + &data); + g_free (country_id); + } + + /* Turn on sorting after filling the store, since that's faster */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE + (list_store), + COMBO_BOX_MODEL_COL_SORT, + GTK_SORT_ASCENDING); + + gtk_combo_box_set_model (GTK_COMBO_BOX (cbv), + GTK_TREE_MODEL (list_store)); + gtk_combo_box_set_active (GTK_COMBO_BOX (cbv), 0); +} + +static void +xkb_layout_chooser_available_layouts_fill (GtkBuilder * + chooser_dialog, + const gchar cblid[], + const gchar cbvid[], + LayoutIterFunc layout_iterator, + ConfigItemProcessFunc + layout_handler, + GCallback combo_changed_notify) +{ + GtkWidget *cbl = CWID (cblid); + GtkWidget *cbev = CWID (cbvid); + GtkCellRenderer *renderer; + GtkListStore *list_store; + + list_store = gtk_list_store_new + (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING); + + gtk_combo_box_set_model (GTK_COMBO_BOX (cbl), + GTK_TREE_MODEL (list_store)); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbl), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbl), + renderer, "markup", + COMBO_BOX_MODEL_COL_VISIBLE, NULL); + + layout_iterator (config_registry, layout_handler, list_store); + + /* Turn on sorting after filling the model since that's faster */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE + (list_store), + COMBO_BOX_MODEL_COL_SORT, + GTK_SORT_ASCENDING); + + g_signal_connect_swapped (G_OBJECT (cbl), "changed", + combo_changed_notify, chooser_dialog); + + /* Setup the variants combo */ + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbev), + renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbev), + renderer, "markup", + COMBO_BOX_MODEL_COL_VISIBLE, NULL); + + g_signal_connect_swapped (G_OBJECT (cbev), "changed", + G_CALLBACK + (xkb_layout_chooser_available_variant_changed), + chooser_dialog); +} + +void +xkl_layout_chooser_add_default_switcher_if_necessary (GSList * + layouts_list) +{ + GSList *options_list = xkb_options_get_selected_list (); + gboolean was_appended; + + options_list = + matekbd_keyboard_config_add_default_switch_option_if_necessary + (layouts_list, options_list, &was_appended); + if (was_appended) + xkb_options_set_selected_list (options_list); + clear_xkb_elements_list (options_list); +} + +static void +xkb_layout_chooser_print (GtkBuilder * chooser_dialog) +{ + GtkWidget *chooser = CWID ("xkb_layout_chooser"); + GtkWidget *kbdraw = + GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw")); + const char *id = + xkb_layout_chooser_get_selected_id (chooser_dialog); + char *descr = xkb_layout_description_utf8 (id); + matekbd_keyboard_drawing_print (MATEKBD_KEYBOARD_DRAWING + (kbdraw), + GTK_WINDOW (CWID + ("xkb_layout_chooser")), + descr); + g_free (descr); +} + +static void +xkb_layout_chooser_response (GtkDialog * dialog, + gint response, GtkBuilder * chooser_dialog) +{ + GdkRectangle rect; + + if (response == GTK_RESPONSE_OK) { + gchar *selected_id = (gchar *) + xkb_layout_chooser_get_selected_id (chooser_dialog); + + if (selected_id != NULL) { + GSList *layouts_list = + xkb_layouts_get_selected_list (); + + selected_id = g_strdup (selected_id); + + layouts_list = + g_slist_append (layouts_list, selected_id); + xkb_layouts_set_selected_list (layouts_list); + + xkl_layout_chooser_add_default_switcher_if_necessary + (layouts_list); + + clear_xkb_elements_list (layouts_list); + } + } else if (response == gtk_dialog_get_response_for_widget + (dialog, CWID ("btnPrint"))) { + xkb_layout_chooser_print (chooser_dialog); + g_signal_stop_emission_by_name (dialog, "response"); + return; + } + + gtk_window_get_position (GTK_WINDOW (dialog), &rect.x, &rect.y); + gtk_window_get_size (GTK_WINDOW (dialog), &rect.width, + &rect.height); + matekbd_preview_save_position (&rect); +} + +void +xkb_layout_choose (GtkBuilder * dialog) +{ + GtkBuilder *chooser_dialog; + + chooser_dialog = gtk_builder_new (); + gtk_builder_add_from_file (chooser_dialog, MATECC_UI_DIR + "/mate-keyboard-properties-layout-chooser.ui", + NULL); + GtkWidget *chooser = CWID ("xkb_layout_chooser"); + GtkWidget *lang_chooser = CWID ("xkb_languages_available"); + GtkWidget *notebook = CWID ("choosers_nb"); + GtkWidget *kbdraw = NULL; + GtkWidget *toplevel = NULL; + + gtk_window_set_transient_for (GTK_WINDOW (chooser), + GTK_WINDOW (WID + ("keyboard_dialog"))); + + xkb_layout_chooser_available_layouts_fill (chooser_dialog, + "xkb_countries_available", + "xkb_country_variants_available", + xkl_config_registry_foreach_country, + (ConfigItemProcessFunc) + xkb_layout_chooser_add_country_to_available_countries, + G_CALLBACK + (xkb_layout_chooser_available_country_changed)); + xkb_layout_chooser_available_layouts_fill (chooser_dialog, + "xkb_languages_available", + "xkb_language_variants_available", + xkl_config_registry_foreach_language, + (ConfigItemProcessFunc) + xkb_layout_chooser_add_language_to_available_languages, + G_CALLBACK + (xkb_layout_chooser_available_language_changed)); + + g_signal_connect_after (G_OBJECT (notebook), "switch_page", + G_CALLBACK + (xkb_layout_chooser_page_changed), + chooser_dialog); + + gtk_combo_box_set_active (GTK_COMBO_BOX + (CWID ("xkb_countries_available")), + FALSE); + + if (gtk_tree_model_iter_n_children + (gtk_combo_box_get_model (GTK_COMBO_BOX (lang_chooser)), + NULL)) { + gtk_combo_box_set_active (GTK_COMBO_BOX + (CWID + ("xkb_languages_available")), + FALSE); + } else { + /* If language info is not available - remove the corresponding tab, + pretend there is no notebook at all */ + gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), 1); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), + FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), + FALSE); + } + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (!strcmp (xkl_engine_get_backend_name (engine), "XKB")) { + kbdraw = xkb_layout_preview_create_widget (chooser_dialog); + g_object_set_data (G_OBJECT (chooser), "kbdraw", kbdraw); + gtk_container_add (GTK_CONTAINER + (CWID ("previewFrame")), kbdraw); + gtk_widget_show_all (kbdraw); + gtk_button_box_set_child_secondary (GTK_BUTTON_BOX + (CWID + ("hbtnBox")), + CWID + ("btnPrint"), TRUE); + } else +#endif + { + gtk_widget_hide_all (CWID ("vboxPreview")); + gtk_widget_hide (CWID ("btnPrint")); + } + + g_signal_connect (G_OBJECT (chooser), + "response", + G_CALLBACK (xkb_layout_chooser_response), + chooser_dialog); + + toplevel = gtk_widget_get_toplevel (chooser); + if (gtk_widget_is_toplevel (toplevel)) { + GdkRectangle *rect = matekbd_preview_load_position (); + if (rect != NULL) { + gtk_window_move (GTK_WINDOW (toplevel), + rect->x, rect->y); + gtk_window_resize (GTK_WINDOW (toplevel), + rect->width, rect->height); + g_free (rect); + } + } + + xkb_layout_preview_update (chooser_dialog); + gtk_dialog_run (GTK_DIALOG (chooser)); + gtk_widget_destroy (chooser); +} + +gchar * +xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog) +{ + GtkWidget *cbv = + CWID (gtk_notebook_get_current_page + (GTK_NOTEBOOK (CWID ("choosers_nb"))) ? + "xkb_language_variants_available" : + "xkb_country_variants_available"); + GtkTreeModel *vm = gtk_combo_box_get_model (GTK_COMBO_BOX (cbv)); + GtkTreeIter viter; + gchar *v_id; + + if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv), &viter)) + return NULL; + + gtk_tree_model_get (vm, &viter, + COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1); + + return v_id; +} diff --git a/capplets/keyboard/mate-keyboard-properties-xkbmc.c b/capplets/keyboard/mate-keyboard-properties-xkbmc.c new file mode 100644 index 00000000..b09068d7 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkbmc.c @@ -0,0 +1,347 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkbmc.c + * Copyright (C) 2003-2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "capplet-util.h" + +#include "mate-keyboard-properties-xkb.h" + +static gchar *current_model_name = NULL; +static gchar *current_vendor_name = NULL; + +static void fill_models_list (GtkBuilder * chooser_dialog); + +static gboolean fill_vendors_list (GtkBuilder * chooser_dialog); + +static GtkTreePath * +gtk_list_store_find_entry (GtkListStore * list_store, + GtkTreeIter * iter, gchar * name, int column_id) +{ + GtkTreePath *path; + char *current_name = NULL; + if (gtk_tree_model_get_iter_first + (GTK_TREE_MODEL (list_store), iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL + (list_store), iter, column_id, + ¤t_name, -1); + if (!g_ascii_strcasecmp (name, current_name)) { + path = + gtk_tree_model_get_path + (GTK_TREE_MODEL (list_store), iter); + return path; + } + g_free (current_name); + } while (gtk_tree_model_iter_next + (GTK_TREE_MODEL (list_store), iter)); + } + return NULL; +} + +static void +add_vendor_to_list (XklConfigRegistry * config_registry, + XklConfigItem * config_item, + GtkTreeView * vendors_list) +{ + GtkTreeIter iter; + GtkTreePath *found_existing; + GtkListStore *list_store; + + gchar *vendor_name = + (gchar *) g_object_get_data (G_OBJECT (config_item), + XCI_PROP_VENDOR); + + if (vendor_name == NULL) + return; + + list_store = + GTK_LIST_STORE (gtk_tree_view_get_model (vendors_list)); + + if (!g_ascii_strcasecmp (config_item->name, current_model_name)) { + current_vendor_name = g_strdup (vendor_name); + } + + found_existing = + gtk_list_store_find_entry (list_store, &iter, vendor_name, 0); + /* This vendor is already there */ + if (found_existing != NULL) { + gtk_tree_path_free (found_existing); + return; + } + + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, vendor_name, -1); +} + +static void +add_model_to_list (XklConfigRegistry * config_registry, + XklConfigItem * config_item, GtkTreeView * models_list) +{ + GtkTreeIter iter; + GtkListStore *list_store = + GTK_LIST_STORE (gtk_tree_view_get_model (models_list)); + char *utf_model_name; + if (current_vendor_name != NULL) { + gchar *vendor_name = + (gchar *) g_object_get_data (G_OBJECT (config_item), + XCI_PROP_VENDOR); + if (vendor_name == NULL) + return; + + if (g_ascii_strcasecmp (vendor_name, current_vendor_name)) + return; + } + utf_model_name = xci_desc_to_utf8 (config_item); + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + 0, utf_model_name, 1, config_item->name, -1); + + g_free (utf_model_name); +} + +static void +xkb_model_chooser_change_vendor_sel (GtkTreeSelection * selection, + GtkBuilder * chooser_dialog) +{ + GtkTreeIter iter; + GtkTreeModel *list_store = NULL; + if (gtk_tree_selection_get_selected + (selection, &list_store, &iter)) { + gchar *vendor_name = NULL; + gtk_tree_model_get (list_store, &iter, + 0, &vendor_name, -1); + + current_vendor_name = vendor_name; + fill_models_list (chooser_dialog); + g_free (vendor_name); + } else { + current_vendor_name = NULL; + fill_models_list (chooser_dialog); + } + +} + +static void +xkb_model_chooser_change_model_sel (GtkTreeSelection * selection, + GtkBuilder * chooser_dialog) +{ + gboolean anysel = + gtk_tree_selection_get_selected (selection, NULL, NULL); + gtk_dialog_set_response_sensitive (GTK_DIALOG + (CWID ("xkb_model_chooser")), + GTK_RESPONSE_OK, anysel); +} + +static void +prepare_vendors_list (GtkBuilder * chooser_dialog) +{ + GtkWidget *vendors_list = CWID ("vendors_list"); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + GtkTreeViewColumn *vendor_col = + gtk_tree_view_column_new_with_attributes (_("Vendors"), + renderer, + "text", 0, + NULL); + gtk_tree_view_column_set_visible (vendor_col, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (vendors_list), + vendor_col); +} + +static gboolean +fill_vendors_list (GtkBuilder * chooser_dialog) +{ + GtkWidget *vendors_list = CWID ("vendors_list"); + GtkListStore *list_store = gtk_list_store_new (1, G_TYPE_STRING); + GtkTreeIter iter; + GtkTreePath *path; + + gtk_tree_view_set_model (GTK_TREE_VIEW (vendors_list), + GTK_TREE_MODEL (list_store)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE + (list_store), 0, + GTK_SORT_ASCENDING); + + current_vendor_name = NULL; + + xkl_config_registry_foreach_model (config_registry, + (ConfigItemProcessFunc) + add_vendor_to_list, + vendors_list); + + if (current_vendor_name != NULL) { + path = gtk_list_store_find_entry (list_store, + &iter, + current_vendor_name, 0); + if (path != NULL) { + gtk_tree_selection_select_iter + (gtk_tree_view_get_selection + (GTK_TREE_VIEW (vendors_list)), &iter); + gtk_tree_view_scroll_to_cell + (GTK_TREE_VIEW (vendors_list), + path, NULL, TRUE, 0.5, 0); + gtk_tree_path_free (path); + } + fill_models_list (chooser_dialog); + g_free (current_vendor_name); + } else { + fill_models_list (chooser_dialog); + } + + g_signal_connect (G_OBJECT + (gtk_tree_view_get_selection + (GTK_TREE_VIEW (vendors_list))), "changed", + G_CALLBACK (xkb_model_chooser_change_vendor_sel), + chooser_dialog); + + return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), + &iter); +} + +static void +prepare_models_list (GtkBuilder * chooser_dialog) +{ + GtkWidget *models_list = CWID ("models_list"); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + GtkTreeViewColumn *description_col = + gtk_tree_view_column_new_with_attributes (_("Models"), + renderer, + "text", 0, + NULL); + gtk_tree_view_column_set_visible (description_col, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (models_list), + description_col); +} + +static void +fill_models_list (GtkBuilder * chooser_dialog) +{ + GtkWidget *models_list = CWID ("models_list"); + GtkTreeIter iter; + GtkTreePath *path; + + GtkListStore *list_store = + gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE + (list_store), 0, + GTK_SORT_ASCENDING); + + gtk_tree_view_set_model (GTK_TREE_VIEW (models_list), + GTK_TREE_MODEL (list_store)); + + xkl_config_registry_foreach_model (config_registry, + (ConfigItemProcessFunc) + add_model_to_list, models_list); + + if (current_model_name != NULL) { + path = gtk_list_store_find_entry (list_store, + &iter, + current_model_name, 1); + if (path != NULL) { + gtk_tree_selection_select_iter + (gtk_tree_view_get_selection + (GTK_TREE_VIEW (models_list)), &iter); + gtk_tree_view_scroll_to_cell + (GTK_TREE_VIEW (models_list), + path, NULL, TRUE, 0.5, 0); + gtk_tree_path_free (path); + } + } + + g_signal_connect (G_OBJECT + (gtk_tree_view_get_selection + (GTK_TREE_VIEW (models_list))), "changed", + G_CALLBACK (xkb_model_chooser_change_model_sel), + chooser_dialog); +} + +static void +xkb_model_chooser_response (GtkDialog * dialog, + gint response, GtkBuilder * chooser_dialog) +{ + if (response == GTK_RESPONSE_OK) { + GtkWidget *models_list = CWID ("models_list"); + GtkTreeSelection *selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW + (models_list)); + GtkTreeIter iter; + GtkTreeModel *list_store = NULL; + if (gtk_tree_selection_get_selected + (selection, &list_store, &iter)) { + gchar *model_name = NULL; + gtk_tree_model_get (list_store, &iter, + 1, &model_name, -1); + + mateconf_client_set_string (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_MODEL, + model_name, NULL); + g_free (model_name); + } + } +} + +void +choose_model (GtkBuilder * dialog) +{ + GtkBuilder *chooser_dialog; + GtkWidget *chooser; + + chooser_dialog = gtk_builder_new (); + gtk_builder_add_from_file (chooser_dialog, MATECC_UI_DIR + "/mate-keyboard-properties-model-chooser.ui", + NULL); + chooser = CWID ("xkb_model_chooser"); + gtk_window_set_transient_for (GTK_WINDOW (chooser), + GTK_WINDOW (WID + ("keyboard_dialog"))); + current_model_name = + mateconf_client_get_string (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_MODEL, NULL); + + + prepare_vendors_list (chooser_dialog); + prepare_models_list (chooser_dialog); + + if (!fill_vendors_list (chooser_dialog)) { + gtk_widget_hide_all (CWID ("vendors_label")); + gtk_widget_hide_all (CWID ("vendors_scrolledwindow")); + current_vendor_name = NULL; + fill_models_list (chooser_dialog); + } + + g_signal_connect (G_OBJECT (chooser), + "response", + G_CALLBACK (xkb_model_chooser_response), + chooser_dialog); + gtk_dialog_run (GTK_DIALOG (chooser)); + gtk_widget_destroy (chooser); + g_free (current_model_name); +} diff --git a/capplets/keyboard/mate-keyboard-properties-xkbot.c b/capplets/keyboard/mate-keyboard-properties-xkbot.c new file mode 100644 index 00000000..1436d86a --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkbot.c @@ -0,0 +1,516 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkbot.c + * Copyright (C) 2003-2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * John Spray + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "capplet-util.h" + +#include "mate-keyboard-properties-xkb.h" + +static GtkBuilder *chooser_dialog = NULL; +static const char *current1st_level_id = NULL; +static GSList *option_checks_list = NULL; +static GtkWidget *current_none_radio = NULL; +static GtkWidget *current_expander = NULL; +static gboolean current_multi_select = FALSE; +static GSList *current_radio_group = NULL; + +#define OPTION_ID_PROP "optionID" +#define SELCOUNTER_PROP "selectionCounter" +#define MATECONFSTATE_PROP "mateconfState" +#define EXPANDERS_PROP "expandersList" + +GSList * +xkb_options_get_selected_list (void) +{ + GSList *retval; + + retval = mateconf_client_get_list (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_OPTIONS, + MATECONF_VALUE_STRING, NULL); + if (retval == NULL) { + GSList *cur_option; + + for (cur_option = initial_config.options; + cur_option != NULL; cur_option = cur_option->next) + retval = + g_slist_prepend (retval, + g_strdup (cur_option->data)); + + retval = g_slist_reverse (retval); + } + + return retval; +} + +/* Returns the selection counter of the expander (static current_expander) */ +static int +xkb_options_expander_selcounter_get (void) +{ + return + GPOINTER_TO_INT (g_object_get_data + (G_OBJECT (current_expander), + SELCOUNTER_PROP)); +} + +/* Increments the selection counter in the expander (static current_expander) + using the value (can be 0)*/ +static void +xkb_options_expander_selcounter_add (int value) +{ + g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, + GINT_TO_POINTER + (xkb_options_expander_selcounter_get () + + value)); +} + +/* Resets the seletion counter in the expander (static current_expander) */ +static void +xkb_options_expander_selcounter_reset (void) +{ + g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, + GINT_TO_POINTER (0)); +} + +/* Formats the expander (static current_expander), based on the selection counter */ +static void +xkb_options_expander_highlight (void) +{ + char *utf_group_name = + g_object_get_data (G_OBJECT (current_expander), + "utfGroupName"); + int counter = xkb_options_expander_selcounter_get (); + if (utf_group_name != NULL) { + gchar *titlemarkup = + g_strconcat (counter > + 0 ? "" : "", + utf_group_name, "", NULL); + gtk_expander_set_label (GTK_EXPANDER (current_expander), + titlemarkup); + g_free (titlemarkup); + } +} + +/* Add optionname from the backend's selection list if it's not + already in there. */ +static void +xkb_options_select (gchar * optionname) +{ + gboolean already_selected = FALSE; + GSList *options_list = xkb_options_get_selected_list (); + GSList *option; + for (option = options_list; option != NULL; option = option->next) + if (!strcmp ((gchar *) option->data, optionname)) + already_selected = TRUE; + + if (!already_selected) + options_list = + g_slist_append (options_list, g_strdup (optionname)); + xkb_options_set_selected_list (options_list); + + clear_xkb_elements_list (options_list); +} + +/* Remove all occurences of optionname from the backend's selection list */ +static void +xkb_options_deselect (gchar * optionname) +{ + GSList *options_list = xkb_options_get_selected_list (); + GSList *nodetmp; + GSList *option = options_list; + while (option != NULL) { + gchar *id = (char *) option->data; + if (!strcmp (id, optionname)) { + nodetmp = option->next; + g_free (id); + options_list = + g_slist_remove_link (options_list, option); + g_slist_free_1 (option); + option = nodetmp; + } else + option = option->next; + } + xkb_options_set_selected_list (options_list); + clear_xkb_elements_list (options_list); +} + +/* Return true if optionname describes a string already in the backend's + list of selected options */ +static gboolean +xkb_options_is_selected (gchar * optionname) +{ + gboolean retval = FALSE; + GSList *options_list = xkb_options_get_selected_list (); + GSList *option; + for (option = options_list; option != NULL; option = option->next) { + if (!strcmp ((gchar *) option->data, optionname)) + retval = TRUE; + } + clear_xkb_elements_list (options_list); + return retval; +} + +/* Make sure selected options stay visible when navigating with the keyboard */ +static gboolean +option_focused_cb (GtkWidget * widget, GdkEventFocus * event, + gpointer data) +{ + GtkScrolledWindow *win = GTK_SCROLLED_WINDOW (data); + GtkAllocation alloc; + GtkAdjustment *adj; + + gtk_widget_get_allocation (widget, &alloc); + adj = gtk_scrolled_window_get_vadjustment (win); + gtk_adjustment_clamp_page (adj, alloc.y, + alloc.y + alloc.height); + + return FALSE; +} + +/* Update xkb backend to reflect the new UI state */ +static void +option_toggled_cb (GtkWidget * checkbutton, gpointer data) +{ + gpointer optionID = + g_object_get_data (G_OBJECT (checkbutton), OPTION_ID_PROP); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))) + xkb_options_select (optionID); + else + xkb_options_deselect (optionID); +} + +/* Add a check_button or radio_button to control a particular option + This function makes particular use of the current... variables at + the top of this file. */ +static void +xkb_options_add_option (XklConfigRegistry * config_registry, + XklConfigItem * config_item, GtkBuilder * dialog) +{ + GtkWidget *option_check; + gchar *utf_option_name = xci_desc_to_utf8 (config_item); + /* Copy this out because we'll load it into the widget with set_data */ + gchar *full_option_name = + g_strdup (matekbd_keyboard_config_merge_items + (current1st_level_id, config_item->name)); + gboolean initial_state; + + if (current_multi_select) + option_check = + gtk_check_button_new_with_label (utf_option_name); + else { + if (current_radio_group == NULL) { + /* The first radio in a group is to be "Default", meaning none of + the below options are to be included in the selected list. + This is a HIG-compliant alternative to allowing no + selection in the group. */ + option_check = + gtk_radio_button_new_with_label + (current_radio_group, _("Default")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON + (option_check), + TRUE); + /* Make option name underscore - + to enforce its first position in the list */ + g_object_set_data_full (G_OBJECT (option_check), + "utfOptionName", + g_strdup (" "), g_free); + option_checks_list = + g_slist_append (option_checks_list, + option_check); + current_radio_group = + gtk_radio_button_get_group (GTK_RADIO_BUTTON + (option_check)); + current_none_radio = option_check; + + g_signal_connect (option_check, "focus-in-event", + G_CALLBACK (option_focused_cb), + WID ("options_scroll")); + } + option_check = + gtk_radio_button_new_with_label (current_radio_group, + utf_option_name); + current_radio_group = + gtk_radio_button_get_group (GTK_RADIO_BUTTON + (option_check)); + g_object_set_data (G_OBJECT (option_check), "NoneRadio", + current_none_radio); + } + + initial_state = xkb_options_is_selected (full_option_name); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option_check), + initial_state); + + g_object_set_data_full (G_OBJECT (option_check), OPTION_ID_PROP, + full_option_name, g_free); + g_object_set_data_full (G_OBJECT (option_check), "utfOptionName", + utf_option_name, g_free); + + g_signal_connect (option_check, "toggled", + G_CALLBACK (option_toggled_cb), NULL); + + option_checks_list = + g_slist_append (option_checks_list, option_check); + + g_signal_connect (option_check, "focus-in-event", + G_CALLBACK (option_focused_cb), + WID ("options_scroll")); + + xkb_options_expander_selcounter_add (initial_state); + g_object_set_data (G_OBJECT (option_check), MATECONFSTATE_PROP, + GINT_TO_POINTER (initial_state)); +} + +static gint +xkb_option_checks_compare (GtkWidget * chk1, GtkWidget * chk2) +{ + const gchar *t1 = + g_object_get_data (G_OBJECT (chk1), "utfOptionName"); + const gchar *t2 = + g_object_get_data (G_OBJECT (chk2), "utfOptionName"); + return g_utf8_collate (t1, t2); +} + +/* Add a group of options: create title and layout widgets and then + add widgets for all the options in the group. */ +static void +xkb_options_add_group (XklConfigRegistry * config_registry, + XklConfigItem * config_item, GtkBuilder * dialog) +{ + GtkWidget *align, *vbox, *option_check; + gboolean allow_multiple_selection = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (config_item), + XCI_PROP_ALLOW_MULTIPLE_SELECTION)); + + GSList *expanders_list = + g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); + + gchar *utf_group_name = xci_desc_to_utf8 (config_item); + gchar *titlemarkup = + g_strconcat ("", utf_group_name, "", NULL); + + current_expander = gtk_expander_new (titlemarkup); + gtk_expander_set_use_markup (GTK_EXPANDER (current_expander), + TRUE); + g_object_set_data_full (G_OBJECT (current_expander), + "utfGroupName", utf_group_name, g_free); + g_object_set_data_full (G_OBJECT (current_expander), "groupId", + g_strdup (config_item->name), g_free); + + g_free (titlemarkup); + align = gtk_alignment_new (0, 0, 1, 1); + gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 12, 12, 0); + vbox = gtk_vbox_new (TRUE, 6); + gtk_container_add (GTK_CONTAINER (align), vbox); + gtk_container_add (GTK_CONTAINER (current_expander), align); + + current_multi_select = (gboolean) allow_multiple_selection; + current_radio_group = NULL; + current1st_level_id = config_item->name; + + option_checks_list = NULL; + + xkl_config_registry_foreach_option (config_registry, + config_item->name, + (ConfigItemProcessFunc) + xkb_options_add_option, + dialog); + /* sort it */ + option_checks_list = + g_slist_sort (option_checks_list, + (GCompareFunc) xkb_option_checks_compare); + while (option_checks_list) { + option_check = GTK_WIDGET (option_checks_list->data); + gtk_box_pack_start (GTK_BOX (vbox), option_check, TRUE, TRUE, 0); + option_checks_list = option_checks_list->next; + } + /* free it */ + g_slist_free (option_checks_list); + option_checks_list = NULL; + + xkb_options_expander_highlight (); + + expanders_list = g_slist_append (expanders_list, current_expander); + g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, + expanders_list); + + g_signal_connect (current_expander, "focus-in-event", + G_CALLBACK (option_focused_cb), + WID ("options_scroll")); +} + +static gint +xkb_options_expanders_compare (GtkWidget * expander1, + GtkWidget * expander2) +{ + const gchar *t1 = + g_object_get_data (G_OBJECT (expander1), "utfGroupName"); + const gchar *t2 = + g_object_get_data (G_OBJECT (expander2), "utfGroupName"); + return g_utf8_collate (t1, t2); +} + +/* Create widgets to represent the options made available by the backend */ +void +xkb_options_load_options (GtkBuilder * dialog) +{ + GtkWidget *opts_vbox = WID ("options_vbox"); + GSList *expanders_list; + GtkWidget *expander; + + current1st_level_id = NULL; + current_none_radio = NULL; + current_multi_select = FALSE; + current_radio_group = NULL; + + /* fill the list */ + xkl_config_registry_foreach_option_group (config_registry, + (ConfigItemProcessFunc) + xkb_options_add_group, + dialog); + /* sort it */ + expanders_list = + g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); + expanders_list = + g_slist_sort (expanders_list, + (GCompareFunc) xkb_options_expanders_compare); + g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, + expanders_list); + while (expanders_list) { + expander = GTK_WIDGET (expanders_list->data); + gtk_box_pack_start (GTK_BOX (opts_vbox), expander, FALSE, + FALSE, 0); + expanders_list = expanders_list->next; + } + + gtk_widget_show_all (opts_vbox); +} + +static void +chooser_response_cb (GtkDialog * dialog, gint response, gpointer data) +{ + switch (response) { + case GTK_RESPONSE_HELP: + capplet_help (GTK_WINDOW (dialog), + "prefs-keyboard-layoutoptions"); + break; + case GTK_RESPONSE_CLOSE:{ + /* just cleanup */ + GSList *expanders_list = + g_object_get_data (G_OBJECT (dialog), + EXPANDERS_PROP); + g_object_set_data (G_OBJECT (dialog), + EXPANDERS_PROP, NULL); + g_slist_free (expanders_list); + + gtk_widget_destroy (GTK_WIDGET (dialog)); + chooser_dialog = NULL; + } + break; + } +} + +/* Create popup dialog */ +void +xkb_options_popup_dialog (GtkBuilder * dialog) +{ + GtkWidget *chooser; + + chooser_dialog = gtk_builder_new (); + gtk_builder_add_from_file (chooser_dialog, MATECC_UI_DIR + "/mate-keyboard-properties-options-dialog.ui", + NULL); + + chooser = CWID ("xkb_options_dialog"); + gtk_window_set_transient_for (GTK_WINDOW (chooser), + GTK_WINDOW (WID + ("keyboard_dialog"))); + xkb_options_load_options (chooser_dialog); + + g_signal_connect (chooser, "response", + G_CALLBACK (chooser_response_cb), dialog); + + gtk_dialog_run (GTK_DIALOG (chooser)); +} + +/* Update selected option counters for a group-bound expander */ +static void +xkb_options_update_option_counters (XklConfigRegistry * config_registry, + XklConfigItem * config_item) +{ + gchar *full_option_name = + g_strdup (matekbd_keyboard_config_merge_items + (current1st_level_id, config_item->name)); + gboolean current_state = + xkb_options_is_selected (full_option_name); + xkb_options_expander_selcounter_add (current_state); +} + +/* Respond to a change in the xkb mateconf settings */ +static void +xkb_options_update (MateConfClient * client, + guint cnxn_id, MateConfEntry * entry, GtkBuilder * dialog) +{ + /* Updating options is handled by mateconf notifies for each widget + This is here to avoid calling it N_OPTIONS times for each mateconf + change. */ + enable_disable_restoring (dialog); + + if (chooser_dialog != NULL) { + GSList *expanders_list = + g_object_get_data (G_OBJECT (chooser_dialog), + EXPANDERS_PROP); + while (expanders_list) { + current_expander = + GTK_WIDGET (expanders_list->data); + gchar *group_id = + g_object_get_data (G_OBJECT (current_expander), + "groupId"); + current1st_level_id = group_id; + xkb_options_expander_selcounter_reset (); + xkl_config_registry_foreach_option + (config_registry, group_id, + (ConfigItemProcessFunc) + xkb_options_update_option_counters, + current_expander); + xkb_options_expander_highlight (); + expanders_list = expanders_list->next; + } + } +} + +void +xkb_options_register_mateconf_listener (GtkBuilder * dialog) +{ + mateconf_client_notify_add (xkb_mateconf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_OPTIONS, + (MateConfClientNotifyFunc) + xkb_options_update, dialog, NULL, NULL); +} diff --git a/capplets/keyboard/mate-keyboard-properties-xkbpv.c b/capplets/keyboard/mate-keyboard-properties-xkbpv.c new file mode 100644 index 00000000..6aec3070 --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties-xkbpv.c @@ -0,0 +1,136 @@ +/* -*- mode: c; style: linux -*- */ + +/* mate-keyboard-properties-xkbpv.c + * Copyright (C) 2003-2007 Sergey V. Udaltsov + * + * Written by: Sergey V. Udaltsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "capplet-util.h" +#include "mate-keyboard-properties-xkb.h" + +#ifdef HAVE_X11_EXTENSIONS_XKB_H +#include "X11/XKBlib.h" +/** + * BAD STYLE: Taken from xklavier_private_xkb.h + * Any ideas on architectural improvements are WELCOME + */ +extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine, + const XklConfigRec * data, + XkbComponentNamesPtr + component_names); + +extern void xkl_xkb_config_native_cleanup (XklEngine * engine, + XkbComponentNamesPtr + component_names); + +/* */ +#endif + +static MatekbdKeyboardDrawingGroupLevel groupsLevels[] = + { {0, 1}, {0, 3}, {0, 0}, {0, 2} }; +static MatekbdKeyboardDrawingGroupLevel *pGroupsLevels[] = { + groupsLevels, groupsLevels + 1, groupsLevels + 2, groupsLevels + 3 +}; + +GtkWidget * +xkb_layout_preview_create_widget (GtkBuilder * chooserDialog) +{ + GtkWidget *kbdraw = matekbd_keyboard_drawing_new (); + + matekbd_keyboard_drawing_set_groups_levels (MATEKBD_KEYBOARD_DRAWING + (kbdraw), pGroupsLevels); + return kbdraw; +} + +void +xkb_layout_preview_update (GtkBuilder * chooser_dialog) +{ +#ifdef HAVE_X11_EXTENSIONS_XKB_H + GtkWidget *chooser = CWID ("xkb_layout_chooser"); + GtkWidget *kbdraw = + GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw")); + gchar *id = xkb_layout_chooser_get_selected_id (chooser_dialog); + xkb_layout_preview_set_drawing_layout (kbdraw, id); + g_free (id); +#endif +} + +void +xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, + const gchar * id) +{ +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (kbdraw != NULL) { + if (id != NULL) { + XklConfigRec *data; + char **p, *layout, *variant; + XkbComponentNamesRec component_names; + + data = xkl_config_rec_new (); + if (xkl_config_rec_get_from_server (data, engine)) { + if ((p = data->layouts) != NULL) + g_strfreev (data->layouts); + + if ((p = data->variants) != NULL) + g_strfreev (data->variants); + + data->layouts = g_new0 (char *, 2); + data->variants = g_new0 (char *, 2); + if (matekbd_keyboard_config_split_items + (id, &layout, &variant) + && variant != NULL) { + data->layouts[0] = + (layout == + NULL) ? NULL : + g_strdup (layout); + data->variants[0] = + (variant == + NULL) ? NULL : + g_strdup (variant); + } else { + data->layouts[0] = + (id == + NULL) ? NULL : g_strdup (id); + data->variants[0] = NULL; + } + + if (xkl_xkb_config_native_prepare + (engine, data, &component_names)) { + matekbd_keyboard_drawing_set_keyboard + (MATEKBD_KEYBOARD_DRAWING + (kbdraw), &component_names); + + xkl_xkb_config_native_cleanup + (engine, &component_names); + } + } + g_object_unref (G_OBJECT (data)); + } else + matekbd_keyboard_drawing_set_keyboard + (MATEKBD_KEYBOARD_DRAWING (kbdraw), NULL); + + } +#endif +} diff --git a/capplets/keyboard/mate-keyboard-properties.c b/capplets/keyboard/mate-keyboard-properties.c new file mode 100644 index 00000000..41c4558e --- /dev/null +++ b/capplets/keyboard/mate-keyboard-properties.c @@ -0,0 +1,265 @@ +/* -*- mode: c; style: linux -*- */ + +/* keyboard-properties.c + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2001 Jonathan Blandford + * + * Written by: Bradford Hovinen + * Rachel Hestilow + * Jonathan Blandford + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "capplet-util.h" +#include "mateconf-property-editor.h" +#include "activate-settings-daemon.h" +#include "capplet-stock-icons.h" + +#include "mate-keyboard-properties-a11y.h" +#include "mate-keyboard-properties-xkb.h" + +enum { + RESPONSE_APPLY = 1, + RESPONSE_CLOSE +}; + +static GtkBuilder * +create_dialog (void) +{ + GtkBuilder *dialog; + GtkSizeGroup *size_group; + GtkWidget *image; + + dialog = gtk_builder_new (); + gtk_builder_add_from_file (dialog, MATECC_UI_DIR + "/mate-keyboard-properties-dialog.ui", + NULL); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("repeat_slow_label")); + gtk_size_group_add_widget (size_group, WID ("delay_short_label")); + gtk_size_group_add_widget (size_group, WID ("blink_slow_label")); + g_object_unref (G_OBJECT (size_group)); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("repeat_fast_label")); + gtk_size_group_add_widget (size_group, WID ("delay_long_label")); + gtk_size_group_add_widget (size_group, WID ("blink_fast_label")); + g_object_unref (G_OBJECT (size_group)); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, WID ("repeat_delay_scale")); + gtk_size_group_add_widget (size_group, WID ("repeat_speed_scale")); + gtk_size_group_add_widget (size_group, WID ("cursor_blink_time_scale")); + g_object_unref (G_OBJECT (size_group)); + + image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (WID ("xkb_layouts_add")), image); + + image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (WID ("xkb_reset_to_defaults")), image); + + return dialog; +} + +static MateConfValue * +blink_from_widget (MateConfPropertyEditor * peditor, const MateConfValue * value) +{ + MateConfValue *new_value; + + new_value = mateconf_value_new (MATECONF_VALUE_INT); + mateconf_value_set_int (new_value, + 2600 - mateconf_value_get_int (value)); + + return new_value; +} + +static MateConfValue * +blink_to_widget (MateConfPropertyEditor * peditor, const MateConfValue * value) +{ + MateConfValue *new_value; + gint current_rate; + + current_rate = mateconf_value_get_int (value); + new_value = mateconf_value_new (MATECONF_VALUE_INT); + mateconf_value_set_int (new_value, + CLAMP (2600 - current_rate, 100, 2500)); + + return new_value; +} + +static void +dialog_response (GtkWidget * widget, + gint response_id, MateConfChangeSet * changeset) +{ + if (response_id == GTK_RESPONSE_HELP) + capplet_help (GTK_WINDOW (widget), "goscustperiph-2"); + else + gtk_main_quit (); +} + +static void +setup_dialog (GtkBuilder * dialog, MateConfChangeSet * changeset) +{ + GObject *peditor; + gchar *monitor; + + peditor = mateconf_peditor_new_boolean + (changeset, "/desktop/mate/peripherals/keyboard/repeat", + WID ("repeat_toggle"), NULL); + mateconf_peditor_widget_set_guard (MATECONF_PROPERTY_EDITOR (peditor), + WID ("repeat_table")); + + mateconf_peditor_new_numeric_range + (changeset, "/desktop/mate/peripherals/keyboard/delay", + WID ("repeat_delay_scale"), NULL); + + mateconf_peditor_new_numeric_range + (changeset, "/desktop/mate/peripherals/keyboard/rate", + WID ("repeat_speed_scale"), NULL); + + peditor = mateconf_peditor_new_boolean + (changeset, "/desktop/mate/interface/cursor_blink", + WID ("cursor_toggle"), NULL); + mateconf_peditor_widget_set_guard (MATECONF_PROPERTY_EDITOR (peditor), + WID ("cursor_hbox")); + mateconf_peditor_new_numeric_range (changeset, + "/desktop/mate/interface/cursor_blink_time", + WID ("cursor_blink_time_scale"), + "conv-to-widget-cb", + blink_to_widget, + "conv-from-widget-cb", + blink_from_widget, NULL); + + /* Ergonomics */ + monitor = g_find_program_in_path ("mate-typing-monitor"); + if (monitor != NULL) { + g_free (monitor); + + peditor = mateconf_peditor_new_boolean + (changeset, "/desktop/mate/typing_break/enabled", + WID ("break_enabled_toggle"), NULL); + mateconf_peditor_widget_set_guard (MATECONF_PROPERTY_EDITOR (peditor), + WID ("break_details_table")); + mateconf_peditor_new_numeric_range (changeset, + "/desktop/mate/typing_break/type_time", + WID ("break_enabled_spin"), NULL); + mateconf_peditor_new_numeric_range (changeset, + "/desktop/mate/typing_break/break_time", + WID ("break_interval_spin"), + NULL); + mateconf_peditor_new_boolean (changeset, + "/desktop/mate/typing_break/allow_postpone", + WID ("break_postponement_toggle"), + NULL); + + } else { + /* don't show the typing break tab if the daemon is not available */ + GtkNotebook *nb = GTK_NOTEBOOK (WID ("keyboard_notebook")); + gint tb_page = gtk_notebook_page_num (nb, WID ("break_enabled_toggle")); + gtk_notebook_remove_page (nb, tb_page); + } + + g_signal_connect (WID ("keyboard_dialog"), "response", + (GCallback) dialog_response, changeset); + + setup_xkb_tabs (dialog, changeset); + setup_a11y_tabs (dialog, changeset); +} + +int +main (int argc, char **argv) +{ + MateConfClient *client; + MateConfChangeSet *changeset; + GtkBuilder *dialog; + GOptionContext *context; + + static gboolean apply_only = FALSE; + static gboolean switch_to_typing_break_page = FALSE; + static gboolean switch_to_a11y_page = FALSE; + + static GOptionEntry cap_options[] = { + {"apply", 0, 0, G_OPTION_ARG_NONE, &apply_only, + N_ + ("Just apply settings and quit (compatibility only; now handled by daemon)"), + NULL}, + {"init-session-settings", 0, 0, G_OPTION_ARG_NONE, + &apply_only, + N_ + ("Just apply settings and quit (compatibility only; now handled by daemon)"), + NULL}, + {"typing-break", 0, 0, G_OPTION_ARG_NONE, + &switch_to_typing_break_page, + N_ + ("Start the page with the typing break settings showing"), + NULL}, + {"a11y", 0, 0, G_OPTION_ARG_NONE, + &switch_to_a11y_page, + N_ + ("Start the page with the accessibility settings showing"), + NULL}, + {NULL} + }; + + + context = g_option_context_new (_("- MATE Keyboard Preferences")); + g_option_context_add_main_entries (context, cap_options, + GETTEXT_PACKAGE); + + capplet_init (context, &argc, &argv); + + activate_settings_daemon (); + + client = mateconf_client_get_default (); + mateconf_client_add_dir (client, + "/desktop/mate/peripherals/keyboard", + MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, "/desktop/mate/interface", + MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + g_object_unref (client); + + changeset = NULL; + dialog = create_dialog (); + setup_dialog (dialog, changeset); + if (switch_to_typing_break_page) { + gtk_notebook_set_current_page (GTK_NOTEBOOK + (WID + ("keyboard_notebook")), + 4); + } + else if (switch_to_a11y_page) { + gtk_notebook_set_current_page (GTK_NOTEBOOK + (WID + ("keyboard_notebook")), + 2); + + } + + capplet_set_icon (WID ("keyboard_dialog"), + "preferences-desktop-keyboard"); + gtk_widget_show (WID ("keyboard_dialog")); + gtk_main (); + + return 0; +} -- cgit v1.2.1