[mutter/wip/garnacho/virtual-input-device: 4/22] clutter/evdev: Move keyboard and pointer notification into seat
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/garnacho/virtual-input-device: 4/22] clutter/evdev: Move keyboard and pointer notification into seat
- Date: Mon, 11 Jul 2016 17:25:17 +0000 (UTC)
commit c1184e4d45799f10775a4105c9315c1f794e927a
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Fri Jun 17 17:42:16 2016 -0400
clutter/evdev: Move keyboard and pointer notification into seat
We notify per seat; so lets move the logic there. Touch and tablets to
follow later.
.../clutter/evdev/clutter-device-manager-evdev.c | 318 ++++---------------
.../clutter/evdev/clutter-device-manager-evdev.h | 26 ++
clutter/clutter/evdev/clutter-seat-evdev.c | 335 ++++++++++++++++++++
clutter/clutter/evdev/clutter-seat-evdev.h | 28 ++
4 files changed, 456 insertions(+), 251 deletions(-)
---
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c
b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 616b4f1..8a3574e 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -61,8 +61,6 @@
#define DISCRETE_SCROLL_STEP 10.0
-#define AUTOREPEAT_VALUE 2
-
/*
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
@@ -153,24 +151,6 @@ static const char *option_xkb_layout = "us";
static const char *option_xkb_variant = "";
static const char *option_xkb_options = "";
-static inline guint64
-us (guint64 us)
-{
- return us;
-}
-
-static inline guint64
-ms2us (guint64 ms)
-{
- return us (ms * 1000);
-}
-
-static inline guint32
-us2ms (guint64 us)
-{
- return (guint32) (us / 1000);
-}
-
static void
clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender,
const ClutterEvent *src,
@@ -254,120 +234,34 @@ queue_event (ClutterEvent *event)
_clutter_event_push (event, FALSE);
}
-static gboolean
-keyboard_repeat (gpointer data);
-
-static void
-notify_key_device (ClutterInputDevice *input_device,
- guint64 time_us,
- guint32 key,
- guint32 state,
- gboolean update_keys)
-{
- ClutterInputDeviceEvdev *device_evdev =
- CLUTTER_INPUT_DEVICE_EVDEV (input_device);
- ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
- ClutterStage *stage;
- ClutterEvent *event = NULL;
- enum xkb_state_component changed_state;
-
- /* We can drop the event on the floor if no stage has been
- * associated with the device yet. */
- stage = _clutter_input_device_get_stage (input_device);
- if (stage == NULL)
- {
- clutter_seat_evdev_clear_repeat_timer (seat);
- return;
- }
-
- event = _clutter_key_event_new_from_evdev (input_device,
- seat->core_keyboard,
- stage,
- seat->xkb,
- seat->button_state,
- us2ms (time_us), key, state);
- _clutter_evdev_event_set_event_code (event, key);
-
- /* We must be careful and not pass multiple releases to xkb, otherwise it gets
- confused and locks the modifiers */
- if (state != AUTOREPEAT_VALUE)
+void
+_clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
+ ClutterInputDevice *core_pointer,
+ uint64_t time_us,
+ float x,
+ float y,
+ float *new_x,
+ float *new_y)
+{
+ if (manager_evdev->priv->constrain_callback)
{
- changed_state = xkb_state_update_key (seat->xkb,
- event->key.hardware_keycode,
- state ? XKB_KEY_DOWN : XKB_KEY_UP);
+ manager_evdev->priv->constrain_callback (core_pointer,
+ us2ms (time_us),
+ x, y,
+ new_x, new_y,
+ manager_evdev->priv->constrain_data);
}
else
{
- changed_state = 0;
- clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
- }
+ ClutterActor *stage = CLUTTER_ACTOR (manager_evdev->priv->stage);
+ float stage_width = clutter_actor_get_width (stage);
+ float stage_height = clutter_actor_get_height (stage);
- queue_event (event);
-
- if (update_keys && (changed_state & XKB_STATE_LEDS))
- clutter_seat_evdev_sync_leds (seat);
-
- if (state == 0 || /* key release */
- !seat->repeat ||
- !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), event->key.hardware_keycode))
- {
- clutter_seat_evdev_clear_repeat_timer (seat);
- return;
- }
-
- if (state == 1) /* key press */
- seat->repeat_count = 0;
-
- seat->repeat_count += 1;
- seat->repeat_key = key;
-
- switch (seat->repeat_count)
- {
- case 1:
- case 2:
- {
- guint32 interval;
-
- clutter_seat_evdev_clear_repeat_timer (seat);
- seat->repeat_device = g_object_ref (input_device);
-
- if (seat->repeat_count == 1)
- interval = seat->repeat_delay;
- else
- interval = seat->repeat_interval;
-
- seat->repeat_timer =
- clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
- interval,
- keyboard_repeat,
- seat,
- NULL);
- return;
- }
- default:
- return;
+ x = CLAMP (x, 0.f, stage_width - 1);
+ y = CLAMP (y, 0.f, stage_height - 1);
}
}
-static gboolean
-keyboard_repeat (gpointer data)
-{
- ClutterSeatEvdev *seat = data;
- GSource *source;
- guint32 time_ms;
-
- g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
- source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
- time_ms = g_source_get_time (source) / 1000;
-
- notify_key_device (seat->repeat_device,
- ms2us (time_ms),
- seat->repeat_key,
- AUTOREPEAT_VALUE,
- FALSE);
-
- return G_SOURCE_CONTINUE;
-}
static ClutterEvent *
new_absolute_motion_event (ClutterInputDevice *input_device,
@@ -606,118 +500,6 @@ notify_scroll (ClutterInputDevice *input_device,
}
static void
-notify_button (ClutterInputDevice *input_device,
- guint64 time_us,
- guint32 button,
- guint32 state)
-{
- ClutterInputDeviceEvdev *device_evdev;
- ClutterSeatEvdev *seat;
- ClutterStage *stage;
- ClutterEvent *event = NULL;
- gint button_nr;
- static gint maskmap[8] =
- {
- CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
- CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
- };
-
- /* We can drop the event on the floor if no stage has been
- * associated with the device yet. */
- stage = _clutter_input_device_get_stage (input_device);
- if (stage == NULL)
- return;
-
- device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
- seat = _clutter_input_device_evdev_get_seat (device_evdev);
-
- /* The evdev button numbers don't map sequentially to clutter button
- * numbers (the right and middle mouse buttons are in the opposite
- * order) so we'll map them directly with a switch statement */
- switch (button)
- {
- case BTN_LEFT:
- case BTN_TOUCH:
- button_nr = CLUTTER_BUTTON_PRIMARY;
- break;
-
- case BTN_RIGHT:
- case BTN_STYLUS:
- button_nr = CLUTTER_BUTTON_SECONDARY;
- break;
-
- case BTN_MIDDLE:
- case BTN_STYLUS2:
- button_nr = CLUTTER_BUTTON_MIDDLE;
- break;
-
- default:
- /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- button_nr = button - BTN_TOOL_PEN + 4;
- else
- button_nr = button - (BTN_LEFT - 1) + 4;
- break;
- }
-
- if (button_nr < 1 || button_nr > 12)
- {
- g_warning ("Unhandled button event 0x%x", button);
- return;
- }
-
- if (state)
- event = clutter_event_new (CLUTTER_BUTTON_PRESS);
- else
- event = clutter_event_new (CLUTTER_BUTTON_RELEASE);
-
- if (button_nr < G_N_ELEMENTS (maskmap))
- {
- /* Update the modifiers */
- if (state)
- seat->button_state |= maskmap[button_nr - 1];
- else
- seat->button_state &= ~maskmap[button_nr - 1];
- }
-
- _clutter_evdev_event_set_time_usec (event, time_us);
- event->button.time = us2ms (time_us);
- event->button.stage = CLUTTER_STAGE (stage);
- _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
- event->button.button = button_nr;
-
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- {
- ClutterPoint point;
-
- clutter_input_device_get_coords (input_device, NULL, &point);
- event->button.x = point.x;
- event->button.y = point.y;
- }
- else
- {
- event->button.x = seat->pointer_x;
- event->button.y = seat->pointer_y;
- }
-
- clutter_event_set_source_device (event, input_device);
-
- _clutter_evdev_event_set_event_code (event, button);
-
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- {
- clutter_event_set_device_tool (event, device_evdev->last_tool);
- clutter_event_set_device (event, input_device);
- }
- else
- clutter_event_set_device (event, seat->core_pointer);
-
- _clutter_input_device_set_stage (seat->core_pointer, stage);
-
- queue_event (event);
-}
-
-static void
notify_touch_event (ClutterInputDevice *input_device,
ClutterEventType evtype,
guint64 time_us,
@@ -1387,6 +1169,14 @@ translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event)
return (gdouble *) g_array_free (axes, FALSE);
}
+static ClutterSeatEvdev *
+seat_from_device (ClutterInputDevice *device)
+{
+ ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
+
+ return _clutter_input_device_evdev_get_seat (device_evdev);
+}
+
static gboolean
process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
struct libinput_event *event)
@@ -1403,8 +1193,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
guint64 time_us;
struct libinput_event_keyboard *key_event =
libinput_event_get_keyboard_event (event);
- device = libinput_device_get_user_data (libinput_device);
+ device = libinput_device_get_user_data (libinput_device);
time_us = libinput_event_keyboard_get_time_usec (key_event);
key = libinput_event_keyboard_get_key (key_event);
key_state = libinput_event_keyboard_get_key_state (key_event) ==
@@ -1419,18 +1209,35 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
seat_key_count != 0))
break;
- notify_key_device (device, time_us, key, key_state, TRUE);
+ clutter_seat_evdev_notify_key (seat_from_device (device),
+ device,
+ time_us, key, key_state, TRUE);
break;
}
case LIBINPUT_EVENT_POINTER_MOTION:
{
- struct libinput_event_pointer *motion_event =
+ struct libinput_event_pointer *pointer_event =
libinput_event_get_pointer_event (event);
- device = libinput_device_get_user_data (libinput_device);
+ uint64_t time_us;
+ double dx;
+ double dy;
+ double dx_unaccel;
+ double dy_unaccel;
- notify_relative_motion (device, motion_event);
+ device = libinput_device_get_user_data (libinput_device);
+ time_us = libinput_event_pointer_get_time_usec (pointer_event);
+ dx = libinput_event_pointer_get_dx (pointer_event);
+ dy = libinput_event_pointer_get_dy (pointer_event);
+ dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event);
+ dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event);
+
+ clutter_seat_evdev_notify_relative_motion (seat_from_device (device),
+ device,
+ time_us,
+ dx, dy,
+ dx_unaccel, dy_unaccel);
break;
}
@@ -1457,7 +1264,12 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
stage_width);
y = libinput_event_pointer_get_absolute_y_transformed (motion_event,
stage_height);
- notify_absolute_motion (device, time_us, x, y, NULL);
+
+ clutter_seat_evdev_notify_absolute_motion (seat_from_device (device),
+ device,
+ time_us,
+ x, y,
+ NULL);
break;
}
@@ -1484,8 +1296,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
seat_button_count != 0))
break;
- notify_button (device, time_us, button, button_state);
-
+ clutter_seat_evdev_notify_button (seat_from_device (device), device,
+ time_us, button, button_state);
break;
}
@@ -1823,34 +1635,38 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
}
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
{
- guint64 time;
+ guint64 time_us;
guint32 button_state;
struct libinput_event_tablet_tool *tablet_event =
libinput_event_get_tablet_tool_event (event);
guint tablet_button;
device = libinput_device_get_user_data (libinput_device);
- time = libinput_event_tablet_tool_get_time_usec (tablet_event);
+ time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
tablet_button = libinput_event_tablet_tool_get_button (tablet_event);
button_state = libinput_event_tablet_tool_get_button_state (tablet_event) ==
LIBINPUT_BUTTON_STATE_PRESSED;
- notify_button (device, time, tablet_button, button_state);
+
+ clutter_seat_evdev_notify_button (seat_from_device (device), device,
+ time_us, tablet_button, button_state);
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
{
- guint64 time;
+ guint64 time_us;
guint32 button_state;
struct libinput_event_tablet_tool *tablet_event =
libinput_event_get_tablet_tool_event (event);
device = libinput_device_get_user_data (libinput_device);
- time = libinput_event_tablet_tool_get_time_usec (tablet_event);
+ time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) ==
LIBINPUT_TABLET_TOOL_TIP_DOWN;
- notify_button (device, time, BTN_TOUCH, button_state);
+
+ clutter_seat_evdev_notify_button (seat_from_device (device), device,
+ time_us, BTN_TOUCH, button_state);
break;
}
default:
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.h
b/clutter/clutter/evdev/clutter-device-manager-evdev.h
index a92a0fc..1b01b8d 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.h
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.h
@@ -68,6 +68,32 @@ struct xkb_keymap * _clutter_device_manager_evdev_get_keymap (ClutterDeviceManag
ClutterStage * _clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev);
+void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
+ ClutterInputDevice *core_pointer,
+ uint64_t time_us,
+ float x,
+ float y,
+ float *new_x,
+ float *new_y);
+
+static inline guint64
+us (guint64 us)
+{
+ return us;
+}
+
+static inline guint64
+ms2us (guint64 ms)
+{
+ return us (ms * 1000);
+}
+
+static inline guint32
+us2ms (guint64 us)
+{
+ return (guint32) (us / 1000);
+}
+
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.c b/clutter/clutter/evdev/clutter-seat-evdev.c
index 1db3f8b..6a7c5ef 100644
--- a/clutter/clutter/evdev/clutter-seat-evdev.c
+++ b/clutter/clutter/evdev/clutter-seat-evdev.c
@@ -28,13 +28,19 @@
#include "clutter-seat-evdev.h"
+#include <linux/input.h>
+
+#include "clutter-event-private.h"
#include "clutter-input-device-evdev.h"
+#include "clutter-main.h"
/* Try to keep the pointer inside the stage. Hopefully no one is using
* this backend with stages smaller than this. */
#define INITIAL_POINTER_X 16
#define INITIAL_POINTER_Y 16
+#define AUTOREPEAT_VALUE 2
+
void
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
struct libinput_seat *libinput_seat)
@@ -171,6 +177,335 @@ clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat)
}
}
+static gboolean
+keyboard_repeat (gpointer data)
+{
+ ClutterSeatEvdev *seat = data;
+ GSource *source;
+ guint32 time_ms;
+
+ g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
+ source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
+ time_ms = g_source_get_time (source) / 1000;
+
+ clutter_seat_evdev_notify_key (seat,
+ seat->repeat_device,
+ ms2us (time_ms),
+ seat->repeat_key,
+ AUTOREPEAT_VALUE,
+ FALSE);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+queue_event (ClutterEvent *event)
+{
+ _clutter_event_push (event, FALSE);
+}
+
+void
+clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
+ ClutterInputDevice *device,
+ uint64_t time_us,
+ uint32_t key,
+ uint32_t state,
+ gboolean update_keys)
+{
+ ClutterStage *stage;
+ ClutterEvent *event = NULL;
+ enum xkb_state_component changed_state;
+
+ /* We can drop the event on the floor if no stage has been
+ * associated with the device yet. */
+ stage = _clutter_input_device_get_stage (device);
+ if (stage == NULL)
+ {
+ clutter_seat_evdev_clear_repeat_timer (seat);
+ return;
+ }
+
+ event = _clutter_key_event_new_from_evdev (device,
+ seat->core_keyboard,
+ stage,
+ seat->xkb,
+ seat->button_state,
+ us2ms (time_us), key, state);
+ _clutter_evdev_event_set_event_code (event, key);
+
+ /* We must be careful and not pass multiple releases to xkb, otherwise it gets
+ confused and locks the modifiers */
+ if (state != AUTOREPEAT_VALUE)
+ {
+ changed_state = xkb_state_update_key (seat->xkb,
+ event->key.hardware_keycode,
+ state ? XKB_KEY_DOWN : XKB_KEY_UP);
+ }
+ else
+ {
+ changed_state = 0;
+ clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
+ }
+
+ queue_event (event);
+
+ if (update_keys && (changed_state & XKB_STATE_LEDS))
+ clutter_seat_evdev_sync_leds (seat);
+
+ if (state == 0 || /* key release */
+ !seat->repeat ||
+ !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb),
+ event->key.hardware_keycode))
+ {
+ clutter_seat_evdev_clear_repeat_timer (seat);
+ return;
+ }
+
+ if (state == 1) /* key press */
+ seat->repeat_count = 0;
+
+ seat->repeat_count += 1;
+ seat->repeat_key = key;
+
+ switch (seat->repeat_count)
+ {
+ case 1:
+ case 2:
+ {
+ guint32 interval;
+
+ clutter_seat_evdev_clear_repeat_timer (seat);
+ seat->repeat_device = g_object_ref (device);
+
+ if (seat->repeat_count == 1)
+ interval = seat->repeat_delay;
+ else
+ interval = seat->repeat_interval;
+
+ seat->repeat_timer =
+ clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
+ interval,
+ keyboard_repeat,
+ seat,
+ NULL);
+ return;
+ }
+ default:
+ return;
+ }
+}
+
+static ClutterEvent *
+new_absolute_motion_event (ClutterSeatEvdev *seat,
+ ClutterInputDevice *input_device,
+ guint64 time_us,
+ gfloat x,
+ gfloat y,
+ gdouble *axes)
+{
+ ClutterStage *stage = _clutter_input_device_get_stage (input_device);
+ ClutterEvent *event;
+
+ event = clutter_event_new (CLUTTER_MOTION);
+
+ if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
+ _clutter_device_manager_evdev_constrain_pointer (seat->manager_evdev,
+ seat->core_pointer,
+ time_us,
+ seat->pointer_x,
+ seat->pointer_y,
+ &x, &y);
+
+ _clutter_evdev_event_set_time_usec (event, time_us);
+ event->motion.time = us2ms (time_us);
+ event->motion.stage = stage;
+ event->motion.device = seat->core_pointer;
+ _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
+ event->motion.x = x;
+ event->motion.y = y;
+ event->motion.axes = axes;
+ clutter_event_set_source_device (event, input_device);
+
+ if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
+ {
+ ClutterInputDeviceEvdev *device_evdev =
+ CLUTTER_INPUT_DEVICE_EVDEV (input_device);
+
+ clutter_event_set_device_tool (event, device_evdev->last_tool);
+ clutter_event_set_device (event, input_device);
+ }
+ else
+ {
+ clutter_event_set_device (event, seat->core_pointer);
+ }
+
+ _clutter_input_device_set_stage (seat->core_pointer, stage);
+
+ if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
+ {
+ seat->pointer_x = x;
+ seat->pointer_y = y;
+ }
+
+ return event;
+}
+
+void
+clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ float dx,
+ float dy,
+ float dx_unaccel,
+ float dy_unaccel)
+{
+ gfloat new_x, new_y;
+ ClutterEvent *event;
+
+ /* We can drop the event on the floor if no stage has been
+ * associated with the device yet. */
+ if (!_clutter_input_device_get_stage (input_device))
+ return;
+
+ new_x = seat->pointer_x + dx;
+ new_y = seat->pointer_y + dy;
+ event = new_absolute_motion_event (seat, input_device,
+ time_us, new_x, new_y, NULL);
+
+ _clutter_evdev_event_set_relative_motion (event,
+ dx, dy,
+ dx_unaccel, dy_unaccel);
+
+ queue_event (event);
+}
+
+void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ float x,
+ float y,
+ double *axes)
+{
+ ClutterEvent *event;
+
+ event = new_absolute_motion_event (seat, input_device, time_us, x, x, axes);
+
+ queue_event (event);
+}
+
+void
+clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ uint32_t button,
+ uint32_t state)
+{
+ ClutterStage *stage;
+ ClutterEvent *event = NULL;
+ gint button_nr;
+ static gint maskmap[8] =
+ {
+ CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
+ CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
+ };
+
+ /* We can drop the event on the floor if no stage has been
+ * associated with the device yet. */
+ stage = _clutter_input_device_get_stage (input_device);
+ if (stage == NULL)
+ return;
+
+ /* The evdev button numbers don't map sequentially to clutter button
+ * numbers (the right and middle mouse buttons are in the opposite
+ * order) so we'll map them directly with a switch statement */
+ switch (button)
+ {
+ case BTN_LEFT:
+ case BTN_TOUCH:
+ button_nr = CLUTTER_BUTTON_PRIMARY;
+ break;
+
+ case BTN_RIGHT:
+ case BTN_STYLUS:
+ button_nr = CLUTTER_BUTTON_SECONDARY;
+ break;
+
+ case BTN_MIDDLE:
+ case BTN_STYLUS2:
+ button_nr = CLUTTER_BUTTON_MIDDLE;
+ break;
+
+ default:
+ /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
+ if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
+ button_nr = button - BTN_TOOL_PEN + 4;
+ else
+ button_nr = button - (BTN_LEFT - 1) + 4;
+ break;
+ }
+
+ if (button_nr < 1 || button_nr > 12)
+ {
+ g_warning ("Unhandled button event 0x%x", button);
+ return;
+ }
+
+ if (state)
+ event = clutter_event_new (CLUTTER_BUTTON_PRESS);
+ else
+ event = clutter_event_new (CLUTTER_BUTTON_RELEASE);
+
+ if (button_nr < G_N_ELEMENTS (maskmap))
+ {
+ /* Update the modifiers */
+ if (state)
+ seat->button_state |= maskmap[button_nr - 1];
+ else
+ seat->button_state &= ~maskmap[button_nr - 1];
+ }
+
+ _clutter_evdev_event_set_time_usec (event, time_us);
+ event->button.time = us2ms (time_us);
+ event->button.stage = CLUTTER_STAGE (stage);
+ _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
+ event->button.button = button_nr;
+
+ if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
+ {
+ ClutterPoint point;
+
+ clutter_input_device_get_coords (input_device, NULL, &point);
+ event->button.x = point.x;
+ event->button.y = point.y;
+ }
+ else
+ {
+ event->button.x = seat->pointer_x;
+ event->button.y = seat->pointer_y;
+ }
+
+ clutter_event_set_source_device (event, input_device);
+
+ _clutter_evdev_event_set_event_code (event, button);
+
+ if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
+ {
+ ClutterInputDeviceEvdev *device_evdev =
+ CLUTTER_INPUT_DEVICE_EVDEV (input_device);
+
+ clutter_event_set_device_tool (event, device_evdev->last_tool);
+ clutter_event_set_device (event, input_device);
+ }
+ else
+ {
+ clutter_event_set_device (event, seat->core_pointer);
+ }
+
+ _clutter_input_device_set_stage (seat->core_pointer, stage);
+
+ queue_event (event);
+}
+
void
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
{
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.h b/clutter/clutter/evdev/clutter-seat-evdev.h
index 9cf3acf..f246434 100644
--- a/clutter/clutter/evdev/clutter-seat-evdev.h
+++ b/clutter/clutter/evdev/clutter-seat-evdev.h
@@ -76,6 +76,34 @@ struct _ClutterSeatEvdev
gfloat accum_scroll_dy;
};
+void clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
+ ClutterInputDevice *device,
+ uint64_t time_us,
+ uint32_t key,
+ uint32_t state,
+ gboolean update_keys);
+
+void clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat_evdev,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ float dx,
+ float dy,
+ float dx_unaccel,
+ float dy_unaccel);
+
+void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat_evdev,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ float x,
+ float y,
+ double *axes);
+
+void clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
+ ClutterInputDevice *input_device,
+ uint64_t time_us,
+ uint32_t button,
+ uint32_t state);
+
void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
struct libinput_seat *libinput_seat);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]