backends/x11: Use new event constructors

Use the new event constructors to create input events, instead
of creating them through clutter_event_new (CLUTTER_NOTHING) and
struct field fiddling.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3153>
This commit is contained in:
Carlos Garnacho 2023-08-02 20:50:26 +02:00
parent 845277f7fb
commit 75e8bab1c1
3 changed files with 319 additions and 355 deletions

View File

@ -67,17 +67,12 @@ meta_backend_x11_handle_event (MetaBackend *backend,
META_STAGE_X11 (clutter_backend_get_stage_window (clutter_backend));
meta_stage_x11_handle_event (stage_x11, xevent);
event = clutter_event_new (CLUTTER_NOTHING);
seat_x11 = META_SEAT_X11 (meta_backend_get_default_seat (backend));
if (meta_seat_x11_translate_event (seat_x11, xevent, event))
{
_clutter_event_push (event, FALSE);
}
else
{
clutter_event_free (event);
event = meta_seat_x11_translate_event (seat_x11, xevent);
if (!event)
goto out;
}
_clutter_event_push (event, FALSE);
/*
* Motion events can generate synthetic enter and leave events, so if we

View File

@ -876,15 +876,14 @@ device_get_tool_serial (MetaSeatX11 *seat_x11,
return serial_id;
}
static gboolean
static ClutterEvent *
translate_hierarchy_event (ClutterBackend *clutter_backend,
MetaSeatX11 *seat_x11,
XIHierarchyEvent *ev,
ClutterEvent *event)
XIHierarchyEvent *ev)
{
Display *xdisplay = xdisplay_from_seat (seat_x11);
int i;
gboolean retval = FALSE;
ClutterEvent *event = NULL;
for (i = 0; i < ev->num_info; i++)
{
@ -908,11 +907,10 @@ translate_hierarchy_event (ClutterBackend *clutter_backend,
device = add_device (seat_x11, clutter_backend, &info[0]);
event->any.type = CLUTTER_DEVICE_ADDED;
event->any.time = ev->time;
clutter_event_set_device (event, device);
retval = TRUE;
event = clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED,
CLUTTER_EVENT_NONE,
ms2us (ev->time),
device);
XIFreeDeviceInfo (info);
}
}
@ -930,11 +928,10 @@ translate_hierarchy_event (ClutterBackend *clutter_backend,
{
remove_device (seat_x11, device);
event->any.type = CLUTTER_DEVICE_REMOVED;
event->any.time = ev->time;
clutter_event_set_device (event, device);
retval = TRUE;
event = clutter_event_device_notify_new (CLUTTER_DEVICE_REMOVED,
CLUTTER_EVENT_NONE,
ms2us (ev->time),
device);
}
}
else if ((ev->info[i].flags & XISlaveAttached) ||
@ -947,7 +944,7 @@ translate_hierarchy_event (ClutterBackend *clutter_backend,
}
}
return retval;
return event;
}
static void
@ -1005,17 +1002,18 @@ emulate_motion (MetaSeatX11 *seat_x11,
{
ClutterInputDevice *pointer;
ClutterEvent *event;
ClutterStage *stage;
pointer = clutter_seat_get_pointer (CLUTTER_SEAT (seat_x11));
stage = CLUTTER_STAGE (meta_backend_get_stage (seat_x11->backend));
event = clutter_event_new (CLUTTER_MOTION);
clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
clutter_event_set_coords (event, x, y);
clutter_event_set_device (event, pointer);
clutter_event_set_source_device (event, NULL);
clutter_event_set_stage (event, stage);
event = clutter_event_motion_new (CLUTTER_EVENT_FLAG_SYNTHETIC,
CLUTTER_CURRENT_TIME,
pointer,
NULL, 0,
GRAPHENE_POINT_INIT (x, y),
GRAPHENE_POINT_INIT (0, 0),
GRAPHENE_POINT_INIT (0, 0),
GRAPHENE_POINT_INIT (0, 0),
NULL);
clutter_event_put (event);
clutter_event_free (event);
@ -1127,17 +1125,17 @@ translate_pad_axis (ClutterInputDevice *device,
return FALSE;
}
static gboolean
translate_pad_event (ClutterEvent *event,
XIDeviceEvent *xev,
static ClutterEvent *
translate_pad_axis_event (XIDeviceEvent *xev,
ClutterInputDevice *device)
{
double value;
uint32_t number, mode = 0;
ClutterEventType evtype;
ClutterEvent *event = NULL;
if (!translate_pad_axis (device, &xev->valuators,
&event->any.type,
&number, &value))
&evtype, &number, &value))
return FALSE;
/* When touching a ring/strip a first XI_Motion event
@ -1151,34 +1149,40 @@ translate_pad_event (ClutterEvent *event,
mode = meta_input_device_x11_get_pad_group_mode (device, number);
#endif
if (event->any.type == CLUTTER_PAD_RING)
if (evtype == CLUTTER_PAD_RING)
{
event->pad_ring.ring_number = number;
event->pad_ring.angle = value;
event->pad_ring.mode = mode;
event = clutter_event_pad_ring_new (CLUTTER_EVENT_NONE,
ms2us (xev->time),
device,
CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN,
number,
0,
value,
mode);
}
else
{
event->pad_strip.strip_number = number;
event->pad_strip.value = value;
event->pad_strip.mode = mode;
event = clutter_event_pad_strip_new (CLUTTER_EVENT_NONE,
ms2us (xev->time),
device,
CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN,
number,
0,
value,
mode);
}
event->any.time = xev->time;
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, device);
g_debug ("%s: win:0x%x, device:%d '%s', time:%d "
g_debug ("%s: win:0x%x, device:%d '%s', time:%lu "
"(value:%f)",
event->any.type == CLUTTER_PAD_RING
evtype == CLUTTER_PAD_RING
? "pad ring "
: "pad strip",
(unsigned int) xev->event,
meta_input_device_x11_get_device_id (device),
clutter_input_device_get_device_name (device),
event->any.time, value);
xev->time, value);
return TRUE;
return event;
}
static ClutterStage *
@ -1476,9 +1480,10 @@ meta_seat_x11_notify_devices (MetaSeatX11 *seat_x11,
{
ClutterEvent *event;
event = clutter_event_new (CLUTTER_DEVICE_ADDED);
clutter_event_set_device (event, device);
clutter_event_set_stage (event, stage);
event = clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED,
CLUTTER_EVENT_NONE,
CLUTTER_CURRENT_TIME,
device);
clutter_event_put (event);
clutter_event_free (event);
}
@ -1998,41 +2003,60 @@ evdev_button_code (uint32_t x_button)
return button;
}
gboolean
static ClutterModifierType
get_modifier_for_button (int i)
{
switch (i)
{
case 1:
return CLUTTER_BUTTON1_MASK;
case 2:
return CLUTTER_BUTTON2_MASK;
case 3:
return CLUTTER_BUTTON3_MASK;
case 4:
return CLUTTER_BUTTON4_MASK;
case 5:
return CLUTTER_BUTTON5_MASK;
default:
return 0;
}
}
ClutterEvent *
meta_seat_x11_translate_event (MetaSeatX11 *seat,
XEvent *xevent,
ClutterEvent *event)
XEvent *xevent)
{
Display *xdisplay = xdisplay_from_seat (seat);
ClutterBackend *clutter_backend =
meta_backend_get_clutter_backend (seat->backend);
gboolean retval = FALSE;
ClutterStage *stage = NULL;
MetaStageX11 *stage_x11 = NULL;
ClutterInputDevice *device, *source_device;
XGenericEventCookie *cookie;
ClutterEvent *event = NULL;
XIEvent *xi_event;
if (meta_keymap_x11_handle_event (seat->keymap, xevent))
return FALSE;
return NULL;
cookie = &xevent->xcookie;
if (cookie->type != GenericEvent ||
cookie->extension != seat->opcode)
return FALSE;
return NULL;
xi_event = (XIEvent *) cookie->data;
if (!xi_event)
return FALSE;
return NULL;
if (cookie->evtype == XI_RawMotion ||
cookie->evtype == XI_RawButtonPress ||
cookie->evtype == XI_RawButtonRelease)
{
translate_raw_event (seat, xevent);
return FALSE;
return NULL;
}
if (!(xi_event->evtype == XI_DeviceChanged ||
@ -2040,20 +2064,18 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
{
stage = get_event_stage (seat, xi_event);
if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return FALSE;
return NULL;
else
stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage));
}
event->any.stage = stage;
switch (xi_event->evtype)
{
case XI_HierarchyChanged:
{
XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event;
retval = translate_hierarchy_event (clutter_backend, seat, xev, event);
event = translate_hierarchy_event (clutter_backend, seat, xev);
}
break;
@ -2077,7 +2099,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
if (source_device)
meta_input_device_x11_reset_scroll_info (source_device);
}
retval = FALSE;
break;
case XI_KeyPress:
case XI_KeyRelease:
@ -2085,56 +2106,58 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
MetaKeymapX11 *keymap_x11 = seat->keymap;
char buffer[7] = { 0, };
gunichar n;
uint32_t keyval, evcode, keycode;
ClutterModifierType state;
int len;
gunichar unicode_value;
source_device = get_source_device_checked (seat, xev);
if (!source_device)
return FALSE;
return NULL;
event->key.type = event->type = (xev->evtype == XI_KeyPress)
? CLUTTER_KEY_PRESS
: CLUTTER_KEY_RELEASE;
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
if (xev->evtype == XI_KeyPress && xev->flags & XIKeyRepeat)
clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED);
event->key.time = xev->time;
event->key.stage = stage;
meta_input_device_x11_translate_state (event, &xev->mods, &xev->buttons, &xev->group);
event->key.hardware_keycode = xev->detail;
keycode = xev->detail;
/* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's
* range, so we do the reverse here. */
event->key.evdev_code = event->key.hardware_keycode - 8;
evcode = keycode - 8;
/* keyval is the key ignoring all modifiers ('1' vs. '!') */
event->key.keyval =
meta_keymap_x11_translate_key_state (keymap_x11,
event->key.hardware_keycode,
&event->key.modifier_state,
keyval = meta_keymap_x11_translate_key_state (keymap_x11,
keycode,
&state,
NULL);
clutter_event_set_source_device (event, source_device);
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
clutter_event_set_device (event, device);
/* XXX keep this in sync with the evdev device manager */
n = print_keysym (event->key.keyval, buffer, sizeof (buffer));
if (n == 0)
len = print_keysym (keyval, buffer, sizeof (buffer));
if (len == 0)
{
/* not printable */
event->key.unicode_value = (gunichar) '\0';
unicode_value = (gunichar) '\0';
}
else
{
event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
if (event->key.unicode_value == -1 ||
event->key.unicode_value == -2)
event->key.unicode_value = (gunichar) '\0';
unicode_value = g_utf8_get_char_validated (buffer, len);
if (unicode_value == -1 ||
unicode_value == -2)
unicode_value = (gunichar) '\0';
}
event = clutter_event_key_new ((xev->evtype == XI_KeyPress) ?
CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE,
(xev->evtype == XI_KeyPress &&
xev->flags & XIKeyRepeat) ?
CLUTTER_EVENT_FLAG_REPEATED :
CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
state,
keyval,
evcode,
keycode,
unicode_value);
g_debug ("%s: win:0x%x device:%d source:%d, key: %12s (%d)",
event->any.type == CLUTTER_KEY_PRESS
? "key press "
@ -2142,13 +2165,11 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
(unsigned int) stage_x11->xwin,
xev->deviceid,
xev->sourceid,
event->key.keyval ? buffer : "(none)",
event->key.keyval);
keyval ? buffer : "(none)",
keyval);
if (xi_event->evtype == XI_KeyPress)
meta_stage_x11_set_user_time (stage_x11, event->key.time);
retval = TRUE;
meta_stage_x11_set_user_time (stage_x11, xev->time);
}
break;
@ -2156,37 +2177,35 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
case XI_ButtonRelease:
{
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
ClutterScrollDirection scroll_direction;
ClutterModifierType state;
ClutterInputDeviceTool *tool;
float x, y;
int button;
uint32_t evdev_code;
double *axes;
source_device = get_source_device_checked (seat, xev);
if (!source_device)
return FALSE;
return NULL;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
{
uint32_t button, group, mode;
/* We got these events because of the passive button grab */
XIAllowEvents (xdisplay, xev->sourceid, XIAsyncDevice, xev->time);
event->any.stage = stage;
if (xev->detail >= 4 && xev->detail <= 7)
{
retval = FALSE;
if (xi_event->evtype == XI_ButtonPress &&
translate_pad_event (event, xev, source_device))
retval = TRUE;
if (xi_event->evtype == XI_ButtonPress)
event = translate_pad_axis_event (xev, source_device);
break;
}
event->any.type =
(xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
: CLUTTER_PAD_BUTTON_RELEASE;
event->any.time = xev->time;
/* The 4-7 button range is taken as non-existent on pad devices,
* let the buttons above that take over this range.
*/
@ -2194,28 +2213,36 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
xev->detail -= 4;
/* Pad buttons are 0-indexed */
event->pad_button.button = xev->detail - 1;
button = xev->detail - 1;
#ifdef HAVE_LIBWACOM
meta_input_device_x11_update_pad_state (device,
event->pad_button.button,
button,
(xi_event->evtype == XI_ButtonPress),
&event->pad_button.group,
&event->pad_button.mode);
&group,
&mode);
#endif
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, source_device);
g_debug ("%s: win:0x%x, device:%d '%s', time:%d "
event = clutter_event_pad_button_new ((xi_event->evtype == XI_ButtonPress) ?
CLUTTER_PAD_BUTTON_PRESS :
CLUTTER_PAD_BUTTON_RELEASE,
CLUTTER_EVENT_NONE,
us2ms (xev->time),
source_device,
button,
group,
mode);
g_debug ("%s: win:0x%x, device:%d '%s', time:%lu "
"(button:%d)",
event->any.type == CLUTTER_BUTTON_PRESS
(xi_event->evtype == XI_ButtonPress)
? "pad button press "
: "pad button release",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (device),
clutter_input_device_get_device_name (device),
event->any.time,
event->pad_button.button);
retval = TRUE;
xev->time,
button);
break;
}
@ -2227,35 +2254,29 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
case 7:
/* we only generate Scroll events on ButtonPress */
if (xi_event->evtype == XI_ButtonRelease)
return FALSE;
event->scroll.type = event->type = CLUTTER_SCROLL;
return NULL;
if (xev->detail == 4)
event->scroll.direction = CLUTTER_SCROLL_UP;
scroll_direction = CLUTTER_SCROLL_UP;
else if (xev->detail == 5)
event->scroll.direction = CLUTTER_SCROLL_DOWN;
scroll_direction = CLUTTER_SCROLL_DOWN;
else if (xev->detail == 6)
event->scroll.direction = CLUTTER_SCROLL_LEFT;
scroll_direction = CLUTTER_SCROLL_LEFT;
else
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
scroll_direction = CLUTTER_SCROLL_RIGHT;
event->scroll.stage = stage;
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
tool = meta_input_device_x11_get_current_tool (source_device);
event->scroll.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->scroll.x, &event->scroll.y);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
event = clutter_event_scroll_discrete_new (CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
tool,
state,
GRAPHENE_POINT_INIT (x, y),
scroll_direction);
clutter_event_set_source_device (event, source_device);
clutter_event_set_device (event, device);
event->scroll.axes = translate_axes (event->scroll.device,
event->scroll.x,
event->scroll.y,
&xev->valuators);
g_debug ("scroll: win:0x%x, device:%d '%s', time:%d "
"(direction:%s, "
"x:%.2f, y:%.2f, "
@ -2275,57 +2296,66 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
break;
default:
event->button.type = event->type =
(xi_event->evtype == XI_ButtonPress) ? CLUTTER_BUTTON_PRESS
: CLUTTER_BUTTON_RELEASE;
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
button = xev->detail;
evdev_code = evdev_button_code (xev->detail);
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
tool = meta_input_device_x11_get_current_tool (source_device);
axes = translate_axes (device, x, y, &xev->valuators);
event->button.stage = stage;
/* The XIButtonState sent in the event specifies the
* state of the buttons before the event. In order to
* get the current state of the buttons, we need to
* filter out the current button.
*/
switch (xi_event->evtype)
{
case XI_ButtonPress:
state |= (get_modifier_for_button (button));
break;
case XI_ButtonRelease:
state &= ~(get_modifier_for_button (button));
break;
default:
break;
}
event->button.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->button.x, &event->button.y);
event->button.button = xev->detail;
event->button.evdev_code = evdev_button_code (xev->detail);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
event = clutter_event_button_new ((xi_event->evtype == XI_ButtonPress) ?
CLUTTER_BUTTON_PRESS :
CLUTTER_BUTTON_RELEASE,
(xev->flags & XIPointerEmulated) ?
CLUTTER_EVENT_FLAG_POINTER_EMULATED :
CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
tool,
state,
GRAPHENE_POINT_INIT (x, y),
button,
evdev_code,
axes);
clutter_event_set_source_device (event, source_device);
clutter_event_set_device (event, device);
clutter_event_set_device_tool (event,
meta_input_device_x11_get_current_tool (source_device));
event->button.axes = translate_axes (event->button.device,
event->button.x,
event->button.y,
&xev->valuators);
g_debug ("%s: win:0x%x, device:%d '%s', time:%d "
g_debug ("%s: win:0x%x, device:%d '%s', time:%lu "
"(button:%d, "
"x:%.2f, y:%.2f, "
"axes:%s, "
"emulated:%s)",
event->any.type == CLUTTER_BUTTON_PRESS
(xi_event->evtype == XI_ButtonPress)
? "button press "
: "button release",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (device),
clutter_input_device_get_device_name (device),
event->any.time,
event->button.button,
event->button.x,
event->button.y,
event->button.axes != NULL ? "yes" : "no",
xev->time,
xev->detail,
x, y,
axes != NULL ? "yes" : "no",
(xev->flags & XIPointerEmulated) ? "yes" : "no");
break;
}
if (xev->flags & XIPointerEmulated)
event->any.flags |= CLUTTER_EVENT_FLAG_POINTER_EMULATED;
if (xi_event->evtype == XI_ButtonPress)
meta_stage_x11_set_user_time (stage_x11, event->button.time);
retval = TRUE;
meta_stage_x11_set_user_time (stage_x11, xev->time);
}
break;
@ -2333,213 +2363,172 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
{
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
double delta_x, delta_y;
ClutterModifierType state;
ClutterInputDeviceTool *tool;
float x, y;
double *axes;
source_device = get_source_device_checked (seat, xev);
if (!source_device)
return FALSE;
break;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
{
event->any.stage = stage;
if (translate_pad_event (event, xev, source_device))
retval = TRUE;
event = translate_pad_axis_event (xev, source_device);
break;
}
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
tool = meta_input_device_x11_get_current_tool (source_device);
if (scroll_valuators_changed (source_device,
&xev->valuators,
&delta_x, &delta_y))
{
event->scroll.type = event->type = CLUTTER_SCROLL;
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
event->scroll.stage = stage;
event->scroll.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->scroll.x, &event->scroll.y);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
clutter_event_set_scroll_delta (event, delta_x, delta_y);
clutter_event_set_source_device (event, source_device);
clutter_event_set_device (event, device);
event = clutter_event_scroll_smooth_new (CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
tool,
state,
GRAPHENE_POINT_INIT (x, y),
GRAPHENE_POINT_INIT (delta_x, delta_y),
CLUTTER_SCROLL_SOURCE_UNKNOWN,
CLUTTER_SCROLL_FINISHED_NONE);
g_debug ("smooth scroll: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, delta:%f, %f)",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (event->scroll.device),
clutter_input_device_get_device_name (event->scroll.device),
event->scroll.x,
event->scroll.y,
x, y,
delta_x, delta_y);
retval = TRUE;
break;
}
event->motion.type = event->type = CLUTTER_MOTION;
event->motion.stage = stage;
event->motion.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->motion.x, &event->motion.y);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
clutter_event_set_source_device (event, source_device);
clutter_event_set_device (event, device);
clutter_event_set_device_tool (event,
meta_input_device_x11_get_current_tool (source_device));
event->motion.axes = translate_axes (event->motion.device,
event->motion.x,
event->motion.y,
&xev->valuators);
if (xev->flags & XIPointerEmulated)
event->any.flags |= CLUTTER_EVENT_FLAG_POINTER_EMULATED;
axes = translate_axes (device, x, y, &xev->valuators);
event = clutter_event_motion_new ((xev->flags & XIPointerEmulated) ?
CLUTTER_EVENT_FLAG_POINTER_EMULATED :
CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
tool,
state,
GRAPHENE_POINT_INIT (x, y),
GRAPHENE_POINT_INIT (0, 0),
GRAPHENE_POINT_INIT (0, 0),
GRAPHENE_POINT_INIT (0, 0),
axes);
g_debug ("motion: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, axes:%s)",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (event->motion.device),
clutter_input_device_get_device_name (event->motion.device),
event->motion.x,
event->motion.y,
event->motion.axes != NULL ? "yes" : "no");
retval = TRUE;
x, y,
axes != NULL ? "yes" : "no");
}
break;
case XI_TouchBegin:
{
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
}
/* Fall through */
case XI_TouchEnd:
{
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
ClutterEventType evtype;
ClutterModifierType state;
ClutterEventSequence *sequence;
float x, y;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
source_device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->sourceid));
if (xi_event->evtype == XI_TouchBegin)
event->touch.type = event->type = CLUTTER_TOUCH_BEGIN;
evtype = CLUTTER_TOUCH_BEGIN;
else
event->touch.type = event->type = CLUTTER_TOUCH_END;
evtype = CLUTTER_TOUCH_END;
event->touch.stage = stage;
event->touch.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->touch.x, &event->touch.y);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
clutter_event_set_source_device (event, source_device);
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
clutter_event_set_device (event, device);
event->touch.axes = translate_axes (event->touch.device,
event->motion.x,
event->motion.y,
&xev->valuators);
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
/* "NULL" sequences are special cased in clutter */
sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
if (xi_event->evtype == XI_TouchBegin)
{
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
state |= CLUTTER_BUTTON1_MASK;
meta_stage_x11_set_user_time (stage_x11, event->touch.time);
meta_stage_x11_set_user_time (stage_x11, xev->time);
meta_seat_x11_update_touchpoint (seat,
GUINT_TO_POINTER (xev->detail),
sequence,
xev->root_x,
xev->root_y);
}
else if (xi_event->evtype == XI_TouchEnd)
{
meta_seat_x11_remove_touchpoint (seat,
GUINT_TO_POINTER (xev->detail));
meta_seat_x11_remove_touchpoint (seat, sequence);
}
/* "NULL" sequences are special cased in clutter */
event->touch.sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
event = clutter_event_touch_new (evtype,
(xev->flags & XITouchEmulatingPointer) ?
CLUTTER_EVENT_FLAG_POINTER_EMULATED :
CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
sequence,
state,
GRAPHENE_POINT_INIT (x, y));
if (xev->flags & XITouchEmulatingPointer)
event->any.flags |= CLUTTER_EVENT_FLAG_POINTER_EMULATED;
g_debug ("touch %s: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)",
event->type == CLUTTER_TOUCH_BEGIN ? "begin" : "end",
g_debug ("touch %s: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f)",
evtype == CLUTTER_TOUCH_BEGIN ? "begin" : "end",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (event->touch.device),
clutter_input_device_get_device_name (event->touch.device),
GPOINTER_TO_UINT (event->touch.sequence),
event->touch.x,
event->touch.y,
event->touch.axes != NULL ? "yes" : "no");
retval = TRUE;
meta_input_device_x11_get_device_id (device),
clutter_input_device_get_device_name (device),
GPOINTER_TO_UINT (sequence),
x, y);
}
break;
case XI_TouchUpdate:
{
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
source_device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->sourceid));
event->touch.type = event->type = CLUTTER_TOUCH_UPDATE;
event->touch.stage = stage;
event->touch.time = xev->time;
/* "NULL" sequences are special cased in clutter */
event->touch.sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->touch.x, &event->touch.y);
clutter_event_set_source_device (event, source_device);
ClutterEventSequence *sequence;
ClutterModifierType state;
float x, y;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
clutter_event_set_device (event, device);
source_device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->sourceid));
event->touch.axes = translate_axes (event->touch.device,
event->motion.x,
event->motion.y,
&xev->valuators);
meta_input_device_x11_translate_state (event,
&xev->mods,
&xev->buttons,
&xev->group);
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
if (xev->flags & XITouchEmulatingPointer)
event->any.flags |= CLUTTER_EVENT_FLAG_POINTER_EMULATED;
/* "NULL" sequences are special cased in clutter */
sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
state = translate_state (&xev->buttons, &xev->mods, &xev->group);
state |= CLUTTER_BUTTON1_MASK;
meta_seat_x11_update_touchpoint (seat,
event->touch.sequence,
sequence,
xev->root_x,
xev->root_y);
g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (event->touch.device),
clutter_input_device_get_device_name (event->touch.device),
GPOINTER_TO_UINT (event->touch.sequence),
event->touch.x,
event->touch.y,
event->touch.axes != NULL ? "yes" : "no");
event = clutter_event_touch_new (CLUTTER_TOUCH_UPDATE,
(xev->flags & XITouchEmulatingPointer) ?
CLUTTER_EVENT_FLAG_POINTER_EMULATED :
CLUTTER_EVENT_NONE,
ms2us (xev->time),
source_device,
sequence,
state,
GRAPHENE_POINT_INIT (x, y));
retval = TRUE;
g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f)",
(unsigned int) stage_x11->xwin,
meta_input_device_x11_get_device_id (device),
clutter_input_device_get_device_name (device),
GPOINTER_TO_UINT (sequence),
x, y);
}
break;
@ -2547,6 +2536,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
case XI_Leave:
{
XIEnterEvent *xev = (XIEnterEvent *) xi_event;
float x, y;
device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->deviceid));
@ -2554,53 +2544,33 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
source_device = g_hash_table_lookup (seat->devices_by_id,
GINT_TO_POINTER (xev->sourceid));
if (xi_event->evtype == XI_Enter)
{
event->crossing.type = event->type = CLUTTER_ENTER;
translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y);
event->crossing.stage = stage;
event->crossing.related = NULL;
event->crossing.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y);
event = clutter_event_crossing_new ((xi_event->evtype == XI_Enter) ?
CLUTTER_ENTER : CLUTTER_LEAVE,
CLUTTER_EVENT_NONE,
ms2us (xev->time),
device,
NULL,
GRAPHENE_POINT_INIT (x, y),
CLUTTER_ACTOR (stage), NULL);
if (xev->deviceid == seat->pointer_id)
seat->has_pointer_focus = TRUE;
}
else
{
event->crossing.type = event->type = CLUTTER_LEAVE;
event->crossing.stage = stage;
event->crossing.related = NULL;
event->crossing.time = xev->time;
translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y);
if (xev->deviceid == seat->pointer_id)
seat->has_pointer_focus = FALSE;
}
seat->has_pointer_focus = (xi_event->evtype == XI_Enter);
meta_input_device_x11_reset_scroll_info (source_device);
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, source_device);
retval = TRUE;
}
break;
case XI_FocusIn:
case XI_FocusOut:
retval = FALSE;
break;
case XI_PropertyEvent:
translate_property_event (seat, xi_event);
retval = FALSE;
break;
}
return retval;
return event;
}
ClutterInputDevice *

View File

@ -33,9 +33,8 @@ MetaSeatX11 * meta_seat_x11_new (MetaBackend *backend,
MetaBackend * meta_seat_x11_get_backend (MetaSeatX11 *seat_x11);
gboolean meta_seat_x11_translate_event (MetaSeatX11 *seat,
XEvent *xevent,
ClutterEvent *event);
ClutterEvent * meta_seat_x11_translate_event (MetaSeatX11 *seat,
XEvent *xevent);
ClutterInputDevice * meta_seat_x11_lookup_device_id (MetaSeatX11 *seat_x11,
int device_id);
void meta_seat_x11_select_stage_events (MetaSeatX11 *seat,