Description: Fix crash with Xkb extension
Author: Roland Stigge <stigge@antcom.de>

Index: keybinder/libkeybinder/bind.c
===================================================================
--- keybinder.orig/libkeybinder/bind.c	2012-05-27 02:08:28.917918754 +0200
+++ keybinder/libkeybinder/bind.c	2012-05-27 02:11:02.237923451 +0200
@@ -71,6 +71,8 @@
 static GSList *bindings = NULL;
 static guint32 last_event_time = 0;
 static gboolean processing_event = FALSE;
+static gboolean detected_xkb_extension = FALSE;
+static gboolean use_xkb_extension = FALSE;
 
 /* Return the modifier mask that needs to be pressed to produce key in the
  * given group (keyboard layout) and level ("shift level").
@@ -191,13 +193,15 @@
 	int k;
 	GdkKeymapKey *keys;
 	gint n_keys;
-	GdkModifierType add_modifiers;
-	XkbDescPtr xmap;
+	GdkModifierType add_modifiers = 0;
+	XkbDescPtr xmap = NULL;
 	gboolean success = FALSE;
 
-	xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
-	                 XkbAllClientInfoMask,
-	                 XkbUseCoreKbd);
+	if (use_xkb_extension) {
+		xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
+		                 XkbAllClientInfoMask,
+		                 XkbUseCoreKbd);
+	}
 
 	gdk_keymap_get_entries_for_keyval(NULL, keyval, &keys, &n_keys);
 
@@ -213,16 +217,24 @@
 			continue;
 		}
 
-		add_modifiers = FinallyGetModifiersForKeycode(xmap,
+
+		TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
+			keys[k].keycode, keys[k].level, keys[k].group));
+		if (use_xkb_extension) {
+			add_modifiers = FinallyGetModifiersForKeycode(xmap,
 		                                              keys[k].keycode,
 		                                              keys[k].group,
 		                                              keys[k].level);
+		} else if (keys[k].level > 0) {
+			/* skip shifted/modified keys in non-xkb mode
+			 * this might mean the key can't be bound at all
+			 */
+			continue;
+		}
 
 		if (add_modifiers == MODIFIERS_ERROR) {
 			continue;
 		}
-		TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
-			keys[k].keycode, keys[k].level, keys[k].group));
 		TRACE (g_print("modifiers: 0x%x (consumed: 0x%x)\n",
 		               add_modifiers | modifiers, add_modifiers));
 		if (grab_ungrab_with_ignorable_modifiers(rootwin,
@@ -240,7 +252,9 @@
 
 	}
 	g_free(keys);
-	XkbFreeClientMap(xmap, 0, TRUE);
+	if (xmap) {
+		XkbFreeClientMap(xmap, 0, TRUE);
+	}
 
 	return success;
 }
@@ -357,7 +371,8 @@
 				xevent->xkey.keycode, 
 				xevent->xkey.state));
 
-		gdk_keymap_translate_keyboard_state(
+		if (use_xkb_extension) {
+			gdk_keymap_translate_keyboard_state(
 				keymap,
 				xevent->xkey.keycode,
 				modifiers,
@@ -366,6 +381,10 @@
 				 */
 				WE_ONLY_USE_ONE_GROUP,
 				&keyval, NULL, NULL, &consumed);
+		} else {
+			consumed = 0;
+			keyval = XLookupKeysym(&xevent->xkey, 0);
+		}
 
 		/* Map non-virtual to virtual modifiers */
 		modifiers &= ~consumed;
@@ -431,6 +450,26 @@
 {
 	GdkKeymap *keymap = gdk_keymap_get_default ();
 	GdkWindow *rootwin = gdk_get_default_root_window ();
+	Display *disp;
+	int xkb_opcode;
+	int xkb_event_base;
+	int xkb_error_base;
+	int majver = XkbMajorVersion;
+	int minver = XkbMinorVersion;
+
+	if (!(disp = XOpenDisplay(NULL))) {
+		g_warning("keybinder_init: Unable to open display");
+		return;
+	}
+
+	detected_xkb_extension = XkbQueryExtension(disp,
+	                                           &xkb_opcode,
+	                                           &xkb_event_base,
+	                                           &xkb_error_base,
+	                                           &majver, &minver);
+
+	use_xkb_extension = detected_xkb_extension;
+	TRACE(g_print("XKB: %d, version: %d, %d\n", use_xkb_extension, majver, minver));
 
 	gdk_window_add_filter (rootwin, filter_func, NULL);
 
@@ -448,6 +487,12 @@
 			  NULL);
 }
 
+void
+keybinder_set_use_cooked_accelerators (gboolean use_cooked)
+{
+       use_xkb_extension = use_cooked && detected_xkb_extension;
+}
+
 gboolean
 keybinder_bind (const char *keystring,
                 KeybinderHandler handler,
Index: keybinder/libkeybinder/keybinder.h
===================================================================
--- keybinder.orig/libkeybinder/keybinder.h	2012-05-27 02:08:28.917918754 +0200
+++ keybinder/libkeybinder/keybinder.h	2012-05-27 02:11:02.237923451 +0200
@@ -32,6 +32,8 @@
 
 void keybinder_init (void);
 
+void keybinder_set_use_cooked_accelerators (gboolean use_cooked);
+
 gboolean keybinder_bind (const char *keystring,
                          KeybinderHandler  handler,
                          void *user_data);
