+ guint i = 0;
+ guint num, caps, scroll;
+
+ num = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_NUMLOCK);
+ caps = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CAPSLOCK);
+ scroll = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SCROLLLOCK);
+
+ mask_list[i++] = 0;
+ mask_list[i++] = num;
+ mask_list[i++] = caps;
+ mask_list[i++] = scroll;
+ mask_list[i++] = num | caps;
+ mask_list[i++] = num | scroll;
+ mask_list[i++] = caps | scroll;
+ mask_list[i++] = num | caps | scroll;
+ g_assert(i == MASK_LIST_SIZE);
+
+ ic = obt_keyboard_context_new(obt_root(ob_screen), grab_window());
+}
+
+void grab_shutdown(gboolean reconfig)
+{
+ obt_keyboard_context_unref(ic);
+ ic = NULL;
+
+ if (reconfig) return;
+
+ while (ungrab_keyboard());
+ while (ungrab_pointer());
+ while (grab_server(FALSE));
+}
+
+void grab_button_full(guint button, guint state, Window win, guint mask,
+ gint pointer_mode, ObCursor cur)
+{
+ guint i;
+
+ /* can get BadAccess from these */
+ obt_display_ignore_errors(TRUE);
+ for (i = 0; i < MASK_LIST_SIZE; ++i)
+ XGrabButton(obt_display, button, state | mask_list[i], win, False,
+ mask, pointer_mode, GrabModeAsync, None, ob_cursor(cur));
+ obt_display_ignore_errors(FALSE);
+ if (obt_display_error_occured)
+ ob_debug("Failed to grab button %d modifiers %d", button, state);
+}
+
+void ungrab_button(guint button, guint state, Window win)
+{
+ guint i;
+
+ for (i = 0; i < MASK_LIST_SIZE; ++i)
+ XUngrabButton(obt_display, button, state | mask_list[i], win);
+}
+
+void grab_key(guint keycode, guint state, Window win, gint keyboard_mode)
+{
+ guint i;
+
+ /* can get BadAccess' from these */
+ obt_display_ignore_errors(TRUE);
+ for (i = 0; i < MASK_LIST_SIZE; ++i)
+ XGrabKey(obt_display, keycode, state | mask_list[i], win, FALSE,
+ GrabModeAsync, keyboard_mode);
+ obt_display_ignore_errors(FALSE);
+ if (obt_display_error_occured)
+ ob_debug("Failed to grab keycode %d modifiers %d", keycode, state);
+}
+
+void ungrab_all_keys(Window win)
+{
+ XUngrabKey(obt_display, AnyKey, AnyModifier, win);
+}
+
+void grab_key_passive_count(int change)
+{
+ if (grab_on_keyboard()) return;
+ passive_count += change;
+ if (passive_count < 0) passive_count = 0;
+}
+
+void ungrab_passive_key(void)
+{
+ /*ob_debug("ungrabbing %d passive grabs\n", passive_count);*/
+ if (passive_count) {
+ /* kill our passive grab */
+ XUngrabKeyboard(obt_display, event_time());
+ passive_count = 0;
+ }