device-manager: Select for events on XIAllMasterDevices

This removes a bit of work that we have to do for every device, and makes it
easy for mutter to patch out parts of the event mask it doesn't want.

https://bugzilla.gnome.org/show_bug.cgi?id=703969
This commit is contained in:
Jasper St. Pierre 2013-07-10 16:53:26 -04:00
parent 032688800c
commit e62cf4745f
6 changed files with 49 additions and 84 deletions

View File

@ -137,8 +137,6 @@ struct _ClutterInputDeviceClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (* select_stage_events) (ClutterInputDevice *device,
ClutterStage *stage);
gboolean (* keycode_to_evdev) (ClutterInputDevice *device, gboolean (* keycode_to_evdev) (ClutterInputDevice *device,
guint hardware_keycode, guint hardware_keycode,
guint *evdev_keycode); guint *evdev_keycode);
@ -196,9 +194,6 @@ void _clutter_input_device_add_slave (ClutterInputDev
void _clutter_input_device_remove_slave (ClutterInputDevice *master, void _clutter_input_device_remove_slave (ClutterInputDevice *master,
ClutterInputDevice *slave); ClutterInputDevice *slave);
void _clutter_input_device_select_stage_events (ClutterInputDevice *device,
ClutterStage *stage);
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
guint index_, guint index_,
gdouble value, gdouble value,

View File

@ -307,20 +307,12 @@ _clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manage
ClutterStage *stage) ClutterStage *stage)
{ {
ClutterDeviceManagerClass *manager_class; ClutterDeviceManagerClass *manager_class;
const GSList *devices, *d;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
devices = manager_class->get_devices (device_manager); if (manager_class->select_stage_events)
manager_class->select_stage_events (device_manager, stage);
for (d = devices; d != NULL; d = d->next)
{
ClutterInputDevice *device = d->data;
if (device->is_enabled)
_clutter_input_device_select_stage_events (device, stage);
}
} }
/* /*

View File

@ -81,9 +81,11 @@ struct _ClutterDeviceManagerClass
ClutterInputDevice *device); ClutterInputDevice *device);
void (* remove_device) (ClutterDeviceManager *manager, void (* remove_device) (ClutterDeviceManager *manager,
ClutterInputDevice *device); ClutterInputDevice *device);
void (* select_stage_events) (ClutterDeviceManager *manager,
ClutterStage *stage);
/* padding */ /* padding */
gpointer _padding[8]; gpointer _padding[7];
}; };

View File

