4
* Copyright 2009 PCMan <pcman.tw@gmail.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27
#include <glib/gi18n.h>
33
#include <X11/XKBlib.h>
35
static char* file = NULL;
38
static GtkWidget *dlg;
39
static GtkRange *mouse_accel;
40
static GtkRange *mouse_threshold;
41
static GtkToggleButton* mouse_left_handed;
42
static GtkRange *kb_delay;
43
static GtkRange *kb_interval;
44
static GtkToggleButton* kb_beep;
46
static int accel = 20, old_accel = 20;
47
static int threshold = 10, old_threshold = 10;
48
static gboolean left_handed = FALSE, old_left_handed = FALSE;
50
static int delay = 500, old_delay = 500;
51
static int interval = 30, old_interval = 30;
52
static gboolean beep = TRUE, old_beep = TRUE;
55
static void on_mouse_accel_changed(GtkRange* range, gpointer user_data)
57
accel = (int)gtk_range_get_value(range);
58
XChangePointerControl(GDK_DISPLAY(), True, False,
62
static void on_mouse_threshold_changed(GtkRange* range, gpointer user_data)
64
/* threshold = 110 - sensitivity. The lower the threshold, the higher the sensitivity */
65
threshold = 110 - (int)gtk_range_get_value(range);
66
XChangePointerControl(GDK_DISPLAY(), False, True,
70
static void on_kb_range_changed(GtkRange* range, int* val)
72
*val = (int)gtk_range_get_value(range);
73
/* apply keyboard values */
74
XkbSetAutoRepeatRate(GDK_DISPLAY(), XkbUseCoreKbd, delay, interval);
77
/* This function is taken from Gnome's control-center 2.6.0.3 (gnome-settings-mouse.c) and was modified*/
78
#define DEFAULT_PTR_MAP_SIZE 128
79
static void set_left_handed_mouse()
81
unsigned char *buttons;
83
gint idx_1 = 0, idx_3 = 1;
85
buttons = g_alloca (DEFAULT_PTR_MAP_SIZE);
86
n_buttons = XGetPointerMapping (GDK_DISPLAY(), buttons, DEFAULT_PTR_MAP_SIZE);
87
if (n_buttons > DEFAULT_PTR_MAP_SIZE)
89
buttons = g_alloca (n_buttons);
90
n_buttons = XGetPointerMapping (GDK_DISPLAY(), buttons, n_buttons);
93
for (i = 0; i < n_buttons; i++)
97
else if (buttons[i] == ((n_buttons < 3) ? 2 : 3))
101
if ((left_handed && idx_1 < idx_3) ||
102
(!left_handed && idx_1 > idx_3))
104
buttons[idx_1] = ((n_buttons < 3) ? 2 : 3);
106
XSetPointerMapping (GDK_DISPLAY(), buttons, n_buttons);
110
static void on_left_handed_toggle(GtkToggleButton* btn, gpointer user_data)
112
left_handed = gtk_toggle_button_get_active(btn);
113
set_left_handed_mouse(left_handed);
116
static void on_kb_beep_toggle(GtkToggleButton* btn, gpointer user_data)
118
XKeyboardControl values;
119
beep = gtk_toggle_button_get_active(btn);
120
values.bell_percent = beep ? -1 : 0;
121
XChangeKeyboardControl(GDK_DISPLAY(), KBBellPercent, &values);
124
static gboolean on_change_val(GtkRange *range, GtkScrollType scroll,
125
gdouble value, gpointer user_data)
127
int interval = GPOINTER_TO_INT(user_data);
131
static void set_range_stops(GtkRange* range, int interval )
134
g_signal_connect(range, "change-value",
135
G_CALLBACK(on_change_val), GINT_TO_POINTER(interval));
139
static void load_settings()
142
const char* session_name = g_getenv("DESKTOP_SESSION");
143
/* load settings from current session config files */
145
session_name = "LXDE";
146
file = g_build_filename( g_get_user_config_dir(), "lxsession", session_name, "desktop.conf", NULL );
147
ret = g_key_file_load_from_file( kf, file, 0, NULL );
152
val = g_key_file_get_integer(kf, "Mouse", "AccFactor", NULL);
154
old_accel = accel = val;
156
val = g_key_file_get_integer(kf, "Mouse", "AccThreshold", NULL);
158
old_threshold = threshold = val;
160
old_left_handed = left_handed = g_key_file_get_boolean(kf, "Mouse", "LeftHanded", NULL);
162
val = g_key_file_get_integer(kf, "Keyboard", "Delay", NULL);
164
old_delay = delay = val;
165
val = g_key_file_get_integer(kf, "Keyboard", "Interval", NULL);
167
old_interval = interval = val;
169
if( g_key_file_has_key(kf, "Keyboard", "Beep", NULL ) )
170
old_beep = beep = g_key_file_get_boolean(kf, "Keyboard", "Beep", NULL);
174
int main(int argc, char** argv)
181
bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
182
bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
183
textdomain ( GETTEXT_PACKAGE );
186
gtk_init(&argc, &argv);
188
gtk_icon_theme_prepend_search_path(gtk_icon_theme_get_default(), PACKAGE_DATA_DIR);
191
builder = gtk_builder_new();
193
gtk_builder_add_from_file( builder, PACKAGE_DATA_DIR "/lxinput.ui", NULL );
194
dlg = (GtkWidget*)gtk_builder_get_object( builder, "dlg" );
195
gtk_dialog_set_alternative_button_order( (GtkDialog*)dlg, GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1 );
197
mouse_accel = (GtkRange*)gtk_builder_get_object(builder,"mouse_accel");
198
mouse_threshold = (GtkRange*)gtk_builder_get_object(builder,"mouse_threshold");
199
mouse_left_handed = (GtkToggleButton*)gtk_builder_get_object(builder,"left_handed");
201
kb_delay = (GtkRange*)gtk_builder_get_object(builder,"kb_delay");
202
kb_interval = (GtkRange*)gtk_builder_get_object(builder,"kb_interval");
203
kb_beep = (GtkToggleButton*)gtk_builder_get_object(builder,"beep");
205
g_object_unref( builder );
208
/* read the config flie */
209
kf = g_key_file_new();
213
gtk_range_set_value(mouse_accel, accel);
214
gtk_range_set_value(mouse_threshold, 110-threshold);
215
gtk_toggle_button_set_active(mouse_left_handed, left_handed);
217
gtk_range_set_value(kb_delay, delay);
218
gtk_range_set_value(kb_interval, interval);
219
gtk_toggle_button_set_active(kb_beep, beep);
221
set_range_stops(mouse_accel, 10);
222
g_signal_connect(mouse_accel, "value-changed", G_CALLBACK(on_mouse_accel_changed), NULL);
223
set_range_stops(mouse_threshold, 10);
224
g_signal_connect(mouse_threshold, "value-changed", G_CALLBACK(on_mouse_threshold_changed), NULL);
225
g_signal_connect(mouse_left_handed, "toggled", G_CALLBACK(on_left_handed_toggle), NULL);
227
set_range_stops(kb_delay, 10);
228
g_signal_connect(kb_delay, "value-changed", G_CALLBACK(on_kb_range_changed), &kb_delay);
229
set_range_stops(kb_interval, 10);
230
g_signal_connect(kb_interval, "value-changed", G_CALLBACK(on_kb_range_changed), &kb_interval);
231
g_signal_connect(kb_beep, "toggled", G_CALLBACK(on_kb_beep_toggle), NULL);
233
if( gtk_dialog_run( (GtkDialog*)dlg ) == GTK_RESPONSE_OK )
237
g_key_file_set_integer(kf, "Mouse", "AccFactor", accel);
238
g_key_file_set_integer(kf, "Mouse", "AccThreshold", threshold);
239
g_key_file_set_integer(kf, "Mouse", "LeftHanded", !!left_handed);
241
g_key_file_set_integer(kf, "Keyboard", "Delay", delay);
242
g_key_file_set_integer(kf, "Keyboard", "Interval", interval);
243
g_key_file_set_integer(kf, "Keyboard", "Beep", !!beep);
245
if( str = g_key_file_to_data( kf, &len, NULL ) )
247
if( g_file_set_contents( file, str, len, &err ) )
249
/* ask the settigns daemon to reload */
250
/* FIXME: is this needed? */
251
/* g_spawn_command_line_sync("lxde-settings-daemon reload", NULL, NULL, NULL, NULL); */
262
/* restore to original settings */
266
interval = old_interval;
268
XkbSetAutoRepeatRate(GDK_DISPLAY(), XkbUseCoreKbd, delay, interval);
273
threshold = old_threshold;
274
left_handed = old_left_handed;
275
XChangePointerControl(GDK_DISPLAY(), True, True,
276
accel, 10, threshold);
277
set_left_handed_mouse();
280
gtk_widget_destroy( dlg );
283
g_key_file_free( kf );