+ guint i = 0;
+ guint num, caps, scroll;
+
+ num = modkeys_key_to_mask(OB_MODKEY_KEY_NUMLOCK);
+ caps = modkeys_key_to_mask(OB_MODKEY_KEY_CAPSLOCK);
+ scroll = modkeys_key_to_mask(OB_MODKEY_KEY_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);
+}
+
+void grab_shutdown(gboolean reconfig)
+{
+ 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;
+
+ xerror_set_ignore(TRUE); /* can get BadAccess from these */
+ xerror_occured = FALSE;
+ for (i = 0; i < MASK_LIST_SIZE; ++i)
+ XGrabButton(ob_display, button, state | mask_list[i], win, False, mask,
+ pointer_mode, GrabModeAsync, None, ob_cursor(cur));
+ xerror_set_ignore(FALSE);
+ if (xerror_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(ob_display, button, state | mask_list[i], win);
+}
+
+void grab_key(guint keycode, guint state, Window win, gint keyboard_mode)
+{
+ guint i;
+
+ xerror_set_ignore(TRUE); /* can get BadAccess' from these */
+ xerror_occured = FALSE;
+ for (i = 0; i < MASK_LIST_SIZE; ++i)
+ XGrabKey(ob_display, keycode, state | mask_list[i], win, FALSE,
+ GrabModeAsync, keyboard_mode);
+ xerror_set_ignore(FALSE);
+ if (xerror_occured)
+ ob_debug("Failed to grab keycode %d modifiers %d", keycode, state);
+}
+
+void ungrab_all_keys(Window win)
+{
+ XUngrabKey(ob_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()
+{
+ ob_debug("ungrabbing %d passive grabs\n", passive_count);
+ if (passive_count) {
+ /* kill out passive grab */
+ XUngrabKeyboard(ob_display, event_curtime);
+ passive_count = 0;
+ }