2016-06-16 23:36:46 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
2019-03-29 21:03:27 +00:00
|
|
|
#include "config.h"
|
2016-06-16 23:36:46 +00:00
|
|
|
|
2020-06-05 10:21:58 +00:00
|
|
|
#include "backends/native/meta-seat-native.h"
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
#include "backends/meta-cursor-tracker-private.h"
|
2020-08-12 10:47:07 +00:00
|
|
|
#include "backends/meta-keymap-utils.h"
|
2020-08-07 13:13:51 +00:00
|
|
|
#include "backends/native/meta-barrier-native.h"
|
2020-11-20 22:53:46 +00:00
|
|
|
#include "backends/native/meta-input-thread.h"
|
2020-08-07 13:13:51 +00:00
|
|
|
#include "backends/native/meta-keymap-native.h"
|
|
|
|
#include "backends/native/meta-virtual-input-device-native.h"
|
|
|
|
#include "clutter/clutter-mutter.h"
|
|
|
|
#include "core/bell.h"
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2021-01-19 10:47:59 +00:00
|
|
|
#include "meta-private-enum-types.h"
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
enum
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
PROP_0,
|
|
|
|
PROP_SEAT_ID,
|
2021-01-19 10:47:59 +00:00
|
|
|
PROP_FLAGS,
|
2021-04-06 15:53:27 +00:00
|
|
|
PROP_BACKEND,
|
2020-08-07 13:13:51 +00:00
|
|
|
N_PROPS,
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
/* This property is overridden */
|
|
|
|
PROP_TOUCH_MODE,
|
|
|
|
};
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
static GParamSpec *props[N_PROPS] = { NULL };
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
static gboolean
|
|
|
|
meta_seat_native_handle_event_post (ClutterSeat *seat,
|
|
|
|
const ClutterEvent *event)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
ClutterInputDevice *device = clutter_event_get_source_device (event);
|
|
|
|
ClutterEventType event_type = event->type;
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2022-01-12 12:56:53 +00:00
|
|
|
if (event_type == CLUTTER_PROXIMITY_OUT)
|
2020-07-11 11:47:51 +00:00
|
|
|
{
|
|
|
|
if (seat_native->tablet_cursors)
|
|
|
|
g_hash_table_remove (seat_native->tablet_cursors, device);
|
2020-08-07 13:13:51 +00:00
|
|
|
return TRUE;
|
2020-07-11 11:47:51 +00:00
|
|
|
}
|
2020-08-07 13:13:51 +00:00
|
|
|
else if (event_type == CLUTTER_DEVICE_ADDED)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL)
|
|
|
|
seat_native->devices = g_list_prepend (seat_native->devices, g_object_ref (device));
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
2020-08-07 13:13:51 +00:00
|
|
|
else if (event_type == CLUTTER_DEVICE_REMOVED)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
GList *l = g_list_find (seat_native->devices, device);
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
if (l)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
seat_native->devices = g_list_delete_link (seat_native->devices, l);
|
|
|
|
g_object_unref (device);
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
return FALSE;
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
|
2020-08-11 15:11:51 +00:00
|
|
|
static void
|
|
|
|
proxy_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl,
|
|
|
|
MetaKeyboardA11yFlags new_flags,
|
|
|
|
MetaKeyboardA11yFlags what_changed,
|
|
|
|
MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
g_signal_emit_by_name (seat_native,
|
|
|
|
"kbd-a11y-flags-changed",
|
|
|
|
new_flags, what_changed);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
proxy_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl,
|
|
|
|
xkb_mod_mask_t new_latched_mods,
|
|
|
|
xkb_mod_mask_t new_locked_mods,
|
|
|
|
MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
g_signal_emit_by_name (seat_native,
|
|
|
|
"kbd-a11y-mods-state-changed",
|
|
|
|
new_latched_mods,
|
|
|
|
new_locked_mods);
|
|
|
|
}
|
|
|
|
|
2020-08-11 15:19:21 +00:00
|
|
|
static void
|
|
|
|
proxy_touch_mode_changed (MetaSeatImpl *seat_impl,
|
|
|
|
gboolean enabled,
|
|
|
|
MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
seat_native->touch_mode = enabled;
|
|
|
|
g_object_notify (G_OBJECT (seat_native), "touch-mode");
|
|
|
|
}
|
|
|
|
|
2020-08-11 15:32:48 +00:00
|
|
|
static void
|
|
|
|
proxy_bell (MetaSeatImpl *seat_impl,
|
|
|
|
MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
clutter_seat_bell_notify (CLUTTER_SEAT (seat_native));
|
|
|
|
}
|
|
|
|
|
2020-08-11 15:38:32 +00:00
|
|
|
static void
|
|
|
|
proxy_mods_state_changed (MetaSeatImpl *seat_impl,
|
|
|
|
ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
ClutterKeymap *keymap;
|
|
|
|
|
|
|
|
keymap = clutter_seat_get_keymap (seat);
|
|
|
|
g_signal_emit_by_name (keymap, "state-changed");
|
|
|
|
}
|
|
|
|
|
2019-09-25 21:04:25 +00:00
|
|
|
static void
|
|
|
|
meta_seat_native_constructed (GObject *object)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat = META_SEAT_NATIVE (object);
|
|
|
|
|
2021-01-19 10:47:59 +00:00
|
|
|
seat->impl = meta_seat_impl_new (seat, seat->seat_id, seat->flags);
|
2020-08-11 15:11:51 +00:00
|
|
|
g_signal_connect (seat->impl, "kbd-a11y-flags-changed",
|
|
|
|
G_CALLBACK (proxy_kbd_a11y_flags_changed), seat);
|
|
|
|
g_signal_connect (seat->impl, "kbd-a11y-mods-state-changed",
|
|
|
|
G_CALLBACK (proxy_kbd_a11y_mods_state_changed), seat);
|
2020-08-11 15:19:21 +00:00
|
|
|
g_signal_connect (seat->impl, "touch-mode",
|
|
|
|
G_CALLBACK (proxy_touch_mode_changed), seat);
|
2020-08-11 15:32:48 +00:00
|
|
|
g_signal_connect (seat->impl, "bell",
|
|
|
|
G_CALLBACK (proxy_bell), seat);
|
2020-08-11 15:38:32 +00:00
|
|
|
g_signal_connect (seat->impl, "mods-state-changed",
|
|
|
|
G_CALLBACK (proxy_mods_state_changed), seat);
|
2019-10-01 15:27:23 +00:00
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
seat->core_pointer = meta_seat_impl_get_pointer (seat->impl);
|
|
|
|
seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl);
|
2020-02-20 11:04:15 +00:00
|
|
|
|
2020-08-12 10:47:07 +00:00
|
|
|
meta_seat_native_set_keyboard_map (seat, "us", "", "");
|
|
|
|
|
2019-09-25 21:04:25 +00:00
|
|
|
if (G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed)
|
|
|
|
G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_seat_native_set_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (object);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_SEAT_ID:
|
|
|
|
seat_native->seat_id = g_value_dup_string (value);
|
|
|
|
break;
|
2021-01-19 10:47:59 +00:00
|
|
|
case PROP_FLAGS:
|
|
|
|
seat_native->flags = g_value_get_flags (value);
|
|
|
|
break;
|
2021-04-06 15:53:27 +00:00
|
|
|
case PROP_BACKEND:
|
|
|
|
seat_native->backend = g_value_get_object (value);
|
|
|
|
break;
|
2020-02-10 19:00:52 +00:00
|
|
|
case PROP_TOUCH_MODE:
|
2019-09-25 21:04:25 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_seat_native_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (object);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_SEAT_ID:
|
|
|
|
g_value_set_string (value, seat_native->seat_id);
|
|
|
|
break;
|
2020-02-10 19:00:52 +00:00
|
|
|
case PROP_TOUCH_MODE:
|
2020-08-11 15:19:21 +00:00
|
|
|
g_value_set_boolean (value, seat_native->touch_mode);
|
2020-02-10 19:00:52 +00:00
|
|
|
break;
|
2021-01-19 10:47:59 +00:00
|
|
|
case PROP_FLAGS:
|
|
|
|
g_value_set_flags (value, seat_native->flags);
|
|
|
|
break;
|
2021-04-06 15:53:27 +00:00
|
|
|
case PROP_BACKEND:
|
|
|
|
g_value_set_object (value, seat_native->backend);
|
|
|
|
break;
|
2019-09-25 21:04:25 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-03-12 07:34:30 +00:00
|
|
|
meta_seat_native_dispose (GObject *object)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
|
|
|
MetaSeatNative *seat = META_SEAT_NATIVE (object);
|
|
|
|
|
2021-03-12 07:34:30 +00:00
|
|
|
g_clear_pointer (&seat->xkb_keymap, xkb_keymap_unref);
|
2020-08-07 13:13:51 +00:00
|
|
|
g_clear_object (&seat->core_pointer);
|
|
|
|
g_clear_object (&seat->core_keyboard);
|
2021-01-14 15:07:40 +00:00
|
|
|
g_clear_pointer (&seat->impl, meta_seat_impl_destroy);
|
2021-03-12 07:34:30 +00:00
|
|
|
g_list_free_full (g_steal_pointer (&seat->devices), g_object_unref);
|
|
|
|
g_clear_pointer (&seat->reserved_virtual_slots, g_hash_table_destroy);
|
2020-07-11 11:47:51 +00:00
|
|
|
g_clear_pointer (&seat->tablet_cursors, g_hash_table_unref);
|
2021-03-12 07:34:30 +00:00
|
|
|
g_clear_object (&seat->cursor_renderer);
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2021-03-12 07:34:30 +00:00
|
|
|
g_clear_pointer (&seat->seat_id, g_free);
|
2019-09-25 21:04:25 +00:00
|
|
|
|
2021-03-12 07:34:30 +00:00
|
|
|
G_OBJECT_CLASS (meta_seat_native_parent_class)->dispose (object);
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ClutterInputDevice *
|
|
|
|
meta_seat_native_get_pointer (ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
|
|
|
return seat_native->core_pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ClutterInputDevice *
|
|
|
|
meta_seat_native_get_keyboard (ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
|
|
|
return seat_native->core_keyboard;
|
|
|
|
}
|
|
|
|
|
2020-03-03 09:47:25 +00:00
|
|
|
static const GList *
|
|
|
|
meta_seat_native_peek_devices (ClutterSeat *seat)
|
2019-09-25 21:04:25 +00:00
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
2020-03-03 09:47:25 +00:00
|
|
|
return (const GList *) seat_native->devices;
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
|
2019-10-01 15:15:41 +00:00
|
|
|
static void
|
|
|
|
meta_seat_native_bell_notify (ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = meta_get_display ();
|
|
|
|
|
|
|
|
meta_bell_notify (display, NULL);
|
|
|
|
}
|
|
|
|
|
2019-10-01 15:27:23 +00:00
|
|
|
static ClutterKeymap *
|
|
|
|
meta_seat_native_get_keymap (ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
if (!seat_native->keymap)
|
|
|
|
seat_native->keymap = meta_seat_impl_get_keymap (seat_native->impl);
|
|
|
|
|
2019-10-01 15:27:23 +00:00
|
|
|
return CLUTTER_KEYMAP (seat_native->keymap);
|
|
|
|
}
|
|
|
|
|
2020-10-22 09:23:03 +00:00
|
|
|
static guint
|
|
|
|
bump_virtual_touch_slot_base (MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
if (seat_native->virtual_touch_slot_base < 0x100)
|
|
|
|
seat_native->virtual_touch_slot_base = 0x100;
|
|
|
|
|
|
|
|
seat_native->virtual_touch_slot_base +=
|
|
|
|
CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS;
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup (seat_native->reserved_virtual_slots,
|
|
|
|
GUINT_TO_POINTER (seat_native->virtual_touch_slot_base)))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return seat_native->virtual_touch_slot_base;
|
|
|
|
}
|
|
|
|
|
2019-10-02 12:40:40 +00:00
|
|
|
static ClutterVirtualInputDevice *
|
|
|
|
meta_seat_native_create_virtual_device (ClutterSeat *seat,
|
|
|
|
ClutterInputDeviceType device_type)
|
|
|
|
{
|
2020-10-22 09:23:03 +00:00
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
guint slot_base;
|
|
|
|
|
|
|
|
slot_base = bump_virtual_touch_slot_base (seat_native);
|
|
|
|
g_hash_table_add (seat_native->reserved_virtual_slots,
|
|
|
|
GUINT_TO_POINTER (slot_base));
|
|
|
|
|
2019-10-02 12:40:40 +00:00
|
|
|
return g_object_new (META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE,
|
|
|
|
"seat", seat,
|
2020-10-22 09:23:03 +00:00
|
|
|
"slot-base", slot_base,
|
2019-10-02 12:40:40 +00:00
|
|
|
"device-type", device_type,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-22 09:23:03 +00:00
|
|
|
void
|
|
|
|
meta_seat_native_release_touch_slots (MetaSeatNative *seat,
|
|
|
|
guint base_slot)
|
|
|
|
{
|
|
|
|
g_hash_table_remove (seat->reserved_virtual_slots,
|
|
|
|
GUINT_TO_POINTER (base_slot));
|
|
|
|
}
|
|
|
|
|
2019-10-02 12:40:40 +00:00
|
|
|
static ClutterVirtualDeviceType
|
|
|
|
meta_seat_native_get_supported_virtual_device_types (ClutterSeat *seat)
|
|
|
|
{
|
|
|
|
return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
|
|
|
|
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER |
|
|
|
|
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN);
|
|
|
|
}
|
|
|
|
|
2019-10-09 16:01:34 +00:00
|
|
|
static void
|
|
|
|
meta_seat_native_warp_pointer (ClutterSeat *seat,
|
|
|
|
int x,
|
|
|
|
int y)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_warp_pointer (seat_native->impl, x, y);
|
2019-10-09 16:01:34 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 20:41:03 +00:00
|
|
|
static gboolean
|
|
|
|
meta_seat_native_query_state (ClutterSeat *seat,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
ClutterEventSequence *sequence,
|
|
|
|
graphene_point_t *coords,
|
|
|
|
ClutterModifierType *modifiers)
|
|
|
|
{
|
|
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
return meta_seat_impl_query_state (seat_native->impl, device, sequence,
|
|
|
|
coords, modifiers);
|
2020-06-05 20:41:03 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 21:04:25 +00:00
|
|
|
static void
|
|
|
|
meta_seat_native_class_init (MetaSeatNativeClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
ClutterSeatClass *seat_class = CLUTTER_SEAT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->constructed = meta_seat_native_constructed;
|
|
|
|
object_class->set_property = meta_seat_native_set_property;
|
|
|
|
object_class->get_property = meta_seat_native_get_property;
|
2021-03-12 07:34:30 +00:00
|
|
|
object_class->dispose = meta_seat_native_dispose;
|
2019-09-25 21:04:25 +00:00
|
|
|
|
|
|
|
seat_class->get_pointer = meta_seat_native_get_pointer;
|
|
|
|
seat_class->get_keyboard = meta_seat_native_get_keyboard;
|
2020-03-03 09:47:25 +00:00
|
|
|
seat_class->peek_devices = meta_seat_native_peek_devices;
|
2019-10-01 15:15:41 +00:00
|
|
|
seat_class->bell_notify = meta_seat_native_bell_notify;
|
2019-10-01 15:27:23 +00:00
|
|
|
seat_class->get_keymap = meta_seat_native_get_keymap;
|
2019-10-02 12:40:40 +00:00
|
|
|
seat_class->create_virtual_device = meta_seat_native_create_virtual_device;
|
|
|
|
seat_class->get_supported_virtual_device_types = meta_seat_native_get_supported_virtual_device_types;
|
2019-10-09 16:01:34 +00:00
|
|
|
seat_class->warp_pointer = meta_seat_native_warp_pointer;
|
2020-08-11 09:27:18 +00:00
|
|
|
seat_class->handle_event_post = meta_seat_native_handle_event_post;
|
2020-06-05 20:41:03 +00:00
|
|
|
seat_class->query_state = meta_seat_native_query_state;
|
2019-09-25 21:04:25 +00:00
|
|
|
|
|
|
|
props[PROP_SEAT_ID] =
|
|
|
|
g_param_spec_string ("seat-id",
|
|
|
|
"Seat ID",
|
|
|
|
"Seat ID",
|
|
|
|
NULL,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY);
|
|
|
|
|
2021-01-19 10:47:59 +00:00
|
|
|
props[PROP_FLAGS] =
|
|
|
|
g_param_spec_flags ("flags",
|
|
|
|
"Flags",
|
|
|
|
"Flags",
|
|
|
|
META_TYPE_SEAT_NATIVE_FLAG,
|
|
|
|
META_SEAT_NATIVE_FLAG_NONE,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY);
|
|
|
|
|
2021-04-06 15:53:27 +00:00
|
|
|
props[PROP_BACKEND] =
|
|
|
|
g_param_spec_object ("backend",
|
|
|
|
"Backend",
|
|
|
|
"Backend",
|
|
|
|
META_TYPE_BACKEND,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY);
|
|
|
|
|
2019-09-25 21:04:25 +00:00
|
|
|
g_object_class_install_properties (object_class, N_PROPS, props);
|
2020-02-10 19:00:52 +00:00
|
|
|
|
|
|
|
g_object_class_override_property (object_class, PROP_TOUCH_MODE,
|
2020-02-11 11:02:04 +00:00
|
|
|
"touch-mode");
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_seat_native_init (MetaSeatNative *seat)
|
|
|
|
{
|
2020-10-22 09:23:03 +00:00
|
|
|
seat->reserved_virtual_slots = g_hash_table_new (NULL, NULL);
|
2019-09-25 21:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_seat_native_release_devices:
|
|
|
|
*
|
|
|
|
* Releases all the evdev devices that Clutter is currently managing. This api
|
|
|
|
* is typically used when switching away from the Clutter application when
|
|
|
|
* switching tty. The devices can be reclaimed later with a call to
|
|
|
|
* meta_seat_native_reclaim_devices().
|
|
|
|
*
|
|
|
|
* This function should only be called after clutter has been initialized.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_seat_native_release_devices (MetaSeatNative *seat)
|
|
|
|
{
|
|
|
|
g_return_if_fail (META_IS_SEAT_NATIVE (seat));
|
|
|
|
|
|
|
|
if (seat->released)
|
|
|
|
{
|
|
|
|
g_warning ("meta_seat_native_release_devices() shouldn't be called "
|
|
|
|
"multiple times without a corresponding call to "
|
|
|
|
"meta_seat_native_reclaim_devices() first");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_release_devices (seat->impl);
|
2019-09-25 21:04:25 +00:00
|
|
|
seat->released = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_seat_native_reclaim_devices:
|
|
|
|
*
|
|
|
|
* This causes Clutter to re-probe for evdev devices. This is must only be
|
|
|
|
* called after a corresponding call to meta_seat_native_release_devices()
|
|
|
|
* was previously used to release all evdev devices. This API is typically
|
|
|
|
* used when a clutter application using evdev has regained focus due to
|
|
|
|
* switching ttys.
|
|
|
|
*
|
|
|
|
* This function should only be called after clutter has been initialized.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_seat_native_reclaim_devices (MetaSeatNative *seat)
|
|
|
|
{
|
|
|
|
if (!seat->released)
|
|
|
|
{
|
|
|
|
g_warning ("Spurious call to meta_seat_native_reclaim_devices() without "
|
|
|
|
"previous call to meta_seat_native_release_devices");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_reclaim_devices (seat->impl);
|
2019-09-25 21:04:25 +00:00
|
|
|
seat->released = FALSE;
|
2016-06-16 23:36:46 +00:00
|
|
|
}
|
2019-10-04 13:44:27 +00:00
|
|
|
|
2020-08-12 10:47:07 +00:00
|
|
|
static struct xkb_keymap *
|
|
|
|
create_keymap (const char *layouts,
|
|
|
|
const char *variants,
|
|
|
|
const char *options)
|
|
|
|
{
|
|
|
|
struct xkb_rule_names names;
|
|
|
|
struct xkb_keymap *keymap;
|
|
|
|
struct xkb_context *context;
|
|
|
|
|
|
|
|
names.rules = DEFAULT_XKB_RULES_FILE;
|
|
|
|
names.model = DEFAULT_XKB_MODEL;
|
|
|
|
names.layout = layouts;
|
|
|
|
names.variant = variants;
|
|
|
|
names.options = options;
|
|
|
|
|
|
|
|
context = meta_create_xkb_context ();
|
|
|
|
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
|
|
xkb_context_unref (context);
|
|
|
|
|
|
|
|
return keymap;
|
|
|
|
}
|
|
|
|
|
2019-10-04 13:44:27 +00:00
|
|
|
/**
|
|
|
|
* meta_seat_native_set_keyboard_map: (skip)
|
|
|
|
* @seat: the #ClutterSeat created by the evdev backend
|
|
|
|
* @keymap: the new keymap
|
|
|
|
*
|
2020-08-26 09:49:50 +00:00
|
|
|
* Instructs @evdev to use the specified keyboard map. This will cause
|
2019-10-04 13:44:27 +00:00
|
|
|
* the backend to drop the state and create a new one with the new
|
|
|
|
* map. To avoid state being lost, callers should ensure that no key
|
|
|
|
* is pressed when calling this function.
|
|
|
|
*/
|
|
|
|
void
|
2020-08-12 10:47:07 +00:00
|
|
|
meta_seat_native_set_keyboard_map (MetaSeatNative *seat,
|
|
|
|
const char *layouts,
|
|
|
|
const char *variants,
|
|
|
|
const char *options)
|
2019-10-04 13:44:27 +00:00
|
|
|
{
|
2020-08-12 10:47:07 +00:00
|
|
|
struct xkb_keymap *keymap, *impl_keymap;
|
|
|
|
|
|
|
|
keymap = create_keymap (layouts, variants, options);
|
|
|
|
impl_keymap = create_keymap (layouts, variants, options);
|
|
|
|
|
|
|
|
if (keymap == NULL)
|
|
|
|
{
|
|
|
|
g_warning ("Unable to load configured keymap: rules=%s, model=%s, layout=%s, variant=%s, options=%s",
|
|
|
|
DEFAULT_XKB_RULES_FILE, DEFAULT_XKB_MODEL, layouts,
|
|
|
|
variants, options);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (seat->xkb_keymap)
|
|
|
|
xkb_keymap_unref (seat->xkb_keymap);
|
|
|
|
seat->xkb_keymap = keymap;
|
2019-10-04 13:44:27 +00:00
|
|
|
|
2020-08-12 10:47:07 +00:00
|
|
|
meta_seat_impl_set_keyboard_map (seat->impl, impl_keymap);
|
|
|
|
xkb_keymap_unref (impl_keymap);
|
2019-10-04 13:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_seat_native_get_keyboard_map: (skip)
|
|
|
|
* @seat: the #ClutterSeat created by the evdev backend
|
|
|
|
*
|
|
|
|
* Retrieves the #xkb_keymap in use by the evdev backend.
|
|
|
|
*
|
|
|
|
* Return value: the #xkb_keymap.
|
|
|
|
*/
|
|
|
|
struct xkb_keymap *
|
|
|
|
meta_seat_native_get_keyboard_map (MetaSeatNative *seat)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (META_IS_SEAT_NATIVE (seat), NULL);
|
|
|
|
|
2020-08-12 10:47:07 +00:00
|
|
|
return seat->xkb_keymap;
|
2019-10-04 13:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_seat_native_set_keyboard_layout_index: (skip)
|
|
|
|
* @seat: the #ClutterSeat created by the evdev backend
|
|
|
|
* @idx: the xkb layout index to set
|
|
|
|
*
|
|
|
|
* Sets the xkb layout index on the backend's #xkb_state .
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat,
|
|
|
|
xkb_layout_index_t idx)
|
|
|
|
{
|
|
|
|
g_return_if_fail (META_IS_SEAT_NATIVE (seat));
|
|
|
|
|
2020-08-12 10:47:07 +00:00
|
|
|
seat->xkb_layout_index = idx;
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_set_keyboard_layout_index (seat->impl, idx);
|
2019-10-04 13:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_seat_native_get_keyboard_layout_index: (skip)
|
|
|
|
*/
|
|
|
|
xkb_layout_index_t
|
|
|
|
meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat)
|
|
|
|
{
|
2020-08-12 10:47:07 +00:00
|
|
|
return seat->xkb_layout_index;
|
2019-10-04 13:44:27 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 10:21:58 +00:00
|
|
|
MetaBarrierManagerNative *
|
|
|
|
meta_seat_native_get_barrier_manager (MetaSeatNative *seat)
|
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
return meta_seat_impl_get_barrier_manager (seat->impl);
|
2020-06-05 10:21:58 +00:00
|
|
|
}
|
2020-07-08 16:17:13 +00:00
|
|
|
|
2021-04-06 15:53:27 +00:00
|
|
|
MetaBackend *
|
|
|
|
meta_seat_native_get_backend (MetaSeatNative *seat_native)
|
|
|
|
{
|
|
|
|
return seat_native->backend;
|
|
|
|
}
|
|
|
|
|
2020-07-08 16:17:13 +00:00
|
|
|
void
|
|
|
|
meta_seat_native_set_pointer_constraint (MetaSeatNative *seat,
|
|
|
|
MetaPointerConstraintImpl *constraint_impl)
|
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_set_pointer_constraint (seat->impl, constraint_impl);
|
2020-07-08 16:17:13 +00:00
|
|
|
}
|
2020-07-10 21:28:50 +00:00
|
|
|
|
|
|
|
MetaCursorRenderer *
|
|
|
|
meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native,
|
|
|
|
ClutterInputDevice *device)
|
|
|
|
{
|
|
|
|
if (device == seat_native->core_pointer)
|
|
|
|
{
|
|
|
|
if (!seat_native->cursor_renderer)
|
|
|
|
{
|
|
|
|
MetaCursorRendererNative *cursor_renderer_native;
|
|
|
|
|
|
|
|
cursor_renderer_native =
|
2020-07-13 11:32:48 +00:00
|
|
|
meta_cursor_renderer_native_new (meta_get_backend (),
|
|
|
|
seat_native->core_pointer);
|
2020-07-10 21:28:50 +00:00
|
|
|
seat_native->cursor_renderer =
|
|
|
|
META_CURSOR_RENDERER (cursor_renderer_native);
|
|
|
|
}
|
|
|
|
|
|
|
|
return seat_native->cursor_renderer;
|
|
|
|
}
|
|
|
|
|
2022-01-12 12:56:53 +00:00
|
|
|
if (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE)
|
|
|
|
{
|
|
|
|
MetaCursorRenderer *cursor_renderer = NULL;
|
|
|
|
|
|
|
|
if (!seat_native->tablet_cursors)
|
|
|
|
{
|
|
|
|
seat_native->tablet_cursors =
|
|
|
|
g_hash_table_new_full (NULL, NULL, NULL,
|
|
|
|
g_object_unref);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cursor_renderer = g_hash_table_lookup (seat_native->tablet_cursors,
|
|
|
|
device);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cursor_renderer)
|
|
|
|
{
|
|
|
|
cursor_renderer = meta_cursor_renderer_new (meta_get_backend (),
|
|
|
|
device);
|
|
|
|
g_hash_table_insert (seat_native->tablet_cursors,
|
|
|
|
device, cursor_renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cursor_renderer;
|
|
|
|
}
|
2020-07-11 11:47:51 +00:00
|
|
|
|
2020-07-10 21:28:50 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2020-07-16 14:41:02 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_seat_native_set_viewports (MetaSeatNative *seat,
|
|
|
|
MetaViewportInfo *viewports)
|
|
|
|
{
|
2020-08-07 13:13:51 +00:00
|
|
|
meta_seat_impl_set_viewports (seat->impl, viewports);
|
2020-07-16 14:41:02 +00:00
|
|
|
}
|