summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Cameron <Brian.Cameron@Sun.COM>2003-05-02 15:03:22 +0000
committerBrian Cameron <bcameron@src.gnome.org>2003-05-02 15:03:22 +0000
commit8b9efea85eba07815d25257059e9c9bafbb1fc8f (patch)
tree481fc0c05c5d703ae8ca1d801c6a38aa074c2399
parent3c333da3f8f2ebe83195a2771f3bab7c528bb70a (diff)
downloadgdm-8b9efea85eba07815d25257059e9c9bafbb1fc8f.tar.gz
gui/modules/keymouselistener.c, gui/modules/AccessKeyMouseEvents.in Now
2003-05-02 Brian Cameron <Brian.Cameron@Sun.COM> * gui/modules/keymouselistener.c, gui/modules/AccessKeyMouseEvents.in Now the keymouselistener does not use grabs, so there is less opportunity for conflict with other programs (like the registryd). Now duration and timeout is specified in ms rather than seconds, which allows more flexibility. Duration values of 0 to indicate a keypress of any length is now supported.
-rw-r--r--ChangeLog9
-rw-r--r--gui/modules/AccessKeyMouseEvents.in19
-rw-r--r--gui/modules/keymouselistener.c132
3 files changed, 42 insertions, 118 deletions
diff --git a/ChangeLog b/ChangeLog
index 84de90a5..4ea7a738 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-05-02 Brian Cameron <Brian.Cameron@Sun.COM>
+ * gui/modules/keymouselistener.c, gui/modules/AccessKeyMouseEvents.in
+ Now the keymouselistener does not use grabs, so there is less
+ opportunity for conflict with other programs (like the registryd).
+ Now duration and timeout is specified in ms rather than seconds,
+ which allows more flexibility. Duration values of 0 to indicate
+ a keypress of any length is now supported.
+
2003-04-30 Niall Power <Niall.Power@Sun.COM>
* configure.in config/gdm.conf.in gui/Makefile.am gui/gdmlogin.c
@@ -18,6 +26,7 @@
with a configurable list of gtk modules. Needed for accessibility.
Adds two new options to gdm.conf: "AddGtkModules" (boolean) and
"GtkModulesList" (string).
+
2003-04-09 Niall Power <Niall.Power@Sun.COM>
* acconfig.h, configure.in: Detect Xsun xinerama and Xdmcp on
Solaris. Patch by Brian Cameron <Brian.Cameron@Sun.COM>
diff --git a/gui/modules/AccessKeyMouseEvents.in b/gui/modules/AccessKeyMouseEvents.in
index c35850e2..b7ab1082 100644
--- a/gui/modules/AccessKeyMouseEvents.in
+++ b/gui/modules/AccessKeyMouseEvents.in
@@ -1,19 +1,28 @@
# This is the configuration file for the keymouselistener.so module.
# The confiuration syntax is as follows:
+#
# For keyboard bindings:
# <modifier>[<modifier>...]key #times duration timeout full_executable_path +args
# e.g.
-# <Control>k 5 1 10 @EXPANDED_BINDIR@/gok
-# Means press Contol-k 5 times, holding the keys down for at least 1 second each time
-# and with no greater interval than 10 seconds between each event in the sequence
-# Completing the sequence will invoke the gnome on screen keyboard program, gok.
+# <Control>k 5 1000 10000 @EXPANDED_BINDIR@/gok
+#
+# Means press Contol-k 5 times, holding each keypress down for at least 1000ms
+# each time and with no greater interval than 10000ms between each event in the
+# sequence. A duration value of 0 indicates that a keypress of any length is
+# accepted. The timeout value is only meaningful if the #times value is > 1.
+# Completing the above example sequence will invoke the gnome on screen keyboard
+# program, gok.
+#
# For mouse button bindings the format is the same except the mouse button number
# is specified instead of a keybinding
+#
# <Mouse#> #times duration timeout full_executable_path +args
# e.g.
-# <Mouse2> 4 3 6 @EXPANDED_BINDIR/gnopernicus
+# <Mouse2> 4 3000 6000 @EXPANDED_BINDIR/gnopernicus
+#
# It is possible to invoke multiple actions from a single binding using the <Add>
# keyword. Each action must be written on a seperate line along with any arguments
# beneath the previous mousebutton or key binding. If none exists the line is ignored.
# e.g.
+#
# <Add> @EXPANDED_BINDIR/gnome-mag
diff --git a/gui/modules/keymouselistener.c b/gui/modules/keymouselistener.c
index b9e9b8ad..6b0bfdb6 100644
--- a/gui/modules/keymouselistener.c
+++ b/gui/modules/keymouselistener.c
@@ -87,8 +87,6 @@ static void load_bindings(gchar *path);
static gchar ** get_exec_environment (XEvent *xevent);
static Binding * parse_line(gchar *buf);
static gboolean binding_already_used (Binding *binding);
-static void do_key_grab (gboolean grab, Key *key);
-static void do_button_grab (gboolean grab, Button *button);
static GdkFilterReturn
bindings_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data);
static gint is_mouseX (const gchar *string);
@@ -129,36 +127,19 @@ static void create_event_watcher ()
{
GSList *li;
GdkDisplay *display;
- GdkScreen *screen;
display = gdk_display_get_default();
- if(!display) {
+ if (!display) {
return;
}
+
/*
* Switch off keyboard autorepeat
*/
XAutoRepeatOff(GDK_DISPLAY_XDISPLAY(display));
-
load_bindings(CONFIGFILE);
-
- for (li = binding_list; li != NULL; li = li->next) {
- Binding *binding = (Binding*) li->data;
- switch (binding->type) {
- case BINDING_TYPE_KEY:
- do_key_grab(TRUE, &(binding->input.key));
- break;
- case BINDING_TYPE_MOUSE:
- do_button_grab(TRUE, &(binding->input.button));
- break;
- default:
- break;
- }
- }
+ gdk_window_add_filter (NULL, bindings_filter, NULL);
- screen = gdk_display_get_screen(display, 0);
- gdk_window_add_filter (gdk_screen_get_root_window (screen),
- bindings_filter, NULL);
return;
}
@@ -360,7 +341,7 @@ parse_line(gchar *buf)
}
*c++ = '\0';
- if ((duration=atoi(tmp_string)) <= 0) {
+ if ((duration=atoi(tmp_string)) < 0) {
/* Add an error message */
return NULL;
}
@@ -452,85 +433,6 @@ binding_already_used (Binding *binding)
return FALSE;
}
-/* inspired from all_combinations from gnome-panel/gnome-panel/global-keys.c */
-static void
-do_key_grab (gboolean grab, Key *key)
-{
- gint indexes[N_BITS];/*indexes of bits we need to flip*/
- gint i, bit, bits_set_cnt;
- gint uppervalue;
- guint mask_to_traverse = IGNORED_MODS & ~ key->state;
- GdkDisplay *dpy = gdk_display_get_default ();
- gint screen_num = gdk_display_get_n_screens (dpy);
-
- bit = 0;
- for (i = 0; i < N_BITS; i++) {
- if (mask_to_traverse & (1<<i))
- indexes[bit++]=i;
- }
-
- bits_set_cnt = bit;
-
- uppervalue = 1<<bits_set_cnt;
- for (i = 0; i < uppervalue; i++) {
- gint j, k, result = 0;
-
- for (j = 0; j < bits_set_cnt; j++) {
- if (i & (1<<j))
- result |= (1<<indexes[j]);
- }
-
- for (k = 0; k < screen_num; k++) {
- GdkScreen *screen = gdk_display_get_screen (dpy, k);
- Window xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen));
-
- if (grab) {
- XGrabKey (GDK_DISPLAY_XDISPLAY (dpy),
- key->keycode,
- (result | key->state),
- xroot,
- False,
- GrabModeAsync,
- GrabModeAsync);
- } else
- XUngrabKey(GDK_DISPLAY_XDISPLAY (dpy),
- key->keycode,
- (result | key->state),
- xroot);
- }
- }
-}
-
-static void
-do_button_grab (gboolean grab, Button *button)
-{
- gint i;
- GdkDisplay *dpy = gdk_display_get_default ();
- gint screen_num = gdk_display_get_n_screens (dpy);
-
- for (i = 0; i < screen_num; i++) {
- GdkScreen *screen = gdk_display_get_screen (dpy, i);
- Window xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen));
-
- if (grab)
- XGrabButton (GDK_DISPLAY_XDISPLAY (dpy),
- button->number,
- AnyModifier,
- xroot,
- False,
- ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync,
- GrabModeAsync,
- 0,
- None);
- else
- XUngrabButton(GDK_DISPLAY_XDISPLAY (dpy),
- button->number,
- AnyModifier,
- xroot);
- }
-}
-
GdkFilterReturn
bindings_filter (GdkXEvent *gdk_xevent,
GdkEvent *event,
@@ -544,16 +446,18 @@ bindings_filter (GdkXEvent *gdk_xevent,
static Binding *curr_binding = NULL;
static gint seq_count = 0;
- if(xevent->type != KeyPress &&
- xevent->type != KeyRelease &&
- xevent->type != ButtonPress &&
- xevent->type != ButtonRelease)
- return GDK_FILTER_CONTINUE;
+ if (xevent->type != KeyPress &&
+ xevent->type != KeyRelease &&
+ xevent->type != ButtonPress &&
+ xevent->type != ButtonRelease)
+ return GDK_FILTER_CONTINUE;
if (!last_event)
last_event = g_new0(XEvent, 1);
+
switch (xevent->type) {
+
case KeyPress:
if (last_event->type != KeyRelease) {
seq_count = 0;
@@ -579,7 +483,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
curr_binding = binding;
if (binding->timeout > 0) {
/* xevent time values are in milliseconds. The config file spec is in seconds */
- if ((xevent->xkey.time - last_event->xkey.time) > (binding->timeout * 1000))
+ if ((xevent->xkey.time - last_event->xkey.time) > binding->timeout)
seq_count = 0; /* The timeout has been exceeded. Reset the sequence. */
}
}
@@ -587,6 +491,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
}
}
break;
+
case KeyRelease:
if ((last_event->type != KeyPress) ||
last_event->xkey.keycode != xevent->xkey.keycode ||
@@ -609,8 +514,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
*/
curr_binding = binding;
if ((binding->duration > 0) &&
- ((xevent->xkey.time - last_event->xkey.time) < (binding->duration * 1000))
- )
+ ((xevent->xkey.time - last_event->xkey.time) < binding->duration))
seq_count = 0;
else
seq_count++;
@@ -618,6 +522,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
}
}
break;
+
case ButtonPress:
if(last_event->type != ButtonRelease)
seq_count = 0;
@@ -640,7 +545,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
curr_binding = binding;
if (binding->timeout > 0 ) {
/* xevent time values are in milliseconds. The config file spec is in seconds */
- if ((xevent->xbutton.time - last_event->xbutton.time) > (binding->timeout * 1000))
+ if ((xevent->xbutton.time - last_event->xbutton.time) > binding->timeout)
seq_count = 0; /* Timeout has elapsed. Reset the sequence. */
}
}
@@ -648,6 +553,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
}
}
break;
+
case ButtonRelease:
if (last_event->type != ButtonPress ||
last_event->xbutton.button != xevent->xbutton.button)
@@ -667,8 +573,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
*/
curr_binding = binding;
if ((binding->duration > 0) &&
- ((xevent->xbutton.time - last_event->xbutton.time) < (binding->duration * 1000))
- )
+ ((xevent->xbutton.time - last_event->xbutton.time) < binding->duration))
seq_count = 0;
else
seq_count++;
@@ -676,6 +581,7 @@ bindings_filter (GdkXEvent *gdk_xevent,
}
}
break;
+
default:
break;
}