summaryrefslogtreecommitdiff
path: root/src/backends/native/meta-virtual-input-device-native.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/native/meta-virtual-input-device-native.c')
-rw-r--r--src/backends/native/meta-virtual-input-device-native.c1110
1 files changed, 0 insertions, 1110 deletions
diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c
deleted file mode 100644
index d2d13748a..000000000
--- a/src/backends/native/meta-virtual-input-device-native.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * 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: Jonas Ã…dahl <jadahl@gmail.com>
- */
-
-#include "config.h"
-
-#include <glib-object.h>
-#include <linux/input.h>
-
-#include "backends/native/meta-input-thread.h"
-#include "backends/native/meta-seat-native.h"
-#include "backends/native/meta-virtual-input-device-native.h"
-#include "clutter/clutter-mutter.h"
-#include "meta/util.h"
-
-enum
-{
- PROP_0,
-
- PROP_SEAT,
- PROP_SLOT_BASE,
-
- PROP_LAST
-};
-
-static GParamSpec *obj_props[PROP_LAST];
-
-typedef struct _ImplState ImplState;
-
-struct _ImplState
-{
- ClutterInputDevice *device;
- int button_count[KEY_CNT];
-};
-
-struct _MetaVirtualInputDeviceNative
-{
- ClutterVirtualInputDevice parent;
-
- MetaSeatNative *seat;
- guint slot_base;
- ImplState *impl_state;
-};
-
-typedef struct
-{
- uint64_t time_us;
- double x;
- double y;
-} MetaVirtualEventMotion;
-
-typedef struct
-{
- uint64_t time_us;
- uint32_t button;
- ClutterButtonState button_state;
-} MetaVirtualEventButton;
-
-typedef struct
-{
- uint64_t time_us;
- double dx;
- double dy;
- ClutterScrollDirection direction;
- ClutterScrollSource scroll_source;
- ClutterScrollFinishFlags finish_flags;
-} MetaVirtualEventScroll;
-
-typedef struct
-{
- uint64_t time_us;
- uint32_t key;
- ClutterKeyState key_state;
-} MetaVirtualEventKey;
-
-typedef struct
-{
- uint64_t time_us;
- int device_slot;
- double x;
- double y;
-} MetaVirtualEventTouch;
-
-G_DEFINE_TYPE (MetaVirtualInputDeviceNative,
- meta_virtual_input_device_native,
- CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
-
-typedef enum _EvdevButtonType
-{
- EVDEV_BUTTON_TYPE_NONE,
- EVDEV_BUTTON_TYPE_KEY,
- EVDEV_BUTTON_TYPE_BUTTON,
-} EvdevButtonType;
-
-static int
-update_button_count_in_impl (MetaVirtualInputDeviceNative *virtual_evdev,
- uint32_t button,
- uint32_t state)
-{
- if (state)
- return ++virtual_evdev->impl_state->button_count[button];
- else
- return --virtual_evdev->impl_state->button_count[button];
-}
-
-static EvdevButtonType
-get_button_type (uint16_t code)
-{
- switch (code)
- {
- case BTN_TOOL_PEN:
- case BTN_TOOL_RUBBER:
- case BTN_TOOL_BRUSH:
- case BTN_TOOL_PENCIL:
- case BTN_TOOL_AIRBRUSH:
- case BTN_TOOL_MOUSE:
- case BTN_TOOL_LENS:
- case BTN_TOOL_QUINTTAP:
- case BTN_TOOL_DOUBLETAP:
- case BTN_TOOL_TRIPLETAP:
- case BTN_TOOL_QUADTAP:
- case BTN_TOOL_FINGER:
- case BTN_TOUCH:
- return EVDEV_BUTTON_TYPE_NONE;
- }
-
- if (code >= KEY_ESC && code <= KEY_MICMUTE)
- return EVDEV_BUTTON_TYPE_KEY;
- if (code >= BTN_MISC && code <= BTN_GEAR_UP)
- return EVDEV_BUTTON_TYPE_BUTTON;
- if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE)
- return EVDEV_BUTTON_TYPE_KEY;
- if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT)
- return EVDEV_BUTTON_TYPE_BUTTON;
- if (code >= KEY_ALS_TOGGLE && code <= KEY_KBDINPUTASSIST_CANCEL)
- return EVDEV_BUTTON_TYPE_KEY;
- if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40)
- return EVDEV_BUTTON_TYPE_BUTTON;
- return EVDEV_BUTTON_TYPE_NONE;
-}
-
-static gboolean
-release_device_in_impl (GTask *task)
-{
- ImplState *impl_state = g_task_get_task_data (task);
- MetaInputDeviceNative *device_native;
- MetaSeatImpl *seat_impl;
- int code;
- uint64_t time_us;
- ClutterEvent *device_event;
-
- device_native = META_INPUT_DEVICE_NATIVE (impl_state->device);
- seat_impl = meta_input_device_native_get_seat_impl (device_native);
- time_us = g_get_monotonic_time ();
-
- meta_topic (META_DEBUG_INPUT,
- "Releasing pressed buttons while destroying virtual input device "
- "(device %p)", device_native);
-
- for (code = 0; code < G_N_ELEMENTS (impl_state->button_count); code++)
- {
- if (impl_state->button_count[code] == 0)
- continue;
-
- switch (get_button_type (code))
- {
- case EVDEV_BUTTON_TYPE_KEY:
- meta_seat_impl_notify_key_in_impl (seat_impl,
- impl_state->device,
- time_us,
- code,
- CLUTTER_KEY_STATE_RELEASED,
- TRUE);
- break;
- case EVDEV_BUTTON_TYPE_BUTTON:
- meta_seat_impl_notify_button_in_impl (seat_impl,
- impl_state->device,
- time_us,
- code,
- CLUTTER_BUTTON_STATE_RELEASED);
- break;
- case EVDEV_BUTTON_TYPE_NONE:
- g_assert_not_reached ();
- }
- }
-
- device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED);
- clutter_event_set_device (device_event, impl_state->device);
- _clutter_event_push (device_event, FALSE);
-
- g_clear_object (&impl_state->device);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-notify_relative_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventMotion *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_relative_motion_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->x, event->y,
- event->x, event->y);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- double dx,
- double dy)
-{
- MetaVirtualEventMotion *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventMotion, 1);
- event->time_us = time_us;
- event->x = dx;
- event->y = dy;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_relative_motion_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_absolute_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventMotion *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_absolute_motion_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->x, event->y,
- NULL);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- double x,
- double y)
-{
- MetaVirtualEventMotion *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventMotion, 1);
- event->time_us = time_us;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_absolute_motion_in_impl);
- g_object_unref (task);
-}
-
-static int
-translate_to_evdev_button (int clutter_button)
-{
- switch (clutter_button)
- {
- case CLUTTER_BUTTON_PRIMARY:
- return BTN_LEFT;
- case CLUTTER_BUTTON_SECONDARY:
- return BTN_RIGHT;
- case CLUTTER_BUTTON_MIDDLE:
- return BTN_MIDDLE;
- default:
- /*
- * For compatibility reasons, all additional buttons go after the old
- * 4-7 scroll ones.
- */
- return clutter_button + (BTN_LEFT - 1) - 4;
- }
-}
-
-static gboolean
-notify_button_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventButton *event = g_task_get_task_data (task);
- int button_count;
- int evdev_button;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- evdev_button = translate_to_evdev_button (event->button);
-
- if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
- {
- g_warning ("Unknown/invalid virtual device button 0x%x pressed",
- evdev_button);
- goto out;
- }
-
- button_count = update_button_count_in_impl (virtual_evdev, evdev_button,
- event->button_state);
- if (button_count < 0 || button_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
- event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, evdev_button, 1 - event->button_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual button-%s of button 0x%x (device %p)",
- event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
- "press" : "release",
- evdev_button, virtual_evdev);
-
- meta_seat_impl_notify_button_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- evdev_button,
- event->button_state);
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t button,
- ClutterButtonState button_state)
-{
- MetaVirtualEventButton *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventButton, 1);
- event->time_us = time_us;
- event->button = button;
- event->button_state = button_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_button_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_key_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventKey *event = g_task_get_task_data (task);
- int key_count;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- if (get_button_type (event->key) != EVDEV_BUTTON_TYPE_KEY)
- {
- g_warning ("Unknown/invalid virtual device key 0x%x pressed", event->key);
- goto out;
- }
-
- key_count = update_button_count_in_impl (virtual_evdev, event->key, event->key_state);
- if (key_count < 0 || key_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x key %s (ignoring)", event->key,
- event->key_state == CLUTTER_KEY_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, event->key, 1 - event->key_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of key 0x%x (device %p)",
- event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- event->key, virtual_evdev);
-
- meta_seat_impl_notify_key_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->key,
- event->key_state,
- TRUE);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t key,
- ClutterKeyState key_state)
-{
- MetaVirtualEventKey *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventKey, 1);
- event->time_us = time_us;
- event->key = key;
- event->key_state = key_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_key_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-pick_keycode_for_keyval_in_current_group_in_impl (ClutterVirtualInputDevice *virtual_device,
- guint keyval,
- guint *keycode_out,
- guint *level_out)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- ClutterBackend *backend;
- ClutterKeymap *keymap;
- struct xkb_keymap *xkb_keymap;
- struct xkb_state *state;
- guint keycode, layout;
- xkb_keycode_t min_keycode, max_keycode;
-
- backend = clutter_get_default_backend ();
- keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend));
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (META_KEYMAP_NATIVE (keymap));
- state = meta_seat_impl_get_xkb_state_in_impl (virtual_evdev->seat->impl);
-
- layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
- min_keycode = xkb_keymap_min_keycode (xkb_keymap);
- max_keycode = xkb_keymap_max_keycode (xkb_keymap);
- for (keycode = min_keycode; keycode < max_keycode; keycode++)
- {
- gint num_levels, level;
- num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
- for (level = 0; level < num_levels; level++)
- {
- const xkb_keysym_t *syms;
- gint num_syms, sym;
- num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
- for (sym = 0; sym < num_syms; sym++)
- {
- if (syms[sym] == keyval)
- {
- *keycode_out = keycode;
- if (level_out)
- *level_out = level;
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
-}
-
-static void
-apply_level_modifiers_in_impl (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t level,
- uint32_t key_state)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- guint keysym, keycode, evcode;
-
- if (level == 0)
- return;
-
- if (level == 1)
- {
- keysym = XKB_KEY_Shift_L;
- }
- else if (level == 2)
- {
- keysym = XKB_KEY_ISO_Level3_Shift;
- }
- else
- {
- g_warning ("Unhandled level: %d", level);
- return;
- }
-
- if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device, keysym,
- &keycode, NULL))
- return;
-
- evcode = meta_xkb_keycode_to_evdev (keycode);
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of modifier key 0x%x (device %p)",
- key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- evcode, virtual_device);
-
- meta_seat_impl_notify_key_in_impl (virtual_evdev->seat->impl,
- virtual_evdev->impl_state->device,
- time_us,
- evcode,
- key_state,
- TRUE);
-}
-
-static gboolean
-notify_keyval_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- ClutterVirtualInputDevice *virtual_device =
- CLUTTER_VIRTUAL_INPUT_DEVICE (virtual_evdev);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventKey *event = g_task_get_task_data (task);
- int key_count;
- guint keycode = 0, level = 0, evcode = 0;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device,
- event->key,
- &keycode, &level))
- {
- g_warning ("No keycode found for keyval %x in current group", event->key);
- goto out;
- }
-
- evcode = meta_xkb_keycode_to_evdev (keycode);
-
- if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
- {
- g_warning ("Unknown/invalid virtual device key 0x%x pressed", evcode);
- goto out;
- }
-
- key_count = update_button_count_in_impl (virtual_evdev, evcode, event->key_state);
- if (key_count < 0 || key_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode,
- event->key_state == CLUTTER_KEY_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, evcode, 1 - event->key_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of key 0x%x with modifier level %d, "
- "press count %d (device %p)",
- event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- evcode, level, key_count, virtual_evdev);
-
- if (event->key_state)
- {
- apply_level_modifiers_in_impl (virtual_device, event->time_us,
- level, event->key_state);
- }
-
- meta_seat_impl_notify_key_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- evcode,
- event->key_state,
- TRUE);
-
- if (!event->key_state)
- {
- apply_level_modifiers_in_impl (virtual_device, event->time_us,
- level, event->key_state);
- }
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t keyval,
- ClutterKeyState key_state)
-{
- MetaVirtualEventKey *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventKey, 1);
- event->time_us = time_us;
- event->key = keyval;
- event->key_state = key_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_keyval_in_impl);
- g_object_unref (task);
-}
-
-static void
-direction_to_discrete (ClutterScrollDirection direction,
- double *discrete_dx,
- double *discrete_dy)
-{
- switch (direction)
- {
- case CLUTTER_SCROLL_UP:
- *discrete_dx = 0.0;
- *discrete_dy = -1.0;
- break;
- case CLUTTER_SCROLL_DOWN:
- *discrete_dx = 0.0;
- *discrete_dy = 1.0;
- break;
- case CLUTTER_SCROLL_LEFT:
- *discrete_dx = -1.0;
- *discrete_dy = 0.0;
- break;
- case CLUTTER_SCROLL_RIGHT:
- *discrete_dx = 1.0;
- *discrete_dy = 0.0;
- break;
- case CLUTTER_SCROLL_SMOOTH:
- g_assert_not_reached ();
- break;
- }
-}
-
-static gboolean
-notify_discrete_scroll_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventScroll *event = g_task_get_task_data (task);
- double discrete_dx = 0.0, discrete_dy = 0.0;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- direction_to_discrete (event->direction, &discrete_dx, &discrete_dy);
-
- meta_seat_impl_notify_discrete_scroll_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- discrete_dx, discrete_dy,
- event->scroll_source);
-
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- ClutterScrollDirection direction,
- ClutterScrollSource scroll_source)
-{
- MetaVirtualEventScroll *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventScroll, 1);
- event->time_us = time_us;
- event->direction = direction;
- event->scroll_source = scroll_source;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_discrete_scroll_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_scroll_continuous_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventScroll *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_scroll_continuous_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->dx, event->dy,
- event->scroll_source,
- CLUTTER_SCROLL_FINISHED_NONE);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- double dx,
- double dy,
- ClutterScrollSource scroll_source,
- ClutterScrollFinishFlags finish_flags)
-{
- MetaVirtualEventScroll *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventScroll, 1);
- event->time_us = time_us;
- event->dx = dx;
- event->dy = dy;
- event->scroll_source = scroll_source;
- event->finish_flags = finish_flags;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_scroll_continuous_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_down_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_acquire_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- touch_state->coords.x = event->x;
- touch_state->coords.y = event->y;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_BEGIN,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot,
- double x,
- double y)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_down_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- touch_state->coords.x = event->x;
- touch_state->coords.y = event->y;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_UPDATE,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot,
- double x,
- double y)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_motion_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_up_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_END,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- meta_seat_impl_release_touch_state_in_impl (virtual_evdev->seat->impl,
- touch_state->seat_slot);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_up_in_impl);
- g_object_unref (task);
-}
-
-static void
-meta_virtual_input_device_native_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_SEAT:
- g_value_set_pointer (value, virtual_evdev->seat);
- break;
- case PROP_SLOT_BASE:
- g_value_set_uint (value, virtual_evdev->slot_base);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_virtual_input_device_native_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_SEAT:
- virtual_evdev->seat = g_value_get_pointer (value);
- break;
- case PROP_SLOT_BASE:
- virtual_evdev->slot_base = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_virtual_input_device_native_constructed (GObject *object)
-{
- ClutterVirtualInputDevice *virtual_device =
- CLUTTER_VIRTUAL_INPUT_DEVICE (object);
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
- ClutterInputDeviceType device_type;
- ClutterEvent *device_event = NULL;
-
- device_type = clutter_virtual_input_device_get_device_type (virtual_device);
-
- meta_topic (META_DEBUG_INPUT,
- "Creating new virtual input device of type %d (%p)",
- device_type, virtual_device);
-
- virtual_evdev->impl_state = g_new0 (ImplState, 1);
- virtual_evdev->impl_state->device =
- meta_input_device_native_new_virtual (virtual_evdev->seat->impl,
- device_type,
- CLUTTER_INPUT_MODE_PHYSICAL);
-
- device_event = clutter_event_new (CLUTTER_DEVICE_ADDED);
- clutter_event_set_device (device_event, virtual_evdev->impl_state->device);
- _clutter_event_push (device_event, FALSE);
-}
-
-static void
-impl_state_free (ImplState *impl_state)
-{
- g_warn_if_fail (!impl_state->device);
- g_free (impl_state);
-}
-
-static void
-meta_virtual_input_device_native_dispose (GObject *object)
-{
- ClutterVirtualInputDevice *virtual_device =
- CLUTTER_VIRTUAL_INPUT_DEVICE (object);
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
- GObjectClass *object_class =
- G_OBJECT_CLASS (meta_virtual_input_device_native_parent_class);
-
- if (virtual_evdev->impl_state)
- {
- GTask *task;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, virtual_evdev->impl_state,
- (GDestroyNotify) impl_state_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) release_device_in_impl);
- g_object_unref (task);
-
- virtual_evdev->impl_state = NULL;
- }
-
- meta_seat_native_release_touch_slots (virtual_evdev->seat,
- virtual_evdev->slot_base);
-
- object_class->dispose (object);
-}
-
-static void
-meta_virtual_input_device_native_init (MetaVirtualInputDeviceNative *virtual_device_evdev)
-{
-}
-
-static void
-meta_virtual_input_device_native_class_init (MetaVirtualInputDeviceNativeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ClutterVirtualInputDeviceClass *virtual_input_device_class =
- CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass);
-
- object_class->get_property = meta_virtual_input_device_native_get_property;
- object_class->set_property = meta_virtual_input_device_native_set_property;
- object_class->constructed = meta_virtual_input_device_native_constructed;
- object_class->dispose = meta_virtual_input_device_native_dispose;
-
- virtual_input_device_class->notify_relative_motion = meta_virtual_input_device_native_notify_relative_motion;
- virtual_input_device_class->notify_absolute_motion = meta_virtual_input_device_native_notify_absolute_motion;
- virtual_input_device_class->notify_button = meta_virtual_input_device_native_notify_button;
- virtual_input_device_class->notify_key = meta_virtual_input_device_native_notify_key;
- virtual_input_device_class->notify_keyval = meta_virtual_input_device_native_notify_keyval;
- virtual_input_device_class->notify_discrete_scroll = meta_virtual_input_device_native_notify_discrete_scroll;
- virtual_input_device_class->notify_scroll_continuous = meta_virtual_input_device_native_notify_scroll_continuous;
- virtual_input_device_class->notify_touch_down = meta_virtual_input_device_native_notify_touch_down;
- virtual_input_device_class->notify_touch_motion = meta_virtual_input_device_native_notify_touch_motion;
- virtual_input_device_class->notify_touch_up = meta_virtual_input_device_native_notify_touch_up;
-
- obj_props[PROP_SEAT] = g_param_spec_pointer ("seat",
- "Seat",
- "Seat",
- CLUTTER_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
- obj_props[PROP_SLOT_BASE] = g_param_spec_uint ("slot-base",
- "Slot base",
- "Base for touch slots",
- 0, G_MAXUINT, 0,
- CLUTTER_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_properties (object_class, PROP_LAST, obj_props);
-}