Index: plugins/mouse_plugin/mouse-plugin-internal.h =================================================================== --- plugins/mouse_plugin/mouse-plugin-internal.h (revision 22981) +++ plugins/mouse_plugin/mouse-plugin-internal.h (working copy) @@ -84,6 +84,16 @@ GtkWidget *cursor_theme_list; GtkWidget *cursor_preview_list; GtkWidget *cursor_size_spinbtn; + +#ifdef USE_XKB + /* accessibility tab */ + GtkWidget *accessx_page; + GtkWidget *checkbutton_mouse; + GtkWidget *scale_mouse_keys_delay; + GtkWidget *scale_mouse_keys_interval; + GtkWidget *scale_mouse_keys_ttm; + GtkWidget *scale_mouse_keys_max_speed; +#endif } Itf; void mouse_plugin_set_initial_cursor_values(McsPlugin *mcs_plugin); Index: plugins/mouse_plugin/mouse_plugin.c =================================================================== --- plugins/mouse_plugin/mouse_plugin.c (revision 22981) +++ plugins/mouse_plugin/mouse_plugin.c (working copy) @@ -24,6 +24,10 @@ #include +#ifdef USE_XKB +#include +#endif + #include #include #include @@ -64,6 +68,14 @@ static int threshold = DEFAULT_THRESHOLD; static int denominator = DEFAULT_DENOMINATOR; +#ifdef USE_XKB +static gboolean mouse_key = FALSE; +static int mouse_keys_delay = 200; +static int mouse_keys_interval = 200; +static int mouse_keys_ttm = 200; +static int mouse_keys_max_speed = 200; +static gboolean xkbpresent = FALSE; +#endif static void get_mouse_values(int *accel_return, int *denom_return, int *thresh_return) { @@ -206,6 +218,95 @@ mouse_plugin_write_options(mcs_plugin); } +void +create_accessx_page(Itf *dialog) +{ + GtkWidget *frame; + GtkWidget *label; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *main_vbox = gtk_vbox_new(FALSE, 5); + + frame = xfce_framebox_new (_("Mouse keys"), FALSE); + gtk_widget_show (frame); + gtk_box_pack_start(GTK_BOX(main_vbox), frame, FALSE, TRUE, 0); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_widget_show (vbox); + xfce_framebox_add (XFCE_FRAMEBOX (frame), vbox); + + dialog->checkbutton_mouse = gtk_check_button_new_with_mnemonic(_("Enable Mouse keys")); + gtk_widget_show(dialog->checkbutton_mouse); + gtk_box_pack_start(GTK_BOX(vbox), dialog->checkbutton_mouse, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->checkbutton_mouse), mouse_key); + + hbox = gtk_hbox_new(TRUE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + label = gtk_label_new (_("Delay :")); + gtk_widget_show (label); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + + dialog->scale_mouse_keys_delay = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (mouse_keys_delay, 10, 500, 10, 10, 0))); + gtk_widget_show(dialog->scale_mouse_keys_delay); + gtk_scale_set_draw_value (GTK_SCALE (dialog->scale_mouse_keys_delay), FALSE); + gtk_range_set_update_policy (GTK_RANGE (dialog->scale_mouse_keys_delay), GTK_UPDATE_DISCONTINUOUS); + gtk_box_pack_start(GTK_BOX(vbox), dialog->scale_mouse_keys_delay, FALSE, TRUE, 0); + gtk_widget_set_sensitive(dialog->scale_mouse_keys_delay, mouse_key); + + label = gtk_label_new (_("Interval :")); + gtk_widget_show (label); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + + dialog->scale_mouse_keys_interval = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (mouse_keys_interval, 10, 500, 10, 10, 0))); + gtk_widget_show(dialog->scale_mouse_keys_interval); + gtk_scale_set_draw_value (GTK_SCALE (dialog->scale_mouse_keys_interval), FALSE); + gtk_range_set_update_policy (GTK_RANGE (dialog->scale_mouse_keys_interval), GTK_UPDATE_DISCONTINUOUS); + gtk_box_pack_start(GTK_BOX(vbox), dialog->scale_mouse_keys_interval, FALSE, TRUE, 0); + gtk_widget_set_sensitive(dialog->scale_mouse_keys_interval, mouse_key); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + label = gtk_label_new (_("Time to max :")); + gtk_widget_show (label); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + + dialog->scale_mouse_keys_ttm= gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (mouse_keys_ttm, 10, 500, 10, 10, 0))); + gtk_widget_show(dialog->scale_mouse_keys_ttm); + gtk_scale_set_draw_value (GTK_SCALE (dialog->scale_mouse_keys_ttm), FALSE); + gtk_range_set_update_policy (GTK_RANGE (dialog->scale_mouse_keys_ttm), GTK_UPDATE_DISCONTINUOUS); + gtk_box_pack_start(GTK_BOX(vbox), dialog->scale_mouse_keys_ttm, FALSE, TRUE, 0); + gtk_widget_set_sensitive(dialog->scale_mouse_keys_ttm, mouse_key); + + label = gtk_label_new (_("Max speed:")); + gtk_widget_show (label); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + + dialog->scale_mouse_keys_max_speed = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (mouse_keys_max_speed, 10, 500, 10, 10, 0))); + gtk_widget_show(dialog->scale_mouse_keys_max_speed); + gtk_scale_set_draw_value (GTK_SCALE (dialog->scale_mouse_keys_max_speed), FALSE); + gtk_range_set_update_policy (GTK_RANGE (dialog->scale_mouse_keys_max_speed), GTK_UPDATE_DISCONTINUOUS); + gtk_box_pack_start(GTK_BOX(vbox), dialog->scale_mouse_keys_max_speed, FALSE, TRUE, 0); + gtk_widget_set_sensitive(dialog->scale_mouse_keys_max_speed, mouse_key); + + dialog->accessx_page = main_vbox; +} + Itf *create_mouse_dialog(McsPlugin * mcs_plugin) { Itf *dialog; @@ -235,7 +336,6 @@ gtk_widget_show(dialog->notebook_vbox); gtk_box_pack_start(GTK_BOX(dialog->dialog_vbox1), dialog->notebook_vbox, TRUE, TRUE, 0); -#ifdef HAVE_XCURSOR_EXTENSION dialog->notebook = gtk_notebook_new(); gtk_widget_show(dialog->notebook); gtk_box_pack_start(GTK_BOX(dialog->notebook_vbox), dialog->notebook, TRUE, TRUE, 0); @@ -246,9 +346,6 @@ gtk_container_set_border_width(GTK_CONTAINER(dialog->vbox1), 6); gtk_widget_show(dialog->vbox1); gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), dialog->vbox1, lbl); -#else - dialog->vbox1 = dialog->notebook_vbox; -#endif sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); @@ -423,10 +520,90 @@ mouse_plugin_create_cursor_page(dialog); gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), dialog->cursor_page, lbl); #endif + +#ifdef USE_XKB + lbl = gtk_label_new(_("Accessibility")); + gtk_widget_show(lbl); + create_accessx_page(dialog); + gtk_widget_show_all(dialog->accessx_page); + gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), dialog->accessx_page, lbl); +#endif return dialog; } +#ifdef USE_XKB +static void +toggle_accessx() +{ + if (xkbpresent) + { + XkbDescPtr xkb = XkbAllocKeyboard (); + if (xkb) + { + gdk_error_trap_push (); + XkbGetControls (GDK_DISPLAY (), XkbAllControlsMask, xkb); + + if(mouse_key) + { + xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask; + xkb->ctrls->mk_delay = mouse_keys_delay; + xkb->ctrls->mk_interval = 1000 / mouse_keys_interval; + xkb->ctrls->mk_time_to_max = mouse_keys_ttm; + xkb->ctrls->mk_max_speed = mouse_keys_max_speed; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbMouseKeysMask; + + XkbSetControls (GDK_DISPLAY (), XkbMouseKeysMask | XkbMouseKeysAccelMask, xkb); + XFree (xkb); + gdk_flush (); + gdk_error_trap_pop (); + } + else + { + g_warning ("XkbAllocKeyboard() returned null pointer"); + } + } +} + +static void +cb_scale_accessx_changed (GtkWidget * widget, gpointer user_data) +{ + Itf *itf = (Itf *)user_data; + McsPlugin *mcs_plugin = itf->mcs_plugin; + + mouse_keys_delay = (int) gtk_range_get_value (GTK_RANGE (itf->scale_mouse_keys_delay)); + mouse_keys_interval = (int) gtk_range_get_value (GTK_RANGE (itf->scale_mouse_keys_interval)); + mouse_keys_ttm= (int) gtk_range_get_value (GTK_RANGE (itf->scale_mouse_keys_ttm)); + mouse_keys_max_speed= (int) gtk_range_get_value (GTK_RANGE (itf->scale_mouse_keys_max_speed)); + + toggle_accessx(); + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysDelay", CHANNEL2, mouse_keys_delay); + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysInterval", CHANNEL2, mouse_keys_interval); + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysTimeToMax", CHANNEL2, mouse_keys_ttm); + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysMaxSpeed", CHANNEL2, mouse_keys_max_speed); +} + +static void +cb_checkbutton_accessx_changed (GtkWidget * widget, gpointer user_data) +{ + Itf *itf = (Itf *)user_data; + McsPlugin *mcs_plugin = itf->mcs_plugin; + + mouse_key = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->checkbutton_mouse)); + gtk_widget_set_sensitive(itf->scale_mouse_keys_delay, mouse_key); + gtk_widget_set_sensitive(itf->scale_mouse_keys_interval, mouse_key); + gtk_widget_set_sensitive(itf->scale_mouse_keys_ttm, mouse_key); + gtk_widget_set_sensitive(itf->scale_mouse_keys_max_speed, mouse_key); + + toggle_accessx(); + + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeys", CHANNEL2, mouse_key ? 1 : 0); + mouse_plugin_write_options (mcs_plugin); +} +#endif + static void setup_dialog(Itf * itf) { g_signal_connect(G_OBJECT(itf->mouse_dialog), "response", G_CALLBACK(cb_dialog_response), itf->mcs_plugin); @@ -438,6 +615,15 @@ g_signal_connect(G_OBJECT(itf->hscale3), "value_changed", (GCallback) cb_dnd_threshold_changed, itf); g_signal_connect(G_OBJECT(itf->hscale4), "value_changed", (GCallback) cb_dbl_clicktime_changed, itf); +#ifdef USE_XKB + g_signal_connect(G_OBJECT(itf->checkbutton_mouse), "toggled", (GCallback) cb_checkbutton_accessx_changed , itf); + g_signal_connect(G_OBJECT(itf->scale_mouse_keys_delay), "value_changed", (GCallback) cb_scale_accessx_changed , itf); + g_signal_connect(G_OBJECT(itf->scale_mouse_keys_interval), "value_changed", (GCallback) cb_scale_accessx_changed, itf); + g_signal_connect(G_OBJECT(itf->scale_mouse_keys_ttm), "value_changed", (GCallback) cb_scale_accessx_changed, itf); + g_signal_connect(G_OBJECT(itf->scale_mouse_keys_max_speed), "value_changed", (GCallback) cb_scale_accessx_changed , itf); +#endif + + xfce_gtk_window_center_on_monitor_with_pointer (GTK_WINDOW (itf->mouse_dialog)); gdk_x11_window_set_user_time(GTK_WIDGET (itf->mouse_dialog)->window, gdk_x11_get_server_time (GTK_WIDGET (itf->mouse_dialog)->window)); @@ -468,6 +654,12 @@ { McsSetting *setting; gchar *rcfile, *path; +#ifdef USE_XKB + int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion; + int xkbopcode, xkbevent, xkberror; +#endif + + path = g_build_filename ("xfce4", RCDIR, RCFILE1, NULL); rcfile = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, path); @@ -578,6 +770,85 @@ mcs_manager_set_int(mcs_plugin->manager, "Mouse/Threshold", CHANNEL2, threshold); } +#ifdef USE_XKB +#ifdef DEBUG + g_message ("Querying Xkb extension"); +#endif + if (XkbQueryExtension (GDK_DISPLAY (), &xkbopcode, &xkbevent, &xkberror, &xkbmajor, &xkbminor)) + { +#ifdef DEBUG + g_message ("Xkb extension found"); +#endif + xkbpresent = TRUE; + } + else + { +#ifdef DEBUG + g_message ("Your X server does not support Xkb extension"); +#endif + xkbpresent = FALSE; + } +#else +#ifdef DEBUG + g_warning ("This build doesn't include support for Xkb extension"); +#endif + setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Mouse/MouseKeys", CHANNEL2); + if(setting) + { + mouse_key = (setting->data.v_int ? TRUE : FALSE); + } + else + { + mouse_key = FALSE; + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeys", CHANNEL2, mouse_key ? 1 : 0); + } + + setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Mouse/MouseKeysDelay", CHANNEL2); + if(setting) + { + mouse_keys_delay = setting->data.v_int; + } + else + { + mouse_keys_delay = 200; + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysDelay", CHANNEL2, mouse_keys_delay); + } + + setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Mouse/MouseKeysInterval", CHANNEL2); + if(setting) + { + mouse_keys_interval = setting->data.v_int; + } + else + { + mouse_keys_interval = 200; + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysInterval", CHANNEL2, mouse_keys_interval); + } + + setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Mouse/MouseKeysMaxSpeed", CHANNEL2); + if(setting) + { + mouse_keys_max_speed = setting->data.v_int; + } + else + { + mouse_keys_max_speed = 200; + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysMaxSpeed", CHANNEL2, mouse_keys_max_speed); + } + + setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Mouse/MouseKeysTimeToMax", CHANNEL2); + if(setting) + { + mouse_keys_ttm = setting->data.v_int; + } + else + { + mouse_keys_ttm = 200; + mcs_manager_set_int (mcs_plugin->manager, "Mouse/MouseKeysTimeToMax", CHANNEL2, mouse_keys_ttm); + } + toggle_accessx; +#endif + set_mouse_values(right_handed, acceleration, threshold); #ifdef HAVE_XCURSOR_EXTENSION Index: plugins/mouse_plugin/Makefile.am =================================================================== --- plugins/mouse_plugin/Makefile.am (revision 22981) +++ plugins/mouse_plugin/Makefile.am (working copy) @@ -20,6 +20,7 @@ $(LIBX11_CFLAGS) \ $(LIBXFCEGUI4_CFLAGS) \ $(XFCE_MCS_MANAGER_CFLAGS) \ + $(XKB_CFLAGS) \ $(PLATFORM_CFLAGS) mouse_plugin_la_LDFLAGS = \ @@ -31,7 +32,8 @@ mouse_plugin_la_LIBADD = \ $(LIBX11_LIBS) \ - $(XCURSOR_LIBS) + $(XCURSOR_LIBS) \ + $(XKB_LIBS) if HAVE_CYGWIN mouse_plugin_la_LDFLAGS += \