+static void
+_deregister_keygrab (SpiDEController *controller,
+ DEControllerGrabMask *grab_mask)
+{
+ GList *l;
+
+ l = g_list_find_custom (controller->keygrabs_list, grab_mask,
+ spi_grab_mask_compare_values);
+
+ if (l)
+ {
+ DEControllerGrabMask *cur_mask = l->data;
+
+ cur_mask->ref_count--;
+ if (cur_mask->ref_count <= 0)
+ {
+ cur_mask->pending_remove = TRUE;
+ }
+ }
+ else
+ {
+ g_warning ("De-registering non-existant grab");
+ }
+}
+
+static void
+handle_keygrab (SpiDEController *controller,
+ DEControllerKeyListener *key_listener,
+ void (*process_cb) (SpiDEController *controller,
+ DEControllerGrabMask *grab_mask))
+{
+ DEControllerGrabMask grab_mask = { 0 };
+
+ grab_mask.mod_mask = key_listener->mask;
+ if (key_listener->keys->_length == 0) /* special case means AnyKey/AllKeys */
+ {
+ grab_mask.key_val = AnyKey;
+ process_cb (controller, &grab_mask);
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < key_listener->keys->_length; ++i)
+ {
+ long int key_val = key_listener->keys->_buffer[i];
+ /* X Grabs require keycodes, not keysyms */
+ if (key_val >= 0)
+ {
+ key_val = XKeysymToKeycode (spi_get_display (), (KeySym) key_val);
+ }
+ grab_mask.key_val = key_val;
+
+ process_cb (controller, &grab_mask);
+ }
+ }
+}
+
+static void
+spi_controller_register_global_keygrabs (SpiDEController *controller,
+ DEControllerKeyListener *key_listener)
+{
+ handle_keygrab (controller, key_listener, _register_keygrab);
+ spi_controller_update_key_grabs (controller, NULL);