summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2016-06-16 19:36:46 -0400
committerCarlos Garnacho <carlosg@gnome.org>2016-07-26 18:45:25 +0200
commitfb473746296dc34946212a87f860f743d2d0bc3e (patch)
tree1815c6c3fc6e3fd29063cdb3e2d79a9a8facf980
parent9a92d5fe89c44841fbaa117abbb1f9426a304f39 (diff)
downloadmutter-fb473746296dc34946212a87f860f743d2d0bc3e.tar.gz
ClutterDeviceManagerEvdev: Split out seat into a separate file
Split out ClutterSeatEvdev functionality into a separate file. https://bugzilla.gnome.org/show_bug.cgi?id=765009
-rw-r--r--clutter/clutter/Makefile.am2
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.c311
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.h7
-rw-r--r--clutter/clutter/evdev/clutter-input-device-evdev.h4
-rw-r--r--clutter/clutter/evdev/clutter-seat-evdev.c214
-rw-r--r--clutter/clutter/evdev/clutter-seat-evdev.h102
6 files changed, 381 insertions, 259 deletions
diff --git a/clutter/clutter/Makefile.am b/clutter/clutter/Makefile.am
index c588d6866..b332df7ff 100644
--- a/clutter/clutter/Makefile.am
+++ b/clutter/clutter/Makefile.am
@@ -468,6 +468,7 @@ backend_source_c += $(glx_source_c)
evdev_c_priv = \
evdev/clutter-device-manager-evdev.c \
evdev/clutter-input-device-evdev.c \
+ evdev/clutter-seat-evdev.c \
evdev/clutter-virtual-input-device-evdev.c \
evdev/clutter-event-evdev.c \
evdev/clutter-input-device-tool-evdev.c \
@@ -475,6 +476,7 @@ evdev_c_priv = \
evdev_h_priv = \
evdev/clutter-device-manager-evdev.h \
evdev/clutter-input-device-evdev.h \
+ evdev/clutter-seat-evdev.h \
evdev/clutter-input-device-tool-evdev.h \
evdev/clutter-virtual-input-device-evdev.h \
$(NULL)
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 865f461eb..48270ed70 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -46,6 +46,7 @@
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-input-device-evdev.h"
+#include "clutter-seat-evdev.h"
#include "clutter-virtual-input-device-evdev.h"
#include "clutter-main.h"
#include "clutter-private.h"
@@ -62,10 +63,6 @@
#define AUTOREPEAT_VALUE 2
-/* 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
/*
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
@@ -77,50 +74,8 @@
*/
#define INITIAL_DEVICE_ID 2
-typedef struct _ClutterTouchState ClutterTouchState;
typedef struct _ClutterEventFilter ClutterEventFilter;
-struct _ClutterTouchState
-{
- guint32 id;
- ClutterPoint coords;
-};
-
-struct _ClutterSeatEvdev
-{
- struct libinput_seat *libinput_seat;
- ClutterDeviceManagerEvdev *manager_evdev;
-
- GSList *devices;
-
- ClutterInputDevice *core_pointer;
- ClutterInputDevice *core_keyboard;
-
- GHashTable *touches;
-
- struct xkb_state *xkb;
- xkb_led_index_t caps_lock_led;
- xkb_led_index_t num_lock_led;
- xkb_led_index_t scroll_lock_led;
- uint32_t button_state;
-
- /* keyboard repeat */
- gboolean repeat;
- guint32 repeat_delay;
- guint32 repeat_interval;
- guint32 repeat_key;
- guint32 repeat_count;
- guint32 repeat_timer;
- ClutterInputDevice *repeat_device;
-
- gfloat pointer_x;
- gfloat pointer_y;
-
- /* Emulation of discrete scroll events out of smooth ones */
- gfloat accum_scroll_dx;
- gfloat accum_scroll_dy;
-};
-
struct _ClutterEventFilter
{
ClutterEvdevFilterFunc func;
@@ -300,24 +255,10 @@ queue_event (ClutterEvent *event)
_clutter_event_push (event, FALSE);
}
-static void
-clear_repeat_timer (ClutterSeatEvdev *seat)
-{
- if (seat->repeat_timer)
- {
- g_source_remove (seat->repeat_timer);
- seat->repeat_timer = 0;
- g_clear_object (&seat->repeat_device);
- }
-}
-
static gboolean
keyboard_repeat (gpointer data);
static void
-clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
-
-static void
notify_key_device (ClutterInputDevice *input_device,
guint64 time_us,
guint32 key,
@@ -336,7 +277,7 @@ notify_key_device (ClutterInputDevice *input_device,
stage = _clutter_input_device_get_stage (input_device);
if (stage == NULL)
{
- clear_repeat_timer (seat);
+ clutter_seat_evdev_clear_repeat_timer (seat);
return;
}
@@ -371,7 +312,7 @@ notify_key_device (ClutterInputDevice *input_device,
!seat->repeat ||
!xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), event->key.hardware_keycode))
{
- clear_repeat_timer (seat);
+ clutter_seat_evdev_clear_repeat_timer (seat);
return;
}
@@ -388,7 +329,7 @@ notify_key_device (ClutterInputDevice *input_device,
{
guint32 interval;
- clear_repeat_timer (seat);
+ clutter_seat_evdev_clear_repeat_timer (seat);
seat->repeat_device = g_object_ref (input_device);
if (seat->repeat_count == 1)
@@ -1207,128 +1148,6 @@ clutter_event_source_free (ClutterEventSource *source)
}
static void
-clutter_touch_state_free (ClutterTouchState *touch_state)
-{
- g_slice_free (ClutterTouchState, touch_state);
-}
-
-static void
-clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
- struct libinput_seat *libinput_seat)
-{
- g_assert (seat->libinput_seat == NULL);
-
- libinput_seat_ref (libinput_seat);
- libinput_seat_set_user_data (libinput_seat, seat);
- seat->libinput_seat = libinput_seat;
-}
-
-static ClutterSeatEvdev *
-clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
-{
- ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
- ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
- ClutterSeatEvdev *seat;
- ClutterInputDevice *device;
- struct xkb_context *ctx;
- struct xkb_rule_names names;
- struct xkb_keymap *keymap;
-
- seat = g_new0 (ClutterSeatEvdev, 1);
- if (!seat)
- return NULL;
-
- device = _clutter_input_device_evdev_new_virtual (
- manager, seat, CLUTTER_POINTER_DEVICE);
- _clutter_input_device_set_stage (device, priv->stage);
- seat->pointer_x = INITIAL_POINTER_X;
- seat->pointer_y = INITIAL_POINTER_Y;
- _clutter_input_device_set_coords (device, NULL,
- seat->pointer_x, seat->pointer_y,
- NULL);
- _clutter_device_manager_add_device (manager, device);
- seat->core_pointer = device;
-
- device = _clutter_input_device_evdev_new_virtual (
- manager, seat, CLUTTER_KEYBOARD_DEVICE);
- _clutter_input_device_set_stage (device, priv->stage);
- _clutter_device_manager_add_device (manager, device);
- seat->core_keyboard = device;
-
- seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) clutter_touch_state_free);
-
- ctx = xkb_context_new(0);
- g_assert (ctx);
-
- names.rules = "evdev";
- names.model = "pc105";
- names.layout = option_xkb_layout;
- names.variant = option_xkb_variant;
- names.options = option_xkb_options;
-
- keymap = xkb_keymap_new_from_names (ctx, &names, 0);
- xkb_context_unref(ctx);
- if (keymap)
- {
- seat->xkb = xkb_state_new (keymap);
-
- seat->caps_lock_led =
- xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS);
- seat->num_lock_led =
- xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM);
- seat->scroll_lock_led =
- xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL);
-
- priv->keymap = keymap;
- }
-
- seat->repeat = TRUE;
- seat->repeat_delay = 250; /* ms */
- seat->repeat_interval = 33; /* ms */
-
- priv->seats = g_slist_append (priv->seats, seat);
- return seat;
-}
-
-static void
-clutter_seat_evdev_free (ClutterSeatEvdev *seat)
-{
- GSList *iter;
-
- for (iter = seat->devices; iter; iter = g_slist_next (iter))
- {
- ClutterInputDevice *device = iter->data;
-
- g_object_unref (device);
- }
- g_slist_free (seat->devices);
- g_hash_table_unref (seat->touches);
-
- xkb_state_unref (seat->xkb);
-
- clear_repeat_timer (seat);
-
- if (seat->libinput_seat)
- libinput_seat_unref (seat->libinput_seat);
-
- g_free (seat);
-}
-
-static void
-clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat, ClutterStage *stage)
-{
- GSList *l;
-
- for (l = seat->devices; l; l = l->next)
- {
- ClutterInputDevice *device = l->data;
-
- _clutter_input_device_set_stage (device, stage);
- }
-}
-
-static void
evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
struct libinput_device *libinput_device)
{
@@ -1347,11 +1166,16 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
* which are located on the main seat. Make whatever seat comes first the
* main seat. */
if (priv->main_seat->libinput_seat == NULL)
- seat = priv->main_seat;
+ {
+ seat = priv->main_seat;
+ }
else
- seat = clutter_seat_evdev_new (manager_evdev);
+ {
+ seat = clutter_seat_evdev_new (manager_evdev);
+ }
clutter_seat_evdev_set_libinput_seat (seat, libinput_seat);
+ priv->seats = g_slist_append (priv->seats, seat);
}
device = _clutter_input_device_evdev_new (manager, seat, libinput_device);
@@ -1430,7 +1254,7 @@ clutter_device_manager_evdev_remove_device (ClutterDeviceManager *manager,
priv->devices = g_slist_remove (priv->devices, device);
if (seat->repeat_timer && seat->repeat_device == device)
- clear_repeat_timer (seat);
+ clutter_seat_evdev_clear_repeat_timer (seat);
g_object_unref (device);
}
@@ -1496,32 +1320,6 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
}
static void
-clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat)
-{
- GSList *iter;
- ClutterInputDeviceEvdev *device_evdev;
- int caps_lock, num_lock, scroll_lock;
- enum libinput_led leds = 0;
-
- caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led);
- num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led);
- scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led);
-
- if (caps_lock)
- leds |= LIBINPUT_LED_CAPS_LOCK;
- if (num_lock)
- leds |= LIBINPUT_LED_NUM_LOCK;
- if (scroll_lock)
- leds |= LIBINPUT_LED_SCROLL_LOCK;
-
- for (iter = seat->devices; iter; iter = iter->next)
- {
- device_evdev = iter->data;
- _clutter_input_device_evdev_update_leds (device_evdev, leds);
- }
-}
-
-static void
flush_event_queue (void)
{
ClutterEvent *event;
@@ -1569,45 +1367,6 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
return handled;
}
-static ClutterTouchState *
-_device_seat_add_touch (ClutterInputDevice *input_device,
- guint32 id)
-{
- ClutterInputDeviceEvdev *device_evdev =
- CLUTTER_INPUT_DEVICE_EVDEV (input_device);
- ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
- ClutterTouchState *touch;
-
- touch = g_slice_new0 (ClutterTouchState);
- touch->id = id;
-
- g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
-
- return touch;
-}
-
-static void
-_device_seat_remove_touch (ClutterInputDevice *input_device,
- guint32 id)
-{
- ClutterInputDeviceEvdev *device_evdev =
- CLUTTER_INPUT_DEVICE_EVDEV (input_device);
- ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
-
- g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
-}
-
-static ClutterTouchState *
-_device_seat_get_touch (ClutterInputDevice *input_device,
- guint32 id)
-{
- ClutterInputDeviceEvdev *device_evdev =
- CLUTTER_INPUT_DEVICE_EVDEV (input_device);
- ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
-
- return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
-}
-
static void
check_notify_discrete_scroll (ClutterDeviceManagerEvdev *manager_evdev,
ClutterInputDevice *device,
@@ -1967,11 +1726,14 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
guint64 time_us;
double x, y;
gfloat stage_width, stage_height;
+ ClutterSeatEvdev *seat;
ClutterStage *stage;
ClutterTouchState *touch_state;
struct libinput_event_touch *touch_event =
libinput_event_get_touch_event (event);
+
device = libinput_device_get_user_data (libinput_device);
+ seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
stage = _clutter_input_device_get_stage (device);
if (stage == NULL)
@@ -1987,7 +1749,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
y = libinput_event_touch_get_y_transformed (touch_event,
stage_height);
- touch_state = _device_seat_add_touch (device, slot);
+ touch_state = clutter_seat_evdev_add_touch (seat, slot);
touch_state->coords.x = x;
touch_state->coords.y = y;
@@ -2000,18 +1762,21 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
{
gint32 slot;
guint64 time_us;
+ ClutterSeatEvdev *seat;
ClutterTouchState *touch_state;
struct libinput_event_touch *touch_event =
libinput_event_get_touch_event (event);
+
device = libinput_device_get_user_data (libinput_device);
+ seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
slot = libinput_event_touch_get_slot (touch_event);
time_us = libinput_event_touch_get_time_usec (touch_event);
- touch_state = _device_seat_get_touch (device, slot);
+ touch_state = clutter_seat_evdev_get_touch (seat, slot);
notify_touch_event (device, CLUTTER_TOUCH_END, time_us, slot,
touch_state->coords.x, touch_state->coords.y);
- _device_seat_remove_touch (device, slot);
+ clutter_seat_evdev_remove_touch (seat, slot);
break;
}
@@ -2022,11 +1787,14 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
guint64 time_us;
double x, y;
gfloat stage_width, stage_height;
+ ClutterSeatEvdev *seat;
ClutterStage *stage;
ClutterTouchState *touch_state;
struct libinput_event_touch *touch_event =
libinput_event_get_touch_event (event);
+
device = libinput_device_get_user_data (libinput_device);
+ seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
stage = _clutter_input_device_get_stage (device);
if (stage == NULL)
@@ -2042,7 +1810,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
y = libinput_event_touch_get_y_transformed (touch_event,
stage_height);
- touch_state = _device_seat_get_touch (device, slot);
+ touch_state = clutter_seat_evdev_get_touch (seat, slot);
touch_state->coords.x = x;
touch_state->coords.y = y;
@@ -2432,6 +2200,8 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
ClutterDeviceManagerEvdevPrivate *priv;
ClutterEventSource *source;
struct udev *udev;
+ struct xkb_context *ctx;
+ struct xkb_rule_names names;
udev = udev_new ();
if (G_UNLIKELY (udev == NULL))
@@ -2462,6 +2232,17 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
udev_unref (udev);
+ names.rules = "evdev";
+ names.model = "pc105";
+ names.layout = option_xkb_layout;
+ names.variant = option_xkb_variant;
+ names.options = option_xkb_options;
+
+ ctx = xkb_context_new (0);
+ g_assert (ctx);
+ priv->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
+ xkb_context_unref (ctx);
+
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
dispatch_libinput (manager_evdev);
@@ -2693,6 +2474,22 @@ _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *mana
compare_ids);
}
+struct xkb_keymap *
+_clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+
+ return priv->keymap;
+}
+
+ClutterStage *
+_clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+
+ return priv->stage;
+}
+
/**
* clutter_evdev_release_devices:
*
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.h b/clutter/clutter/evdev/clutter-device-manager-evdev.h
index 2f6e1a96e..a92a0fc02 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.h
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.h
@@ -24,6 +24,7 @@
#ifndef __CLUTTER_DEVICE_MANAGER_EVDEV_H__
#define __CLUTTER_DEVICE_MANAGER_EVDEV_H__
+#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
G_BEGIN_DECLS
@@ -39,6 +40,8 @@ typedef struct _ClutterDeviceManagerEvdev ClutterDeviceManagerEvdev;
typedef struct _ClutterDeviceManagerEvdevClass ClutterDeviceManagerEvdevClass;
typedef struct _ClutterDeviceManagerEvdevPrivate ClutterDeviceManagerEvdevPrivate;
+typedef struct _ClutterSeatEvdev ClutterSeatEvdev;
+
struct _ClutterDeviceManagerEvdev
{
ClutterDeviceManager parent_instance;
@@ -61,6 +64,10 @@ gint _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev
void _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev,
ClutterInputDevice *device);
+struct xkb_keymap * _clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev);
+
+ClutterStage * _clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev);
+
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.h b/clutter/clutter/evdev/clutter-input-device-evdev.h
index 88d98d92d..1c63828df 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.h
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.h
@@ -29,7 +29,8 @@
#include <glib-object.h>
#include <libinput.h>
-#include <clutter/clutter-input-device.h>
+#include "clutter/clutter-device-manager-private.h"
+#include "evdev/clutter-seat-evdev.h"
G_BEGIN_DECLS
@@ -56,7 +57,6 @@ G_BEGIN_DECLS
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
typedef struct _ClutterInputDeviceEvdev ClutterInputDeviceEvdev;
-typedef struct _ClutterSeatEvdev ClutterSeatEvdev;
typedef struct _ClutterEventEvdev ClutterEventEvdev;
struct _ClutterInputDeviceEvdev
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.c b/clutter/clutter/evdev/clutter-seat-evdev.c
new file mode 100644
index 000000000..e07637d67
--- /dev/null
+++ b/clutter/clutter/evdev/clutter-seat-evdev.c
@@ -0,0 +1,214 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corp.
+ * Copyright (C) 2014 Jonas Ådahl
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Damien Lespiau <damien.lespiau@intel.com>
+ * Author: Jonas Ådahl <jadahl@gmail.com>
+ */
+
+#include "clutter-build-config.h"
+
+#include "clutter-seat-evdev.h"
+
+#include "clutter-input-device-evdev.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
+
+void
+clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
+ struct libinput_seat *libinput_seat)
+{
+ g_assert (seat->libinput_seat == NULL);
+
+ libinput_seat_ref (libinput_seat);
+ libinput_seat_set_user_data (libinput_seat, seat);
+ seat->libinput_seat = libinput_seat;
+}
+
+void
+clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat)
+{
+ GSList *iter;
+ ClutterInputDeviceEvdev *device_evdev;
+ int caps_lock, num_lock, scroll_lock;
+ enum libinput_led leds = 0;
+
+ caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led);
+ num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led);
+ scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led);
+
+ if (caps_lock)
+ leds |= LIBINPUT_LED_CAPS_LOCK;
+ if (num_lock)
+ leds |= LIBINPUT_LED_NUM_LOCK;
+ if (scroll_lock)
+ leds |= LIBINPUT_LED_SCROLL_LOCK;
+
+ for (iter = seat->devices; iter; iter = iter->next)
+ {
+ device_evdev = iter->data;
+ _clutter_input_device_evdev_update_leds (device_evdev, leds);
+ }
+}
+
+static void
+clutter_touch_state_free (ClutterTouchState *touch_state)
+{
+ g_slice_free (ClutterTouchState, touch_state);
+}
+
+ClutterTouchState *
+clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
+ guint32 id)
+{
+ ClutterTouchState *touch;
+
+ touch = g_slice_new0 (ClutterTouchState);
+ touch->id = id;
+
+ g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
+
+ return touch;
+}
+
+void
+clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
+ guint32 id)
+{
+ g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
+}
+
+ClutterTouchState *
+clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
+ guint32 id)
+{
+ return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
+}
+
+ClutterSeatEvdev *
+clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
+ ClutterSeatEvdev *seat;
+ ClutterInputDevice *device;
+ ClutterStage *stage;
+ struct xkb_keymap *keymap;
+
+ seat = g_new0 (ClutterSeatEvdev, 1);
+ if (!seat)
+ return NULL;
+
+ seat->manager_evdev = manager_evdev;
+ device = _clutter_input_device_evdev_new_virtual (
+ manager, seat, CLUTTER_POINTER_DEVICE);
+ stage = _clutter_device_manager_evdev_get_stage (manager_evdev);
+ _clutter_input_device_set_stage (device, stage);
+ seat->pointer_x = INITIAL_POINTER_X;
+ seat->pointer_y = INITIAL_POINTER_Y;
+ _clutter_input_device_set_coords (device, NULL,
+ seat->pointer_x, seat->pointer_y,
+ NULL);
+ _clutter_device_manager_add_device (manager, device);
+ seat->core_pointer = device;
+
+ device = _clutter_input_device_evdev_new_virtual (
+ manager, seat, CLUTTER_KEYBOARD_DEVICE);
+ _clutter_input_device_set_stage (device, stage);
+ _clutter_device_manager_add_device (manager, device);
+ seat->core_keyboard = device;
+
+ seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) clutter_touch_state_free);
+
+ seat->repeat = TRUE;
+ seat->repeat_delay = 250; /* ms */
+ seat->repeat_interval = 33; /* ms */
+
+ keymap = _clutter_device_manager_evdev_get_keymap (manager_evdev);
+ if (keymap)
+ {
+ seat->xkb = xkb_state_new (keymap);
+
+ seat->caps_lock_led =
+ xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS);
+ seat->num_lock_led =
+ xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM);
+ seat->scroll_lock_led =
+ xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL);
+ }
+
+ return seat;
+}
+
+void
+clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat)
+{
+ if (seat->repeat_timer)
+ {
+ g_source_remove (seat->repeat_timer);
+ seat->repeat_timer = 0;
+ g_clear_object (&seat->repeat_device);
+ }
+}
+
+void
+clutter_seat_evdev_free (ClutterSeatEvdev *seat)
+{
+ GSList *iter;
+
+ for (iter = seat->devices; iter; iter = g_slist_next (iter))
+ {
+ ClutterInputDevice *device = iter->data;
+
+ g_object_unref (device);
+ }
+ g_slist_free (seat->devices);
+ g_hash_table_unref (seat->touches);
+
+ xkb_state_unref (seat->xkb);
+
+ clutter_seat_evdev_clear_repeat_timer (seat);
+
+ if (seat->libinput_seat)
+ libinput_seat_unref (seat->libinput_seat);
+
+ g_free (seat);
+}
+
+void
+clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
+ ClutterStage *stage)
+{
+ GSList *l;
+
+ _clutter_input_device_set_stage (seat->core_pointer, stage);
+ _clutter_input_device_set_stage (seat->core_keyboard, stage);
+
+ for (l = seat->devices; l; l = l->next)
+ {
+ ClutterInputDevice *device = l->data;
+
+ _clutter_input_device_set_stage (device, stage);
+ }
+}
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.h b/clutter/clutter/evdev/clutter-seat-evdev.h
new file mode 100644
index 000000000..9cf3acf08
--- /dev/null
+++ b/clutter/clutter/evdev/clutter-seat-evdev.h
@@ -0,0 +1,102 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corp.
+ * Copyright (C) 2014 Jonas Ådahl
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Damien Lespiau <damien.lespiau@intel.com>
+ * Author: Jonas Ådahl <jadahl@gmail.com>
+ */
+
+#ifndef __CLUTTER_SEAT_EVDEV_H__
+#define __CLUTTER_SEAT_EVDEV_H__
+
+#include <libinput.h>
+
+#include "clutter-input-device.h"
+#include "clutter-device-manager-evdev.h"
+#include "clutter-xkb-utils.h"
+
+typedef struct _ClutterTouchState ClutterTouchState;
+
+struct _ClutterTouchState
+{
+ guint32 id;
+ ClutterPoint coords;
+};
+
+struct _ClutterSeatEvdev
+{
+ struct libinput_seat *libinput_seat;
+ ClutterDeviceManagerEvdev *manager_evdev;
+
+ GSList *devices;
+
+ ClutterInputDevice *core_pointer;
+ ClutterInputDevice *core_keyboard;
+
+ GHashTable *touches;
+
+ struct xkb_state *xkb;
+ xkb_led_index_t caps_lock_led;
+ xkb_led_index_t num_lock_led;
+ xkb_led_index_t scroll_lock_led;
+ uint32_t button_state;
+
+ /* keyboard repeat */
+ gboolean repeat;
+ guint32 repeat_delay;
+ guint32 repeat_interval;
+ guint32 repeat_key;
+ guint32 repeat_count;
+ guint32 repeat_timer;
+ ClutterInputDevice *repeat_device;
+
+ gfloat pointer_x;
+ gfloat pointer_y;
+
+ /* Emulation of discrete scroll events out of smooth ones */
+ gfloat accum_scroll_dx;
+ gfloat accum_scroll_dy;
+};
+
+void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
+ struct libinput_seat *libinput_seat);
+
+void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
+
+ClutterTouchState * clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
+ guint32 id);
+
+void clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
+ guint32 id);
+
+ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
+ guint32 id);
+
+void clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
+ ClutterStage *stage);
+
+void clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat);
+
+ClutterSeatEvdev * clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev);
+
+void clutter_seat_evdev_free (ClutterSeatEvdev *seat);
+
+#endif /* __CLUTTER_SEAT_EVDEV_H__ */