mirror of
https://github.com/brl/mutter.git
synced 2025-06-14 01:09:30 +00:00
clutter: Move evdev input to src/backends/native
The end goal is to have all clutter backend code in src/backends. Input is the larger chunk of it, which is now part of our specific MutterClutterBackendNative, this extends to device manager, input devices, tools and keymap. This was supposed to be nice and incremental, but there's no sane way to cut this through. As a result of the refactor, a number of private Clutter functions are now exported for external backends to be possible. https://gitlab.gnome.org/GNOME/mutter/merge_requests/672
This commit is contained in:

committed by
Jonas Ådahl

parent
ea54ce7d96
commit
8b03d9ecc3
@ -50,6 +50,8 @@
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
#include "backends/native/meta-clutter-backend-native.h"
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-event-native.h"
|
||||
#include "backends/native/meta-input-settings-native.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
@ -57,7 +59,6 @@
|
||||
#include "backends/native/meta-monitor-manager-kms.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
#include "backends/native/meta-stage-native.h"
|
||||
#include "clutter/evdev/clutter-evdev.h"
|
||||
#include "core/meta-border.h"
|
||||
#include "meta/main.h"
|
||||
|
||||
@ -343,10 +344,10 @@ meta_backend_native_post_init (MetaBackend *backend)
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||
|
||||
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
NULL, NULL);
|
||||
clutter_evdev_set_relative_motion_filter (manager, relative_motion_filter,
|
||||
meta_backend_get_monitor_manager (backend));
|
||||
meta_device_manager_native_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
NULL, NULL);
|
||||
meta_device_manager_native_set_relative_motion_filter (manager, relative_motion_filter,
|
||||
meta_backend_get_monitor_manager (backend));
|
||||
|
||||
if (meta_settings_is_experimental_feature_enabled (settings,
|
||||
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER))
|
||||
@ -411,7 +412,7 @@ meta_backend_native_warp_pointer (MetaBackend *backend,
|
||||
guint32 time_ = 0;
|
||||
|
||||
/* Warp the input device pointer state. */
|
||||
clutter_evdev_warp_pointer (device, time_, x, y);
|
||||
meta_device_manager_native_warp_pointer (device, time_, x, y);
|
||||
|
||||
/* Warp displayed pointer cursor. */
|
||||
meta_cursor_tracker_update_position (cursor_tracker, x, y);
|
||||
@ -450,7 +451,7 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
clutter_evdev_set_keyboard_map (manager, keymap);
|
||||
meta_device_manager_native_set_keyboard_map (manager, keymap);
|
||||
|
||||
meta_backend_notify_keymap_changed (backend);
|
||||
|
||||
@ -461,7 +462,7 @@ static struct xkb_keymap *
|
||||
meta_backend_native_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
return clutter_evdev_get_keyboard_map (manager);
|
||||
return meta_device_manager_native_get_keyboard_map (manager);
|
||||
}
|
||||
|
||||
static xkb_layout_index_t
|
||||
@ -469,7 +470,7 @@ meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
return clutter_evdev_get_keyboard_layout_index (manager);
|
||||
return meta_device_manager_native_get_keyboard_layout_index (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -483,7 +484,7 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
if (old_idx == idx)
|
||||
return;
|
||||
|
||||
clutter_evdev_set_keyboard_layout_index (manager, idx);
|
||||
meta_device_manager_native_set_keyboard_layout_index (manager, idx);
|
||||
meta_backend_notify_keymap_layout_group_changed (backend, idx);
|
||||
}
|
||||
|
||||
@ -492,7 +493,7 @@ meta_backend_native_set_numlock (MetaBackend *backend,
|
||||
gboolean numlock_state)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
clutter_evdev_set_keyboard_numlock (manager, numlock_state);
|
||||
meta_device_manager_native_set_keyboard_numlock (manager, numlock_state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -503,9 +504,9 @@ meta_backend_native_get_relative_motion_deltas (MetaBackend *backend,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel)
|
||||
{
|
||||
return clutter_evdev_event_get_relative_motion (event,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
return meta_event_native_get_relative_motion (event,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -798,7 +799,7 @@ meta_backend_native_pause (MetaBackendNative *native)
|
||||
MetaMonitorManagerKms *monitor_manager_kms =
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
|
||||
clutter_evdev_release_devices ();
|
||||
meta_device_manager_native_release_devices ();
|
||||
clutter_stage_freeze_updates (stage);
|
||||
|
||||
disconnect_udev_device_added_handler (native);
|
||||
@ -821,7 +822,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
||||
|
||||
connect_udev_device_added_handler (native);
|
||||
|
||||
clutter_evdev_reclaim_devices ();
|
||||
meta_device_manager_native_reclaim_devices ();
|
||||
clutter_stage_thaw_updates (stage);
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-renderer.h"
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "backends/native/meta-stage-native.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "core/bell.h"
|
||||
@ -54,6 +56,8 @@ struct _MetaClutterBackendNative
|
||||
ClutterBackendEglNative parent;
|
||||
|
||||
MetaStageNative *stage_native;
|
||||
MetaKeymapNative *keymap;
|
||||
MetaDeviceManagerNative *device_manager;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaClutterBackendNative, meta_clutter_backend_native,
|
||||
@ -103,6 +107,33 @@ meta_clutter_backend_native_bell_notify (ClutterBackend *backend)
|
||||
meta_bell_notify (display, NULL);
|
||||
}
|
||||
|
||||
static ClutterDeviceManager *
|
||||
meta_clutter_backend_native_get_device_manager (ClutterBackend *backend)
|
||||
{
|
||||
MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (backend);
|
||||
|
||||
return CLUTTER_DEVICE_MANAGER (backend_native->device_manager);
|
||||
}
|
||||
|
||||
static ClutterKeymap *
|
||||
meta_clutter_backend_native_get_keymap (ClutterBackend *backend)
|
||||
{
|
||||
MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (backend);
|
||||
|
||||
return CLUTTER_KEYMAP (backend_native->keymap);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_clutter_backend_native_init_events (ClutterBackend *backend)
|
||||
{
|
||||
MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (backend);
|
||||
|
||||
backend_native->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL);
|
||||
backend_native->device_manager = g_object_new (META_TYPE_DEVICE_MANAGER_NATIVE,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_clutter_backend_native_init (MetaClutterBackendNative *clutter_backend_nativen)
|
||||
{
|
||||
@ -116,4 +147,7 @@ meta_clutter_backend_native_class_init (MetaClutterBackendNativeClass *klass)
|
||||
clutter_backend_class->get_renderer = meta_clutter_backend_native_get_renderer;
|
||||
clutter_backend_class->create_stage = meta_clutter_backend_native_create_stage;
|
||||
clutter_backend_class->bell_notify = meta_clutter_backend_native_bell_notify;
|
||||
clutter_backend_class->get_device_manager = meta_clutter_backend_native_get_device_manager;
|
||||
clutter_backend_class->get_keymap = meta_clutter_backend_native_get_keymap;
|
||||
clutter_backend_class->init_events = meta_clutter_backend_native_init_events;
|
||||
}
|
||||
|
2703
src/backends/native/meta-device-manager-native.c
Normal file
2703
src/backends/native/meta-device-manager-native.c
Normal file
File diff suppressed because it is too large
Load Diff
194
src/backends/native/meta-device-manager-native.h
Normal file
194
src/backends/native/meta-device-manager-native.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef META_DEVICE_MANAGER_NATIVE_H
|
||||
#define META_DEVICE_MANAGER_NATIVE_H
|
||||
|
||||
#include <libinput.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "clutter/clutter-mutter.h"
|
||||
|
||||
#define META_TYPE_DEVICE_MANAGER_NATIVE (meta_device_manager_native_get_type ())
|
||||
#define META_DEVICE_MANAGER_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MANAGER_NATIVE, MetaDeviceManagerNative))
|
||||
#define META_IS_DEVICE_MANAGER_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MANAGER_NATIVE))
|
||||
#define META_DEVICE_MANAGER_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_MANAGER_NATIVE, MetaDeviceManagerNativeClass))
|
||||
#define META_IS_DEVICE_MANAGER_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_MANAGER_NATIVE))
|
||||
#define META_DEVICE_MANAGER_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_MANAGER_NATIVE, MetaDeviceManagerNativeClass))
|
||||
|
||||
typedef struct _MetaDeviceManagerNative MetaDeviceManagerNative;
|
||||
typedef struct _MetaDeviceManagerNativeClass MetaDeviceManagerNativeClass;
|
||||
typedef struct _MetaDeviceManagerNativePrivate MetaDeviceManagerNativePrivate;
|
||||
|
||||
struct _MetaDeviceManagerNative
|
||||
{
|
||||
ClutterDeviceManager parent_instance;
|
||||
|
||||
MetaDeviceManagerNativePrivate *priv;
|
||||
};
|
||||
|
||||
struct _MetaDeviceManagerNativeClass
|
||||
{
|
||||
ClutterDeviceManagerClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_device_manager_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gint meta_device_manager_native_acquire_device_id (MetaDeviceManagerNative *manager_evdev);
|
||||
|
||||
void meta_device_manager_native_release_device_id (MetaDeviceManagerNative *manager_evdev,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
ClutterStage * meta_device_manager_native_get_stage (MetaDeviceManagerNative *manager_evdev);
|
||||
|
||||
void meta_device_manager_native_constrain_pointer (MetaDeviceManagerNative *manager_evdev,
|
||||
ClutterInputDevice *core_pointer,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
float *new_x,
|
||||
float *new_y);
|
||||
|
||||
void meta_device_manager_native_filter_relative_motion (MetaDeviceManagerNative *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy);
|
||||
|
||||
void meta_device_manager_native_dispatch (MetaDeviceManagerNative *manager_evdev);
|
||||
|
||||
struct xkb_state * meta_device_manager_native_get_xkb_state (MetaDeviceManagerNative *manager_evdev);
|
||||
|
||||
static inline guint64
|
||||
us (guint64 us)
|
||||
{
|
||||
return us;
|
||||
}
|
||||
|
||||
static inline guint64
|
||||
ms2us (guint64 ms)
|
||||
{
|
||||
return us (ms * 1000);
|
||||
}
|
||||
|
||||
static inline guint32
|
||||
us2ms (guint64 us)
|
||||
{
|
||||
return (guint32) (us / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* MetaOpenDeviceCallback:
|
||||
* @path: the device path
|
||||
* @flags: flags to be passed to open
|
||||
*
|
||||
* This callback will be called when Clutter needs to access an input
|
||||
* device. It should return an open file descriptor for the file at @path,
|
||||
* or -1 if opening failed.
|
||||
*/
|
||||
typedef int (*MetaOpenDeviceCallback) (const char *path,
|
||||
int flags,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
typedef void (*MetaCloseDeviceCallback) (int fd,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_device_manager_native_set_device_callbacks (MetaOpenDeviceCallback open_callback,
|
||||
MetaCloseDeviceCallback close_callback,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_device_manager_native_set_seat_id (const gchar *seat_id);
|
||||
|
||||
void meta_device_manager_native_release_devices (void);
|
||||
void meta_device_manager_native_reclaim_devices (void);
|
||||
|
||||
/**
|
||||
* MetaPointerConstrainCallback:
|
||||
* @device: the core pointer device
|
||||
* @time: the event time in milliseconds
|
||||
* @x: (inout): the new X coordinate
|
||||
* @y: (inout): the new Y coordinate
|
||||
* @user_data: user data passed to this function
|
||||
*
|
||||
* This callback will be called for all pointer motion events, and should
|
||||
* update (@x, @y) to constrain the pointer position appropriately.
|
||||
* The subsequent motion event will use the updated values as the new coordinates.
|
||||
* Note that the coordinates are not clamped to the stage size, and the callback
|
||||
* must make sure that this happens before it returns.
|
||||
* Also note that the event will be emitted even if the pointer is constrained
|
||||
* to be in the same position.
|
||||
*/
|
||||
typedef void (* MetaPointerConstrainCallback) (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float *x,
|
||||
float *y,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_device_manager_native_set_pointer_constrain_callback (ClutterDeviceManager *evdev,
|
||||
MetaPointerConstrainCallback callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_notify);
|
||||
|
||||
typedef void (* MetaRelativeMotionFilter) (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_device_manager_native_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
MetaRelativeMotionFilter filter,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_device_manager_native_set_keyboard_map (ClutterDeviceManager *evdev,
|
||||
struct xkb_keymap *keymap);
|
||||
|
||||
struct xkb_keymap * meta_device_manager_native_get_keyboard_map (ClutterDeviceManager *evdev);
|
||||
|
||||
void meta_device_manager_native_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_layout_index_t idx);
|
||||
|
||||
xkb_layout_index_t meta_device_manager_native_get_keyboard_layout_index (ClutterDeviceManager *evdev);
|
||||
|
||||
void meta_device_manager_native_set_keyboard_numlock (ClutterDeviceManager *evdev,
|
||||
gboolean numlock_state);
|
||||
|
||||
void meta_device_manager_native_set_keyboard_repeat (ClutterDeviceManager *evdev,
|
||||
gboolean repeat,
|
||||
guint32 delay,
|
||||
guint32 interval);
|
||||
|
||||
typedef gboolean (* MetaEvdevFilterFunc) (struct libinput_event *event,
|
||||
gpointer data);
|
||||
|
||||
void meta_device_manager_native_add_filter (MetaEvdevFilterFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_notify);
|
||||
void meta_device_manager_native_remove_filter (MetaEvdevFilterFunc func,
|
||||
gpointer data);
|
||||
|
||||
void meta_device_manager_native_warp_pointer (ClutterInputDevice *pointer_device,
|
||||
guint32 time_,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
#endif /* META_DEVICE_MANAGER_NATIVE_H */
|
208
src/backends/native/meta-event-native.c
Normal file
208
src/backends/native/meta-event-native.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authored by:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-event-native.h"
|
||||
#include "backends/native/meta-input-device-native.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
|
||||
typedef struct _MetaEventNative MetaEventNative;
|
||||
|
||||
struct _MetaEventNative
|
||||
{
|
||||
guint32 evcode;
|
||||
|
||||
guint64 time_usec;
|
||||
|
||||
gboolean has_relative_motion;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
};
|
||||
|
||||
static MetaEventNative *
|
||||
meta_event_native_new (void)
|
||||
{
|
||||
return g_slice_new0 (MetaEventNative);
|
||||
}
|
||||
|
||||
MetaEventNative *
|
||||
meta_event_native_copy (MetaEventNative *event_evdev)
|
||||
{
|
||||
if (event_evdev != NULL)
|
||||
return g_slice_dup (MetaEventNative, event_evdev);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_event_native_free (MetaEventNative *event_evdev)
|
||||
{
|
||||
if (event_evdev != NULL)
|
||||
g_slice_free (MetaEventNative, event_evdev);
|
||||
}
|
||||
|
||||
static MetaEventNative *
|
||||
meta_event_native_ensure_platform_data (ClutterEvent *event)
|
||||
{
|
||||
MetaEventNative *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (!event_evdev)
|
||||
{
|
||||
event_evdev = meta_event_native_new ();
|
||||
_clutter_event_set_platform_data (event, event_evdev);
|
||||
}
|
||||
|
||||
return event_evdev;
|
||||
}
|
||||
|
||||
void
|
||||
meta_event_native_set_event_code (ClutterEvent *event,
|
||||
guint32 evcode)
|
||||
{
|
||||
MetaEventNative *event_evdev;
|
||||
|
||||
event_evdev = meta_event_native_ensure_platform_data (event);
|
||||
event_evdev->evcode = evcode;
|
||||
}
|
||||
|
||||
void
|
||||
meta_event_native_set_time_usec (ClutterEvent *event,
|
||||
guint64 time_usec)
|
||||
{
|
||||
MetaEventNative *event_evdev;
|
||||
|
||||
event_evdev = meta_event_native_ensure_platform_data (event);
|
||||
event_evdev->time_usec = time_usec;
|
||||
}
|
||||
|
||||
void
|
||||
meta_event_native_set_relative_motion (ClutterEvent *event,
|
||||
double dx,
|
||||
double dy,
|
||||
double dx_unaccel,
|
||||
double dy_unaccel)
|
||||
{
|
||||
MetaEventNative *event_evdev;
|
||||
|
||||
event_evdev = meta_event_native_ensure_platform_data (event);
|
||||
event_evdev->dx = dx;
|
||||
event_evdev->dy = dy;
|
||||
event_evdev->dx_unaccel = dx_unaccel;
|
||||
event_evdev->dy_unaccel = dy_unaccel;
|
||||
event_evdev->has_relative_motion = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_event_native_get_event_code:
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* Returns the event code of the original event. See linux/input.h for more
|
||||
* information.
|
||||
*
|
||||
* Returns: The event code.
|
||||
**/
|
||||
guint32
|
||||
meta_event_native_get_event_code (const ClutterEvent *event)
|
||||
{
|
||||
MetaEventNative *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev)
|
||||
return event_evdev->evcode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_event_native_get_time_usec:
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* Returns the time in microsecond granularity, or 0 if unavailable.
|
||||
*
|
||||
* Returns: The time in microsecond granularity, or 0 if unavailable.
|
||||
*/
|
||||
guint64
|
||||
meta_event_native_get_time_usec (const ClutterEvent *event)
|
||||
{
|
||||
MetaEventNative *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev)
|
||||
return event_evdev->time_usec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_event_get_pointer_motion
|
||||
* @event: a #ClutterEvent
|
||||
*
|
||||
* If available, the normal and unaccelerated motion deltas are written
|
||||
* to the dx, dy, dx_unaccel and dy_unaccel and TRUE is returned.
|
||||
*
|
||||
* If unavailable, FALSE is returned.
|
||||
*
|
||||
* Returns: TRUE on success, otherwise FALSE.
|
||||
**/
|
||||
gboolean
|
||||
meta_event_native_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel)
|
||||
{
|
||||
MetaEventNative *event_evdev = _clutter_event_get_platform_data (event);
|
||||
|
||||
if (event_evdev && event_evdev->has_relative_motion)
|
||||
{
|
||||
if (dx)
|
||||
*dx = event_evdev->dx;
|
||||
if (dy)
|
||||
*dy = event_evdev->dy;
|
||||
if (dx_unaccel)
|
||||
*dx_unaccel = event_evdev->dx_unaccel;
|
||||
if (dy_unaccel)
|
||||
*dy_unaccel = event_evdev->dy_unaccel;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_event_native_sequence_get_slot:
|
||||
* @sequence: a #ClutterEventSequence
|
||||
*
|
||||
* Retrieves the touch slot triggered by this @sequence
|
||||
*
|
||||
* Returns: the libinput touch slot.
|
||||
*
|
||||
* Since: 1.20
|
||||
* Stability: unstable
|
||||
**/
|
||||
int32_t
|
||||
meta_event_native_sequence_get_slot (const ClutterEventSequence *sequence)
|
||||
{
|
||||
if (!sequence)
|
||||
return -1;
|
||||
|
||||
return GPOINTER_TO_INT (sequence) - 1;
|
||||
}
|
50
src/backends/native/meta-event-native.h
Normal file
50
src/backends/native/meta-event-native.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authored by:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_EVENT_NATIVE_H
|
||||
#define META_EVENT_NATIVE_H
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
typedef struct _MetaEventNative MetaEventNative;
|
||||
|
||||
MetaEventNative * meta_event_native_copy (MetaEventNative *event_evdev);
|
||||
void meta_event_native_free (MetaEventNative *event_evdev);
|
||||
|
||||
guint32 meta_event_native_get_event_code (const ClutterEvent *event);
|
||||
void meta_event_native_set_event_code (ClutterEvent *event,
|
||||
guint32 evcode);
|
||||
guint64 meta_event_native_get_time_usec (const ClutterEvent *event);
|
||||
void meta_event_native_set_time_usec (ClutterEvent *event,
|
||||
guint64 time_usec);
|
||||
void meta_event_native_set_relative_motion (ClutterEvent *event,
|
||||
double dx,
|
||||
double dy,
|
||||
double dx_unaccel,
|
||||
double dy_unaccel);
|
||||
gboolean meta_event_native_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel);
|
||||
|
||||
int32_t meta_event_native_sequence_get_slot (const ClutterEventSequence *sequence);
|
||||
|
||||
#endif /* META_EVENT_NATIVE_H */
|
1560
src/backends/native/meta-input-device-native.c
Normal file
1560
src/backends/native/meta-input-device-native.c
Normal file
File diff suppressed because it is too large
Load Diff
145
src/backends/native/meta-input-device-native.h
Normal file
145
src/backends/native/meta-input-device-native.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
* Copyright (C) 2014 Jonas Ådahl
|
||||
*
|
||||
* 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 META_INPUT_DEVICE_NATIVE_H
|
||||
#define META_INPUT_DEVICE_NATIVE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
|
||||
#define META_TYPE_INPUT_DEVICE_NATIVE meta_input_device_native_get_type()
|
||||
|
||||
#define META_INPUT_DEVICE_NATIVE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNative))
|
||||
|
||||
#define META_INPUT_DEVICE_NATIVE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass))
|
||||
|
||||
#define META_IS_INPUT_DEVICE_NATIVE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
META_TYPE_INPUT_DEVICE_NATIVE))
|
||||
|
||||
#define META_IS_INPUT_DEVICE_NATIVE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
META_TYPE_INPUT_DEVICE_NATIVE))
|
||||
|
||||
#define META_INPUT_DEVICE_NATIVE_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass))
|
||||
|
||||
typedef struct _MetaInputDeviceNative MetaInputDeviceNative;
|
||||
typedef struct _MetaInputDeviceNativeClass MetaInputDeviceNativeClass;
|
||||
|
||||
struct _MetaInputDeviceNative
|
||||
{
|
||||
ClutterInputDevice parent;
|
||||
|
||||
struct libinput_device *libinput_device;
|
||||
MetaSeatNative *seat;
|
||||
ClutterInputDeviceTool *last_tool;
|
||||
|
||||
cairo_matrix_t device_matrix;
|
||||
gdouble device_aspect_ratio; /* w:h */
|
||||
gdouble output_ratio; /* w:h */
|
||||
|
||||
GHashTable *touches;
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKeyboardA11yFlags a11y_flags;
|
||||
GList *slow_keys_list;
|
||||
guint debounce_timer;
|
||||
guint16 debounce_key;
|
||||
xkb_mod_mask_t stickykeys_depressed_mask;
|
||||
xkb_mod_mask_t stickykeys_latched_mask;
|
||||
xkb_mod_mask_t stickykeys_locked_mask;
|
||||
guint toggle_slowkeys_timer;
|
||||
guint16 shift_count;
|
||||
guint32 last_shift_time;
|
||||
gint mousekeys_btn;
|
||||
gboolean mousekeys_btn_states[3];
|
||||
guint32 mousekeys_first_motion_time; /* ms */
|
||||
guint32 mousekeys_last_motion_time; /* ms */
|
||||
guint mousekeys_init_delay;
|
||||
guint mousekeys_accel_time;
|
||||
guint mousekeys_max_speed;
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
};
|
||||
|
||||
struct _MetaInputDeviceNativeClass
|
||||
{
|
||||
ClutterInputDeviceClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType meta_input_device_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDevice * meta_input_device_native_new (ClutterDeviceManager *manager,
|
||||
MetaSeatNative *seat,
|
||||
struct libinput_device *libinput_device);
|
||||
|
||||
ClutterInputDevice * meta_input_device_native_new_virtual (ClutterDeviceManager *manager,
|
||||
MetaSeatNative *seat,
|
||||
ClutterInputDeviceType type,
|
||||
ClutterInputMode mode);
|
||||
|
||||
MetaSeatNative * meta_input_device_native_get_seat (MetaInputDeviceNative *device);
|
||||
|
||||
void meta_input_device_native_update_leds (MetaInputDeviceNative *device,
|
||||
enum libinput_led leds);
|
||||
|
||||
ClutterInputDeviceType meta_input_device_native_determine_type (struct libinput_device *libinput_device);
|
||||
|
||||
|
||||
void meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
||||
ClutterStage *stage,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
MetaTouchState * meta_input_device_native_acquire_touch_state (MetaInputDeviceNative *device,
|
||||
int device_slot);
|
||||
|
||||
MetaTouchState * meta_input_device_native_lookup_touch_state (MetaInputDeviceNative *device,
|
||||
int device_slot);
|
||||
|
||||
void meta_input_device_native_release_touch_state (MetaInputDeviceNative *device,
|
||||
MetaTouchState *touch_state);
|
||||
|
||||
void meta_input_device_native_release_touch_slots (MetaInputDeviceNative *device_evdev,
|
||||
uint64_t time_us);
|
||||
|
||||
void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev);
|
||||
|
||||
struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device);
|
||||
|
||||
#endif /* META_INPUT_DEVICE_NATIVE_H */
|
161
src/backends/native/meta-input-device-tool-native.c
Normal file
161
src/backends/native/meta-input-device-tool-native.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright © 2009, 2010, 2011 Intel Corp.
|
||||
*
|
||||
* 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: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-input-device-tool-native.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputDeviceToolNative, meta_input_device_tool_native,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL)
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_finalize (GObject *object)
|
||||
{
|
||||
MetaInputDeviceToolNative *tool = META_INPUT_DEVICE_TOOL_NATIVE (object);
|
||||
|
||||
g_hash_table_unref (tool->button_map);
|
||||
libinput_tablet_tool_unref (tool->tool);
|
||||
|
||||
G_OBJECT_CLASS (meta_input_device_tool_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_class_init (MetaInputDeviceToolNativeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_input_device_tool_native_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool)
|
||||
{
|
||||
tool->button_map = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
|
||||
evdev_tool = g_object_new (META_TYPE_INPUT_DEVICE_TOOL_NATIVE,
|
||||
"type", type,
|
||||
"serial", serial,
|
||||
"id", libinput_tablet_tool_get_tool_id (tool),
|
||||
NULL);
|
||||
|
||||
evdev_tool->tool = libinput_tablet_tool_ref (tool);
|
||||
|
||||
return CLUTTER_INPUT_DEVICE_TOOL (evdev_tool);
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4])
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
|
||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||
g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 &&
|
||||
curve[1] >= 0 && curve[1] <= 1 &&
|
||||
curve[2] >= 0 && curve[2] <= 1 &&
|
||||
curve[3] >= 0 && curve[3] <= 1);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool->pressure_curve[0] = curve[0];
|
||||
evdev_tool->pressure_curve[1] = curve[1];
|
||||
evdev_tool->pressure_curve[2] = curve[2];
|
||||
evdev_tool->pressure_curve[3] = curve[3];
|
||||
}
|
||||
|
||||
void
|
||||
meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
|
||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
|
||||
if (evcode == 0)
|
||||
{
|
||||
g_hash_table_remove (evdev_tool->button_map, GUINT_TO_POINTER (button));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (evdev_tool->button_map, GUINT_TO_POINTER (button),
|
||||
GUINT_TO_POINTER (evcode));
|
||||
}
|
||||
}
|
||||
|
||||
static gdouble
|
||||
calculate_bezier_position (gdouble pos,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2)
|
||||
{
|
||||
gdouble int1_y, int2_y;
|
||||
|
||||
pos = CLAMP (pos, 0, 1);
|
||||
|
||||
/* Intersection between 0,0 and x1,y1 */
|
||||
int1_y = pos * y1;
|
||||
|
||||
/* Intersection between x2,y2 and 1,1 */
|
||||
int2_y = (pos * (1 - y2)) + y2;
|
||||
|
||||
/* Find the new position in the line traced by the previous points */
|
||||
return (pos * (int2_y - int1_y)) + int1_y;
|
||||
}
|
||||
|
||||
gdouble
|
||||
meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
|
||||
return calculate_bezier_position (CLAMP (pressure, 0, 1),
|
||||
evdev_tool->pressure_curve[0],
|
||||
evdev_tool->pressure_curve[1],
|
||||
evdev_tool->pressure_curve[2],
|
||||
evdev_tool->pressure_curve[3]);
|
||||
}
|
||||
|
||||
guint
|
||||
meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), 0);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
|
||||
return GPOINTER_TO_UINT (g_hash_table_lookup (evdev_tool->button_map,
|
||||
GUINT_TO_POINTER (button)));
|
||||
}
|
86
src/backends/native/meta-input-device-tool-native.h
Normal file
86
src/backends/native/meta-input-device-tool-native.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright © 2009, 2010, 2011 Intel Corp.
|
||||
*
|
||||
* 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: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_DEVICE_NATIVE_TOOL_H
|
||||
#define META_INPUT_DEVICE_NATIVE_TOOL_H
|
||||
|
||||
#include <libinput.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_INPUT_DEVICE_TOOL_NATIVE (meta_input_device_tool_native_get_type ())
|
||||
|
||||
#define META_INPUT_DEVICE_TOOL_NATIVE(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((o), \
|
||||
META_TYPE_INPUT_DEVICE_TOOL_NATIVE, MetaInputDeviceToolNative))
|
||||
|
||||
#define META_IS_INPUT_DEVICE_TOOL_NATIVE(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((o), \
|
||||
META_TYPE_INPUT_DEVICE_TOOL_NATIVE))
|
||||
|
||||
#define META_INPUT_DEVICE_TOOL_NATIVE_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((c), \
|
||||
META_TYPE_INPUT_DEVICE_TOOL_EVDEV, MetaInputDeviceToolNativeClass))
|
||||
|
||||
#define META_IS_INPUT_DEVICE_TOOL_NATIVE_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((c), \
|
||||
META_TYPE_INPUT_DEVICE_TOOL_NATIVE))
|
||||
|
||||
#define META_INPUT_DEVICE_TOOL_NATIVE_GET_CLASS(o) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((o), \
|
||||
META_TYPE_INPUT_DEVICE_TOOL_NATIVE, MetaInputDeviceToolNativeClass))
|
||||
|
||||
typedef struct _MetaInputDeviceToolNative MetaInputDeviceToolNative;
|
||||
typedef struct _MetaInputDeviceToolNativeClass MetaInputDeviceToolNativeClass;
|
||||
|
||||
struct _MetaInputDeviceToolNative
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
GHashTable *button_map;
|
||||
gdouble pressure_curve[4];
|
||||
};
|
||||
|
||||
struct _MetaInputDeviceToolNativeClass
|
||||
{
|
||||
ClutterInputDeviceToolClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_input_device_tool_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDeviceTool * meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
gdouble meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure);
|
||||
guint meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button);
|
||||
|
||||
void meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4]);
|
||||
void meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_INPUT_DEVICE_NATIVE_TOOL_H */
|
@ -28,8 +28,9 @@
|
||||
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-input-device-native.h"
|
||||
#include "backends/native/meta-input-device-tool-native.h"
|
||||
#include "backends/native/meta-input-settings-native.h"
|
||||
#include "clutter/evdev/clutter-evdev.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
@ -56,7 +57,7 @@ meta_input_settings_native_set_send_events (MetaInputSettings *settings,
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
|
||||
@ -81,7 +82,7 @@ meta_input_settings_native_set_speed (MetaInputSettings *settings,
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
libinput_device_config_accel_set_speed (libinput_device,
|
||||
@ -95,7 +96,7 @@ meta_input_settings_native_set_left_handed (MetaInputSettings *settings,
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -110,7 +111,7 @@ meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings,
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -128,7 +129,7 @@ meta_input_settings_native_set_tap_and_drag_enabled (MetaInputSettings *setting
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -146,7 +147,7 @@ meta_input_settings_native_set_disable_while_typing (MetaInputSettings *setting
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
|
||||
if (!libinput_device)
|
||||
return;
|
||||
@ -165,7 +166,7 @@ meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings,
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -200,7 +201,7 @@ meta_input_settings_native_set_edge_scroll (MetaInputSettings *settin
|
||||
struct libinput_device *libinput_device;
|
||||
enum libinput_config_scroll_method current, method;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
|
||||
method = edge_scrolling_enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
current = libinput_device_config_scroll_get_method (libinput_device);
|
||||
@ -217,7 +218,7 @@ meta_input_settings_native_set_two_finger_scroll (MetaInputSettings *
|
||||
struct libinput_device *libinput_device;
|
||||
enum libinput_config_scroll_method current, method;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
|
||||
method = two_finger_scroll_enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
current = libinput_device_config_scroll_get_method (libinput_device);
|
||||
@ -232,7 +233,7 @@ meta_input_settings_native_has_two_finger_scroll (MetaInputSettings *settings,
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return FALSE;
|
||||
|
||||
@ -248,7 +249,7 @@ meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
|
||||
enum libinput_config_scroll_method method;
|
||||
guint evcode;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -282,7 +283,7 @@ meta_input_settings_native_set_click_method (MetaInputSettings *settin
|
||||
enum libinput_config_click_method click_method = 0;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return;
|
||||
|
||||
@ -316,7 +317,7 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
clutter_evdev_set_keyboard_repeat (manager, enabled, delay, interval);
|
||||
meta_device_manager_native_set_keyboard_repeat (manager, enabled, delay, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -327,7 +328,7 @@ set_device_accel_profile (ClutterInputDevice *device,
|
||||
enum libinput_config_accel_profile libinput_profile;
|
||||
uint32_t profiles;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
|
||||
switch (profile)
|
||||
{
|
||||
@ -363,7 +364,7 @@ has_udev_property (ClutterInputDevice *device,
|
||||
struct udev_device *udev_device;
|
||||
struct udev_device *parent_udev_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return FALSE;
|
||||
|
||||
@ -500,7 +501,7 @@ meta_input_settings_native_set_tablet_area (MetaInputSettings *settings,
|
||||
gfloat matrix[6] = { scale_x, 0., offset_x,
|
||||
0., scale_y, offset_y };
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device = meta_input_device_native_get_libinput_device (device);
|
||||
if (!libinput_device ||
|
||||
!libinput_device_config_calibration_has_matrix (libinput_device))
|
||||
return;
|
||||
@ -521,7 +522,7 @@ meta_input_settings_native_set_stylus_pressure (MetaInputSettings *settings
|
||||
pressure_curve[2] = (gdouble) curve[2] / 100;
|
||||
pressure_curve[3] = (gdouble) curve[3] / 100;
|
||||
|
||||
clutter_evdev_input_device_tool_set_pressure_curve (tool, pressure_curve);
|
||||
meta_input_device_tool_native_set_pressure_curve (tool, pressure_curve);
|
||||
}
|
||||
|
||||
static guint
|
||||
@ -551,12 +552,12 @@ meta_input_settings_native_set_stylus_button_map (MetaInputSettings *se
|
||||
GDesktopStylusButtonAction secondary,
|
||||
GDesktopStylusButtonAction tertiary)
|
||||
{
|
||||
clutter_evdev_input_device_tool_set_button_code (tool, CLUTTER_BUTTON_MIDDLE,
|
||||
action_to_evcode (primary));
|
||||
clutter_evdev_input_device_tool_set_button_code (tool, CLUTTER_BUTTON_SECONDARY,
|
||||
action_to_evcode (secondary));
|
||||
clutter_evdev_input_device_tool_set_button_code (tool, 8, /* Back */
|
||||
action_to_evcode (tertiary));
|
||||
meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_MIDDLE,
|
||||
action_to_evcode (primary));
|
||||
meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_SECONDARY,
|
||||
action_to_evcode (secondary));
|
||||
meta_input_device_tool_native_set_button_code (tool, 8, /* Back */
|
||||
action_to_evcode (tertiary));
|
||||
}
|
||||
|
||||
static void
|
||||
|
128
src/backends/native/meta-keymap-native.c
Normal file
128
src/backends/native/meta-keymap-native.c
Normal 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 "config.h"
|
||||
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
|
||||
static const char *option_xkb_layout = "us";
|
||||
static const char *option_xkb_variant = "";
|
||||
static const char *option_xkb_options = "";
|
||||
|
||||
typedef struct _MetaKeymapNative MetaKeymapNative;
|
||||
|
||||
struct _MetaKeymapNative
|
||||
{
|
||||
ClutterKeymap parent_instance;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native,
|
||||
CLUTTER_TYPE_KEYMAP)
|
||||
|
||||
static void
|
||||
meta_keymap_native_finalize (GObject *object)
|
||||
{
|
||||
MetaKeymapNative *keymap = META_KEYMAP_NATIVE (object);
|
||||
|
||||
xkb_keymap_unref (keymap->keymap);
|
||||
|
||||
G_OBJECT_CLASS (meta_keymap_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaDeviceManagerNative *device_manager;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
device_manager =
|
||||
META_DEVICE_MANAGER_NATIVE (clutter_device_manager_get_default ());
|
||||
xkb_state = meta_device_manager_native_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
|
||||
meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
MetaDeviceManagerNative *device_manager;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
device_manager =
|
||||
META_DEVICE_MANAGER_NATIVE (clutter_device_manager_get_default ());
|
||||
xkb_state = meta_device_manager_native_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
|
||||
meta_keymap_native_class_init (MetaKeymapNativeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_keymap_native_finalize;
|
||||
|
||||
keymap_class->get_num_lock_state = meta_keymap_native_get_num_lock_state;
|
||||
keymap_class->get_caps_lock_state = meta_keymap_native_get_caps_lock_state;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_keymap_native_init (MetaKeymapNative *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
|
||||
meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||
struct xkb_keymap *xkb_keymap)
|
||||
{
|
||||
if (keymap->keymap)
|
||||
xkb_keymap_unref (keymap->keymap);
|
||||
keymap->keymap = xkb_keymap_ref (xkb_keymap);
|
||||
}
|
||||
|
||||
struct xkb_keymap *
|
||||
meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap)
|
||||
{
|
||||
return keymap->keymap;
|
||||
}
|
32
src/backends/native/meta-keymap-native.h
Normal file
32
src/backends/native/meta-keymap-native.h
Normal 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 "backends/native/meta-xkb-utils.h"
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
#define META_TYPE_KEYMAP_NATIVE (meta_keymap_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native,
|
||||
META, KEYMAP_NATIVE,
|
||||
ClutterKeymap)
|
||||
|
||||
void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||
struct xkb_keymap *xkb_keymap);
|
||||
struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap);
|
@ -24,6 +24,7 @@
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
@ -37,9 +38,9 @@
|
||||
#include "backends/native/dbus-utils.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/evdev/clutter-evdev.h"
|
||||
|
||||
#include "meta-dbus-login1.h"
|
||||
|
||||
@ -524,11 +525,11 @@ meta_launcher_new (GError **error)
|
||||
self->sysfs_fds = g_hash_table_new (NULL, NULL);
|
||||
self->session_active = TRUE;
|
||||
|
||||
clutter_evdev_set_seat_id (self->seat_id);
|
||||
meta_device_manager_native_set_seat_id (self->seat_id);
|
||||
|
||||
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
||||
on_evdev_device_close,
|
||||
self);
|
||||
meta_device_manager_native_set_device_callbacks (on_evdev_device_open,
|
||||
on_evdev_device_close,
|
||||
self);
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
|
904
src/backends/native/meta-seat-native.c
Normal file
904
src/backends/native/meta-seat-native.c
Normal file
@ -0,0 +1,904 @@
|
||||
/*
|
||||
* 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 "config.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
#include "backends/native/meta-event-native.h"
|
||||
#include "backends/native/meta-input-device-native.h"
|
||||
#include "backends/native/meta-input-device-tool-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "clutter/clutter-mutter.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
|
||||
|
||||
#define AUTOREPEAT_VALUE 2
|
||||
|
||||
#define DISCRETE_SCROLL_STEP 10.0
|
||||
|
||||
#ifndef BTN_STYLUS3
|
||||
#define BTN_STYLUS3 0x149 /* Linux 4.15 */
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_seat_native_set_libinput_seat (MetaSeatNative *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
|
||||
meta_seat_native_sync_leds (MetaSeatNative *seat)
|
||||
{
|
||||
GSList *iter;
|
||||
MetaInputDeviceNative *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;
|
||||
meta_input_device_native_update_leds (device_evdev, leds);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_touch_state_free (MetaTouchState *touch_state)
|
||||
{
|
||||
g_slice_free (MetaTouchState, touch_state);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_seat_slot_allocated (MetaSeatNative *seat,
|
||||
int seat_slot)
|
||||
{
|
||||
if (seat_slot >= seat->n_alloc_touch_states)
|
||||
{
|
||||
const int size_increase = 5;
|
||||
int i;
|
||||
|
||||
seat->n_alloc_touch_states += size_increase;
|
||||
seat->touch_states = g_realloc_n (seat->touch_states,
|
||||
seat->n_alloc_touch_states,
|
||||
sizeof (MetaTouchState *));
|
||||
for (i = 0; i < size_increase; i++)
|
||||
seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MetaTouchState *
|
||||
meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
||||
int device_slot)
|
||||
{
|
||||
MetaTouchState *touch_state;
|
||||
int seat_slot;
|
||||
|
||||
for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++)
|
||||
{
|
||||
if (!seat->touch_states[seat_slot])
|
||||
break;
|
||||
}
|
||||
|
||||
ensure_seat_slot_allocated (seat, seat_slot);
|
||||
|
||||
touch_state = g_slice_new0 (MetaTouchState);
|
||||
*touch_state = (MetaTouchState) {
|
||||
.seat = seat,
|
||||
.seat_slot = seat_slot,
|
||||
.device_slot = device_slot,
|
||||
};
|
||||
|
||||
seat->touch_states[seat_slot] = touch_state;
|
||||
|
||||
return touch_state;
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_release_touch_state (MetaSeatNative *seat,
|
||||
MetaTouchState *touch_state)
|
||||
{
|
||||
g_clear_pointer (&seat->touch_states[touch_state->seat_slot],
|
||||
clutter_touch_state_free);
|
||||
}
|
||||
|
||||
MetaSeatNative *
|
||||
meta_seat_native_new (MetaDeviceManagerNative *manager_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
|
||||
MetaSeatNative *seat;
|
||||
ClutterInputDevice *device;
|
||||
ClutterStage *stage;
|
||||
ClutterKeymap *keymap;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
|
||||
seat = g_new0 (MetaSeatNative, 1);
|
||||
if (!seat)
|
||||
return NULL;
|
||||
|
||||
seat->manager_evdev = manager_evdev;
|
||||
device = meta_input_device_native_new_virtual (
|
||||
manager, seat, CLUTTER_POINTER_DEVICE,
|
||||
CLUTTER_INPUT_MODE_MASTER);
|
||||
stage = meta_device_manager_native_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 = meta_input_device_native_new_virtual (
|
||||
manager, seat, CLUTTER_KEYBOARD_DEVICE,
|
||||
CLUTTER_INPUT_MODE_MASTER);
|
||||
_clutter_input_device_set_stage (device, stage);
|
||||
_clutter_device_manager_add_device (manager, device);
|
||||
seat->core_keyboard = device;
|
||||
|
||||
seat->repeat = TRUE;
|
||||
seat->repeat_delay = 250; /* ms */
|
||||
seat->repeat_interval = 33; /* ms */
|
||||
|
||||
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
||||
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
||||
|
||||
if (xkb_keymap)
|
||||
{
|
||||
seat->xkb = xkb_state_new (xkb_keymap);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_clear_repeat_timer (MetaSeatNative *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)
|
||||
{
|
||||
MetaSeatNative *seat = data;
|
||||
GSource *source;
|
||||
|
||||
/* There might be events queued in libinput that could cancel the
|
||||
repeat timer. */
|
||||
meta_device_manager_native_dispatch (seat->manager_evdev);
|
||||
if (!seat->repeat_timer)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
|
||||
source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
|
||||
|
||||
meta_seat_native_notify_key (seat,
|
||||
seat->repeat_device,
|
||||
g_source_get_time (source),
|
||||
seat->repeat_key,
|
||||
AUTOREPEAT_VALUE,
|
||||
FALSE);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_event (ClutterEvent *event)
|
||||
{
|
||||
_clutter_event_push (event, FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
update_button_count (MetaSeatNative *seat,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
return ++seat->button_count[button];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle cases where we newer saw the initial pressed event. */
|
||||
if (seat->button_count[button] == 0)
|
||||
return 0;
|
||||
|
||||
return --seat->button_count[button];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
gboolean update_keys)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
enum xkb_state_component changed_state;
|
||||
|
||||
if (state != AUTOREPEAT_VALUE)
|
||||
{
|
||||
/* Drop any repeated button press (for example from virtual devices. */
|
||||
int count = update_button_count (seat, key, state);
|
||||
if (state && count > 1)
|
||||
return;
|
||||
if (!state && count != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (device);
|
||||
if (stage == NULL)
|
||||
{
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
return;
|
||||
}
|
||||
|
||||
event = meta_key_event_new_from_evdev (device,
|
||||
seat->core_keyboard,
|
||||
stage,
|
||||
seat->xkb,
|
||||
seat->button_state,
|
||||
us2ms (time_us), key, state);
|
||||
meta_event_native_set_event_code (event, key);
|
||||
|
||||
/* We must be careful and not pass multiple releases to xkb, otherwise it gets
|
||||
confused and locks the modifiers */
|
||||
if (state != AUTOREPEAT_VALUE)
|
||||
{
|
||||
changed_state = xkb_state_update_key (seat->xkb,
|
||||
event->key.hardware_keycode,
|
||||
state ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
}
|
||||
else
|
||||
{
|
||||
changed_state = 0;
|
||||
clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED);
|
||||
}
|
||||
|
||||
queue_event (event);
|
||||
|
||||
if (update_keys && (changed_state & XKB_STATE_LEDS))
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
g_signal_emit_by_name (clutter_backend_get_keymap (backend), "state-changed");
|
||||
meta_seat_native_sync_leds (seat);
|
||||
meta_input_device_native_a11y_maybe_notify_toggle_keys (META_INPUT_DEVICE_NATIVE (seat->core_keyboard));
|
||||
}
|
||||
|
||||
if (state == 0 || /* key release */
|
||||
!seat->repeat ||
|
||||
!xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb),
|
||||
event->key.hardware_keycode))
|
||||
{
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == 1) /* key press */
|
||||
seat->repeat_count = 0;
|
||||
|
||||
seat->repeat_count += 1;
|
||||
seat->repeat_key = key;
|
||||
|
||||
switch (seat->repeat_count)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
guint32 interval;
|
||||
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
seat->repeat_device = g_object_ref (device);
|
||||
|
||||
if (seat->repeat_count == 1)
|
||||
interval = seat->repeat_delay;
|
||||
else
|
||||
interval = seat->repeat_interval;
|
||||
|
||||
seat->repeat_timer =
|
||||
clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
|
||||
interval,
|
||||
keyboard_repeat,
|
||||
seat,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterEvent *
|
||||
new_absolute_motion_event (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gdouble *axes)
|
||||
{
|
||||
ClutterStage *stage = _clutter_input_device_get_stage (input_device);
|
||||
ClutterEvent *event;
|
||||
|
||||
event = clutter_event_new (CLUTTER_MOTION);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
meta_device_manager_native_constrain_pointer (seat->manager_evdev,
|
||||
seat->core_pointer,
|
||||
time_us,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&x, &y);
|
||||
}
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
event->motion.time = us2ms (time_us);
|
||||
event->motion.stage = stage;
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->motion.x = x;
|
||||
event->motion.y = y;
|
||||
event->motion.axes = axes;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (input_device);
|
||||
|
||||
clutter_event_set_device_tool (event, device_evdev->last_tool);
|
||||
clutter_event_set_device (event, input_device);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
}
|
||||
|
||||
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
seat->pointer_x = x;
|
||||
seat->pointer_y = y;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_relative_motion (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float dx,
|
||||
float dy,
|
||||
float dx_unaccel,
|
||||
float dy_unaccel)
|
||||
{
|
||||
gfloat new_x, new_y;
|
||||
ClutterEvent *event;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
if (!_clutter_input_device_get_stage (input_device))
|
||||
return;
|
||||
|
||||
meta_device_manager_native_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
new_x = seat->pointer_x + dx;
|
||||
new_y = seat->pointer_y + dy;
|
||||
event = new_absolute_motion_event (seat, input_device,
|
||||
time_us, new_x, new_y, NULL);
|
||||
|
||||
meta_event_native_set_relative_motion (event,
|
||||
dx, dy,
|
||||
dx_unaccel, dy_unaccel);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_absolute_motion (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
|
||||
event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev = (MetaInputDeviceNative *) input_device;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gint button_nr;
|
||||
static gint maskmap[8] =
|
||||
{
|
||||
CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
|
||||
CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
|
||||
};
|
||||
int button_count;
|
||||
|
||||
/* Drop any repeated button press (for example from virtual devices. */
|
||||
button_count = update_button_count (seat, button, state);
|
||||
if (state && button_count > 1)
|
||||
return;
|
||||
if (!state && button_count != 0)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
/* The evdev button numbers don't map sequentially to clutter button
|
||||
* numbers (the right and middle mouse buttons are in the opposite
|
||||
* order) so we'll map them directly with a switch statement */
|
||||
switch (button)
|
||||
{
|
||||
case BTN_LEFT:
|
||||
case BTN_TOUCH:
|
||||
button_nr = CLUTTER_BUTTON_PRIMARY;
|
||||
break;
|
||||
|
||||
case BTN_RIGHT:
|
||||
case BTN_STYLUS:
|
||||
button_nr = CLUTTER_BUTTON_SECONDARY;
|
||||
break;
|
||||
|
||||
case BTN_MIDDLE:
|
||||
case BTN_STYLUS2:
|
||||
button_nr = CLUTTER_BUTTON_MIDDLE;
|
||||
break;
|
||||
|
||||
case 0x149: /* BTN_STYLUS3 */
|
||||
button_nr = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
button_nr = button - BTN_TOOL_PEN + 4;
|
||||
else
|
||||
button_nr = button - (BTN_LEFT - 1) + 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (button_nr < 1 || button_nr > 12)
|
||||
{
|
||||
g_warning ("Unhandled button event 0x%x", button);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state)
|
||||
event = clutter_event_new (CLUTTER_BUTTON_PRESS);
|
||||
else
|
||||
event = clutter_event_new (CLUTTER_BUTTON_RELEASE);
|
||||
|
||||
if (button_nr < G_N_ELEMENTS (maskmap))
|
||||
{
|
||||
/* Update the modifiers */
|
||||
if (state)
|
||||
seat->button_state |= maskmap[button_nr - 1];
|
||||
else
|
||||
seat->button_state &= ~maskmap[button_nr - 1];
|
||||
}
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
event->button.time = us2ms (time_us);
|
||||
event->button.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->button.button = button_nr;
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
ClutterPoint point;
|
||||
|
||||
clutter_input_device_get_coords (input_device, NULL, &point);
|
||||
event->button.x = point.x;
|
||||
event->button.y = point.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->button.x = seat->pointer_x;
|
||||
event->button.y = seat->pointer_y;
|
||||
}
|
||||
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
if (device_evdev->last_tool)
|
||||
{
|
||||
/* Apply the button event code as per the tool mapping */
|
||||
guint mapped_button;
|
||||
|
||||
mapped_button = meta_input_device_tool_native_get_button_code (device_evdev->last_tool,
|
||||
button_nr);
|
||||
if (mapped_button != 0)
|
||||
button = mapped_button;
|
||||
}
|
||||
|
||||
meta_event_native_set_event_code (event, button);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
clutter_event_set_device_tool (event, device_evdev->last_tool);
|
||||
clutter_event_set_device (event, input_device);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
}
|
||||
|
||||
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev;
|
||||
MetaSeatNative *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
||||
seat = meta_input_device_native_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
* 1/10. */
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
scroll_factor = 1.0 / DISCRETE_SCROLL_STEP;
|
||||
clutter_event_set_scroll_delta (event,
|
||||
scroll_factor * dx,
|
||||
scroll_factor * dy);
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
event->scroll.finish_flags = flags;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
MetaInputDeviceNative *device_evdev;
|
||||
MetaSeatNative *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
if (direction == CLUTTER_SCROLL_SMOOTH)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
||||
seat = meta_input_device_native_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
int i, n_xscrolls, n_yscrolls;
|
||||
|
||||
n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP);
|
||||
n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP);
|
||||
|
||||
for (i = 0; i < n_xscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dx > 0 ?
|
||||
CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_yscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dy > 0 ?
|
||||
CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP);
|
||||
seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP);
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL)
|
||||
seat->accum_scroll_dx = 0;
|
||||
else
|
||||
seat->accum_scroll_dx += dx;
|
||||
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL)
|
||||
seat->accum_scroll_dy = 0;
|
||||
else
|
||||
seat->accum_scroll_dy += dy;
|
||||
|
||||
notify_scroll (input_device, time_us, dx, dy, scroll_source,
|
||||
finish_flags, FALSE);
|
||||
check_notify_discrete_scroll (seat, input_device, time_us, scroll_source);
|
||||
}
|
||||
|
||||
static ClutterScrollDirection
|
||||
discrete_to_direction (double discrete_dx,
|
||||
double discrete_dy)
|
||||
{
|
||||
if (discrete_dx > 0)
|
||||
return CLUTTER_SCROLL_RIGHT;
|
||||
else if (discrete_dx < 0)
|
||||
return CLUTTER_SCROLL_LEFT;
|
||||
else if (discrete_dy > 0)
|
||||
return CLUTTER_SCROLL_DOWN;
|
||||
else if (discrete_dy < 0)
|
||||
return CLUTTER_SCROLL_UP;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
notify_scroll (input_device, time_us,
|
||||
discrete_dx * DISCRETE_SCROLL_STEP,
|
||||
discrete_dy * DISCRETE_SCROLL_STEP,
|
||||
scroll_source, CLUTTER_SCROLL_FINISHED_NONE,
|
||||
TRUE);
|
||||
notify_discrete_scroll (input_device, time_us,
|
||||
discrete_to_direction (discrete_dx, discrete_dy),
|
||||
scroll_source, FALSE);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
event = clutter_event_new (evtype);
|
||||
|
||||
meta_event_native_set_time_usec (event, time_us);
|
||||
event->touch.time = us2ms (time_us);
|
||||
event->touch.stage = CLUTTER_STAGE (stage);
|
||||
event->touch.x = x;
|
||||
event->touch.y = y;
|
||||
meta_input_device_native_translate_coordinates (input_device, stage,
|
||||
&event->touch.x,
|
||||
&event->touch.y);
|
||||
|
||||
/* "NULL" sequences are special cased in clutter */
|
||||
event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1));
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
if (evtype == CLUTTER_TOUCH_BEGIN ||
|
||||
evtype == CLUTTER_TOUCH_UPDATE)
|
||||
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
|
||||
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_free (MetaSeatNative *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_free (seat->touch_states);
|
||||
|
||||
xkb_state_unref (seat->xkb);
|
||||
|
||||
meta_seat_native_clear_repeat_timer (seat);
|
||||
|
||||
if (seat->libinput_seat)
|
||||
libinput_seat_unref (seat->libinput_seat);
|
||||
|
||||
g_free (seat);
|
||||
}
|
||||
|
||||
ClutterInputDevice *
|
||||
meta_seat_native_get_device (MetaSeatNative *seat,
|
||||
gint id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
GSList *l;
|
||||
|
||||
for (l = seat->devices; l; l = l->next)
|
||||
{
|
||||
device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_id (device) == id)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_seat_native_set_stage (MetaSeatNative *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);
|
||||
}
|
||||
}
|
160
src/backends/native/meta-seat-native.h
Normal file
160
src/backends/native/meta-seat-native.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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 META_SEAT_NATIVE_H
|
||||
#define META_SEAT_NATIVE_H
|
||||
|
||||
#include <libinput.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
#include "backends/native/meta-device-manager-native.h"
|
||||
#include "backends/native/meta-xkb-utils.h"
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
typedef struct _MetaTouchState MetaTouchState;
|
||||
typedef struct _MetaSeatNative MetaSeatNative;
|
||||
|
||||
struct _MetaTouchState
|
||||
{
|
||||
MetaSeatNative *seat;
|
||||
|
||||
int device_slot;
|
||||
int seat_slot;
|
||||
ClutterPoint coords;
|
||||
};
|
||||
|
||||
struct _MetaSeatNative
|
||||
{
|
||||
struct libinput_seat *libinput_seat;
|
||||
MetaDeviceManagerNative *manager_evdev;
|
||||
|
||||
GSList *devices;
|
||||
|
||||
ClutterInputDevice *core_pointer;
|
||||
ClutterInputDevice *core_keyboard;
|
||||
|
||||
MetaTouchState **touch_states;
|
||||
int n_alloc_touch_states;
|
||||
|
||||
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;
|
||||
xkb_layout_index_t layout_idx;
|
||||
uint32_t button_state;
|
||||
int button_count[KEY_CNT];
|
||||
|
||||
/* 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 meta_seat_native_notify_key (MetaSeatNative *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
gboolean update_keys);
|
||||
|
||||
void meta_seat_native_notify_relative_motion (MetaSeatNative *seat_evdev,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float dx,
|
||||
float dy,
|
||||
float dx_unaccel,
|
||||
float dy_unaccel);
|
||||
|
||||
void meta_seat_native_notify_absolute_motion (MetaSeatNative *seat_evdev,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
float x,
|
||||
float y,
|
||||
double *axes);
|
||||
|
||||
void meta_seat_native_notify_button (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
uint32_t state);
|
||||
|
||||
void meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags);
|
||||
|
||||
void meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource source);
|
||||
|
||||
void meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
void meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
|
||||
struct libinput_seat *libinput_seat);
|
||||
|
||||
void meta_seat_native_sync_leds (MetaSeatNative *seat);
|
||||
|
||||
ClutterInputDevice * meta_seat_native_get_device (MetaSeatNative *seat,
|
||||
gint id);
|
||||
|
||||
MetaTouchState * meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
||||
int device_slot);
|
||||
|
||||
void meta_seat_native_release_touch_state (MetaSeatNative *seat,
|
||||
MetaTouchState *touch_state);
|
||||
|
||||
MetaTouchState * meta_seat_native_get_touch (MetaSeatNative *seat,
|
||||
guint32 id);
|
||||
|
||||
void meta_seat_native_set_stage (MetaSeatNative *seat,
|
||||
ClutterStage *stage);
|
||||
|
||||
void meta_seat_native_clear_repeat_timer (MetaSeatNative *seat);
|
||||
|
||||
MetaSeatNative * meta_seat_native_new (MetaDeviceManagerNative *manager_evdev);
|
||||
|
||||
void meta_seat_native_free (MetaSeatNative *seat);
|
||||
|
||||
#endif /* META_SEAT_NATIVE_H */
|
701
src/backends/native/meta-virtual-input-device-native.c
Normal file
701
src/backends/native/meta-virtual-input-device-native.c
Normal file
@ -0,0 +1,701 @@
|
||||
/*
|
||||
* 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-device-native.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
#include "backends/native/meta-virtual-input-device-native.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SEAT,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
struct _MetaVirtualInputDeviceNative
|
||||
{
|
||||
ClutterVirtualInputDevice parent;
|
||||
|
||||
ClutterInputDevice *device;
|
||||
MetaSeatNative *seat;
|
||||
int button_count[KEY_CNT];
|
||||
};
|
||||
|
||||
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 (MetaVirtualInputDeviceNative *virtual_evdev,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
if (state)
|
||||
return ++virtual_evdev->button_count[button];
|
||||
else
|
||||
return --virtual_evdev->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 void
|
||||
release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
int code;
|
||||
uint64_t time_us;
|
||||
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++)
|
||||
{
|
||||
if (virtual_evdev->button_count[code] == 0)
|
||||
continue;
|
||||
|
||||
switch (get_button_type (code))
|
||||
{
|
||||
case EVDEV_BUTTON_TYPE_KEY:
|
||||
clutter_virtual_input_device_notify_key (virtual_device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_KEY_STATE_RELEASED);
|
||||
break;
|
||||
case EVDEV_BUTTON_TYPE_BUTTON:
|
||||
clutter_virtual_input_device_notify_button (virtual_device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case EVDEV_BUTTON_TYPE_NONE:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_relative_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_absolute_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
x, y,
|
||||
NULL);
|
||||
}
|
||||
|
||||
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 void
|
||||
meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
ClutterButtonState button_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
int button_count;
|
||||
int evdev_button;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
evdev_button = translate_to_evdev_button (button);
|
||||
|
||||
if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
||||
evdev_button);
|
||||
return;
|
||||
}
|
||||
|
||||
button_count = update_button_count (virtual_evdev, evdev_button, button_state);
|
||||
if (button_count < 0 || button_count > 1)
|
||||
{
|
||||
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
|
||||
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases");
|
||||
update_button_count (virtual_evdev, evdev_button, 1 - button_state);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_seat_native_notify_button (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evdev_button,
|
||||
button_state);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t key,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
int key_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
|
||||
return;
|
||||
}
|
||||
|
||||
key_count = update_button_count (virtual_evdev, key, key_state);
|
||||
if (key_count < 0 || key_count > 1)
|
||||
{
|
||||
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", key,
|
||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases");
|
||||
update_button_count (virtual_evdev, key, 1 - key_state);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
key,
|
||||
key_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_device,
|
||||
guint keyval,
|
||||
guint *keycode_out,
|
||||
guint *level_out)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
ClutterKeymap *keymap;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
struct xkb_state *state;
|
||||
guint keycode, layout;
|
||||
xkb_keycode_t min_keycode, max_keycode;
|
||||
|
||||
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
||||
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
||||
state = virtual_evdev->seat->xkb;
|
||||
|
||||
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 (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\n", level);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pick_keycode_for_keyval_in_current_group (virtual_device, keysym,
|
||||
&keycode, NULL))
|
||||
return;
|
||||
|
||||
clutter_input_device_keycode_to_evdev (virtual_evdev->device,
|
||||
keycode, &evcode);
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
int key_count;
|
||||
guint keycode = 0, level = 0, evcode = 0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (!pick_keycode_for_keyval_in_current_group (virtual_device,
|
||||
keyval, &keycode, &level))
|
||||
{
|
||||
g_warning ("No keycode found for keyval %x in current group", keyval);
|
||||
return;
|
||||
}
|
||||
|
||||
clutter_input_device_keycode_to_evdev (virtual_evdev->device,
|
||||
keycode, &evcode);
|
||||
|
||||
if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode);
|
||||
return;
|
||||
}
|
||||
|
||||
key_count = update_button_count (virtual_evdev, evcode, key_state);
|
||||
if (key_count < 0 || key_count > 1)
|
||||
{
|
||||
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", keycode,
|
||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases");
|
||||
update_button_count (virtual_evdev, evcode, 1 - key_state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_state)
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
evcode,
|
||||
key_state,
|
||||
TRUE);
|
||||
|
||||
if (!key_state)
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
}
|
||||
|
||||
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 void
|
||||
meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
double discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
direction_to_discrete (direction, &discrete_dx, &discrete_dy);
|
||||
|
||||
meta_seat_native_notify_discrete_scroll (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
meta_seat_native_notify_scroll_continuous (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
scroll_source,
|
||||
CLUTTER_SCROLL_FINISHED_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_acquire_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
{
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||
MetaInputDeviceNative *device_evdev =
|
||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
||||
MetaTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
|
||||
meta_input_device_native_release_touch_state (device_evdev, touch_state);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDeviceType device_type;
|
||||
ClutterStage *stage;
|
||||
|
||||
manager = clutter_virtual_input_device_get_manager (virtual_device);
|
||||
device_type = clutter_virtual_input_device_get_device_type (virtual_device);
|
||||
|
||||
virtual_evdev->device =
|
||||
meta_input_device_native_new_virtual (manager,
|
||||
virtual_evdev->seat,
|
||||
device_type,
|
||||
CLUTTER_INPUT_MODE_SLAVE);
|
||||
|
||||
stage = meta_device_manager_native_get_stage (META_DEVICE_MANAGER_NATIVE (manager));
|
||||
_clutter_input_device_set_stage (virtual_evdev->device, stage);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_virtual_input_device_native_finalize (GObject *object)
|
||||
{
|
||||
ClutterVirtualInputDevice *virtual_device =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE (object);
|
||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||
GObjectClass *object_class;
|
||||
|
||||
release_pressed_buttons (virtual_device);
|
||||
g_clear_object (&virtual_evdev->device);
|
||||
|
||||
object_class =
|
||||
G_OBJECT_CLASS (meta_virtual_input_device_native_parent_class);
|
||||
object_class->finalize (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->finalize = meta_virtual_input_device_native_finalize;
|
||||
|
||||
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",
|
||||
P_("Seat"),
|
||||
P_("Seat"),
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
|
||||
}
|
31
src/backends/native/meta-virtual-input-device-native.h
Normal file
31
src/backends/native/meta-virtual-input-device-native.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef META_VIRTUAL_INPUT_DEVICE_NATIVE_H
|
||||
#define META_VIRTUAL_INPUT_DEVICE_NATIVE_H
|
||||
|
||||
#include "clutter/clutter-virtual-input-device.h"
|
||||
|
||||
#define META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE (meta_virtual_input_device_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaVirtualInputDeviceNative,
|
||||
meta_virtual_input_device_native,
|
||||
META, VIRTUAL_INPUT_DEVICE_NATIVE,
|
||||
ClutterVirtualInputDevice)
|
||||
|
||||
#endif /* META_VIRTUAL_INPUT_DEVICE_NATIVE_H */
|
111
src/backends/native/meta-xkb-utils.c
Normal file
111
src/backends/native/meta-xkb-utils.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* 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/>.
|
||||
|
||||
* Authors:
|
||||
* Kristian Høgsberg
|
||||
* Damien Lespiau <damien.lespiau@intel.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-xkb-utils.h"
|
||||
#include "clutter/clutter-keysyms.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
|
||||
/*
|
||||
* _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent
|
||||
* @device: a ClutterInputDevice
|
||||
* @stage: the stage the event should be delivered to
|
||||
* @xkb: XKB rules to translate the event
|
||||
* @_time: timestamp of the event
|
||||
* @key: a key code coming from a Linux input device
|
||||
* @state: TRUE if a press event, FALSE if a release event
|
||||
* @modifer_state: in/out
|
||||
*
|
||||
* Translate @key to a #ClutterKeyEvent using rules from xbbcommon.
|
||||
*
|
||||
* Return value: the new #ClutterEvent
|
||||
*/
|
||||
ClutterEvent *
|
||||
meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
ClutterInputDevice *core_device,
|
||||
ClutterStage *stage,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state,
|
||||
uint32_t _time,
|
||||
xkb_keycode_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
xkb_keysym_t sym;
|
||||
const xkb_keysym_t *syms;
|
||||
char buffer[8];
|
||||
int n;
|
||||
|
||||
if (state)
|
||||
event = clutter_event_new (CLUTTER_KEY_PRESS);
|
||||
else
|
||||
event = clutter_event_new (CLUTTER_KEY_RELEASE);
|
||||
|
||||
/* We use a fixed offset of 8 because evdev starts KEY_* numbering from
|
||||
* 0, whereas X11's minimum keycode, for really stupid reasons, is 8.
|
||||
* So the evdev XKB rules are based on the keycodes all being shifted
|
||||
* upwards by 8. */
|
||||
key += 8;
|
||||
|
||||
n = xkb_key_get_syms (xkb_state, key, &syms);
|
||||
if (n == 1)
|
||||
sym = syms[0];
|
||||
else
|
||||
sym = XKB_KEY_NoSymbol;
|
||||
|
||||
event->key.stage = stage;
|
||||
event->key.time = _time;
|
||||
meta_xkb_translate_state (event, xkb_state, button_state);
|
||||
event->key.hardware_keycode = key;
|
||||
event->key.keyval = sym;
|
||||
clutter_event_set_device (event, core_device);
|
||||
clutter_event_set_source_device (event, device);
|
||||
|
||||
n = xkb_keysym_to_utf8 (sym, buffer, sizeof (buffer));
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* not printable */
|
||||
event->key.unicode_value = (gunichar) '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
|
||||
if (event->key.unicode_value == -1 || event->key.unicode_value == -2)
|
||||
event->key.unicode_value = (gunichar) '\0';
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void
|
||||
meta_xkb_translate_state (ClutterEvent *event,
|
||||
struct xkb_state *state,
|
||||
uint32_t button_state)
|
||||
{
|
||||
_clutter_event_set_state_full (event,
|
||||
button_state,
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state);
|
||||
}
|
40
src/backends/native/meta-xkb-utils.h
Normal file
40
src/backends/native/meta-xkb-utils.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* 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/>.
|
||||
|
||||
* Authors:
|
||||
* Damien Lespiau <damien.lespiau@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef META_XKB_UTILS_H
|
||||
#define META_XKB_UTILS_H
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||
ClutterInputDevice *core_keyboard,
|
||||
ClutterStage *stage,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state,
|
||||
uint32_t _time,
|
||||
uint32_t key,
|
||||
uint32_t state);
|
||||
void meta_xkb_translate_state (ClutterEvent *event,
|
||||
struct xkb_state *xkb_state,
|
||||
uint32_t button_state);
|
||||
|
||||
#endif /* META_XKB_UTILS_H */
|
Reference in New Issue
Block a user