diff options
author | Brian Cameron <Brian.Cameron@Sun.Com> | 2005-02-14 22:22:42 +0000 |
---|---|---|
committer | Brian Cameron <bcameron@src.gnome.org> | 2005-02-14 22:22:42 +0000 |
commit | c17679d7b3d3ee59a0f2b732bf09133b17582c2e (patch) | |
tree | 96c58c70a396b519deea5f9889569bc3a4ade682 | |
parent | b007f1be1ca71a2c094bb50700bc0e87bf70aea5 (diff) | |
download | gdm-c17679d7b3d3ee59a0f2b732bf09133b17582c2e.tar.gz |
Updated files to also integrate patch for bug #142834.
Thu Feb 14 16:20:00 2005 Brian Cameron <Brian.Cameron@Sun.Com>
* acconfig.h, gui/modules/Makefile.am,
gui/modules/dwellmouselistener.c,
gui/modules/keymouselistener.c: Updated files to
also integrate patch for bug #142834.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | acconfig.h | 9 | ||||
-rw-r--r-- | gui/modules/Makefile.am | 4 | ||||
-rw-r--r-- | gui/modules/dwellmouselistener.c | 14 | ||||
-rw-r--r-- | gui/modules/keymouselistener.c | 225 |
5 files changed, 159 insertions, 102 deletions
@@ -1,3 +1,10 @@ +Thu Feb 14 16:20:00 2005 Brian Cameron <Brian.Cameron@Sun.Com> + + * acconfig.h, gui/modules/Makefile.am, + gui/modules/dwellmouselistener.c, + gui/modules/keymouselistener.c: Updated files to + also integrate patch for bug #142834. + Thu Feb 14 15:10:00 2005 Brian Cameron <Brian.Cameron@Sun.Com> * configure.in, gui/modules/AccessKeyMouseEvents.in, @@ -5,7 +12,7 @@ Thu Feb 14 15:10:00 2005 Brian Cameron <Brian.Cameron@Sun.Com> gui/modules/keymouselistener.c: Update gesture listeners so that they listen for XInput events. Also adds better default gestures for gok and gnopernicus. - Fixes bug 142833. + Fixes bug #142833. Thu Feb 07 21:10:00 2005 Brian Cameron <Brian.Cameron@Sun.Com> @@ -25,16 +25,17 @@ #undef HAVE_PASSWDEXPIRED #undef HAVE_SCHED_YIELD #undef HAVE_SELINUX +#undef HAVE_SETENV +#undef HAVE_SETRESUID #undef HAVE_SHADOW +#undef HAVE_SOLARIS_XINERAMA #undef HAVE_STPCPY #undef HAVE_SYS_SOCKIO_H #undef HAVE_TCPWRAPPERS +#undef HAVE_UNSETENV #undef HAVE_XINERAMA #undef HAVE_XFREE_XINERAMA -#undef HAVE_SOLARIS_XINERAMA -#undef HAVE_SETENV -#undef HAVE_UNSETENV -#undef HAVE_SETRESUID +#undef HAVE_XINPUT #undef EXPANDED_AUTHDIR #undef EXPANDED_DATADIR #undef EXPANDED_BINDIR diff --git a/gui/modules/Makefile.am b/gui/modules/Makefile.am index cdd7f351..a117a039 100644 --- a/gui/modules/Makefile.am +++ b/gui/modules/Makefile.am @@ -22,7 +22,7 @@ libkeymouselistener_la_LDFLAGS = \ -rpath $(moduledir) -module -avoid-version \ $(GUI_LIBS) \ $(X_LIBS) \ - $(X_EXTRA_LIBS) \ + $(X_EXTRA_LIBS) \ -L$(top_builddir)/vicious-extensions \ -lviciousui @@ -33,7 +33,7 @@ libdwellmouselistener_la_LDFLAGS = \ -rpath $(moduledir) -module -avoid-version \ $(GUI_LIBS) \ $(X_LIBS) \ - $(X_EXTRA_LIBS) \ + $(X_EXTRA_LIBS) \ -L$(top_builddir)/vicious-extensions \ -lviciousui diff --git a/gui/modules/dwellmouselistener.c b/gui/modules/dwellmouselistener.c index 10cba22a..0ed59cf6 100644 --- a/gui/modules/dwellmouselistener.c +++ b/gui/modules/dwellmouselistener.c @@ -33,11 +33,11 @@ #include <X11/Xlib.h> #include <config.h> - + #ifdef HAVE_XINPUT #include <X11/extensions/XInput.h> #endif - + /* * Note that CONFIGFILE will have to be changed to something more generic * if this module is ever moved outside of gdm. @@ -87,7 +87,6 @@ static GSList *binding_list = NULL; extern char **environ; static guint enter_signal_id = 0; static guint leave_signal_id = 0; - static int xinput_type_motion = 0; static Crossings *crossings = NULL; @@ -96,7 +95,7 @@ static guint max_crossings = 0; static XID *ext_input_devices = NULL; static gint ext_device_count = 0; static gboolean latch_core_pointer = TRUE; - + static void create_event_watcher (); static void load_bindings(gchar *path); static gchar * screen_exec_display_string (GdkScreen *screen, const char *old); @@ -112,6 +111,7 @@ is_ext_device (XID id) gint i; for (i = 0; i < ext_device_count; i++) if (id == ext_input_devices[i]) return TRUE; + g_message ("is-ext-device failed for %d", id); return FALSE; } @@ -667,8 +667,8 @@ leave_enter_emission_hook (GSignalInvocationHint *ihint, g_timeout_add (2000, change_cursor_back, NULL); - latch_core_pointer = FALSE; - /* once we've recognized a gesture, we need to leave the pointer alone */ + latch_core_pointer = FALSE; + /* once we've recognized a gesture, we need to leave the pointer alone */ } } } @@ -743,7 +743,7 @@ create_event_watcher (void) G_MODULE_EXPORT void gtk_module_init (int *argc, char* argv[]); void gtk_module_init (int *argc, char* argv[]) -{ +{ create_event_watcher (); } diff --git a/gui/modules/keymouselistener.c b/gui/modules/keymouselistener.c index 6660cba5..98ce7c87 100644 --- a/gui/modules/keymouselistener.c +++ b/gui/modules/keymouselistener.c @@ -42,33 +42,18 @@ #include <X11/extensions/XInput.h> #endif + /* * Note that CONFIGFILE will have to be changed to something more generic * if this module is ever moved outside of gdm. */ +#undef DEBUG_GESTURES + #define CONFIGFILE EXPANDED_SYSCONFDIR "/gdm/modules/AccessKeyMouseEvents" #define iseol(ch) ((ch) == '\r' || (ch) == '\f' || (ch) == '\0' || \ (ch) == '\n') -#ifdef HAVE_XINPUT -#define XEV_KEYCODE(xev) ((xev->type == KeyPress || xev->type == KeyRelease ) ? xev->xkey.keycode :\ - (xev->type == xinput_types[XINPUT_TYPE_KEY_PRESS] || \ - xev->type == xinput_types[XINPUT_TYPE_KEY_RELEASE]) ?\ - ((XDeviceKeyEvent *)xev)->keycode : -1) -#else -#define XEV_KEYCODE(xev) (xev->xkey.keycode) -#endif - -#ifdef HAVE_XINPUT -#define XEV_STATE(xev) ((xev->type == KeyPress || xev->type == KeyRelease ) ? xev->xkey.state :\ - (xev->type == xinput_types[XINPUT_TYPE_KEY_PRESS] || \ - xev->type == xinput_types[XINPUT_TYPE_KEY_RELEASE]) ?\ - ((XDeviceKeyEvent *)xev)->state : -1) -#else -#define XEV_STATE(xev) (xev->xkey.state) -#endif - #define N_INPUT_TYPES 40 typedef enum @@ -110,6 +95,8 @@ typedef struct { guint n_times; guint duration; guint timeout; + gint start_time; + gint seq_count; } Gesture; static int xinput_types[N_INPUT_TYPES]; @@ -123,11 +110,12 @@ static void create_event_watcher (); static void load_gestures(gchar *path); static gchar ** get_exec_environment (XEvent *xevent); static Gesture * parse_line(gchar *buf); -static gboolean gesture_already_used (Gesture *gesture); static GdkFilterReturn gestures_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data); static gint is_mouseX (const gchar *string); static gint is_switchX (const gchar *string); +#define gesture_list_get_matches(a, b, c) (g_slist_find_custom (a, b, c)) + static void free_gesture (Gesture *gesture) { @@ -286,10 +274,8 @@ load_gestures(gchar *path) } free_gesture (tmp_gesture); /* We must be able to deal with multiple unambiguous gestures attached to one switch/button */ - } else if (1) /* ! gesture_already_used (tmp_gesture)) see bug 144048 */ + } else gesture_list = g_slist_append (gesture_list, tmp_gesture); - else - free_gesture (tmp_gesture); } } fclose(fp); @@ -379,7 +365,10 @@ parse_line (gchar *buf) if (strcmp (tmp_gesture->gesture_str, "<Add>") != 0) { guint n, duration, timeout; gchar *tmp_string; - + + tmp_gesture->start_time = 0; + tmp_gesture->seq_count = 0; + button = is_mouseX (tmp_gesture->gesture_str); if (button > 0) { tmp_gesture->type = GESTURE_TYPE_MOUSE; @@ -504,39 +493,12 @@ parse_line (gchar *buf) /* * These modifiers are ignored because they make no sense. - * .eg <NumLock>x + * .eg <NumLock>x + * FIXME: [sadly, NumLock isn't always mapped to the same modifier, so the logic below is faulty - bill] */ -#define IGNORED_MODS (GDK_LOCK_MASK | \ - GDK_MOD3_MASK | GDK_MOD5_MASK) +#define IGNORED_MODS (GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK) #define USED_MODS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | \ - GDK_MOD2_MASK | GDK_MOD4_MASK) - -#define N_BITS 32 - -static gboolean -gesture_already_used (Gesture *gesture) -{ - GSList *li; - - for (li = gesture_list; li != NULL; li = li->next) { - Gesture *tmp_gesture = (Gesture*) li->data; - - if (tmp_gesture != gesture && tmp_gesture->type == gesture->type) { - switch (tmp_gesture->type) { - case (GESTURE_TYPE_KEY): - if (tmp_gesture->input.key.keycode == gesture->input.key.keycode && - tmp_gesture->input.key.state == gesture->input.key.state) - return TRUE; - case (GESTURE_TYPE_MOUSE): - if (tmp_gesture->input.button.number == gesture->input.button.number) - return TRUE; - default: - break; - } - } - } - return FALSE; -} + GDK_MOD4_MASK | GDK_MOD5_MASK) static gboolean change_cursor_back (gpointer data) @@ -549,30 +511,87 @@ change_cursor_back (gpointer data) } static gint +event_time (XEvent *ev) +{ + if ((ev->type == KeyPress) || + (ev->type == KeyRelease)) + return ((XKeyEvent *) ev)->time; + else if ((ev->type == ButtonPress) || + (ev->type == ButtonRelease)) + return ((XButtonEvent *) ev)->time; + else if ((ev->type == xinput_types[XINPUT_TYPE_KEY_PRESS]) || + (ev->type == xinput_types[XINPUT_TYPE_KEY_RELEASE])) + return ((XDeviceKeyEvent *) ev)->time; + else if ((ev->type == xinput_types[XINPUT_TYPE_BUTTON_PRESS]) || + (ev->type == xinput_types[XINPUT_TYPE_BUTTON_RELEASE])) + return ((XDeviceButtonEvent *) ev)->time; + else + return 0; +} + +static gint +elapsed_time (XEvent *ev1, XEvent *ev2) +{ + return event_time (ev2) - event_time (ev1); +} + +static gboolean +keycodes_equal (XEvent *ev1, XEvent *ev2) +{ + if (ev1->type == ev2->type) + { + if (ev1->type == KeyPress || ev1->type == KeyRelease) + { + return (((XKeyEvent *) ev1)->keycode == ((XKeyEvent *) ev2)->keycode); + } + else if (ev1->type == xinput_types[XINPUT_TYPE_KEY_PRESS] || ev1->type == xinput_types[XINPUT_TYPE_KEY_RELEASE]) + { + return (((XDeviceKeyEvent *) ev1)->keycode == ((XDeviceKeyEvent *) ev2)->keycode); + } + } + return FALSE; +} + +static gint key_gesture_compare_func (gconstpointer a, gconstpointer b) { const Gesture *gesture = a; const XEvent *xev = b; - if ((gesture->type == GESTURE_TYPE_KEY) && - (XEV_KEYCODE (xev) == gesture->input.key.keycode) && - ((XEV_STATE (xev) & USED_MODS) == gesture->input.key.state)) + if (gesture->type == GESTURE_TYPE_KEY) + { + if (((xev->type == KeyPress) || (xev->type == KeyRelease)) && + (xev->xkey.keycode == gesture->input.key.keycode) && + ((xev->xkey.state & USED_MODS) == gesture->input.key.state)) + return 0; + else if (((xev->type == xinput_types[XINPUT_TYPE_KEY_PRESS]) || (xev->type == xinput_types[XINPUT_TYPE_KEY_RELEASE])) && + (xev->xkey.keycode == gesture->input.key.keycode) && + ((xev->xkey.state & USED_MODS) == gesture->input.key.state)) return 0; + else + return 1; + } else if ((gesture->type == GESTURE_TYPE_MOUSE) && - (xev->type == ButtonPress || xev->type == ButtonRelease) && + ((xev->type == ButtonPress) || (xev->type == ButtonRelease)) && (xev->xbutton.button == gesture->input.button.number)) return 0; else if ((gesture->type == GESTURE_TYPE_BUTTON) && -#ifdef HAVE_XINPUT - (xev->type == xinput_types [XINPUT_TYPE_BUTTON_PRESS] || - xev->type == xinput_types[XINPUT_TYPE_BUTTON_RELEASE]) && -#endif + ((xev->type == xinput_types[XINPUT_TYPE_BUTTON_PRESS]) || (xev->type == xinput_types[XINPUT_TYPE_BUTTON_RELEASE])) && ((XDeviceButtonEvent *) xev)->button == gesture->input.button.number) return 0; else return 1; } +#define event_is_gesture_type(xevent) (xevent->type == KeyPress ||\ + xevent->type == KeyRelease ||\ + xevent->type == ButtonPress ||\ + xevent->type == ButtonRelease ||\ + xevent->type == xinput_types[XINPUT_TYPE_KEY_PRESS] ||\ + xevent->type == xinput_types[XINPUT_TYPE_KEY_RELEASE] ||\ + xevent->type == xinput_types[XINPUT_TYPE_BUTTON_PRESS] ||\ + xevent->type == xinput_types[XINPUT_TYPE_BUTTON_RELEASE]) + static GdkFilterReturn gestures_filter (GdkXEvent *gdk_xevent, GdkEvent *event, @@ -586,58 +605,72 @@ gestures_filter (GdkXEvent *gdk_xevent, static XEvent *last_event = NULL; static gint seq_count = 0; - if (xevent->type != KeyPress && - xevent->type != KeyRelease && - xevent->type != ButtonPress && - xevent->type != ButtonRelease && - xevent->type != xinput_types[XINPUT_TYPE_KEY_PRESS] && - xevent->type != xinput_types[XINPUT_TYPE_KEY_RELEASE] && - xevent->type != xinput_types[XINPUT_TYPE_BUTTON_PRESS] && - xevent->type != xinput_types[XINPUT_TYPE_BUTTON_RELEASE]) - return GDK_FILTER_CONTINUE; + if (!event_is_gesture_type (xevent)) + return GDK_FILTER_CONTINUE; if (!last_event) last_event = g_new0(XEvent, 1); if ((xevent->type == KeyPress) || (xevent->type == xinput_types[XINPUT_TYPE_KEY_PRESS])) { +#ifdef DEBUG_GESTURES + g_message ("key press"); +#endif if (last_event->type == KeyPress && last_event->xkey.keycode == xevent->xkey.keycode) { - /* they comes from auto key-repeat */ + /* these come from auto key-repeat */ +#ifdef DEBUG_GESTURES + g_message ("rejecting repeat"); +#endif return GDK_FILTER_CONTINUE; } - if (seq_count > 0 && - (xevent->type == KeyPress && - last_event->type != KeyRelease)) { + if (seq_count > 0 && + last_event->type != KeyRelease) { +#ifdef DEBUG_GESTURES + g_message ("last event wasn't a release, resetting seq"); +#endif seq_count = 0; } else if (seq_count > 0 && - xevent->type == KeyPress && - last_event->xkey.keycode != xevent->xkey.keycode) { + keycodes_equal (last_event, xevent)) { +#ifdef DEBUG_GESTURES + g_message ("keycode doesn't match last event, resetting seq"); +#endif seq_count = 0; } /* * Find the associated gesture for this keycode & state */ - li = g_slist_find_custom (gesture_list, xevent, key_gesture_compare_func); + li = gesture_list_get_matches (gesture_list, xevent, key_gesture_compare_func); if (li) { curr_gesture = li->data; +#ifdef DEBUG_GESTURES + g_message ("found a press match [%s]", curr_gesture->gesture_str); +#endif if (curr_gesture->timeout > 0 && seq_count > 0 && /* xevent time values are in milliseconds. The config file spec is in ms */ - (xevent->xkey.time - last_event->xkey.time) > curr_gesture->timeout) { + elapsed_time (last_event, xevent) > curr_gesture->timeout) { +#ifdef DEBUG_GESTURES + g_message ("timeout exceeded: reset seq and gesture"); +#endif seq_count = 0; /* The timeout has been exceeded. Reset the sequence. */ - curr_gesture = NULL; } } } else if ((xevent->type == KeyRelease) || (xevent->type == xinput_types[XINPUT_TYPE_KEY_RELEASE])) { +#ifdef DEBUG_GESTURES + g_message ("key release"); +#endif if (seq_count > 0 && - (last_event->type != KeyPress || - last_event->xkey.keycode != xevent->xkey.keycode)) { + ((last_event->type != KeyPress && last_event->type != xinput_types[XINPUT_TYPE_KEY_PRESS]) || + !keycodes_equal (last_event, xevent))) { +#ifdef DEBUG_GESTURES + g_message ("either last event not a keypress, or keycodes don't match. Resetting seq."); +#endif seq_count = 0; } @@ -648,15 +681,24 @@ gestures_filter (GdkXEvent *gdk_xevent, * otherwise key gestures based on modifier keys such as * Control_R won't work. */ - li = g_slist_find_custom (gesture_list, xevent, key_gesture_compare_func); + li = gesture_list_get_matches (gesture_list, xevent, key_gesture_compare_func); if (li) { curr_gesture = li->data; +#ifdef DEBUG_GESTURES + g_message ("found a release match [%s]", curr_gesture->gesture_str); +#endif if ((curr_gesture->duration > 0) && - ((xevent->xkey.time - last_event->xkey.time) < curr_gesture->duration)) { + (elapsed_time (last_event, xevent) < curr_gesture->duration)) { seq_count = 0; curr_gesture = NULL; +#ifdef DEBUG_GESTURES + g_message ("setting current gesture to NULL"); +#endif } else { seq_count++; +#ifdef DEBUG_GESTURES + g_message ("incrementing seq_count"); +#endif } } } @@ -665,9 +707,13 @@ gestures_filter (GdkXEvent *gdk_xevent, gint button = 0; gint time = 0; + if (xevent->type == ButtonPress) { button = xevent->xbutton.button; time = xevent->xbutton.time; +#ifdef DEBUG_GESTURES + g_message ("button press: %d", button); +#endif if (seq_count > 0 && (last_event->type != ButtonRelease)) seq_count = 0; else if (seq_count > 0 && last_event->xbutton.button != button) { @@ -678,6 +724,9 @@ gestures_filter (GdkXEvent *gdk_xevent, else { button = ((XDeviceButtonEvent *) xevent)->button; time = ((XDeviceButtonEvent *) xevent)->time; +#ifdef DEBUG_GESTURES + g_message ("xinput button press: %d", button); +#endif if (seq_count > 0 && last_event->type != xinput_types[XINPUT_TYPE_BUTTON_RELEASE]) { seq_count = 0; } @@ -690,7 +739,7 @@ gestures_filter (GdkXEvent *gdk_xevent, /* * Find the associated gesture for this button. */ - li = g_slist_find_custom (gesture_list, xevent, key_gesture_compare_func); + li = gesture_list_get_matches (gesture_list, xevent, key_gesture_compare_func); if (li) { #ifdef DEBUG_GESTURES g_message ("found match for press"); @@ -699,7 +748,7 @@ gestures_filter (GdkXEvent *gdk_xevent, if (curr_gesture->timeout > 0 && seq_count > 0) { /* xevent time values are in milliseconds. The config file spec is in ms */ if (curr_gesture->type == - (xevent->xbutton.time - last_event->xbutton.time) > curr_gesture->timeout) { + elapsed_time (last_event, xevent) > curr_gesture->timeout) { seq_count = 0; /* Timeout has elapsed. Reset the sequence. */ curr_gesture = NULL; #ifdef DEBUG_GESTURES @@ -747,14 +796,14 @@ gestures_filter (GdkXEvent *gdk_xevent, } #endif - li = g_slist_find_custom (gesture_list, xevent, key_gesture_compare_func); + li = gesture_list_get_matches (gesture_list, xevent, key_gesture_compare_func); if (li) { #ifdef DEBUG_GESTURES g_message ("found match for release"); #endif curr_gesture = li->data; if ((curr_gesture->duration > 0) && - ((time - last_event->xbutton.time) < curr_gesture->duration)) { + (elapsed_time (last_event, xevent) < curr_gesture->duration)) { seq_count = 0; curr_gesture = NULL; #ifdef DEBUG_GESTURES |