1
0
Fork 0

evdev: Implement ClutterKeymap

Just move the minimal bits to this ClutterKeymapEvdev object. Much
of the functionality of a keymap is spread along ClutterSeatEvdev,
ClutterDeviceManagerEvdev and ClutterVirtualInputDevice. Future
refactors are due here.

Also, ideally keymaps are per-seat objects (at least keyboard state
is). We don't expose much info about seats altogether outside the
evdev device manager implementation. We just poke the main seat at
places, but eventually seats should be public.
This commit is contained in:
Carlos Garnacho 2019-01-10 16:13:20 +01:00
parent 7ae698795e
commit 6de81b0513
9 changed files with 232 additions and 55 deletions

View file

@ -24,6 +24,7 @@
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include <clutter/clutter-keymap.h>
#include <clutter/clutter-stage-window.h>
#include "clutter-event-translator.h"
@ -60,6 +61,8 @@ struct _ClutterBackend
GList *event_translators;
ClutterInputMethod *input_method;
ClutterKeymap *keymap;
};
struct _ClutterBackendClass

View file

@ -577,6 +577,18 @@ clutter_backend_real_get_device_manager (ClutterBackend *backend)
return backend->device_manager;
}
static ClutterKeymap *
clutter_backend_real_get_keymap (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->keymap == NULL))
{
g_critical ("No keymap available, expect broken keyboard input");
return NULL;
}
return backend->keymap;
}
static gboolean
clutter_backend_real_translate_event (ClutterBackend *backend,
gpointer native,
@ -675,6 +687,7 @@ clutter_backend_class_init (ClutterBackendClass *klass)
klass->translate_event = clutter_backend_real_translate_event;
klass->create_context = clutter_backend_real_create_context;
klass->get_features = clutter_backend_real_get_features;
klass->get_keymap = clutter_backend_real_get_keymap;
}
static void

View file

@ -44,6 +44,7 @@
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-input-device-evdev.h"
#include "clutter-keymap-evdev.h"
#include "clutter-seat-evdev.h"
#include "clutter-virtual-input-device-evdev.h"
#include "clutter-main.h"
@ -91,7 +92,6 @@ struct _ClutterDeviceManagerEvdevPrivate
GSList *seats;
ClutterSeatEvdev *main_seat;
struct xkb_keymap *keymap;
ClutterPointerConstrainCallback constrain_callback;
gpointer constrain_data;
@ -147,10 +147,6 @@ static const char *device_type_str[] = {
* appear and disappear from the system.
*/
static const char *option_xkb_layout = "us";
static const char *option_xkb_variant = "";
static const char *option_xkb_options = "";
static void
clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender,
const ClutterEvent *src,
@ -1933,8 +1929,6 @@ 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))
@ -1966,17 +1960,6 @@ 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);
priv->seats = g_slist_append (priv->seats, priv->main_seat);
@ -2030,9 +2013,6 @@ clutter_device_manager_evdev_finalize (GObject *object)
g_slist_free_full (priv->seats, (GDestroyNotify) clutter_seat_evdev_free);
g_slist_free (priv->devices);
if (priv->keymap)
xkb_keymap_unref (priv->keymap);
if (priv->event_source != NULL)
clutter_event_source_free (priv->event_source);
@ -2159,6 +2139,7 @@ _clutter_events_evdev_init (ClutterBackend *backend)
backend->device_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
"backend", backend,
NULL);
backend->keymap = g_object_new (CLUTTER_TYPE_KEYMAP_EVDEV, NULL);
}
void
@ -2218,14 +2199,6 @@ _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)
{
@ -2288,6 +2261,11 @@ clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
ClutterSeatEvdev *seat;
xkb_mod_mask_t latched_mods;
xkb_mod_mask_t locked_mods;
struct xkb_keymap *xkb_keymap;
ClutterKeymap *keymap;
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
priv = manager_evdev->priv;
@ -2300,7 +2278,7 @@ clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
locked_mods = xkb_state_serialize_mods (seat->xkb,
XKB_STATE_MODS_LOCKED);
xkb_state_unref (seat->xkb);
seat->xkb = xkb_state_new (priv->keymap);
seat->xkb = xkb_state_new (xkb_keymap);
xkb_state_update_mask (seat->xkb,
0, /* depressed */
@ -2308,9 +2286,9 @@ clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
locked_mods,
0, 0, seat->layout_idx);
seat->caps_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_CAPS);
seat->num_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_NUM);
seat->scroll_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_SCROLL);
seat->caps_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS);
seat->num_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM);
seat->scroll_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
clutter_seat_evdev_sync_leds (seat);
}
@ -2395,20 +2373,18 @@ clutter_evdev_set_device_callbacks (ClutterOpenDeviceCallback open_callback,
*/
void
clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
struct xkb_keymap *keymap)
struct xkb_keymap *xkb_keymap)
{
ClutterDeviceManagerEvdev *manager_evdev;
ClutterDeviceManagerEvdevPrivate *priv;
ClutterKeymap *keymap;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
clutter_keymap_evdev_set_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap),
xkb_keymap);
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
priv = manager_evdev->priv;
if (priv->keymap)
xkb_keymap_unref (priv->keymap);
priv->keymap = xkb_keymap_ref (keymap);
clutter_evdev_update_xkb_state (manager_evdev);
}
@ -2503,12 +2479,18 @@ clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
ClutterDeviceManagerEvdevPrivate *priv;
GSList *iter;
xkb_mod_mask_t numlock;
struct xkb_keymap *xkb_keymap;
ClutterKeymap *keymap;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
priv = manager_evdev->priv;
numlock = (1 << xkb_keymap_mod_get_index(priv->keymap, "Mod2"));
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2"));
for (iter = priv->seats; iter; iter = iter->next)
{
@ -2759,3 +2741,9 @@ clutter_evdev_set_seat_id (const gchar *seat_id)
g_free (evdev_seat_id);
evdev_seat_id = g_strdup (seat_id);
}
struct xkb_state *
_clutter_device_manager_evdev_get_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
{
return manager_evdev->priv->main_seat->xkb;
}

