diff options
-rw-r--r-- | clutter/clutter/Makefile.am | 2 | ||||
-rw-r--r-- | clutter/clutter/evdev/clutter-device-manager-evdev.c | 311 | ||||
-rw-r--r-- | clutter/clutter/evdev/clutter-device-manager-evdev.h | 7 | ||||
-rw-r--r-- | clutter/clutter/evdev/clutter-input-device-evdev.h | 4 | ||||
-rw-r--r-- | clutter/clutter/evdev/clutter-seat-evdev.c | 214 | ||||
-rw-r--r-- | clutter/clutter/evdev/clutter-seat-evdev.h | 102 |
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__ */ |