clutter_x11_register_input_devices (ClutterBackendX11 *backend)
{
ClutterDeviceManager *manager;
- gboolean have_an_xpointer = FALSE;
+ ClutterInputDevice *device;
#ifdef HAVE_XINPUT
XDeviceInfo *x_devices = NULL;
int res, opcode, event, error;
int i, n_devices;
- GSList *devices = NULL;
#endif /* HAVE_XINPUT */
manager = clutter_device_manager_get_default ();
goto default_device;
}
+ backend->xi_event_base = event;
+
x_devices = XListInputDevices (backend->xdpy, &n_devices);
if (n_devices == 0)
{
info->use == IsXExtensionDevice)
{
ClutterInputDeviceType device_type;
- ClutterInputDevice *device;
gint n_events = 0;
switch (info->use)
{
case IsXExtensionPointer:
device_type = CLUTTER_POINTER_DEVICE;
- have_an_xpointer = TRUE;
break;
#if 0
NULL);
n_events = _clutter_input_device_x11_construct (device, backend);
- if (info->use == IsXExtensionPointer && n_events > 0)
- have_an_xpointer = TRUE;
+ _clutter_device_manager_add_device (manager, device);
- /* add it to a temporary list; we don't add the device
- * straight to the device manager because the XInput
- * initialization might still fail
- */
- devices = g_slist_prepend (devices, device);
+ if (info->use == IsXExtensionPointer && n_events > 0)
+ backend->have_xinput = TRUE;
}
}
XFree (x_devices);
-
- devices = g_slist_reverse (devices);
-
- if (have_an_xpointer)
- {
- GSList *l;
-
- for (l = devices; l != NULL; l = l->next)
- _clutter_device_manager_add_device (manager, l->data);
-
- backend->have_xinput = TRUE;
- }
- else
- {
- g_warning ("No usable XInput pointer devices found");
-
- g_slist_foreach (devices, (GFunc) g_object_unref, NULL);
-
- backend->have_xinput = FALSE;
- }
-
- g_slist_free (devices);
#endif /* HAVE_XINPUT */
default_device:
* - we do not have XInput support compiled in
* - we do not have XInput support enabled
* - we do not have the XInput extension
- * - we do not have a XInput pointer device
*
* we register two default devices, one for the pointer
- * and one for the keyboard
+ * and one for the keyboard. this block must also be
+ * executed for the XInput support because XI does not
+ * cover core devices
*/
- if (!have_an_xpointer)
- {
- ClutterInputDevice *d;
-
- d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
- "id", 0,
- "name", "Core Pointer",
- "device-type", CLUTTER_POINTER_DEVICE,
- "is-core", TRUE,
- NULL);
- CLUTTER_NOTE (BACKEND, "Added core pointer device %d", d->id);
- _clutter_device_manager_add_device (manager, d);
- backend->core_pointer = d;
-
- d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
- "id", 1,
- "name", "Core Keyboard",
- "device-type", CLUTTER_KEYBOARD_DEVICE,
- "is-core", TRUE,
- NULL);
- CLUTTER_NOTE (BACKEND, "Added core keyboard device %d", d->id);
- _clutter_device_manager_add_device (manager, d);
- backend->core_keyboard = d;
- }
+ device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
+ "id", 0,
+ "name", "Core Pointer",
+ "device-type", CLUTTER_POINTER_DEVICE,
+ "is-core", TRUE,
+ NULL);
+ CLUTTER_NOTE (BACKEND, "Added core pointer device");
+ _clutter_device_manager_add_device (manager, device);
+ backend->core_pointer = device;
+
+ device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
+ "id", 1,
+ "name", "Core Keyboard",
+ "device-type", CLUTTER_KEYBOARD_DEVICE,
+ "is-core", TRUE,
+ NULL);
+ CLUTTER_NOTE (BACKEND, "Added core keyboard device");
+ _clutter_device_manager_add_device (manager, device);
+ backend->core_keyboard = device;
}
gboolean
CLUTTER_NOTE (EVENT, "XInput event type: %d", xevent->type);
- if (xevent->type == button_press)
+ if (xevent->type == EnterNotify)
+ {
+ device = backend_x11->core_pointer;
+
+ /* Convert enter notifies to motion events because X
+ doesn't emit the corresponding motion notify */
+ event->motion.type = event->type = CLUTTER_MOTION;
+ event->motion.time = xevent->xcrossing.time;
+ event->motion.x = xevent->xcrossing.x;
+ event->motion.y = xevent->xcrossing.y;
+ event->motion.modifier_state = xevent->xcrossing.state;
+ event->motion.source = CLUTTER_ACTOR (stage);
+ event->motion.device = device;
+
+ /* we know that we are entering the stage here */
+ _clutter_input_device_set_stage (device, stage);
+ CLUTTER_NOTE (EVENT, "Entering the stage");
+ }
+ else if (xevent->type == LeaveNotify)
+ {
+ device = backend_x11->core_pointer;
+
+ if (device->stage == NULL)
+ {
+ CLUTTER_NOTE (EVENT,
+ "Discarding LeaveNotify for ButtonRelease "
+ "event off-stage");
+ return FALSE;
+ }
+
+ event->crossing.type = event->type = CLUTTER_LEAVE;
+ event->crossing.time = xevent->xcrossing.time;
+ event->crossing.x = xevent->xcrossing.x;
+ event->crossing.y = xevent->xcrossing.y;
+ event->crossing.source = CLUTTER_ACTOR (stage);
+ event->crossing.device = device;
+
+ /* we know that we are leaving the stage here */
+ _clutter_input_device_set_stage (device, NULL);
+ CLUTTER_NOTE (EVENT, "Leaving the stage (time:%u)",
+ event->crossing.time);
+ }
+ else if (xevent->type == button_press)
{
XDeviceButtonEvent *xbev = (XDeviceButtonEvent *) xevent;
device = _clutter_x11_get_device_for_xid (xbev->deviceid);
+ _clutter_input_device_set_stage (device, stage);
CLUTTER_NOTE (EVENT,
"XI ButtonPress for %li ('%s') at %d, %d",
XDeviceButtonEvent *xbev = (XDeviceButtonEvent *)xevent;
device = _clutter_x11_get_device_for_xid (xbev->deviceid);
+ _clutter_input_device_set_stage (device, stage);
CLUTTER_NOTE (EVENT, "XI ButtonRelease for %li ('%s') at %d, %d",
xbev->deviceid,
XDeviceMotionEvent *xmev = (XDeviceMotionEvent *)xevent;
device = _clutter_x11_get_device_for_xid (xmev->deviceid);
+ _clutter_input_device_set_stage (device, stage);
CLUTTER_NOTE(EVENT, "XI Motion for %li ('%s') at %d, %d",
xmev->deviceid,
for (i = 0; i < x_device->num_classes; i++)
{
XInputClassInfo *xclass_info = x_device->classes + i;
- int button_press, button_release, motion_notify;
+ int *button_press, *button_release, *motion_notify;
button_press =
- backend->event_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT];
+ &backend->event_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT];
button_release =
- backend->event_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT];
+ &backend->event_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT];
motion_notify =
- backend->event_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT];
+ &backend->event_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT];
switch (xclass_info->input_class)
{
case ButtonClass:
DeviceButtonPress (x_device,
- button_press,
+ *button_press,
device_x11->xevent_list[n_events]);
n_events++;
DeviceButtonRelease (x_device,
- button_release,
+ *button_release,
device_x11->xevent_list[n_events]);
n_events++;
break;
case ValuatorClass:
DeviceMotionNotify (x_device,
- motion_notify,
+ *motion_notify,
device_x11->xevent_list[n_events]);
n_events++;
break;