Always register core devices
Even with XInput support we should always register core devices. This allows us to handle enter and leave events correctly on the Stage and to have a working XInput 1.x support in Clutter.
This commit is contained in:
parent
e0b8d63159
commit
d8e167f151
@ -99,12 +99,11 @@ static void
|
||||
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 ();
|
||||
@ -126,6 +125,8 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
|
||||
goto default_device;
|
||||
}
|
||||
|
||||
backend->xi_event_base = event;
|
||||
|
||||
x_devices = XListInputDevices (backend->xdpy, &n_devices);
|
||||
if (n_devices == 0)
|
||||
{
|
||||
@ -149,14 +150,12 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
|
||||
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
|
||||
@ -178,40 +177,14 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
|
||||
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:
|
||||
@ -220,35 +193,31 @@ 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;
|
||||
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;
|
||||
|
||||
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", 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
|
||||
|
@ -76,6 +76,7 @@ struct _ClutterBackendX11
|
||||
Atom atom_NET_WM_NAME;
|
||||
Atom atom_UTF8_STRING;
|
||||
|
||||
int xi_event_base;
|
||||
int event_types[CLUTTER_X11_XINPUT_LAST_EVENT];
|
||||
gboolean have_xinput;
|
||||
|
||||
|
@ -803,11 +803,54 @@ event_translate (ClutterBackend *backend,
|
||||
|
||||
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",
|
||||
@ -858,6 +901,7 @@ event_translate (ClutterBackend *backend,
|
||||
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,
|
||||
@ -887,6 +931,7 @@ event_translate (ClutterBackend *backend,
|
||||
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,
|
||||
|
@ -141,14 +141,14 @@ _clutter_input_device_x11_construct (ClutterInputDevice *device,
|
||||
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)
|
||||
{
|
||||
@ -169,19 +169,19 @@ _clutter_input_device_x11_construct (ClutterInputDevice *device,
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user