/*
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; You may only use version 2 of the License,
you have no option to use any other 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., 675 Mass Ave, Cambridge, MA 02139, USA.
GNOME Control Center - (c) 1998 Jonathan Blandford <jrb@redhat.com>
xfce4 mcs plugin - (c) 2002 Olivier Fourdan
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <X11/Xlib.h>
#ifdef USE_XKB
#include <X11/XKBlib.h>
#endif
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <libxfce4mcs/mcs-common.h>
#include <libxfce4mcs/mcs-manager.h>
#include <libxfce4util/libxfce4util.h>
#include <xfce-mcs-manager/manager-plugin.h>
#include <libxfcegui4/libxfcegui4.h>
#include <libxfcegui4/netk-trayicon.h>
#include "mouse-plugin-internal.h"
#define DEFAULT_ACCELERATION 2
#define DEFAULT_THRESHOLD 4
#define DEFAULT_DENOMINATOR 1
#define DEFAULT_DBL_CLICKTIME 300
#define DEFAULT_DND_THRESHOLD 8
#define ACCEL_MIN 1
#define ACCEL_MAX 30
#define THRESH_MIN 1
#define THRESH_MAX 20
#define DND_THRESH_MIN 1
#define DND_THRESH_MAX 50
#define DBL_CLICK_MIN 100
#define DBL_CLICK_MAX 2000
#define DEFAULT_ICON_SIZE 48
#define DEFAULT_PTR_MAP_SIZE 128
#ifdef USE_XKB
static const char * mouse_tray_image_xpm[] = {
"16 16 3 1",
" c None",
". c #000000",
"+ c #FFFFFF",
" ",
" ...... ",
" .+.++.+. ",
" .+.++.+. ",
" .++.++.++. ",
" .++.++.++. ",
" .......... ",
" .++++++++. ",
" .++++++++. ",
" .++++++++. ",
" .++++++++. ",
" .++++++++. ",
" .++++++++. ",
" .++++++. ",
" ...... ",
" "};
#endif
static void create_channel(McsPlugin * mcs_plugin);
static void run_dialog(McsPlugin * mcs_plugin);
static gboolean is_running = FALSE;
static gboolean right_handed = TRUE;
static int dbl_clicktime = DEFAULT_DBL_CLICKTIME;
static int dnd_threshold = DEFAULT_DND_THRESHOLD;
static int acceleration = DEFAULT_ACCELERATION;
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;
GtkWidget *mouse_tray_icon = NULL;
GtkWidget *mouse_tray_image = NULL;
#endif
static void get_mouse_values(int *accel_return, int *denom_return, int *thresh_return)
{
gdk_flush();
gdk_error_trap_push();
/* Reset */
XChangePointerControl(GDK_DISPLAY(), True, True, -1, -1, -1);
gdk_flush();
XGetPointerControl(GDK_DISPLAY(), accel_return, denom_return, thresh_return);
/* Paranoid check */
if (*denom_return < 1)
{
*denom_return = 1;
}
gdk_flush();
gdk_error_trap_pop();
}
static void set_mouse_values(gboolean right_handed, int accel, int threshold)
{
unsigned char *buttons;
gint n_buttons, i;
gint idx_1 = 0, idx_3 = 1;
gdk_flush();
gdk_error_trap_push();
XChangePointerControl(GDK_DISPLAY(), True, True, accel, denominator, threshold);
buttons = g_alloca (DEFAULT_PTR_MAP_SIZE);
n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons, DEFAULT_PTR_MAP_SIZE);
if (n_buttons > DEFAULT_PTR_MAP_SIZE)
{
buttons = g_alloca (n_buttons);
n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons, n_buttons);
}
for (i = 0; i < n_buttons; i++)
{
if (buttons[i] == 1)
{
idx_1 = i;
}
else if (buttons[i] == ((n_buttons < 3) ? 2 : 3))
{
idx_3 = i;
}
}
if ((!right_handed && (idx_1 < idx_3)) || (right_handed && (idx_1 > idx_3)))
{
buttons[idx_1] = ((n_buttons < 3) ? 2 : 3);
buttons[idx_3] = 1;
}
XSetPointerMapping (GDK_DISPLAY (), buttons, n_buttons);
}
static void cb_dialog_response(GtkWidget * dialog, gint response_id)
{
if(response_id == GTK_RESPONSE_HELP)
{
g_message("HELP: TBD");
}
else
{
is_running = FALSE;
gtk_widget_destroy(dialog);
}
}
static void cb_righthandled_changed(GtkWidget * dialog, gpointer user_data)
{
Itf *itf = (Itf *) user_data;
McsPlugin *mcs_plugin = itf->mcs_plugin;
right_handed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(itf->radiobutton2));
set_mouse_values(right_handed, acceleration, threshold);
mcs_manager_set_int(mcs_plugin->manager, "Mouse/RightHanded", CHANNEL2, right_handed ? 1 : 0);
mcs_manager_notify(mcs_plugin->manager, CHANNEL2);
mouse_plugin_write_options(mcs_plugin);
}
static void cb_acceleration_changed(GtkWidget * dialog, gpointer user_data)
{
Itf *itf = (Itf *) user_data;
McsPlugin *mcs_plugin = itf->mcs_plugin;
acceleration = (int)gtk_range_get_value(GTK_RANGE(itf->hscale1));
set_mouse_values(right_handed, acceleration, threshold);
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Acceleration", CHANNEL2, acceleration);
mcs_manager_notify(mcs_plugin->manager, CHANNEL2);
mouse_plugin_write_options(mcs_plugin);
}
static void cb_threshold_changed(GtkWidget * dialog, gpointer user_data)
{
Itf *itf = (Itf *) user_data;
McsPlugin *mcs_plugin = itf->mcs_plugin;
threshold = (int)gtk_range_get_value(GTK_RANGE(itf->hscale2));
set_mouse_values(right_handed, acceleration, threshold);
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Threshold", CHANNEL2, threshold);
mcs_manager_notify(mcs_plugin->manager, CHANNEL2);
mouse_plugin_write_options(mcs_plugin);
}
static void cb_dnd_threshold_changed(GtkWidget * dialog, gpointer user_data)
{
Itf *itf = (Itf *) user_data;
McsPlugin *mcs_plugin = itf->mcs_plugin;
dnd_threshold = (int)gtk_range_get_value(GTK_RANGE(itf->hscale3));
mcs_manager_set_int(mcs_plugin->manager, "Net/DndDragThreshold", CHANNEL1, dnd_threshold);
mcs_manager_notify(mcs_plugin->manager, CHANNEL1);
mouse_plugin_write_options(mcs_plugin);
}
static void cb_dbl_clicktime_changed(GtkWidget * dialog, gpointer user_data)
{
Itf *itf = (Itf *) user_data;
McsPlugin *mcs_plugin = itf->mcs_plugin;
dbl_clicktime = (int)gtk_range_get_value(GTK_RANGE(itf->hscale4));
mcs_manager_set_int(mcs_plugin->manager, "Net/DoubleClickTime", CHANNEL1, dbl_clicktime);
mcs_manager_notify(mcs_plugin->manager, CHANNEL1);
mouse_plugin_write_options(mcs_plugin);
}
#ifdef USE_XKB
void
create_accessx_page(Itf *dialog)
{
GtkWidget *label;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *main_vbox = gtk_vbox_new(FALSE, 5);
vbox = gtk_vbox_new (FALSE, 5);
gtk_widget_show (vbox);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
dialog->checkbutton_mouse = gtk_check_button_new_with_mnemonic(_("Enable mouse emulation"));
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;
}
#endif
Itf *create_mouse_dialog(McsPlugin * mcs_plugin)
{
Itf *dialog;
GtkSizeGroup *sg;
GtkWidget *frame_bin;
GtkWidget *label;
dialog = g_new(Itf, 1);
dialog->mcs_plugin = mcs_plugin;
dialog->radiobutton1_group = NULL;
dialog->mouse_dialog = xfce_titled_dialog_new();
gtk_window_set_icon_name(GTK_WINDOW(dialog->mouse_dialog), "xfce4-mouse");
gtk_window_set_title(GTK_WINDOW(dialog->mouse_dialog), _("Mouse Preferences"));
gtk_dialog_set_has_separator(GTK_DIALOG(dialog->mouse_dialog), FALSE);
dialog->dialog_vbox1 = GTK_DIALOG(dialog->mouse_dialog)->vbox;
gtk_widget_show(dialog->dialog_vbox1);
dialog->notebook_vbox = gtk_vbox_new(FALSE, 6);
gtk_container_set_border_width(GTK_CONTAINER(dialog->notebook_vbox), 6);
gtk_widget_show(dialog->notebook_vbox);
gtk_box_pack_start(GTK_BOX(dialog->dialog_vbox1), dialog->notebook_vbox, TRUE, TRUE, 0);
dialog->notebook = gtk_notebook_new();
gtk_widget_show(dialog->notebook);
gtk_box_pack_start(GTK_BOX(dialog->notebook_vbox), dialog->notebook, TRUE, TRUE, 0);
label = gtk_label_new(_("Behavior"));
gtk_widget_show(label);
dialog->vbox1 = gtk_vbox_new(FALSE, 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, label);
sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
/* button order */
dialog->frame1 = xfce_create_framebox (_("Button settings"), &frame_bin);
gtk_widget_show(dialog->frame1);
gtk_box_pack_start(GTK_BOX(dialog->vbox1), dialog->frame1, FALSE, TRUE, 0);
dialog->hbox2 = gtk_hbox_new(FALSE, 0);
gtk_widget_show(dialog->hbox2);
gtk_container_add (GTK_CONTAINER (frame_bin), dialog->hbox2);
dialog->radiobutton1 = gtk_radio_button_new_with_mnemonic(NULL, _("Left Handed"));
gtk_widget_show(dialog->radiobutton1);
gtk_box_pack_start(GTK_BOX(dialog->hbox2), dialog->radiobutton1, FALSE, FALSE, 0);
gtk_radio_button_set_group(GTK_RADIO_BUTTON(dialog->radiobutton1), dialog->radiobutton1_group);
dialog->radiobutton1_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->radiobutton1));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radiobutton1), !right_handed);
dialog->radiobutton2 = gtk_radio_button_new_with_mnemonic(NULL, _("Right handed"));
gtk_widget_show(dialog->radiobutton2);
gtk_box_pack_start(GTK_BOX(dialog->hbox2), dialog->radiobutton2, FALSE, FALSE, 0);
gtk_radio_button_set_group(GTK_RADIO_BUTTON(dialog->radiobutton2), dialog->radiobutton1_group);
dialog->radiobutton1_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->radiobutton2));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radiobutton2), right_handed);
/* motion settings */
dialog->frame2 = xfce_create_framebox (_("Motion settings"), &frame_bin);
gtk_widget_show(dialog->frame2);
gtk_box_pack_start(GTK_BOX(dialog->vbox1), dialog->frame2, FALSE, TRUE, 0);
dialog->table1 = gtk_table_new(2, 4, FALSE);
gtk_widget_show(dialog->table1);
gtk_container_add (GTK_CONTAINER (frame_bin), dialog->table1);
dialog->label3 = gtk_label_new(_("Acceleration :"));
gtk_widget_show(dialog->label3);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label3, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label3), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label3), 0, 0.5);
gtk_size_group_add_widget (sg, dialog->label3);
dialog->label4 = xfce_create_small_label(_("Slow"));
gtk_widget_show(dialog->label4);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label4, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 6, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label4), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label4), 1, 0.5);
dialog->hscale1 = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(acceleration, ACCEL_MIN, ACCEL_MAX, 1, 5, 0)));
gtk_widget_show(dialog->hscale1);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->hscale1, 2, 3, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(dialog->hscale1), FALSE);
gtk_scale_set_digits(GTK_SCALE(dialog->hscale1), 0);
gtk_range_set_update_policy(GTK_RANGE(dialog->hscale1), GTK_UPDATE_DISCONTINUOUS);
dialog->label5 = xfce_create_small_label(_("Fast"));
gtk_widget_show(dialog->label5);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label5, 3, 4, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label5), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label5), 0, 0.5);
dialog->label6 = gtk_label_new(_("Threshold :"));
gtk_widget_show(dialog->label6);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label6, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label6), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label6), 0, 0.5);
gtk_size_group_add_widget (sg, dialog->label6);
dialog->label7 = xfce_create_small_label(_("Low"));
gtk_widget_show(dialog->label7);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label7, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 6, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label7), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label7), 1, 0.5);
dialog->hscale2 = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(threshold, THRESH_MIN, THRESH_MAX, 1, 5, 0)));
gtk_widget_show(dialog->hscale2);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->hscale2, 2, 3, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(dialog->hscale2), FALSE);
gtk_scale_set_digits(GTK_SCALE(dialog->hscale2), 0);
gtk_range_set_update_policy(GTK_RANGE(dialog->hscale2), GTK_UPDATE_DISCONTINUOUS);
dialog->label8 = xfce_create_small_label(_("High"));
gtk_widget_show(dialog->label8);
gtk_table_attach(GTK_TABLE(dialog->table1), dialog->label8, 3, 4, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label8), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label8), 0, 0.5);
/* drag and drop */
dialog->frame3 = xfce_create_framebox (_("Drag and drop"), &frame_bin);
gtk_widget_show(dialog->frame3);
gtk_box_pack_start(GTK_BOX(dialog->vbox1), dialog->frame3, FALSE, TRUE, 0);
dialog->table2 = gtk_table_new(1, 4, FALSE);
gtk_widget_show(dialog->table2);
gtk_container_add (GTK_CONTAINER (frame_bin), dialog->table2);
dialog->label10 = gtk_label_new(_("Threshold :"));
gtk_widget_show(dialog->label10);
gtk_table_attach(GTK_TABLE(dialog->table2), dialog->label10, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label10), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label10), 0, 0.5);
gtk_size_group_add_widget (sg, dialog->label10);
dialog->label11 = xfce_create_small_label(_("Low"));
gtk_widget_show(dialog->label11);
gtk_table_attach(GTK_TABLE(dialog->table2), dialog->label11, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 6, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label11), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label11), 1, 0.5);
dialog->hscale3 = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(dnd_threshold, DND_THRESH_MIN, DND_THRESH_MAX, 1, 5, 0)));
gtk_widget_show(dialog->hscale3);
gtk_table_attach(GTK_TABLE(dialog->table2), dialog->hscale3, 2, 3, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(dialog->hscale3), FALSE);
gtk_scale_set_digits(GTK_SCALE(dialog->hscale3), 0);
gtk_range_set_update_policy(GTK_RANGE(dialog->hscale3), GTK_UPDATE_DISCONTINUOUS);
dialog->label12 = xfce_create_small_label(_("High"));
gtk_widget_show(dialog->label12);
gtk_table_attach(GTK_TABLE(dialog->table2), dialog->label12, 3, 4, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label12), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label12), 0, 0.5);
/* double click */
dialog->frame4 = xfce_create_framebox (_("Double click"), &frame_bin);
gtk_widget_show(dialog->frame4);
gtk_box_pack_start(GTK_BOX(dialog->vbox1), dialog->frame4, FALSE, TRUE, 0);
dialog->table3 = gtk_table_new(1, 4, FALSE);
gtk_widget_show(dialog->table3);
gtk_container_add (GTK_CONTAINER (frame_bin), dialog->table3);
dialog->label14 = gtk_label_new(_("Speed :"));
gtk_widget_show(dialog->label14);
gtk_table_attach(GTK_TABLE(dialog->table3), dialog->label14, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label14), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label14), 0, 0.5);
gtk_size_group_add_widget (sg, dialog->label14);
dialog->label15 = xfce_create_small_label(_("Slow"));
gtk_widget_show(dialog->label15);
gtk_table_attach(GTK_TABLE(dialog->table3), dialog->label15, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 6, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label15), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label15), 1, 0.5);
dialog->hscale4 = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(dbl_clicktime, DBL_CLICK_MIN, DBL_CLICK_MAX, 10, 100, 0)));
gtk_widget_show(dialog->hscale4);
gtk_table_attach(GTK_TABLE(dialog->table3), dialog->hscale4, 2, 3, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(dialog->hscale4), FALSE);
gtk_scale_set_digits(GTK_SCALE(dialog->hscale4), 0);
gtk_range_set_update_policy(GTK_RANGE(dialog->hscale4), GTK_UPDATE_DISCONTINUOUS);
gtk_range_set_inverted(GTK_RANGE(dialog->hscale4), TRUE);
dialog->label16 = xfce_create_small_label(_("Fast"));
gtk_widget_show(dialog->label16);
gtk_table_attach(GTK_TABLE(dialog->table3), dialog->label16, 3, 4, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
gtk_label_set_justify(GTK_LABEL(dialog->label16), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment(GTK_MISC(dialog->label16), 0, 0.5);
/* dialog action area */
dialog->dialog_action_area1 = GTK_DIALOG(dialog->mouse_dialog)->action_area;
gtk_widget_show(dialog->dialog_action_area1);
gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog->dialog_action_area1), GTK_BUTTONBOX_END);
dialog->closebutton1 = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
gtk_widget_show(dialog->closebutton1);
gtk_dialog_add_action_widget(GTK_DIALOG(dialog->mouse_dialog), dialog->closebutton1, GTK_RESPONSE_CLOSE);
GTK_WIDGET_SET_FLAGS(dialog->closebutton1, GTK_CAN_DEFAULT);
#ifdef HAVE_XCURSOR_EXTENSION
label = gtk_label_new(_("Cursor"));
gtk_widget_show(label);
mouse_plugin_create_cursor_page(dialog);
gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), dialog->cursor_page, label);
#endif
#ifdef USE_XKB
label = gtk_label_new(_("Accessibility"));
gtk_widget_show(label);
create_accessx_page(dialog);
gtk_widget_show_all(dialog->accessx_page);
gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), dialog->accessx_page, label);
#endif
return dialog;
}
#ifdef USE_XKB
static void
cb_mouse_tray_icon_embedded(GtkWidget *tray_icon, gpointer user_data)
{
gtk_container_add(GTK_CONTAINER(tray_icon), mouse_tray_image);
gtk_widget_show_all(tray_icon);
}
static void
mouse_tray_icon_reconnect()
{
mouse_tray_icon = netk_tray_icon_new(DefaultScreenOfDisplay(GDK_DISPLAY()));
g_signal_connect(G_OBJECT(mouse_tray_icon), "embedded", G_CALLBACK(cb_mouse_tray_icon_embedded), NULL);
}
static void
cb_mouse_tray_icon_destroy(GtkWidget *tray_icon, GtkWidget *image)
{
gtk_widget_ref(image);
gtk_container_remove(GTK_CONTAINER(tray_icon), image);
mouse_tray_icon_reconnect();
}
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;
if(!mouse_tray_icon)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data(mouse_tray_image_xpm);
mouse_tray_image = gtk_image_new_from_pixbuf(pixbuf);
mouse_tray_icon = netk_tray_icon_new(DefaultScreenOfDisplay(GDK_DISPLAY()));
gtk_container_add(GTK_CONTAINER(mouse_tray_icon), mouse_tray_image);
g_signal_connect(G_OBJECT(mouse_tray_icon), "destroy", G_CALLBACK(cb_mouse_tray_icon_destroy), mouse_tray_image);
}
if(mouse_tray_icon)
gtk_widget_show_all(mouse_tray_icon);
}
else
{
xkb->ctrls->enabled_ctrls &= ~XkbMouseKeysMask;
if(mouse_tray_icon)
gtk_widget_hide(mouse_tray_icon);
}
XkbSetControls (GDK_DISPLAY (), XkbControlsEnabledMask | 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);
mcs_manager_notify(mcs_plugin->manager, CHANNEL2);
mouse_plugin_write_options (mcs_plugin);
}
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);
mcs_manager_notify(mcs_plugin->manager, CHANNEL2);
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);
g_signal_connect(G_OBJECT(itf->radiobutton2), "toggled", G_CALLBACK(cb_righthandled_changed), itf);
g_signal_connect(G_OBJECT(itf->hscale1), "value_changed", (GCallback) cb_acceleration_changed, itf);
g_signal_connect(G_OBJECT(itf->hscale2), "value_changed", (GCallback) cb_threshold_changed, itf);
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));
gtk_widget_show(itf->mouse_dialog);
}
McsPluginInitResult
mcs_plugin_init(McsPlugin *mcs_plugin)
{
/* This is required for UTF-8 at least - Please don't remove it */
xfce_textdomain(GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
create_channel(mcs_plugin);
mcs_plugin->plugin_name = g_strdup(PLUGIN_NAME);
/* the button label in the xfce-mcs-manager dialog */
mcs_plugin->caption = g_strdup (Q_ ("Button Label|Mouse"));
mcs_plugin->run_dialog = run_dialog;
mcs_manager_notify(mcs_plugin->manager, CHANNEL1);
mcs_plugin->icon = xfce_themed_icon_load ("xfce4-mouse", 48);
if (G_LIKELY (mcs_plugin->icon != NULL))
g_object_set_data_full (G_OBJECT (mcs_plugin->icon), "mcs-plugin-icon-name", g_strdup ("xfce4-mouse"), g_free);
return(MCS_PLUGIN_INIT_OK);
}
static void
create_channel(McsPlugin *mcs_plugin)
{
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);
if (!rcfile)
{
rcfile = xfce_get_userfile(OLDRCDIR, RCFILE1, NULL);
}
if (g_file_test (rcfile, G_FILE_TEST_EXISTS))
{
mcs_manager_add_channel_from_file(mcs_plugin->manager, CHANNEL1,
rcfile);
}
else
{
mcs_manager_add_channel(mcs_plugin->manager, CHANNEL1);
}
g_free(path);
g_free(rcfile);
path = g_build_filename ("xfce4", RCDIR, RCFILE2, NULL);
rcfile = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, path);
if (!rcfile)
{
rcfile = xfce_get_userfile(OLDRCDIR, RCFILE2, NULL);
}
if (g_file_test (rcfile, G_FILE_TEST_EXISTS))
{
mcs_manager_add_channel_from_file(mcs_plugin->manager, CHANNEL2, rcfile);
}
else
{
mcs_manager_add_channel(mcs_plugin->manager, CHANNEL2);
}
g_free(path);
g_free(rcfile);
/* Retrieve server defaults */
get_mouse_values(&acceleration, &denominator, &threshold);
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Net/DoubleClickTime", CHANNEL1);
if (setting)
{
dbl_clicktime = setting->data.v_int;
}
else
{
dbl_clicktime = DEFAULT_DBL_CLICKTIME;
mcs_manager_set_int(mcs_plugin->manager, "Net/DoubleClickTime", CHANNEL1, dbl_clicktime);
}
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Net/DndDragThreshold", CHANNEL1);
if(setting)
{
dnd_threshold = setting->data.v_int;
}
else
{
dnd_threshold = DEFAULT_DND_THRESHOLD;
mcs_manager_set_int(mcs_plugin->manager, "Net/DndDragThreshold", CHANNEL1, dnd_threshold);
}
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Mouse/RightHanded", CHANNEL2);
if(setting)
{
right_handed = (setting->data.v_int ? TRUE : FALSE);
}
else
{
right_handed = TRUE;
mcs_manager_set_int(mcs_plugin->manager, "Mouse/RightHanded", CHANNEL2, right_handed ? 1 : 0);
}
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Mouse/Denominator", CHANNEL2);
if((setting) && (setting->data.v_int))
{
denominator = setting->data.v_int;
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Mouse/Acceleration", CHANNEL2);
if(setting)
{
acceleration = setting->data.v_int;
}
else
{
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Acceleration", CHANNEL2, acceleration);
}
setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Mouse/Threshold", CHANNEL2);
if(setting)
{
threshold = setting->data.v_int;
}
else
{
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Threshold", CHANNEL2, threshold);
}
}
else
{
/* Set default server values */
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Denominator", CHANNEL2, denominator);
mcs_manager_set_int(mcs_plugin->manager, "Mouse/Acceleration", CHANNEL2, acceleration);
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;
}
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
mouse_plugin_set_initial_cursor_values(mcs_plugin);
#endif
#if 0
/* I fail to see why we need to save the options here, during startup... */
mouse_plugin_write_options (mcs_plugin);
#endif
}
gboolean
mouse_plugin_write_options(McsPlugin *mcs_plugin)
{
gboolean result = FALSE;
gchar *rcfile, *path;
path = g_build_filename ("xfce4", RCDIR, RCFILE1, NULL);
rcfile = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, path, TRUE);
if (G_LIKELY (rcfile != NULL))
{
result = mcs_manager_save_channel_to_file (mcs_plugin->manager, CHANNEL1, rcfile);
g_free (rcfile);
}
g_free (path);
path = g_build_filename ("xfce4", RCDIR, RCFILE2, NULL);
rcfile = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, path, TRUE);
if (G_LIKELY (rcfile != NULL))
{
result &= mcs_manager_save_channel_to_file (mcs_plugin->manager, CHANNEL2, rcfile);
g_free (rcfile);
}
g_free (path);
return(result);
}
static void
run_dialog(McsPlugin *mcs_plugin)
{
static Itf *dialog = NULL;
xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
if (is_running)
{
if((dialog) && (dialog->mouse_dialog))
{
gtk_window_present(GTK_WINDOW(dialog->mouse_dialog));
}
return;
}
is_running = TRUE;
dialog = create_mouse_dialog(mcs_plugin);
setup_dialog(dialog);
}
/* macro defined in manager-plugin.h */
MCS_PLUGIN_CHECK_INIT
syntax highlighted by Code2HTML, v. 0.9.1