@ -1615,26 +1615,6 @@ clutter_input_device_get_associated_device (ClutterInputDevice *device)
return device->associated; return device->associated;
} }
/*< internal >
* clutter_input_device_select_stage_events:
* @device: a #ClutterInputDevice
* @stage: the #ClutterStage to select events on
*
* Selects input device events on @stage.
*
* The implementation of this function depends on the backend used.
*/
void
_clutter_input_device_select_stage_events (ClutterInputDevice *device,
ClutterStage *stage)
{
ClutterInputDeviceClass *device_class;
device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
if (device_class->select_stage_events != NULL)
device_class->select_stage_events (device, stage);
}
/** /**
* clutter_input_device_keycode_to_evdev: * clutter_input_device_keycode_to_evdev:
* @device: A #ClutterInputDevice * @device: A #ClutterInputDevice

View File

@ -688,6 +688,49 @@ scroll_valuators_changed (ClutterInputDevice *device,
return retval; return retval;
} }
static void
clutter_device_manager_xi2_select_stage_events (ClutterDeviceManager *manager,
ClutterStage *stage)
{
ClutterBackendX11 *backend_x11;
ClutterStageX11 *stage_x11;
XIEventMask xi_event_mask;
unsigned char *mask;
int len;
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
len = XIMaskLen (XI_LASTEVENT);
mask = g_new0 (unsigned char, len);
XISetMask (mask, XI_Motion);
XISetMask (mask, XI_ButtonPress);
XISetMask (mask, XI_ButtonRelease);
XISetMask (mask, XI_KeyPress);
XISetMask (mask, XI_KeyRelease);
XISetMask (mask, XI_Enter);
XISetMask (mask, XI_Leave);
#ifdef HAVE_XINPUT_2_2
/* enable touch event support if we're running on XInput 2.2 */
if (backend_x11->xi_minor >= 2)
{
XISetMask (mask, XI_TouchBegin);
XISetMask (mask, XI_TouchUpdate);
XISetMask (mask, XI_TouchEnd);
}
#endif /* HAVE_XINPUT_2_2 */
xi_event_mask.deviceid = XIAllMasterDevices;
xi_event_mask.mask = mask;
xi_event_mask.mask_len = len;
XISelectEvents (backend_x11->xdpy, stage_x11->xwin, &xi_event_mask, 1);
g_free (mask);
}
static ClutterTranslateReturn static ClutterTranslateReturn
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
gpointer native, gpointer native,
@ -1483,6 +1526,7 @@ clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass)
manager_class->get_devices = clutter_device_manager_xi2_get_devices; manager_class->get_devices = clutter_device_manager_xi2_get_devices;
manager_class->get_core_device = clutter_device_manager_xi2_get_core_device; manager_class->get_core_device = clutter_device_manager_xi2_get_core_device;
manager_class->get_device = clutter_device_manager_xi2_get_device; manager_class->get_device = clutter_device_manager_xi2_get_device;
manager_class->select_stage_events = clutter_device_manager_xi2_select_stage_events;
} }
static void static void

View File

@ -53,53 +53,6 @@ G_DEFINE_TYPE (ClutterInputDeviceXI2,
clutter_input_device_xi2, clutter_input_device_xi2,
CLUTTER_TYPE_INPUT_DEVICE); CLUTTER_TYPE_INPUT_DEVICE);
static void
clutter_input_device_xi2_select_stage_events (ClutterInputDevice *device,
ClutterStage *stage)
{
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
ClutterBackendX11 *backend_x11;
ClutterStageX11 *stage_x11;
XIEventMask xi_event_mask;
unsigned char *mask;
int len;
backend_x11 = CLUTTER_BACKEND_X11 (device->backend);
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
len = XIMaskLen (XI_LASTEVENT);
mask = g_new0 (unsigned char, len);
XISetMask (mask, XI_Motion);
XISetMask (mask, XI_ButtonPress);
XISetMask (mask, XI_ButtonRelease);
XISetMask (mask, XI_KeyPress);
XISetMask (mask, XI_KeyRelease);
XISetMask (mask, XI_Enter);
XISetMask (mask, XI_Leave);
#ifdef HAVE_XINPUT_2_2
/* enable touch event support if we're running on XInput 2.2 */
if (backend_x11->xi_minor >= 2)
{
XISetMask (mask, XI_TouchBegin);
XISetMask (mask, XI_TouchUpdate);
XISetMask (mask, XI_TouchEnd);
}
#endif /* HAVE_XINPUT_2_2 */
xi_event_mask.deviceid = device_xi2->device_id;
xi_event_mask.mask = mask;
xi_event_mask.mask_len = len;
CLUTTER_NOTE (BACKEND, "Selecting device id '%d' events",
device_xi2->device_id);
XISelectEvents (backend_x11->xdpy, stage_x11->xwin, &xi_event_mask, 1);
g_free (mask);
}
static void static void
clutter_input_device_xi2_constructed (GObject *gobject) clutter_input_device_xi2_constructed (GObject *gobject)
{ {
@ -133,7 +86,6 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
gobject_class->constructed = clutter_input_device_xi2_constructed; gobject_class->constructed = clutter_input_device_xi2_constructed;
device_class->select_stage_events = clutter_input_device_xi2_select_stage_events;
device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev; device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
} }