View file

@ -64,8 +64,6 @@ 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);
void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
@ -85,6 +83,8 @@ void _clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerE
void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev);
struct xkb_state * _clutter_device_manager_evdev_get_xkb_state (ClutterDeviceManagerEvdev *manager_evdev);
static inline guint64
us (guint64 us)
{

View file

@ -0,0 +1,128 @@
/*
* Copyright (C) 2018 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#include "clutter-build-config.h"
#include "clutter-device-manager-evdev.h"
#include "clutter-keymap-evdev.h"
static const char *option_xkb_layout = "us";
static const char *option_xkb_variant = "";
static const char *option_xkb_options = "";
typedef struct _ClutterKeymapEvdev ClutterKeymapEvdev;
struct _ClutterKeymapEvdev
{
ClutterKeymap parent_instance;
struct xkb_keymap *keymap;
};
G_DEFINE_TYPE (ClutterKeymapEvdev, clutter_keymap_evdev,
CLUTTER_TYPE_KEYMAP)
static void
clutter_keymap_evdev_finalize (GObject *object)
{
ClutterKeymapEvdev *keymap = CLUTTER_KEYMAP_EVDEV (object);
xkb_keymap_unref (keymap->keymap);
G_OBJECT_CLASS (clutter_keymap_evdev_parent_class)->finalize (object);
}
static gboolean
clutter_keymap_evdev_get_num_lock_state (ClutterKeymap *keymap)
{
ClutterDeviceManagerEvdev *device_manager;
struct xkb_state *xkb_state;
device_manager =
CLUTTER_DEVICE_MANAGER_EVDEV (clutter_device_manager_get_default ());
xkb_state = _clutter_device_manager_evdev_get_xkb_state (device_manager);
return xkb_state_mod_name_is_active (xkb_state,
XKB_MOD_NAME_NUM,
XKB_STATE_MODS_LATCHED ||
XKB_STATE_MODS_LOCKED);
}
static gboolean
clutter_keymap_evdev_get_caps_lock_state (ClutterKeymap *keymap)
{
ClutterDeviceManagerEvdev *device_manager;
struct xkb_state *xkb_state;
device_manager =
CLUTTER_DEVICE_MANAGER_EVDEV (clutter_device_manager_get_default ());
xkb_state = _clutter_device_manager_evdev_get_xkb_state (device_manager);
return xkb_state_mod_name_is_active (xkb_state,
XKB_MOD_NAME_CAPS,
XKB_STATE_MODS_LATCHED ||
XKB_STATE_MODS_LOCKED);
}
static void
clutter_keymap_evdev_class_init (ClutterKeymapEvdevClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass);
object_class->finalize = clutter_keymap_evdev_finalize;
keymap_class->get_num_lock_state = clutter_keymap_evdev_get_num_lock_state;
keymap_class->get_caps_lock_state = clutter_keymap_evdev_get_caps_lock_state;
}
static void
clutter_keymap_evdev_init (ClutterKeymapEvdev *keymap)
{
struct xkb_context *ctx;
struct xkb_rule_names names;
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);
keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
xkb_context_unref (ctx);
}
void
clutter_keymap_evdev_set_keyboard_map (ClutterKeymapEvdev *keymap,
struct xkb_keymap *xkb_keymap)
{
if (keymap->keymap)
xkb_keymap_unref (keymap->keymap);
keymap->keymap = xkb_keymap_ref (xkb_keymap);
}
struct xkb_keymap *
clutter_keymap_evdev_get_keyboard_map (ClutterKeymapEvdev *keymap)
{
return keymap->keymap;
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2018 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#include "clutter-xkb-utils.h"
#include "clutter-keymap.h"
#define CLUTTER_TYPE_KEYMAP_EVDEV (clutter_keymap_evdev_get_type ())
G_DECLARE_FINAL_TYPE (ClutterKeymapEvdev, clutter_keymap_evdev,
CLUTTER, KEYMAP_EVDEV,
ClutterKeymap)
void clutter_keymap_evdev_set_keyboard_map (ClutterKeymapEvdev *keymap,
struct xkb_keymap *xkb_keymap);
struct xkb_keymap * clutter_keymap_evdev_get_keyboard_map (ClutterKeymapEvdev *keymap);

View file

@ -34,6 +34,7 @@
#include "clutter-event-private.h"
#include "clutter-input-device-evdev.h"
#include "clutter-input-device-tool-evdev.h"
#include "clutter-keymap-evdev.h"
#include "clutter-main.h"
/* Try to keep the pointer inside the stage. Hopefully no one is using
@ -152,7 +153,8 @@ clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
ClutterSeatEvdev *seat;
ClutterInputDevice *device;
ClutterStage *stage;
struct xkb_keymap *keymap;
ClutterKeymap *keymap;
struct xkb_keymap *xkb_keymap;
seat = g_new0 (ClutterSeatEvdev, 1);
if (!seat)
@ -183,17 +185,19 @@ clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
seat->repeat_delay = 250; /* ms */
seat->repeat_interval = 33; /* ms */
keymap = _clutter_device_manager_evdev_get_keymap (manager_evdev);
if (keymap)
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
if (xkb_keymap)
{
seat->xkb = xkb_state_new (keymap);
seat->xkb = xkb_state_new (xkb_keymap);
seat->caps_lock_led =
xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS);
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS);
seat->num_lock_led =
xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM);
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM);
seat->scroll_lock_led =
xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL);
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
}
return seat;
@ -316,7 +320,13 @@ clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat,
queue_event (event);
if (update_keys && (changed_state & XKB_STATE_LEDS))
clutter_seat_evdev_sync_leds (seat);
{
ClutterBackend *backend;
backend = clutter_get_default_backend ();
g_signal_emit_by_name (clutter_backend_get_keymap (backend), "state-changed");
clutter_seat_evdev_sync_leds (seat);
}
if (state == 0 || /* key release */
!seat->repeat ||

View file

@ -29,6 +29,7 @@
#include "clutter-private.h"
#include "clutter-virtual-input-device.h"
#include "evdev/clutter-input-device-evdev.h"
#include "evdev/clutter-keymap-evdev.h"
#include "evdev/clutter-seat-evdev.h"
#include "evdev/clutter-virtual-input-device-evdev.h"
@ -286,14 +287,14 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev
{
ClutterVirtualInputDeviceEvdev *virtual_evdev =
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
ClutterDeviceManager *manager;
ClutterKeymap *keymap;
struct xkb_keymap *xkb_keymap;
struct xkb_state *state;
guint keycode, layout;
xkb_keycode_t min_keycode, max_keycode;
manager = clutter_virtual_input_device_get_manager (virtual_device);
xkb_keymap = _clutter_device_manager_evdev_get_keymap (CLUTTER_DEVICE_MANAGER_EVDEV (manager));
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
xkb_keymap = clutter_keymap_evdev_get_keyboard_map (CLUTTER_KEYMAP_EVDEV (keymap));
state = virtual_evdev->seat->xkb;
layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);

View file

@ -358,6 +358,7 @@ if have_native_backend
'evdev/clutter-event-evdev.c',
'evdev/clutter-input-device-evdev.c',
'evdev/clutter-input-device-tool-evdev.c',
'evdev/clutter-keymap-evdev.c',
'evdev/clutter-seat-evdev.c',
'evdev/clutter-virtual-input-device-evdev.c',
'evdev/clutter-xkb-utils.c',
@ -369,6 +370,7 @@ if have_native_backend
'evdev/clutter-device-manager-evdev.h',
'evdev/clutter-input-device-evdev.h',
'evdev/clutter-input-device-tool-evdev.h',
'evdev/clutter-keymap-evdev.h',
'evdev/clutter-seat-evdev.h',
'evdev/clutter-virtual-input-device-evdev.h',
'evdev/clutter-xkb-utils.h',