x11: Always handle core device events before XI events

The XI 1.0 layer is complementary to the X11 core devices handling; this
means that core events will still be emitted for the core pointer and
keyboard devices, and that secondary (floating) devices should be
handled on top of that.

Thus, the XI event handling code should be executed (if explicitly
compiled in and enabled) if the core device events have not been parsed.

Note: this is going away with XI2, which completely replaces both core and
XI1 events.
This commit is contained in:
Emmanuele Bassi 2010-01-15 16:28:00 +00:00
parent dc39e9eff9
commit 94f9f3bd93

View File

@ -1,7 +1,8 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
* Authored By Matthew Allum <mallum@openedhand.com>
* Copyright (C) 2006-2007 OpenedHand
*
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
* Copyright (C) 2009, 2010 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -17,6 +18,10 @@
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authored by:
* Matthew Allum <mallum@openedhand.com>
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
@ -669,8 +674,6 @@ event_translate (ClutterBackend *backend,
/* Input device event handling.. */
if (not_yet_handled)
{
if (!clutter_x11_has_xinput ())
{
device = backend_x11->core_pointer;
@ -714,6 +717,8 @@ event_translate (ClutterBackend *backend,
}
set_user_time (backend_x11, &xwindow, event->button.time);
res = TRUE;
break;
case ButtonRelease:
@ -724,7 +729,7 @@ event_translate (ClutterBackend *backend,
xevent->xbutton.button == 7)
{
res = FALSE;
break;
goto out;
}
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
@ -734,6 +739,8 @@ event_translate (ClutterBackend *backend,
event->button.modifier_state = xevent->xbutton.state;
event->button.button = xevent->xbutton.button;
event->button.device = device;
res = TRUE;
break;
case MotionNotify:
@ -743,9 +750,15 @@ event_translate (ClutterBackend *backend,
event->motion.y = xevent->xmotion.y;
event->motion.modifier_state = xevent->xmotion.state;
event->motion.device = device;
res = TRUE;
break;
case EnterNotify:
/* we know that we are entering the stage here */
_clutter_input_device_set_stage (device, stage);
CLUTTER_NOTE (EVENT, "Entering the stage");
/* Convert enter notifies to motion events because X
doesn't emit the corresponding motion notify */
event->motion.type = event->type = CLUTTER_MOTION;
@ -756,9 +769,7 @@ event_translate (ClutterBackend *backend,
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");
res = TRUE;
break;
case LeaveNotify:
@ -768,30 +779,32 @@ event_translate (ClutterBackend *backend,
"Discarding LeaveNotify for ButtonRelease "
"event off-stage");
res = FALSE;
break;
goto out;
}
/* 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);
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);
res = TRUE;
break;
default:
/* ignore every other event */
res = FALSE;
break;
}
}
else
{ /* XInput fun.. Needs clean up. */
/* XInput fun...*/
if (!res && clutter_x11_has_xinput ())
{
#ifdef HAVE_XINPUT
int *ev_types = backend_x11->event_types;
int button_press, button_release;
@ -803,49 +816,7 @@ event_translate (ClutterBackend *backend,
CLUTTER_NOTE (EVENT, "XInput event type: %d", xevent->type);
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)
if (xevent->type == button_press)
{
XDeviceButtonEvent *xbev = (XDeviceButtonEvent *) xevent;
@ -895,6 +866,8 @@ event_translate (ClutterBackend *backend,
}
set_user_time (backend_x11, &xwindow, xbev->time);
res = TRUE;
}
else if (xevent->type == button_release)
{
@ -915,7 +888,8 @@ event_translate (ClutterBackend *backend,
xbev->button == 6 ||
xbev->button == 7)
{
return FALSE;
res = FALSE;
goto out;
}
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
@ -925,6 +899,8 @@ event_translate (ClutterBackend *backend,
event->button.modifier_state = xbev->state;
event->button.button = xbev->button;
event->button.device = device;
res = TRUE;
}
else if (xevent->type == motion_notify)
{
@ -945,36 +921,9 @@ event_translate (ClutterBackend *backend,
event->motion.y = xmev->y;
event->motion.modifier_state = xmev->state;
event->motion.device = device;
res = TRUE;
}
#if 0
/* the Xinput handling of key presses/releases disabled for now since
* it makes keyrepeat, and key presses and releases outside the window
* not generate events even when the window has focus
*/
else if (xevent->type == ev_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT])
{
XEvent xevent_converted;
XDeviceKeyEvent *xkev = (XDeviceKeyEvent *)xevent;
convert_xdevicekey_to_xkey (xkev, &xevent_converted);
event->key.type = event->type = CLUTTER_KEY_PRESS;
translate_key_event (backend, event, &xevent_converted);
set_user_time (backend_x11, &xwindow, xkev->time);
}
else if (xevent->type == ev_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT])
{
XEvent xevent_converted;
XDeviceKeyEvent *xkev = (XDeviceKeyEvent *)xevent;
convert_xdevicekey_to_xkey (xkev, &xevent_converted);
event->key.type = event->type = CLUTTER_KEY_RELEASE;
translate_key_event (backend, event, &xevent_converted);
}
#endif
else
#endif /* HAVE_XINPUT */
{
@ -982,8 +931,8 @@ event_translate (ClutterBackend *backend,
res = FALSE;
}
}
}
out:
return res;
}