2010-11-04 10:38:32 -04:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2010 Intel Corp.
|
2013-12-15 11:38:56 -05:00
|
|
|
* Copyright (C) 2014 Jonas Ådahl
|
2010-11-04 10:38:32 -04:00
|
|
|
*
|
|
|
|
* 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>
|
2013-12-15 11:38:56 -05:00
|
|
|
* Author: Jonas Ådahl <jadahl@gmail.com>
|
2010-11-04 10:38:32 -04:00
|
|
|
*/
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
#include "config.h"
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2013-09-09 04:51:11 -04:00
|
|
|
#include <math.h>
|
2015-10-09 14:43:25 -04:00
|
|
|
#include <float.h>
|
2010-11-04 10:38:32 -04:00
|
|
|
#include <linux/input.h>
|
2010-11-09 12:50:23 -05:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
2013-12-15 11:38:56 -05:00
|
|
|
#include <libinput.h>
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
#include "backends/native/meta-device-manager-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 "backends/native/meta-seat-native.h"
|
|
|
|
#include "backends/native/meta-virtual-input-device-native.h"
|
|
|
|
#include "backends/native/meta-xkb-utils.h"
|
|
|
|
#include "clutter/clutter-mutter.h"
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2015-09-30 02:26:09 -04:00
|
|
|
/*
|
|
|
|
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
|
|
|
|
* pointer and core keyboard).
|
|
|
|
*
|
|
|
|
* Since the two first devices that will ever be created will be the virtual
|
|
|
|
* pointer and virtual keyboard of the first seat, we fulfill the made
|
|
|
|
* assumptions by having the first device having ID 2 and following 3.
|
|
|
|
*/
|
|
|
|
#define INITIAL_DEVICE_ID 2
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
typedef struct _MetaEventFilter MetaEventFilter;
|
2014-04-25 13:54:35 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
struct _MetaEventFilter
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEvdevFilterFunc func;
|
2014-04-25 13:54:35 -04:00
|
|
|
gpointer data;
|
|
|
|
GDestroyNotify destroy_notify;
|
|
|
|
};
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
typedef struct _MetaEventSource MetaEventSource;
|
2013-09-09 04:51:11 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
struct _MetaDeviceManagerNativePrivate
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2013-12-15 11:38:56 -05:00
|
|
|
struct libinput *libinput;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2012-01-22 10:36:17 -05:00
|
|
|
ClutterStage *stage;
|
|
|
|
gboolean released;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventSource *event_source;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
GSList *devices;
|
|
|
|
GSList *seats;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *main_seat;
|
2012-01-17 08:37:26 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaPointerConstrainCallback constrain_callback;
|
|
|
|
gpointer constrain_data;
|
|
|
|
GDestroyNotify constrain_data_notify;
|
2013-08-23 06:15:40 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaRelativeMotionFilter relative_motion_filter;
|
2017-02-03 00:02:50 -05:00
|
|
|
gpointer relative_motion_filter_user_data;
|
|
|
|
|
2012-01-17 08:37:26 -05:00
|
|
|
ClutterStageManager *stage_manager;
|
2019-11-15 19:25:52 -05:00
|
|
|
gulong stage_added_handler;
|
|
|
|
gulong stage_removed_handler;
|
2014-04-25 13:54:35 -04:00
|
|
|
|
|
|
|
GSList *event_filters;
|
2015-09-30 02:26:09 -04:00
|
|
|
|
|
|
|
gint device_id_next;
|
|
|
|
GList *free_device_ids;
|
2010-11-04 10:38:32 -04:00
|
|
|
};
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (MetaDeviceManagerNative,
|
|
|
|
meta_device_manager_native,
|
2015-11-17 11:40:30 -05:00
|
|
|
CLUTTER_TYPE_DEVICE_MANAGER,
|
2019-03-29 17:03:27 -04:00
|
|
|
G_ADD_PRIVATE (MetaDeviceManagerNative))
|
2013-07-03 09:14:01 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
static MetaOpenDeviceCallback device_open_callback;
|
|
|
|
static MetaCloseDeviceCallback device_close_callback;
|
|
|
|
static gpointer device_callback_data;
|
|
|
|
static gchar * evdev_seat_id;
|
2013-07-15 12:24:35 -04:00
|
|
|
|
2014-05-19 11:46:17 -04:00
|
|
|
#ifdef CLUTTER_ENABLE_DEBUG
|
2013-09-11 04:50:16 -04:00
|
|
|
static const char *device_type_str[] = {
|
|
|
|
"pointer", /* CLUTTER_POINTER_DEVICE */
|
|
|
|
"keyboard", /* CLUTTER_KEYBOARD_DEVICE */
|
|
|
|
"extension", /* CLUTTER_EXTENSION_DEVICE */
|
|
|
|
"joystick", /* CLUTTER_JOYSTICK_DEVICE */
|
|
|
|
"tablet", /* CLUTTER_TABLET_DEVICE */
|
|
|
|
"touchpad", /* CLUTTER_TOUCHPAD_DEVICE */
|
|
|
|
"touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */
|
|
|
|
"pen", /* CLUTTER_PEN_DEVICE */
|
|
|
|
"eraser", /* CLUTTER_ERASER_DEVICE */
|
|
|
|
"cursor", /* CLUTTER_CURSOR_DEVICE */
|
2016-05-10 11:04:18 -04:00
|
|
|
"pad", /* CLUTTER_PAD_DEVICE */
|
2013-09-11 04:50:16 -04:00
|
|
|
};
|
2014-05-19 11:46:17 -04:00
|
|
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
2013-09-11 04:50:16 -04:00
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
/*
|
2019-03-29 17:03:27 -04:00
|
|
|
* MetaEventSource management
|
2010-11-09 12:50:23 -05:00
|
|
|
*
|
|
|
|
* The device manager is responsible for managing the GSource when devices
|
2010-11-30 09:50:13 -05:00
|
|
|
* appear and disappear from the system.
|
2010-11-09 12:50:23 -05:00
|
|
|
*/
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2015-11-17 11:40:30 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_copy_event_data (ClutterDeviceManager *device_manager,
|
|
|
|
const ClutterEvent *src,
|
|
|
|
ClutterEvent *dest)
|
2015-11-17 11:40:30 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventNative *event_evdev;
|
2015-11-17 11:42:44 -05:00
|
|
|
|
|
|
|
event_evdev = _clutter_event_get_platform_data (src);
|
|
|
|
if (event_evdev != NULL)
|
2019-03-29 17:03:27 -04:00
|
|
|
_clutter_event_set_platform_data (dest, meta_event_native_copy (event_evdev));
|
2015-11-17 11:40:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_free_event_data (ClutterDeviceManager *device_manager,
|
|
|
|
ClutterEvent *event)
|
2015-11-17 11:40:30 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventNative *event_evdev;
|
2015-11-17 11:42:44 -05:00
|
|
|
|
|
|
|
event_evdev = _clutter_event_get_platform_data (event);
|
|
|
|
if (event_evdev != NULL)
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_free (event_evdev);
|
2015-11-17 11:40:30 -05:00
|
|
|
}
|
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
/*
|
2019-03-29 17:03:27 -04:00
|
|
|
* MetaEventSource for reading input devices
|
2010-11-09 12:50:23 -05:00
|
|
|
*/
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
struct _MetaEventSource
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
|
|
|
GSource source;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2013-12-15 11:38:56 -05:00
|
|
|
GPollFD event_poll_fd;
|
2010-11-09 12:50:23 -05:00
|
|
|
};
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
process_events (MetaDeviceManagerNative *manager_evdev);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_prepare (GSource *source,
|
|
|
|
gint *timeout)
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_acquire_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
*timeout = -1;
|
|
|
|
retval = clutter_events_pending ();
|
|
|
|
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_release_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_check (GSource *source)
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventSource *event_source = (MetaEventSource *) source;
|
2010-11-09 12:50:23 -05:00
|
|
|
gboolean retval;
|
|
|
|
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_acquire_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
retval = ((event_source->event_poll_fd.revents & G_IO_IN) ||
|
|
|
|
clutter_events_pending ());
|
|
|
|
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_release_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2010-11-11 19:07:35 -05:00
|
|
|
static void
|
|
|
|
queue_event (ClutterEvent *event)
|
|
|
|
{
|
2011-01-19 11:34:49 -05:00
|
|
|
_clutter_event_push (event, FALSE);
|
2010-11-11 19:07:35 -05:00
|
|
|
}
|
|
|
|
|
2016-06-17 17:42:16 -04:00
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
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)
|
2010-11-11 19:07:35 -05:00
|
|
|
{
|
2016-06-17 17:42:16 -04:00
|
|
|
if (manager_evdev->priv->constrain_callback)
|
2013-08-09 05:53:46 -04:00
|
|
|
{
|
2016-06-17 17:42:16 -04:00
|
|
|
manager_evdev->priv->constrain_callback (core_pointer,
|
|
|
|
us2ms (time_us),
|
|
|
|
x, y,
|
|
|
|
new_x, new_y,
|
|
|
|
manager_evdev->priv->constrain_data);
|
2013-08-09 05:53:46 -04:00
|
|
|
}
|
2013-09-06 10:56:55 -04:00
|
|
|
else
|
2014-01-13 10:05:57 -05:00
|
|
|
{
|
2016-06-17 17:42:16 -04:00
|
|
|
ClutterActor *stage = CLUTTER_ACTOR (manager_evdev->priv->stage);
|
|
|
|
float stage_width = clutter_actor_get_width (stage);
|
|
|
|
float stage_height = clutter_actor_get_height (stage);
|
2014-01-13 10:05:57 -05:00
|
|
|
|
2018-11-12 09:10:29 -05:00
|
|
|
*new_x = CLAMP (x, 0.f, stage_width - 1);
|
|
|
|
*new_y = CLAMP (y, 0.f, stage_height - 1);
|
2014-01-13 10:05:57 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-03 00:02:50 -05:00
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_filter_relative_motion (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
float x,
|
|
|
|
float y,
|
|
|
|
float *dx,
|
|
|
|
float *dy)
|
2017-02-03 00:02:50 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2017-02-03 00:02:50 -05:00
|
|
|
|
|
|
|
if (!priv->relative_motion_filter)
|
|
|
|
return;
|
|
|
|
|
|
|
|
priv->relative_motion_filter (device, x, y, dx, dy,
|
|
|
|
priv->relative_motion_filter_user_data);
|
|
|
|
}
|
2010-11-11 19:07:35 -05:00
|
|
|
|
2015-12-01 23:17:23 -05:00
|
|
|
static ClutterEvent *
|
|
|
|
new_absolute_motion_event (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
float x,
|
|
|
|
float y,
|
|
|
|
double *axes)
|
2010-11-11 19:07:35 -05:00
|
|
|
{
|
2013-12-15 11:38:56 -05:00
|
|
|
gfloat stage_width, stage_height;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2011-12-05 08:59:12 -05:00
|
|
|
ClutterStage *stage;
|
2013-08-09 05:53:46 -04:00
|
|
|
ClutterEvent *event = NULL;
|
2011-12-05 08:59:12 -05:00
|
|
|
|
|
|
|
stage = _clutter_input_device_get_stage (input_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (input_device->device_manager);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2013-08-09 05:53:46 -04:00
|
|
|
|
2011-12-05 08:59:12 -05:00
|
|
|
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
|
|
|
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
2010-11-11 19:07:35 -05:00
|
|
|
|
|
|
|
event = clutter_event_new (CLUTTER_MOTION);
|
|
|
|
|
2015-01-09 11:38:42 -05:00
|
|
|
if (manager_evdev->priv->constrain_callback &&
|
|
|
|
clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
|
2013-08-23 06:15:40 -04:00
|
|
|
{
|
2013-12-15 11:38:56 -05:00
|
|
|
manager_evdev->priv->constrain_callback (seat->core_pointer,
|
2015-07-06 22:23:12 -04:00
|
|
|
us2ms (time_us),
|
|
|
|
seat->pointer_x,
|
|
|
|
seat->pointer_y,
|
|
|
|
&x, &y,
|
2013-08-23 06:15:40 -04:00
|
|
|
manager_evdev->priv->constrain_data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-15 11:38:56 -05:00
|
|
|
x = CLAMP (x, 0.f, stage_width - 1);
|
|
|
|
y = CLAMP (y, 0.f, stage_height - 1);
|
2013-08-23 06:15:40 -04:00
|
|
|
}
|
2010-11-11 19:07:35 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2015-12-01 23:39:44 -05:00
|
|
|
event->motion.time = us2ms (time_us);
|
2011-12-05 08:59:12 -05:00
|
|
|
event->motion.stage = stage;
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
2013-12-15 11:38:56 -05:00
|
|
|
event->motion.x = x;
|
|
|
|
event->motion.y = y;
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_translate_coordinates (input_device, stage,
|
|
|
|
&event->motion.x,
|
|
|
|
&event->motion.y);
|
2015-01-09 11:10:11 -05:00
|
|
|
event->motion.axes = axes;
|
2018-11-19 08:55:51 -05:00
|
|
|
clutter_event_set_device (event, seat->core_pointer);
|
2013-08-09 05:53:46 -04:00
|
|
|
clutter_event_set_source_device (event, input_device);
|
2010-11-11 19:07:35 -05:00
|
|
|
|
2015-01-09 11:38:42 -05:00
|
|
|
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);
|
|
|
|
|
2014-04-25 14:03:09 -04:00
|
|
|
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
|
|
|
|
2015-06-17 10:56:59 -04:00
|
|
|
if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
|
|
|
|
{
|
|
|
|
seat->pointer_x = x;
|
|
|
|
seat->pointer_y = y;
|
|
|
|
}
|
2015-03-16 22:58:35 -04:00
|
|
|
|
2015-12-01 23:17:23 -05:00
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
notify_absolute_motion (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
float x,
|
|
|
|
float y,
|
|
|
|
double *axes)
|
2015-12-01 23:17:23 -05:00
|
|
|
{
|
|
|
|
ClutterEvent *event;
|
|
|
|
|
2015-01-09 11:10:11 -05:00
|
|
|
event = new_absolute_motion_event (input_device, time_us, x, y, axes);
|
2015-12-01 23:17:23 -05:00
|
|
|
|
2010-11-11 19:07:35 -05:00
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
2016-05-13 14:01:54 -04:00
|
|
|
static void
|
|
|
|
notify_relative_tool_motion (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
float dx,
|
|
|
|
float dy,
|
|
|
|
double *axes)
|
2016-05-13 14:01:54 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
2016-05-13 14:01:54 -04:00
|
|
|
ClutterEvent *event;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2016-05-13 14:01:54 -04:00
|
|
|
gfloat x, y;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2016-05-13 14:01:54 -04:00
|
|
|
x = input_device->current_x + dx;
|
|
|
|
y = input_device->current_y + dy;
|
2017-02-03 00:10:50 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_filter_relative_motion (seat->manager_evdev,
|
2017-02-03 00:10:50 -05:00
|
|
|
input_device,
|
|
|
|
seat->pointer_x,
|
|
|
|
seat->pointer_y,
|
|
|
|
&dx,
|
|
|
|
&dy);
|
|
|
|
|
2016-05-13 14:01:54 -04:00
|
|
|
event = new_absolute_motion_event (input_device, time_us, x, y, axes);
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_relative_motion (event, dx, dy, 0, 0);
|
2016-05-13 14:01:54 -04:00
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
2015-05-22 12:33:31 -04:00
|
|
|
static void
|
|
|
|
notify_pinch_gesture_event (ClutterInputDevice *input_device,
|
|
|
|
ClutterTouchpadGesturePhase phase,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
double dx,
|
|
|
|
double dy,
|
|
|
|
double angle_delta,
|
|
|
|
double scale,
|
|
|
|
uint32_t n_fingers)
|
2015-05-22 12:33:31 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2015-05-22 12:33:31 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterEvent *event = NULL;
|
2019-02-20 09:53:44 -05:00
|
|
|
graphene_point_t pos;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
/* 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);
|
2015-10-12 14:41:57 -04:00
|
|
|
if (stage == NULL)
|
2015-05-22 12:33:31 -04:00
|
|
|
return;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH);
|
|
|
|
|
|
|
|
clutter_input_device_get_coords (seat->core_pointer, NULL, &pos);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2015-05-22 12:33:31 -04:00
|
|
|
event->touchpad_pinch.phase = phase;
|
2015-12-01 23:39:44 -05:00
|
|
|
event->touchpad_pinch.time = us2ms (time_us);
|
2015-05-22 12:33:31 -04:00
|
|
|
event->touchpad_pinch.stage = CLUTTER_STAGE (stage);
|
|
|
|
event->touchpad_pinch.x = pos.x;
|
|
|
|
event->touchpad_pinch.y = pos.y;
|
2015-07-24 13:08:44 -04:00
|
|
|
event->touchpad_pinch.dx = dx;
|
|
|
|
event->touchpad_pinch.dy = dy;
|
2015-05-22 12:33:31 -04:00
|
|
|
event->touchpad_pinch.angle_delta = angle_delta;
|
|
|
|
event->touchpad_pinch.scale = scale;
|
2016-05-03 07:29:56 -04:00
|
|
|
event->touchpad_pinch.n_fingers = n_fingers;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
clutter_event_set_device (event, seat->core_pointer);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
notify_swipe_gesture_event (ClutterInputDevice *input_device,
|
|
|
|
ClutterTouchpadGesturePhase phase,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
uint32_t n_fingers,
|
|
|
|
double dx,
|
|
|
|
double dy)
|
2015-05-22 12:33:31 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2015-05-22 12:33:31 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterEvent *event = NULL;
|
2019-02-20 09:53:44 -05:00
|
|
|
graphene_point_t pos;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
/* 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);
|
2015-10-12 14:41:57 -04:00
|
|
|
if (stage == NULL)
|
2015-05-22 12:33:31 -04:00
|
|
|
return;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2015-05-22 12:33:31 -04:00
|
|
|
event->touchpad_swipe.phase = phase;
|
2015-12-01 23:39:44 -05:00
|
|
|
event->touchpad_swipe.time = us2ms (time_us);
|
2015-05-22 12:33:31 -04:00
|
|
|
event->touchpad_swipe.stage = CLUTTER_STAGE (stage);
|
|
|
|
|
|
|
|
clutter_input_device_get_coords (seat->core_pointer, NULL, &pos);
|
|
|
|
event->touchpad_swipe.x = pos.x;
|
|
|
|
event->touchpad_swipe.y = pos.y;
|
|
|
|
event->touchpad_swipe.dx = dx;
|
|
|
|
event->touchpad_swipe.dy = dy;
|
|
|
|
event->touchpad_swipe.n_fingers = n_fingers;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
clutter_event_set_device (event, seat->core_pointer);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
2015-01-09 11:38:42 -05:00
|
|
|
static void
|
|
|
|
notify_proximity (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
2015-01-09 11:38:42 -05:00
|
|
|
gboolean in)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2015-01-09 11:38:42 -05:00
|
|
|
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;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2015-01-09 11:38:42 -05:00
|
|
|
|
|
|
|
if (in)
|
|
|
|
event = clutter_event_new (CLUTTER_PROXIMITY_IN);
|
|
|
|
else
|
|
|
|
event = clutter_event_new (CLUTTER_PROXIMITY_OUT);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2015-01-09 11:38:42 -05:00
|
|
|
|
|
|
|
event->proximity.time = us2ms (time_us);
|
|
|
|
event->proximity.stage = CLUTTER_STAGE (stage);
|
|
|
|
clutter_event_set_device_tool (event, device_evdev->last_tool);
|
|
|
|
clutter_event_set_device (event, seat->core_pointer);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
|
|
|
|
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
2016-05-10 11:05:19 -04:00
|
|
|
static void
|
|
|
|
notify_pad_button (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
uint32_t button,
|
|
|
|
uint32_t mode_group,
|
|
|
|
uint32_t mode,
|
|
|
|
uint32_t pressed)
|
2016-05-10 11:05:19 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2016-05-10 11:05:19 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterEvent *event;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
if (pressed)
|
|
|
|
event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS);
|
|
|
|
else
|
|
|
|
event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2016-05-10 11:05:19 -04:00
|
|
|
event->pad_button.stage = stage;
|
|
|
|
event->pad_button.button = button;
|
|
|
|
event->pad_button.group = mode_group;
|
2016-12-28 05:32:07 -05:00
|
|
|
event->pad_button.mode = mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
clutter_event_set_device (event, input_device);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
clutter_event_set_time (event, us2ms (time_us));
|
|
|
|
|
|
|
|
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
notify_pad_strip (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
uint32_t strip_number,
|
|
|
|
uint32_t strip_source,
|
|
|
|
uint32_t mode_group,
|
|
|
|
uint32_t mode,
|
|
|
|
double value)
|
2016-05-10 11:05:19 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
2016-05-10 11:05:19 -04:00
|
|
|
ClutterInputDevicePadSource source;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2016-05-10 11:05:19 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterEvent *event;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER)
|
|
|
|
source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER;
|
|
|
|
else
|
|
|
|
source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
|
|
|
event = clutter_event_new (CLUTTER_PAD_STRIP);
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2016-05-10 11:05:19 -04:00
|
|
|
event->pad_strip.strip_source = source;
|
|
|
|
event->pad_strip.stage = stage;
|
|
|
|
event->pad_strip.strip_number = strip_number;
|
|
|
|
event->pad_strip.value = value;
|
|
|
|
event->pad_strip.group = mode_group;
|
2016-12-28 05:32:07 -05:00
|
|
|
event->pad_strip.mode = mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
clutter_event_set_device (event, input_device);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
clutter_event_set_time (event, us2ms (time_us));
|
|
|
|
|
|
|
|
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
notify_pad_ring (ClutterInputDevice *input_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us,
|
|
|
|
uint32_t ring_number,
|
|
|
|
uint32_t ring_source,
|
|
|
|
uint32_t mode_group,
|
|
|
|
uint32_t mode,
|
|
|
|
double angle)
|
2016-05-10 11:05:19 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
2016-05-10 11:05:19 -04:00
|
|
|
ClutterInputDevicePadSource source;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2016-05-10 11:05:19 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterEvent *event;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER)
|
|
|
|
source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER;
|
|
|
|
else
|
|
|
|
source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
|
|
|
event = clutter_event_new (CLUTTER_PAD_RING);
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_set_time_usec (event, time_us);
|
2016-05-10 11:05:19 -04:00
|
|
|
event->pad_ring.ring_source = source;
|
|
|
|
event->pad_ring.stage = stage;
|
|
|
|
event->pad_ring.ring_number = ring_number;
|
|
|
|
event->pad_ring.angle = angle;
|
|
|
|
event->pad_ring.group = mode_group;
|
2016-12-28 05:32:07 -05:00
|
|
|
event->pad_ring.mode = mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
clutter_event_set_device (event, input_device);
|
|
|
|
clutter_event_set_source_device (event, input_device);
|
|
|
|
clutter_event_set_time (event, us2ms (time_us));
|
|
|
|
|
|
|
|
_clutter_input_device_set_stage (seat->core_pointer, stage);
|
|
|
|
|
|
|
|
queue_event (event);
|
|
|
|
}
|
|
|
|
|
2013-09-09 04:51:11 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
dispatch_libinput (MetaDeviceManagerNative *manager_evdev)
|
2013-09-09 04:51:11 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2013-09-06 10:03:29 -04:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_dispatch (priv->libinput);
|
|
|
|
process_events (manager_evdev);
|
2013-09-06 10:03:29 -04:00
|
|
|
}
|
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_dispatch (GSource *g_source,
|
|
|
|
GSourceFunc callback,
|
|
|
|
gpointer user_data)
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventSource *source = (MetaEventSource *) g_source;
|
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2010-11-11 19:07:35 -05:00
|
|
|
ClutterEvent *event;
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_acquire_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
manager_evdev = source->manager_evdev;
|
2011-06-17 06:31:34 -04:00
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
/* Don't queue more events if we haven't finished handling the previous batch
|
|
|
|
*/
|
2013-09-06 10:03:29 -04:00
|
|
|
if (clutter_events_pending ())
|
|
|
|
goto queue_event;
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
dispatch_libinput (manager_evdev);
|
2013-09-06 10:03:29 -04:00
|
|
|
|
|
|
|
queue_event:
|
2010-11-09 12:50:23 -05:00
|
|
|
event = clutter_event_get ();
|
|
|
|
|
|
|
|
if (event)
|
|
|
|
{
|
2013-09-04 07:36:41 -04:00
|
|
|
ClutterModifierType event_state;
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterInputDevice *input_device =
|
|
|
|
clutter_event_get_source_device (event);
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev =
|
|
|
|
META_INPUT_DEVICE_NATIVE (input_device);
|
|
|
|
MetaSeatNative *seat =
|
|
|
|
meta_input_device_native_get_seat (device_evdev);
|
2013-09-04 07:36:41 -04:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
/* Drop events if we don't have any stage to forward them to */
|
|
|
|
if (!_clutter_input_device_get_stage (input_device))
|
|
|
|
goto out;
|
2013-09-04 07:36:41 -04:00
|
|
|
|
2019-08-06 07:04:51 -04:00
|
|
|
/* update the device states *before* the event */
|
2014-07-11 09:30:29 -04:00
|
|
|
event_state = seat->button_state |
|
|
|
|
xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE);
|
2013-12-15 11:38:56 -05:00
|
|
|
_clutter_input_device_set_state (seat->core_pointer, event_state);
|
|
|
|
_clutter_input_device_set_state (seat->core_keyboard, event_state);
|
2019-08-06 07:04:51 -04:00
|
|
|
|
|
|
|
/* forward the event into clutter for emission etc. */
|
|
|
|
_clutter_stage_queue_event (event->any.stage, event, FALSE);
|
2010-11-09 12:50:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-07-05 09:30:26 -04:00
|
|
|
_clutter_threads_release_lock ();
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
static GSourceFuncs event_funcs = {
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_prepare,
|
|
|
|
meta_event_check,
|
|
|
|
meta_event_dispatch,
|
2010-11-09 12:50:23 -05:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
static MetaEventSource *
|
|
|
|
meta_event_source_new (MetaDeviceManagerNative *manager_evdev)
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2013-12-15 11:38:56 -05:00
|
|
|
GSource *source;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventSource *event_source;
|
2013-11-19 11:02:58 -05:00
|
|
|
gint fd;
|
2013-07-15 12:24:35 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
source = g_source_new (&event_funcs, sizeof (MetaEventSource));
|
|
|
|
event_source = (MetaEventSource *) source;
|
2010-11-09 12:50:23 -05:00
|
|
|
|
|
|
|
/* setup the source */
|
2013-12-15 11:38:56 -05:00
|
|
|
event_source->manager_evdev = manager_evdev;
|
|
|
|
|
|
|
|
fd = libinput_get_fd (priv->libinput);
|
2010-11-09 12:50:23 -05:00
|
|
|
event_source->event_poll_fd.fd = fd;
|
|
|
|
event_source->event_poll_fd.events = G_IO_IN;
|
2013-11-19 11:02:58 -05:00
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
/* and finally configure and attach the GSource */
|
|
|
|
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
|
|
|
|
g_source_add_poll (source, &event_source->event_poll_fd);
|
|
|
|
g_source_set_can_recurse (source, TRUE);
|
|
|
|
g_source_attach (source, NULL);
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
return event_source;
|
2010-11-09 12:50:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_source_free (MetaEventSource *source)
|
2010-11-09 12:50:23 -05:00
|
|
|
{
|
|
|
|
GSource *g_source = (GSource *) source;
|
|
|
|
|
|
|
|
/* ignore the return value of close, it's not like we can do something
|
|
|
|
* about it */
|
|
|
|
close (source->event_poll_fd.fd);
|
|
|
|
|
|
|
|
g_source_destroy (g_source);
|
|
|
|
g_source_unref (g_source);
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
evdev_add_device (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_device *libinput_device)
|
2010-11-09 11:56:26 -05:00
|
|
|
{
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterDeviceManager *manager = (ClutterDeviceManager *) manager_evdev;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterInputDeviceType type;
|
|
|
|
struct libinput_seat *libinput_seat;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterInputDevice *device;
|
2010-11-09 11:56:26 -05:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_seat = libinput_device_get_seat (libinput_device);
|
|
|
|
seat = libinput_seat_get_user_data (libinput_seat);
|
|
|
|
if (seat == NULL)
|
2010-11-09 11:56:26 -05:00
|
|
|
{
|
2014-03-10 10:25:22 -04:00
|
|
|
/* Clutter has the notion of global "core" pointers and keyboard devices,
|
|
|
|
* which are located on the main seat. Make whatever seat comes first the
|
|
|
|
* main seat. */
|
|
|
|
if (priv->main_seat->libinput_seat == NULL)
|
|
|
|
seat = priv->main_seat;
|
|
|
|
else
|
2018-05-16 19:53:48 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
seat = meta_seat_native_new (manager_evdev);
|
2018-05-16 19:53:48 -04:00
|
|
|
priv->seats = g_slist_append (priv->seats, seat);
|
|
|
|
}
|
2014-03-10 10:25:22 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_set_libinput_seat (seat, libinput_seat);
|
2010-11-09 11:56:26 -05:00
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device = meta_input_device_native_new (manager, seat, libinput_device);
|
2013-12-15 11:38:56 -05:00
|
|
|
_clutter_input_device_set_stage (device, manager_evdev->priv->stage);
|
|
|
|
|
|
|
|
_clutter_device_manager_add_device (manager, device);
|
2010-11-09 11:56:26 -05:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
/* Clutter assumes that device types are exclusive in the
|
|
|
|
* ClutterInputDevice API */
|
2019-03-29 17:03:27 -04:00
|
|
|
type = meta_input_device_native_determine_type (libinput_device);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
if (type == CLUTTER_KEYBOARD_DEVICE)
|
|
|
|
{
|
|
|
|
_clutter_input_device_set_associated_device (device, seat->core_keyboard);
|
|
|
|
_clutter_input_device_add_slave (seat->core_keyboard, device);
|
|
|
|
}
|
|
|
|
else if (type == CLUTTER_POINTER_DEVICE)
|
|
|
|
{
|
|
|
|
_clutter_input_device_set_associated_device (device, seat->core_pointer);
|
|
|
|
_clutter_input_device_add_slave (seat->core_pointer, device);
|
2010-11-09 11:56:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
evdev_remove_device (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
MetaInputDeviceNative *device_evdev)
|
2010-11-09 11:56:26 -05:00
|
|
|
{
|
|
|
|
ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterInputDevice *input_device = CLUTTER_INPUT_DEVICE (device_evdev);
|
2010-11-09 11:56:26 -05:00
|
|
|
|
|
|
|
_clutter_device_manager_remove_device (manager, input_device);
|
|
|
|
}
|
|
|
|
|
2010-11-04 10:38:32 -04:00
|
|
|
/*
|
|
|
|
* ClutterDeviceManager implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_add_device (ClutterDeviceManager *manager,
|
|
|
|
ClutterInputDevice *device)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
seat->devices = g_slist_prepend (seat->devices, device);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv->devices = g_slist_prepend (priv->devices, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_remove_device (ClutterDeviceManager *manager,
|
|
|
|
ClutterInputDevice *device)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
|
|
|
MetaInputDeviceNative *device_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
2010-11-09 12:50:23 -05:00
|
|
|
/* Remove the device */
|
2013-12-15 11:38:56 -05:00
|
|
|
seat->devices = g_slist_remove (seat->devices, device);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv->devices = g_slist_remove (priv->devices, device);
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2014-01-13 10:05:57 -05:00
|
|
|
if (seat->repeat_timer && seat->repeat_device == device)
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_clear_repeat_timer (seat);
|
2014-01-13 10:05:57 -05:00
|
|
|
|
2013-11-21 08:50:40 -05:00
|
|
|
g_object_unref (device);
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static const GSList *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_devices (ClutterDeviceManager *manager)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
return META_DEVICE_MANAGER_NATIVE (manager)->priv->devices;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ClutterInputDevice *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_core_device (ClutterDeviceManager *manager,
|
|
|
|
ClutterInputDeviceType type)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case CLUTTER_POINTER_DEVICE:
|
2013-12-15 11:38:56 -05:00
|
|
|
return priv->main_seat->core_pointer;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
|
|
|
case CLUTTER_KEYBOARD_DEVICE:
|
2013-12-15 11:38:56 -05:00
|
|
|
return priv->main_seat->core_keyboard;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
|
|
|
case CLUTTER_EXTENSION_DEVICE:
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ClutterInputDevice *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_device (ClutterDeviceManager *manager,
|
|
|
|
gint id)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2010-11-04 10:38:32 -04:00
|
|
|
GSList *l;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
for (l = priv->seats; l; l = l->next)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat = l->data;
|
|
|
|
ClutterInputDevice *device = meta_seat_native_get_device (seat, id);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2018-05-15 07:09:59 -04:00
|
|
|
if (device)
|
|
|
|
return device;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
2018-05-16 19:53:48 -04:00
|
|
|
return NULL;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
2014-10-14 06:41:10 -04:00
|
|
|
static void
|
|
|
|
flush_event_queue (void)
|
|
|
|
{
|
|
|
|
ClutterEvent *event;
|
|
|
|
|
|
|
|
while ((event = clutter_event_get ()) != NULL)
|
|
|
|
{
|
|
|
|
_clutter_process_event (event);
|
|
|
|
clutter_event_free (event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
process_base_event (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_event *event)
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
|
|
|
ClutterInputDevice *device;
|
|
|
|
struct libinput_device *libinput_device;
|
|
|
|
gboolean handled = TRUE;
|
|
|
|
|
|
|
|
switch (libinput_event_get_type (event))
|
|
|
|
{
|
|
|
|
case LIBINPUT_EVENT_DEVICE_ADDED:
|
|
|
|
libinput_device = libinput_event_get_device (event);
|
|
|
|
|
|
|
|
evdev_add_device (manager_evdev, libinput_device);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_DEVICE_REMOVED:
|
2014-10-14 06:41:10 -04:00
|
|
|
/* Flush all queued events, there
|
|
|
|
* might be some from this device.
|
|
|
|
*/
|
|
|
|
flush_event_queue ();
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_device = libinput_event_get_device (event);
|
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
evdev_remove_device (manager_evdev,
|
2019-03-29 17:03:27 -04:00
|
|
|
META_INPUT_DEVICE_NATIVE (device));
|
2013-12-15 11:38:56 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
handled = FALSE;
|
2012-01-22 10:36:17 -05:00
|
|
|
}
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
return handled;
|
2012-01-22 10:36:17 -05:00
|
|
|
}
|
|
|
|
|
2015-10-23 11:31:47 -04:00
|
|
|
static ClutterScrollSource
|
|
|
|
translate_scroll_source (enum libinput_pointer_axis_source source)
|
|
|
|
{
|
|
|
|
switch (source)
|
|
|
|
{
|
|
|
|
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
|
|
|
|
return CLUTTER_SCROLL_SOURCE_WHEEL;
|
|
|
|
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
|
|
|
|
return CLUTTER_SCROLL_SOURCE_FINGER;
|
|
|
|
case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
|
|
|
|
return CLUTTER_SCROLL_SOURCE_CONTINUOUS;
|
|
|
|
default:
|
|
|
|
return CLUTTER_SCROLL_SOURCE_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-09 11:38:42 -05:00
|
|
|
static ClutterInputDeviceToolType
|
|
|
|
translate_tool_type (struct libinput_tablet_tool *libinput_tool)
|
|
|
|
{
|
|
|
|
enum libinput_tablet_tool_type tool;
|
|
|
|
|
|
|
|
tool = libinput_tablet_tool_get_type (libinput_tool);
|
|
|
|
|
|
|
|
switch (tool)
|
|
|
|
{
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PEN:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_PEN;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_ERASER;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_BRUSH;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_PENCIL;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_MOUSE;
|
|
|
|
case LIBINPUT_TABLET_TOOL_TYPE_LENS:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_LENS;
|
|
|
|
default:
|
|
|
|
return CLUTTER_INPUT_DEVICE_TOOL_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
input_device_update_tool (ClutterInputDevice *input_device,
|
|
|
|
struct libinput_tablet_tool *libinput_tool)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device);
|
2015-01-09 11:38:42 -05:00
|
|
|
ClutterInputDeviceTool *tool = NULL;
|
|
|
|
ClutterInputDeviceToolType tool_type;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t tool_serial;
|
2015-01-09 11:38:42 -05:00
|
|
|
|
|
|
|
if (libinput_tool)
|
|
|
|
{
|
|
|
|
tool_serial = libinput_tablet_tool_get_serial (libinput_tool);
|
|
|
|
tool_type = translate_tool_type (libinput_tool);
|
|
|
|
tool = clutter_input_device_lookup_tool (input_device,
|
|
|
|
tool_serial, tool_type);
|
|
|
|
|
|
|
|
if (!tool)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
tool = meta_input_device_tool_native_new (libinput_tool,
|
|
|
|
tool_serial, tool_type);
|
2015-01-09 11:38:42 -05:00
|
|
|
clutter_input_device_add_tool (input_device, tool);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-31 12:36:50 -04:00
|
|
|
if (evdev_device->last_tool != tool)
|
|
|
|
{
|
|
|
|
evdev_device->last_tool = tool;
|
|
|
|
g_signal_emit_by_name (clutter_device_manager_get_default (),
|
|
|
|
"tool-changed", input_device, tool);
|
|
|
|
}
|
2015-01-09 11:38:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static gdouble *
|
2016-10-31 12:43:38 -04:00
|
|
|
translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event,
|
|
|
|
ClutterInputDeviceTool *tool)
|
2015-01-09 11:38:42 -05:00
|
|
|
{
|
|
|
|
GArray *axes = g_array_new (FALSE, FALSE, sizeof (gdouble));
|
|
|
|
struct libinput_tablet_tool *libinput_tool;
|
|
|
|
gdouble value;
|
|
|
|
|
|
|
|
libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event);
|
|
|
|
|
|
|
|
value = libinput_event_tablet_tool_get_x (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
value = libinput_event_tablet_tool_get_y (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_distance (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_distance (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_pressure (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_pressure (tablet_event);
|
2019-03-29 17:03:27 -04:00
|
|
|
value = meta_input_device_tool_native_translate_pressure (tool, value);
|
2015-01-09 11:38:42 -05:00
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_tilt (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_tilt_x (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
value = libinput_event_tablet_tool_get_tilt_y (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_rotation (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_rotation (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_slider (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_slider_position (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libinput_tablet_tool_has_wheel (libinput_tool))
|
|
|
|
{
|
|
|
|
value = libinput_event_tablet_tool_get_wheel_delta (tablet_event);
|
|
|
|
g_array_append_val (axes, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axes->len == 0)
|
|
|
|
{
|
|
|
|
g_array_free (axes, TRUE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return (gdouble *) g_array_free (axes, FALSE);
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
static MetaSeatNative *
|
2016-06-17 17:42:16 -04:00
|
|
|
seat_from_device (ClutterInputDevice *device)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
2016-06-17 17:42:16 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
return meta_input_device_native_get_seat (device_evdev);
|
2016-06-17 17:42:16 -04:00
|
|
|
}
|
|
|
|
|
2016-08-23 03:38:00 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
notify_continuous_axis (MetaSeatNative *seat,
|
2016-08-23 03:38:00 -04:00
|
|
|
ClutterInputDevice *device,
|
|
|
|
uint64_t time_us,
|
|
|
|
ClutterScrollSource scroll_source,
|
|
|
|
struct libinput_event_pointer *axis_event)
|
|
|
|
{
|
|
|
|
gdouble dx = 0.0, dy = 0.0;
|
|
|
|
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
|
|
|
|
|
|
|
if (libinput_event_pointer_has_axis (axis_event,
|
|
|
|
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
|
|
|
{
|
|
|
|
dx = libinput_event_pointer_get_axis_value (
|
|
|
|
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
|
|
|
|
|
|
|
if (fabs (dx) < DBL_EPSILON)
|
|
|
|
finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL;
|
|
|
|
}
|
|
|
|
if (libinput_event_pointer_has_axis (axis_event,
|
|
|
|
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
|
|
|
{
|
|
|
|
dy = libinput_event_pointer_get_axis_value (
|
|
|
|
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
|
|
|
|
|
|
|
if (fabs (dy) < DBL_EPSILON)
|
|
|
|
finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL;
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_scroll_continuous (seat, device, time_us,
|
|
|
|
dx, dy,
|
|
|
|
scroll_source, finish_flags);
|
2016-08-23 03:38:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
notify_discrete_axis (MetaSeatNative *seat,
|
2016-08-23 03:38:00 -04:00
|
|
|
ClutterInputDevice *device,
|
|
|
|
uint64_t time_us,
|
|
|
|
ClutterScrollSource scroll_source,
|
|
|
|
struct libinput_event_pointer *axis_event)
|
|
|
|
{
|
|
|
|
gdouble discrete_dx = 0.0, discrete_dy = 0.0;
|
|
|
|
|
|
|
|
if (libinput_event_pointer_has_axis (axis_event,
|
|
|
|
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
|
|
|
{
|
|
|
|
discrete_dx = libinput_event_pointer_get_axis_value_discrete (
|
|
|
|
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
|
|
|
}
|
|
|
|
if (libinput_event_pointer_has_axis (axis_event,
|
|
|
|
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
|
|
|
{
|
|
|
|
discrete_dy = libinput_event_pointer_get_axis_value_discrete (
|
|
|
|
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_discrete_scroll (seat, device,
|
|
|
|
time_us,
|
|
|
|
discrete_dx, discrete_dy,
|
|
|
|
scroll_source);
|
2016-08-23 03:38:00 -04:00
|
|
|
}
|
|
|
|
|
2018-09-06 00:44:04 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
process_tablet_axis (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_event *event)
|
2018-09-06 00:44:04 -04:00
|
|
|
{
|
|
|
|
struct libinput_device *libinput_device = libinput_event_get_device (event);
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time;
|
2018-09-06 00:44:04 -04:00
|
|
|
double x, y, dx, dy, *axes;
|
2019-08-16 13:33:43 -04:00
|
|
|
float stage_width, stage_height;
|
2018-09-06 00:44:04 -04:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterInputDevice *device;
|
|
|
|
struct libinput_event_tablet_tool *tablet_event =
|
|
|
|
libinput_event_get_tablet_tool_event (event);
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *evdev_device;
|
2018-09-06 00:44:04 -04:00
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
evdev_device = META_INPUT_DEVICE_NATIVE (device);
|
2018-09-06 00:44:04 -04:00
|
|
|
|
|
|
|
stage = _clutter_input_device_get_stage (device);
|
|
|
|
if (!stage)
|
|
|
|
return;
|
|
|
|
|
|
|
|
axes = translate_tablet_axes (tablet_event,
|
|
|
|
evdev_device->last_tool);
|
|
|
|
if (!axes)
|
|
|
|
return;
|
|
|
|
|
|
|
|
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
|
|
|
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
|
|
|
|
|
|
|
time = libinput_event_tablet_tool_get_time_usec (tablet_event);
|
|
|
|
|
|
|
|
if (clutter_input_device_get_mapping_mode (device) == CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE ||
|
|
|
|
clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE ||
|
|
|
|
clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS)
|
|
|
|
{
|
|
|
|
dx = libinput_event_tablet_tool_get_dx (tablet_event);
|
|
|
|
dy = libinput_event_tablet_tool_get_dy (tablet_event);
|
|
|
|
notify_relative_tool_motion (device, time, dx, dy, axes);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width);
|
|
|
|
y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height);
|
|
|
|
notify_absolute_motion (device, time, x, y, axes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
process_device_event (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_event *event)
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
|
|
|
gboolean handled = TRUE;
|
|
|
|
struct libinput_device *libinput_device = libinput_event_get_device(event);
|
|
|
|
ClutterInputDevice *device;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaInputDeviceNative *device_evdev;
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
switch (libinput_event_get_type (event))
|
|
|
|
{
|
|
|
|
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t key, key_state, seat_key_count;
|
|
|
|
uint64_t time_us;
|
2013-12-15 11:38:56 -05:00
|
|
|
struct libinput_event_keyboard *key_event =
|
|
|
|
libinput_event_get_keyboard_event (event);
|
|
|
|
|
2016-06-17 17:42:16 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_keyboard_get_time_usec (key_event);
|
2013-12-15 11:38:56 -05:00
|
|
|
key = libinput_event_keyboard_get_key (key_event);
|
|
|
|
key_state = libinput_event_keyboard_get_key_state (key_event) ==
|
2014-06-25 07:18:02 -04:00
|
|
|
LIBINPUT_KEY_STATE_PRESSED;
|
2015-01-27 23:11:34 -05:00
|
|
|
seat_key_count =
|
|
|
|
libinput_event_keyboard_get_seat_key_count (key_event);
|
|
|
|
|
|
|
|
/* Ignore key events that are not seat wide state changes. */
|
|
|
|
if ((key_state == LIBINPUT_KEY_STATE_PRESSED &&
|
|
|
|
seat_key_count != 1) ||
|
|
|
|
(key_state == LIBINPUT_KEY_STATE_RELEASED &&
|
|
|
|
seat_key_count != 0))
|
|
|
|
break;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_key (seat_from_device (device),
|
|
|
|
device,
|
|
|
|
time_us, key, key_state, TRUE);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_MOTION:
|
|
|
|
{
|
2016-06-17 17:42:16 -04:00
|
|
|
struct libinput_event_pointer *pointer_event =
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_event_get_pointer_event (event);
|
2016-06-17 17:42:16 -04:00
|
|
|
uint64_t time_us;
|
|
|
|
double dx;
|
|
|
|
double dy;
|
|
|
|
double dx_unaccel;
|
|
|
|
double dy_unaccel;
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2016-06-17 17:42:16 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
time_us = libinput_event_pointer_get_time_usec (pointer_event);
|
|
|
|
dx = libinput_event_pointer_get_dx (pointer_event);
|
|
|
|
dy = libinput_event_pointer_get_dy (pointer_event);
|
|
|
|
dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event);
|
|
|
|
dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_relative_motion (seat_from_device (device),
|
|
|
|
device,
|
|
|
|
time_us,
|
|
|
|
dx, dy,
|
|
|
|
dx_unaccel, dy_unaccel);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2014-06-02 17:16:21 -04:00
|
|
|
double x, y;
|
2019-08-16 13:33:43 -04:00
|
|
|
float stage_width, stage_height;
|
2013-12-15 11:38:56 -05:00
|
|
|
ClutterStage *stage;
|
|
|
|
struct libinput_event_pointer *motion_event =
|
|
|
|
libinput_event_get_pointer_event (event);
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
|
|
|
|
stage = _clutter_input_device_get_stage (device);
|
2015-10-12 14:41:57 -04:00
|
|
|
if (stage == NULL)
|
2013-12-15 11:38:56 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
|
|
|
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
|
|
|
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_pointer_get_time_usec (motion_event);
|
2013-12-15 11:38:56 -05:00
|
|
|
x = libinput_event_pointer_get_absolute_x_transformed (motion_event,
|
|
|
|
stage_width);
|
|
|
|
y = libinput_event_pointer_get_absolute_y_transformed (motion_event,
|
|
|
|
stage_height);
|
2016-06-17 17:42:16 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_absolute_motion (seat_from_device (device),
|
|
|
|
device,
|
|
|
|
time_us,
|
|
|
|
x, y,
|
|
|
|
NULL);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_BUTTON:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t button, button_state, seat_button_count;
|
|
|
|
uint64_t time_us;
|
2013-12-15 11:38:56 -05:00
|
|
|
struct libinput_event_pointer *button_event =
|
|
|
|
libinput_event_get_pointer_event (event);
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_pointer_get_time_usec (button_event);
|
2013-12-15 11:38:56 -05:00
|
|
|
button = libinput_event_pointer_get_button (button_event);
|
|
|
|
button_state = libinput_event_pointer_get_button_state (button_event) ==
|
2014-06-05 03:50:33 -04:00
|
|
|
LIBINPUT_BUTTON_STATE_PRESSED;
|
2015-01-27 23:12:48 -05:00
|
|
|
seat_button_count =
|
|
|
|
libinput_event_pointer_get_seat_button_count (button_event);
|
|
|
|
|
|
|
|
/* Ignore button events that are not seat wide state changes. */
|
|
|
|
if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED &&
|
|
|
|
seat_button_count != 1) ||
|
|
|
|
(button_state == LIBINPUT_BUTTON_STATE_RELEASED &&
|
|
|
|
seat_button_count != 0))
|
|
|
|
break;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_button (seat_from_device (device), device,
|
|
|
|
time_us, button, button_state);
|
2013-12-15 11:38:56 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_AXIS:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2015-01-15 19:03:52 -05:00
|
|
|
enum libinput_pointer_axis_source source;
|
2013-12-15 11:38:56 -05:00
|
|
|
struct libinput_event_pointer *axis_event =
|
|
|
|
libinput_event_get_pointer_event (event);
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2015-10-23 11:31:47 -04:00
|
|
|
ClutterScrollSource scroll_source;
|
2015-01-15 19:03:52 -05:00
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
seat = meta_input_device_native_get_seat (META_INPUT_DEVICE_NATIVE (device));
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_pointer_get_time_usec (axis_event);
|
2015-01-15 19:03:52 -05:00
|
|
|
source = libinput_event_pointer_get_axis_source (axis_event);
|
2015-10-23 11:31:47 -04:00
|
|
|
scroll_source = translate_scroll_source (source);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2015-01-15 19:03:52 -05:00
|
|
|
/* libinput < 0.8 sent wheel click events with value 10. Since 0.8
|
|
|
|
the value is the angle of the click in degrees. To keep
|
|
|
|
backwards-compat with existing clients, we just send multiples of
|
|
|
|
the click count. */
|
|
|
|
|
2016-08-23 03:38:00 -04:00
|
|
|
switch (scroll_source)
|
2015-01-15 19:03:52 -05:00
|
|
|
{
|
2016-08-23 03:38:00 -04:00
|
|
|
case CLUTTER_SCROLL_SOURCE_WHEEL:
|
|
|
|
notify_discrete_axis (seat, device, time_us, scroll_source,
|
|
|
|
axis_event);
|
|
|
|
break;
|
|
|
|
case CLUTTER_SCROLL_SOURCE_FINGER:
|
|
|
|
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
|
|
|
|
case CLUTTER_SCROLL_SOURCE_UNKNOWN:
|
|
|
|
notify_continuous_axis (seat, device, time_us, scroll_source,
|
|
|
|
axis_event);
|
|
|
|
break;
|
2015-01-15 19:03:52 -05:00
|
|
|
}
|
2013-12-15 11:38:56 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-04-25 14:07:53 -04:00
|
|
|
case LIBINPUT_EVENT_TOUCH_DOWN:
|
|
|
|
{
|
2018-01-26 11:25:56 -05:00
|
|
|
int device_slot;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2014-06-02 17:16:21 -04:00
|
|
|
double x, y;
|
2019-08-16 13:33:43 -04:00
|
|
|
float stage_width, stage_height;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2014-04-25 14:07:53 -04:00
|
|
|
ClutterStage *stage;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaTouchState *touch_state;
|
2014-04-25 14:07:53 -04:00
|
|
|
struct libinput_event_touch *touch_event =
|
|
|
|
libinput_event_get_touch_event (event);
|
2016-06-16 19:36:46 -04:00
|
|
|
|
2014-04-25 14:07:53 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2014-04-25 14:07:53 -04:00
|
|
|
|
|
|
|
stage = _clutter_input_device_get_stage (device);
|
2015-10-12 14:41:57 -04:00
|
|
|
if (stage == NULL)
|
2014-04-25 14:07:53 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
|
|
|
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
|
|
|
|
2018-01-26 11:25:56 -05:00
|
|
|
device_slot = libinput_event_touch_get_slot (touch_event);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_touch_get_time_usec (touch_event);
|
2014-04-25 14:07:53 -04:00
|
|
|
x = libinput_event_touch_get_x_transformed (touch_event,
|
|
|
|
stage_width);
|
|
|
|
y = libinput_event_touch_get_y_transformed (touch_event,
|
|
|
|
stage_height);
|
|
|
|
|
2018-01-26 11:25:56 -05:00
|
|
|
touch_state =
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_acquire_touch_state (device_evdev,
|
|
|
|
device_slot);
|
2014-06-02 17:16:21 -04:00
|
|
|
touch_state->coords.x = x;
|
|
|
|
touch_state->coords.y = y;
|
2014-04-25 14:07:53 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_touch_event (seat, device,
|
|
|
|
CLUTTER_TOUCH_BEGIN,
|
|
|
|
time_us,
|
|
|
|
touch_state->seat_slot,
|
|
|
|
touch_state->coords.x,
|
|
|
|
touch_state->coords.y);
|
2014-04-25 14:07:53 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_UP:
|
|
|
|
{
|
2018-01-26 11:25:56 -05:00
|
|
|
int device_slot;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
|
|
|
MetaTouchState *touch_state;
|
2014-04-25 14:07:53 -04:00
|
|
|
struct libinput_event_touch *touch_event =
|
|
|
|
libinput_event_get_touch_event (event);
|
2016-06-16 19:36:46 -04:00
|
|
|
|
2014-04-25 14:07:53 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2014-04-25 14:07:53 -04:00
|
|
|
|
2018-01-26 11:25:56 -05:00
|
|
|
device_slot = libinput_event_touch_get_slot (touch_event);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_touch_get_time_usec (touch_event);
|
2018-01-26 11:25:56 -05:00
|
|
|
touch_state =
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_lookup_touch_state (device_evdev,
|
|
|
|
device_slot);
|
2017-12-11 05:22:21 -05:00
|
|
|
if (!touch_state)
|
|
|
|
break;
|
2014-04-25 14:07:53 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_touch_event (seat, device,
|
|
|
|
CLUTTER_TOUCH_END, 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);
|
2014-04-25 14:07:53 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_MOTION:
|
|
|
|
{
|
2018-01-26 11:25:56 -05:00
|
|
|
int device_slot;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2014-06-02 17:16:21 -04:00
|
|
|
double x, y;
|
2019-08-16 13:33:43 -04:00
|
|
|
float stage_width, stage_height;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2014-04-25 14:07:53 -04:00
|
|
|
ClutterStage *stage;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaTouchState *touch_state;
|
2014-04-25 14:07:53 -04:00
|
|
|
struct libinput_event_touch *touch_event =
|
|
|
|
libinput_event_get_touch_event (event);
|
2016-06-16 19:36:46 -04:00
|
|
|
|
2014-04-25 14:07:53 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
|
|
|
seat = meta_input_device_native_get_seat (device_evdev);
|
2014-04-25 14:07:53 -04:00
|
|
|
|
|
|
|
stage = _clutter_input_device_get_stage (device);
|
2015-10-12 14:41:57 -04:00
|
|
|
if (stage == NULL)
|
2014-04-25 14:07:53 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
|
|
|
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
|
|
|
|
2018-01-26 11:25:56 -05:00
|
|
|
device_slot = libinput_event_touch_get_slot (touch_event);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_touch_get_time_usec (touch_event);
|
2014-04-25 14:07:53 -04:00
|
|
|
x = libinput_event_touch_get_x_transformed (touch_event,
|
|
|
|
stage_width);
|
|
|
|
y = libinput_event_touch_get_y_transformed (touch_event,
|
|
|
|
stage_height);
|
|
|
|
|
2018-01-26 11:25:56 -05:00
|
|
|
touch_state =
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_lookup_touch_state (device_evdev,
|
|
|
|
device_slot);
|
2017-12-11 05:22:21 -05:00
|
|
|
if (!touch_state)
|
|
|
|
break;
|
|
|
|
|
2014-06-02 17:16:21 -04:00
|
|
|
touch_state->coords.x = x;
|
|
|
|
touch_state->coords.y = y;
|
2014-04-25 14:07:53 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_touch_event (seat, device,
|
|
|
|
CLUTTER_TOUCH_UPDATE,
|
|
|
|
time_us,
|
|
|
|
touch_state->seat_slot,
|
|
|
|
touch_state->coords.x,
|
|
|
|
touch_state->coords.y);
|
2014-04-25 14:07:53 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
2014-04-25 14:07:53 -04:00
|
|
|
struct libinput_event_touch *touch_event =
|
|
|
|
libinput_event_get_touch_event (event);
|
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2019-03-29 17:03:27 -04:00
|
|
|
device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_touch_get_time_usec (touch_event);
|
2014-04-25 14:07:53 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_release_touch_slots (device_evdev, time_us);
|
2014-04-25 14:07:53 -04:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2015-05-22 12:33:31 -04:00
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
|
|
|
{
|
|
|
|
struct libinput_event_gesture *gesture_event =
|
|
|
|
libinput_event_get_gesture_event (event);
|
|
|
|
ClutterTouchpadGesturePhase phase;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t n_fingers;
|
|
|
|
uint64_t time_us;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN)
|
|
|
|
phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
|
|
|
|
else
|
|
|
|
phase = libinput_event_gesture_get_cancelled (gesture_event) ?
|
|
|
|
CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END;
|
|
|
|
|
2016-05-03 07:29:56 -04:00
|
|
|
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
2016-05-03 07:29:56 -04:00
|
|
|
notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers);
|
2015-05-22 12:33:31 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
|
|
|
{
|
|
|
|
struct libinput_event_gesture *gesture_event =
|
|
|
|
libinput_event_get_gesture_event (event);
|
|
|
|
gdouble angle_delta, scale, dx, dy;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t n_fingers;
|
|
|
|
uint64_t time_us;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
2016-05-03 07:29:56 -04:00
|
|
|
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
angle_delta = libinput_event_gesture_get_angle_delta (gesture_event);
|
|
|
|
scale = libinput_event_gesture_get_scale (gesture_event);
|
|
|
|
dx = libinput_event_gesture_get_dx (gesture_event);
|
2019-12-13 14:27:43 -05:00
|
|
|
dy = libinput_event_gesture_get_dy (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
notify_pinch_gesture_event (device,
|
|
|
|
CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE,
|
2016-05-03 07:29:56 -04:00
|
|
|
time_us, dx, dy, angle_delta, scale, n_fingers);
|
2015-05-22 12:33:31 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
|
|
|
{
|
|
|
|
struct libinput_event_gesture *gesture_event =
|
|
|
|
libinput_event_get_gesture_event (event);
|
|
|
|
ClutterTouchpadGesturePhase phase;
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t n_fingers;
|
|
|
|
uint64_t time_us;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
|
|
|
|
|
|
|
if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN)
|
|
|
|
phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
|
|
|
|
else
|
|
|
|
phase = libinput_event_gesture_get_cancelled (gesture_event) ?
|
|
|
|
CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END;
|
|
|
|
|
2015-12-01 23:39:44 -05:00
|
|
|
notify_swipe_gesture_event (device, phase, time_us, n_fingers, 0, 0);
|
2015-05-22 12:33:31 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
|
|
|
{
|
|
|
|
struct libinput_event_gesture *gesture_event =
|
|
|
|
libinput_event_get_gesture_event (event);
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t n_fingers;
|
|
|
|
uint64_t time_us;
|
|
|
|
double dx, dy;
|
2015-05-22 12:33:31 -04:00
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
2015-05-22 12:33:31 -04:00
|
|
|
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
|
|
|
dx = libinput_event_gesture_get_dx (gesture_event);
|
|
|
|
dy = libinput_event_gesture_get_dy (gesture_event);
|
|
|
|
|
|
|
|
notify_swipe_gesture_event (device,
|
|
|
|
CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE,
|
2015-12-01 23:39:44 -05:00
|
|
|
time_us, n_fingers, dx, dy);
|
2015-05-22 12:33:31 -04:00
|
|
|
break;
|
|
|
|
}
|
2015-01-09 11:38:42 -05:00
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
|
|
|
|
{
|
2018-09-06 00:44:04 -04:00
|
|
|
process_tablet_axis (manager_evdev, event);
|
2015-01-09 11:38:42 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time;
|
2015-01-09 11:38:42 -05:00
|
|
|
struct libinput_event_tablet_tool *tablet_event =
|
|
|
|
libinput_event_get_tablet_tool_event (event);
|
|
|
|
struct libinput_tablet_tool *libinput_tool = NULL;
|
|
|
|
enum libinput_tablet_tool_proximity_state state;
|
|
|
|
|
|
|
|
state = libinput_event_tablet_tool_get_proximity_state (tablet_event);
|
|
|
|
time = libinput_event_tablet_tool_get_time_usec (tablet_event);
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
|
|
|
|
libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event);
|
|
|
|
|
2016-10-31 12:36:50 -04:00
|
|
|
if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN)
|
|
|
|
input_device_update_tool (device, libinput_tool);
|
2015-01-09 11:38:42 -05:00
|
|
|
notify_proximity (device, time, state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
|
2016-10-31 12:36:50 -04:00
|
|
|
if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT)
|
|
|
|
input_device_update_tool (device, NULL);
|
2015-01-09 11:38:42 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
|
|
|
uint32_t button_state;
|
2015-01-09 11:38:42 -05:00
|
|
|
struct libinput_event_tablet_tool *tablet_event =
|
|
|
|
libinput_event_get_tablet_tool_event (event);
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t tablet_button;
|
2015-01-09 11:38:42 -05:00
|
|
|
|
2018-09-06 00:44:04 -04:00
|
|
|
process_tablet_axis (manager_evdev, event);
|
|
|
|
|
2015-01-09 11:38:42 -05:00
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2016-06-17 17:42:16 -04:00
|
|
|
time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
|
2015-01-09 11:38:42 -05:00
|
|
|
tablet_button = libinput_event_tablet_tool_get_button (tablet_event);
|
|
|
|
|
|
|
|
button_state = libinput_event_tablet_tool_get_button_state (tablet_event) ==
|
|
|
|
LIBINPUT_BUTTON_STATE_PRESSED;
|
2016-06-17 17:42:16 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_button (seat_from_device (device), device,
|
|
|
|
time_us, tablet_button, button_state);
|
2015-01-09 11:38:42 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time_us;
|
|
|
|
uint32_t button_state;
|
2015-01-09 11:38:42 -05:00
|
|
|
struct libinput_event_tablet_tool *tablet_event =
|
|
|
|
libinput_event_get_tablet_tool_event (event);
|
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
2016-06-17 17:42:16 -04:00
|
|
|
time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
|
2015-01-09 11:38:42 -05:00
|
|
|
|
|
|
|
button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) ==
|
|
|
|
LIBINPUT_TABLET_TOOL_TIP_DOWN;
|
2016-06-17 17:42:16 -04:00
|
|
|
|
2018-09-06 00:44:04 -04:00
|
|
|
/* To avoid jumps on tip, notify axes before the tip down event
|
|
|
|
but after the tip up event */
|
|
|
|
if (button_state)
|
|
|
|
process_tablet_axis (manager_evdev, event);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_notify_button (seat_from_device (device), device,
|
|
|
|
time_us, BTN_TOUCH, button_state);
|
2018-09-06 00:44:04 -04:00
|
|
|
if (!button_state)
|
|
|
|
process_tablet_axis (manager_evdev, event);
|
2015-01-09 11:38:42 -05:00
|
|
|
break;
|
|
|
|
}
|
2016-05-10 11:05:19 -04:00
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time;
|
|
|
|
uint32_t button_state, button, group, mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
struct libinput_tablet_pad_mode_group *mode_group;
|
|
|
|
struct libinput_event_tablet_pad *pad_event =
|
|
|
|
libinput_event_get_tablet_pad_event (event);
|
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
time = libinput_event_tablet_pad_get_time_usec (pad_event);
|
|
|
|
|
|
|
|
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
|
|
|
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
2016-12-28 05:32:07 -05:00
|
|
|
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
|
|
|
button = libinput_event_tablet_pad_get_button_number (pad_event);
|
|
|
|
button_state = libinput_event_tablet_pad_get_button_state (pad_event) ==
|
|
|
|
LIBINPUT_BUTTON_STATE_PRESSED;
|
2016-12-28 05:32:07 -05:00
|
|
|
notify_pad_button (device, time, button, group, mode, button_state);
|
2016-05-10 11:05:19 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time;
|
|
|
|
uint32_t number, source, group, mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
struct libinput_tablet_pad_mode_group *mode_group;
|
|
|
|
struct libinput_event_tablet_pad *pad_event =
|
|
|
|
libinput_event_get_tablet_pad_event (event);
|
2019-08-16 13:33:43 -04:00
|
|
|
double value;
|
2016-05-10 11:05:19 -04:00
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
time = libinput_event_tablet_pad_get_time_usec (pad_event);
|
|
|
|
number = libinput_event_tablet_pad_get_strip_number (pad_event);
|
|
|
|
value = libinput_event_tablet_pad_get_strip_position (pad_event);
|
|
|
|
source = libinput_event_tablet_pad_get_strip_source (pad_event);
|
|
|
|
|
|
|
|
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
|
|
|
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
2016-12-28 05:32:07 -05:00
|
|
|
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
2016-12-28 05:32:07 -05:00
|
|
|
notify_pad_strip (device, time, number, source, group, mode, value);
|
2016-05-10 11:05:19 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_RING:
|
|
|
|
{
|
2019-08-16 13:33:43 -04:00
|
|
|
uint64_t time;
|
|
|
|
uint32_t number, source, group, mode;
|
2016-05-10 11:05:19 -04:00
|
|
|
struct libinput_tablet_pad_mode_group *mode_group;
|
|
|
|
struct libinput_event_tablet_pad *pad_event =
|
|
|
|
libinput_event_get_tablet_pad_event (event);
|
2019-08-16 13:33:43 -04:00
|
|
|
double angle;
|
2016-05-10 11:05:19 -04:00
|
|
|
|
|
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
|
|
time = libinput_event_tablet_pad_get_time_usec (pad_event);
|
|
|
|
number = libinput_event_tablet_pad_get_ring_number (pad_event);
|
|
|
|
angle = libinput_event_tablet_pad_get_ring_position (pad_event);
|
|
|
|
source = libinput_event_tablet_pad_get_ring_source (pad_event);
|
|
|
|
|
|
|
|
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
|
|
|
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
2016-12-28 05:32:07 -05:00
|
|
|
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
2016-05-10 11:05:19 -04:00
|
|
|
|
2016-12-28 05:32:07 -05:00
|
|
|
notify_pad_ring (device, time, number, source, group, mode, angle);
|
2016-05-10 11:05:19 -04:00
|
|
|
break;
|
|
|
|
}
|
2013-12-15 11:38:56 -05:00
|
|
|
default:
|
|
|
|
handled = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
}
|
|
|
|
|
2014-04-25 13:54:35 -04:00
|
|
|
static gboolean
|
2019-03-29 17:03:27 -04:00
|
|
|
filter_event (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_event *event)
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
|
|
|
gboolean retval = CLUTTER_EVENT_PROPAGATE;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventFilter *filter;
|
2014-04-25 13:54:35 -04:00
|
|
|
GSList *tmp_list;
|
|
|
|
|
|
|
|
tmp_list = manager_evdev->priv->event_filters;
|
|
|
|
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
filter = tmp_list->data;
|
|
|
|
retval = filter->func (event, filter->data);
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
|
|
|
|
if (retval != CLUTTER_EVENT_PROPAGATE)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
process_event (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
struct libinput_event *event)
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
2014-04-25 13:54:35 -04:00
|
|
|
gboolean retval;
|
|
|
|
|
|
|
|
retval = filter_event (manager_evdev, event);
|
|
|
|
|
|
|
|
if (retval != CLUTTER_EVENT_PROPAGATE)
|
|
|
|
return;
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
if (process_base_event (manager_evdev, event))
|
|
|
|
return;
|
|
|
|
if (process_device_event (manager_evdev, event))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
process_events (MetaDeviceManagerNative *manager_evdev)
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2013-12-15 11:38:56 -05:00
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
|
|
while ((event = libinput_get_event (priv->libinput)))
|
|
|
|
{
|
|
|
|
process_event(manager_evdev, event);
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
open_restricted (const char *path,
|
|
|
|
int flags,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
gint fd;
|
|
|
|
|
2014-03-01 13:06:25 -05:00
|
|
|
if (device_open_callback)
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
2014-03-01 13:06:25 -05:00
|
|
|
fd = device_open_callback (path, flags, device_callback_data, &error);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
g_warning ("Could not open device %s: %s", path, error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fd = open (path, O_RDWR | O_NONBLOCK);
|
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
g_warning ("Could not open device %s: %s", path, strerror (errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
close_restricted (int fd,
|
|
|
|
void *user_data)
|
|
|
|
{
|
2014-03-01 13:06:25 -05:00
|
|
|
if (device_close_callback)
|
|
|
|
device_close_callback (fd, device_callback_data);
|
|
|
|
else
|
|
|
|
close (fd);
|
2013-12-15 11:38:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct libinput_interface libinput_interface = {
|
|
|
|
open_restricted,
|
|
|
|
close_restricted
|
|
|
|
};
|
|
|
|
|
2016-05-02 23:27:57 -04:00
|
|
|
static ClutterVirtualInputDevice *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_create_virtual_device (ClutterDeviceManager *manager,
|
|
|
|
ClutterInputDeviceType device_type)
|
2016-05-02 23:27:57 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev =
|
|
|
|
META_DEVICE_MANAGER_NATIVE (manager);
|
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2016-06-22 05:46:25 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
return g_object_new (META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE,
|
2016-06-16 19:39:56 -04:00
|
|
|
"device-manager", manager,
|
2016-06-22 05:46:25 -04:00
|
|
|
"seat", priv->main_seat,
|
2016-06-22 05:38:00 -04:00
|
|
|
"device-type", device_type,
|
2016-06-16 19:39:56 -04:00
|
|
|
NULL);
|
2016-05-02 23:27:57 -04:00
|
|
|
}
|
|
|
|
|
2018-01-29 01:23:39 -05:00
|
|
|
static ClutterVirtualDeviceType
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
|
2018-01-29 01:23:39 -05:00
|
|
|
{
|
|
|
|
return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
|
|
|
|
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER |
|
|
|
|
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN);
|
|
|
|
}
|
|
|
|
|
2016-09-07 05:38:33 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_compress_motion (ClutterDeviceManager *device_manger,
|
|
|
|
ClutterEvent *event,
|
|
|
|
const ClutterEvent *to_discard)
|
2016-09-07 05:38:33 -04:00
|
|
|
{
|
|
|
|
double dx, dy;
|
|
|
|
double dx_unaccel, dy_unaccel;
|
|
|
|
double dst_dx = 0.0, dst_dy = 0.0;
|
|
|
|
double dst_dx_unaccel = 0.0, dst_dy_unaccel = 0.0;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
if (!meta_event_native_get_relative_motion (to_discard,
|
|
|
|
&dx, &dy,
|
|
|
|
&dx_unaccel, &dy_unaccel))
|
2016-09-07 05:38:33 -04:00
|
|
|
return;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_native_get_relative_motion (event,
|
|
|
|
&dst_dx, &dst_dy,
|
|
|
|
&dst_dx_unaccel, &dst_dy_unaccel);
|
|
|
|
meta_event_native_set_relative_motion (event,
|
|
|
|
dx + dst_dx,
|
|
|
|
dy + dst_dy,
|
|
|
|
dx_unaccel + dst_dx_unaccel,
|
|
|
|
dy_unaccel + dst_dy_unaccel);
|
2016-09-07 05:38:33 -04:00
|
|
|
}
|
|
|
|
|
2017-10-13 04:38:05 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
|
|
|
ClutterKbdA11ySettings *settings)
|
2017-10-13 04:38:05 -04:00
|
|
|
{
|
|
|
|
ClutterInputDevice *device;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
device = meta_device_manager_native_get_core_device (device_manager, CLUTTER_KEYBOARD_DEVICE);
|
2017-10-13 04:38:05 -04:00
|
|
|
if (device)
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device),
|
|
|
|
settings);
|
2017-10-13 04:38:05 -04:00
|
|
|
}
|
|
|
|
|
2010-11-04 10:38:32 -04:00
|
|
|
/*
|
|
|
|
* GObject implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_constructed (GObject *object)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
|
|
|
MetaEventSource *source;
|
2013-12-15 11:38:56 -05:00
|
|
|
struct udev *udev;
|
|
|
|
|
|
|
|
udev = udev_new ();
|
2014-06-25 07:18:02 -04:00
|
|
|
if (G_UNLIKELY (udev == NULL))
|
2013-12-15 11:38:56 -05:00
|
|
|
{
|
|
|
|
g_warning ("Failed to create udev object");
|
|
|
|
return;
|
|
|
|
}
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (object);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
2014-06-25 07:18:02 -04:00
|
|
|
priv->libinput = libinput_udev_create_context (&libinput_interface,
|
|
|
|
manager_evdev,
|
|
|
|
udev);
|
|
|
|
if (priv->libinput == NULL)
|
|
|
|
{
|
|
|
|
g_critical ("Failed to create the libinput object.");
|
|
|
|
return;
|
|
|
|
}
|
2013-09-06 10:56:55 -04:00
|
|
|
|
2017-02-02 13:01:25 -05:00
|
|
|
if (libinput_udev_assign_seat (priv->libinput,
|
|
|
|
evdev_seat_id ? evdev_seat_id : "seat0") == -1)
|
2013-09-06 10:56:55 -04:00
|
|
|
{
|
2014-06-25 07:18:02 -04:00
|
|
|
g_critical ("Failed to assign a seat to the libinput object.");
|
|
|
|
libinput_unref (priv->libinput);
|
|
|
|
priv->libinput = NULL;
|
2013-12-15 11:38:56 -05:00
|
|
|
return;
|
2013-09-06 10:56:55 -04:00
|
|
|
}
|
2013-08-09 05:53:46 -04:00
|
|
|
|
2014-06-25 07:18:02 -04:00
|
|
|
udev_unref (udev);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
priv->main_seat = meta_seat_native_new (manager_evdev);
|
2018-05-16 19:53:48 -04:00
|
|
|
priv->seats = g_slist_append (priv->seats, priv->main_seat);
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2014-03-10 10:25:22 -04:00
|
|
|
dispatch_libinput (manager_evdev);
|
2014-02-24 10:41:51 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
source = meta_event_source_new (manager_evdev);
|
2013-12-15 11:38:56 -05:00
|
|
|
priv->event_source = source;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
2012-01-17 08:37:26 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_dispose (GObject *object)
|
2012-01-17 08:37:26 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2012-01-17 08:37:26 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (object);
|
2012-01-17 08:37:26 -05:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
2019-11-15 19:25:52 -05:00
|
|
|
g_clear_signal_handler (&priv->stage_added_handler, priv->stage_manager);
|
|
|
|
g_clear_signal_handler (&priv->stage_removed_handler, priv->stage_manager);
|
2012-01-17 08:37:26 -05:00
|
|
|
|
|
|
|
if (priv->stage_manager)
|
|
|
|
{
|
|
|
|
g_object_unref (priv->stage_manager);
|
|
|
|
priv->stage_manager = NULL;
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
G_OBJECT_CLASS (meta_device_manager_native_parent_class)->dispose (object);
|
2012-01-17 08:37:26 -05:00
|
|
|
}
|
|
|
|
|
2010-11-04 10:38:32 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_finalize (GObject *object)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (object);
|
2010-11-04 10:38:32 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_slist_free_full (priv->seats, (GDestroyNotify) meta_seat_native_free);
|
2010-11-09 12:50:23 -05:00
|
|
|
g_slist_free (priv->devices);
|
|
|
|
|
2014-06-25 07:18:02 -04:00
|
|
|
if (priv->event_source != NULL)
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_event_source_free (priv->event_source);
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2014-06-25 07:18:02 -04:00
|
|
|
if (priv->constrain_data_notify != NULL)
|
2013-08-23 06:15:40 -04:00
|
|
|
priv->constrain_data_notify (priv->constrain_data);
|
|
|
|
|
2014-06-25 07:18:02 -04:00
|
|
|
if (priv->libinput != NULL)
|
|
|
|
libinput_unref (priv->libinput);
|
2013-12-15 11:38:56 -05:00
|
|
|
|
2015-09-30 02:26:09 -04:00
|
|
|
g_list_free (priv->free_device_ids);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
G_OBJECT_CLASS (meta_device_manager_native_parent_class)->finalize (object);
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_class_init (MetaDeviceManagerNativeClass *klass)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2010-11-04 10:38:32 -04:00
|
|
|
ClutterDeviceManagerClass *manager_class;
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
object_class->constructed = meta_device_manager_native_constructed;
|
|
|
|
object_class->finalize = meta_device_manager_native_finalize;
|
|
|
|
object_class->dispose = meta_device_manager_native_dispose;
|
2010-11-04 10:38:32 -04:00
|
|
|
|
|
|
|
manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass);
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_class->add_device = meta_device_manager_native_add_device;
|
|
|
|
manager_class->remove_device = meta_device_manager_native_remove_device;
|
|
|
|
manager_class->get_devices = meta_device_manager_native_get_devices;
|
|
|
|
manager_class->get_core_device = meta_device_manager_native_get_core_device;
|
|
|
|
manager_class->get_device = meta_device_manager_native_get_device;
|
|
|
|
manager_class->create_virtual_device = meta_device_manager_native_create_virtual_device;
|
|
|
|
manager_class->get_supported_virtual_device_types = meta_device_manager_native_get_supported_virtual_device_types;
|
|
|
|
manager_class->compress_motion = meta_device_manager_native_compress_motion;
|
|
|
|
manager_class->apply_kbd_a11y_settings = meta_device_manager_native_apply_kbd_a11y_settings;
|
|
|
|
manager_class->copy_event_data = meta_device_manager_native_copy_event_data;
|
|
|
|
manager_class->free_event_data = meta_device_manager_native_free_event_data;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
|
|
|
|
2012-01-17 08:37:26 -05:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_stage_added_cb (ClutterStageManager *manager,
|
|
|
|
ClutterStage *stage,
|
|
|
|
MetaDeviceManagerNative *self)
|
2012-01-17 08:37:26 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = self->priv;
|
2012-01-17 08:37:26 -05:00
|
|
|
GSList *l;
|
|
|
|
|
2012-01-22 10:36:17 -05:00
|
|
|
/* NB: Currently we can only associate a single stage with all evdev
|
|
|
|
* devices.
|
|
|
|
*
|
|
|
|
* We save a pointer to the stage so if we release/reclaim input
|
|
|
|
* devices due to switching virtual terminals then we know what
|
|
|
|
* stage to re associate the devices with.
|
|
|
|
*/
|
|
|
|
priv->stage = stage;
|
|
|
|
|
2012-01-17 08:37:26 -05:00
|
|
|
/* Set the stage of any devices that don't already have a stage */
|
2013-12-15 11:38:56 -05:00
|
|
|
for (l = priv->seats; l; l = l->next)
|
2012-01-17 08:37:26 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat = l->data;
|
2012-01-17 08:37:26 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_set_stage (seat, stage);
|
2012-01-17 08:37:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We only want to do this once so we can catch the default
|
|
|
|
stage. If the application has multiple stages then it will need
|
|
|
|
to manage the stage of the input devices itself */
|
2019-11-15 19:25:52 -05:00
|
|
|
g_clear_signal_handler (&priv->stage_added_handler, priv->stage_manager);
|
2012-01-17 08:37:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_stage_removed_cb (ClutterStageManager *manager,
|
|
|
|
ClutterStage *stage,
|
|
|
|
MetaDeviceManagerNative *self)
|
2012-01-17 08:37:26 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = self->priv;
|
2012-01-17 08:37:26 -05:00
|
|
|
GSList *l;
|
|
|
|
|
|
|
|
/* Remove the stage of any input devices that were pointing to this
|
|
|
|
stage so we don't send events to invalid stages */
|
2013-12-15 11:38:56 -05:00
|
|
|
for (l = priv->seats; l; l = l->next)
|
2012-01-17 08:37:26 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat = l->data;
|
2012-01-17 08:37:26 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_set_stage (seat, NULL);
|
2012-01-17 08:37:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-04 10:38:32 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_init (MetaDeviceManagerNative *self)
|
2010-11-04 10:38:32 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2012-01-17 08:37:26 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
priv = self->priv = meta_device_manager_native_get_instance_private (self);
|
2012-01-17 08:37:26 -05:00
|
|
|
|
|
|
|
priv->stage_manager = clutter_stage_manager_get_default ();
|
|
|
|
g_object_ref (priv->stage_manager);
|
|
|
|
|
|
|
|
/* evdev doesn't have any way to link an event to a particular stage
|
|
|
|
so we'll have to leave it up to applications to set the
|
|
|
|
corresponding stage for an input device. However to make it
|
|
|
|
easier for applications that are only using one fullscreen stage
|
|
|
|
(which is probably the most frequent use-case for the evdev
|
|
|
|
backend) we'll associate any input devices that don't have a
|
|
|
|
stage with the first stage created. */
|
|
|
|
priv->stage_added_handler =
|
|
|
|
g_signal_connect (priv->stage_manager,
|
|
|
|
"stage-added",
|
2019-03-29 17:03:27 -04:00
|
|
|
G_CALLBACK (meta_device_manager_native_stage_added_cb),
|
2012-01-17 08:37:26 -05:00
|
|
|
self);
|
|
|
|
priv->stage_removed_handler =
|
|
|
|
g_signal_connect (priv->stage_manager,
|
|
|
|
"stage-removed",
|
2019-03-29 17:03:27 -04:00
|
|
|
G_CALLBACK (meta_device_manager_native_stage_removed_cb),
|
2012-01-17 08:37:26 -05:00
|
|
|
self);
|
2015-09-30 02:26:09 -04:00
|
|
|
|
|
|
|
priv->device_id_next = INITIAL_DEVICE_ID;
|
2010-11-04 10:38:32 -04:00
|
|
|
}
|
2010-11-09 12:50:23 -05:00
|
|
|
|
2015-09-30 02:26:09 -04:00
|
|
|
gint
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_acquire_device_id (MetaDeviceManagerNative *manager_evdev)
|
2015-09-30 02:26:09 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2015-09-30 02:26:09 -04:00
|
|
|
GList *first;
|
|
|
|
gint next_id;
|
|
|
|
|
|
|
|
if (priv->free_device_ids == NULL)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
/* We ran out of free ID's, so append 10 new ones. */
|
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
priv->free_device_ids =
|
|
|
|
g_list_append (priv->free_device_ids,
|
|
|
|
GINT_TO_POINTER (priv->device_id_next++));
|
|
|
|
}
|
|
|
|
|
|
|
|
first = g_list_first (priv->free_device_ids);
|
|
|
|
next_id = GPOINTER_TO_INT (first->data);
|
2017-11-06 14:34:21 -05:00
|
|
|
priv->free_device_ids = g_list_delete_link (priv->free_device_ids, first);
|
2015-09-30 02:26:09 -04:00
|
|
|
|
|
|
|
return next_id;
|
|
|
|
}
|
|
|
|
|
2016-11-25 06:44:56 -05:00
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_dispatch (MetaDeviceManagerNative *manager_evdev)
|
2016-11-25 06:44:56 -05:00
|
|
|
{
|
|
|
|
dispatch_libinput (manager_evdev);
|
|
|
|
}
|
|
|
|
|
2015-09-30 02:26:09 -04:00
|
|
|
static int
|
|
|
|
compare_ids (gconstpointer a,
|
|
|
|
gconstpointer b)
|
|
|
|
{
|
|
|
|
return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_release_device_id (MetaDeviceManagerNative *manager_evdev,
|
|
|
|
ClutterInputDevice *device)
|
2015-09-30 02:26:09 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2015-09-30 02:26:09 -04:00
|
|
|
gint device_id;
|
|
|
|
|
|
|
|
device_id = clutter_input_device_get_device_id (device);
|
|
|
|
priv->free_device_ids = g_list_insert_sorted (priv->free_device_ids,
|
|
|
|
GINT_TO_POINTER (device_id),
|
|
|
|
compare_ids);
|
|
|
|
}
|
|
|
|
|
2016-06-16 19:36:46 -04:00
|
|
|
ClutterStage *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_stage (MetaDeviceManagerNative *manager_evdev)
|
2016-06-16 19:36:46 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2016-06-16 19:36:46 -04:00
|
|
|
|
|
|
|
return priv->stage;
|
|
|
|
}
|
|
|
|
|
2012-01-22 10:36:17 -05:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_release_devices:
|
2012-01-22 10:36:17 -05:00
|
|
|
*
|
|
|
|
* Releases all the evdev devices that Clutter is currently managing. This api
|
|
|
|
* is typically used when switching away from the Clutter application when
|
|
|
|
* switching tty. The devices can be reclaimed later with a call to
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_reclaim_devices().
|
2012-01-22 10:36:17 -05:00
|
|
|
*
|
|
|
|
* This function should only be called after clutter has been initialized.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_release_devices (void)
|
2012-01-22 10:36:17 -05:00
|
|
|
{
|
|
|
|
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2012-01-22 10:36:17 -05:00
|
|
|
|
|
|
|
if (!manager)
|
|
|
|
{
|
|
|
|
g_warning ("clutter_evdev_release_devices shouldn't be called "
|
|
|
|
"before clutter_init()");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (manager));
|
2012-01-22 10:36:17 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2013-12-15 11:38:56 -05:00
|
|
|
priv = manager_evdev->priv;
|
2012-01-22 10:36:17 -05:00
|
|
|
|
|
|
|
if (priv->released)
|
|
|
|
{
|
|
|
|
g_warning ("clutter_evdev_release_devices() shouldn't be called "
|
|
|
|
"multiple times without a corresponding call to "
|
|
|
|
"clutter_evdev_reclaim_devices() first");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_suspend (priv->libinput);
|
|
|
|
process_events (manager_evdev);
|
2012-01-22 10:36:17 -05:00
|
|
|
|
|
|
|
priv->released = TRUE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 17:48:42 -04:00
|
|
|
static void
|
2019-03-29 17:03:27 -04:00
|
|
|
update_xkb_state (MetaDeviceManagerNative *manager_evdev)
|
2014-07-21 17:48:42 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2014-07-21 17:48:42 -04:00
|
|
|
GSList *iter;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat;
|
2014-07-21 17:48:42 -04:00
|
|
|
xkb_mod_mask_t latched_mods;
|
|
|
|
xkb_mod_mask_t locked_mods;
|
2019-01-10 10:13:20 -05:00
|
|
|
struct xkb_keymap *xkb_keymap;
|
|
|
|
ClutterKeymap *keymap;
|
|
|
|
|
|
|
|
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
2019-03-29 17:03:27 -04:00
|
|
|
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
2014-07-21 17:48:42 -04:00
|
|
|
|
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
|
|
|
for (iter = priv->seats; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
seat = iter->data;
|
|
|
|
|
|
|
|
latched_mods = xkb_state_serialize_mods (seat->xkb,
|
|
|
|
XKB_STATE_MODS_LATCHED);
|
|
|
|
locked_mods = xkb_state_serialize_mods (seat->xkb,
|
|
|
|
XKB_STATE_MODS_LOCKED);
|
|
|
|
xkb_state_unref (seat->xkb);
|
2019-01-10 10:13:20 -05:00
|
|
|
seat->xkb = xkb_state_new (xkb_keymap);
|
2014-07-21 17:48:42 -04:00
|
|
|
|
|
|
|
xkb_state_update_mask (seat->xkb,
|
|
|
|
0, /* depressed */
|
|
|
|
latched_mods,
|
|
|
|
locked_mods,
|
2017-12-19 10:32:32 -05:00
|
|
|
0, 0, seat->layout_idx);
|
2014-07-21 17:48:42 -04:00
|
|
|
|
2019-01-10 10:13:20 -05:00
|
|
|
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);
|
2014-07-21 17:48:42 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_sync_leds (seat);
|
2014-07-21 17:48:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-22 10:36:17 -05:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_reclaim_devices:
|
2012-01-22 10:36:17 -05:00
|
|
|
*
|
|
|
|
* This causes Clutter to re-probe for evdev devices. This is must only be
|
|
|
|
* called after a corresponding call to clutter_evdev_release_devices()
|
|
|
|
* was previously used to release all evdev devices. This API is typically
|
|
|
|
* used when a clutter application using evdev has regained focus due to
|
|
|
|
* switching ttys.
|
|
|
|
*
|
|
|
|
* This function should only be called after clutter has been initialized.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_reclaim_devices (void)
|
2012-01-22 10:36:17 -05:00
|
|
|
{
|
|
|
|
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev =
|
|
|
|
META_DEVICE_MANAGER_NATIVE (manager);
|
|
|
|
MetaDeviceManagerNativePrivate *priv = manager_evdev->priv;
|
2012-01-22 10:36:17 -05:00
|
|
|
|
|
|
|
if (!priv->released)
|
|
|
|
{
|
|
|
|
g_warning ("Spurious call to clutter_evdev_reclaim_devices() without "
|
|
|
|
"previous call to clutter_evdev_release_devices");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-15 11:38:56 -05:00
|
|
|
libinput_resume (priv->libinput);
|
2019-03-29 17:03:27 -04:00
|
|
|
update_xkb_state (manager_evdev);
|
2013-12-15 11:38:56 -05:00
|
|
|
process_events (manager_evdev);
|
2014-03-01 14:12:54 -05:00
|
|
|
|
|
|
|
priv->released = FALSE;
|
2012-01-22 10:36:17 -05:00
|
|
|
}
|
2013-07-15 12:24:35 -04:00
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_device_callbacks: (skip)
|
2014-03-01 13:06:25 -05:00
|
|
|
* @open_callback: the user replacement for open()
|
|
|
|
* @close_callback: the user replacement for close()
|
2013-07-15 12:24:35 -04:00
|
|
|
* @user_data: user data for @callback
|
|
|
|
*
|
|
|
|
* Through this function, the application can set a custom callback
|
|
|
|
* to invoked when Clutter is about to open an evdev device. It can do
|
|
|
|
* so if special handling is needed, for example to circumvent permission
|
|
|
|
* problems.
|
|
|
|
*
|
|
|
|
* Setting @callback to %NULL will reset the default behavior.
|
|
|
|
*
|
|
|
|
* For reliable effects, this function must be called before clutter_init().
|
2014-02-27 05:22:50 -05:00
|
|
|
*
|
|
|
|
* Since: 1.16
|
|
|
|
* Stability: unstable
|
2013-07-15 12:24:35 -04:00
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_device_callbacks (MetaOpenDeviceCallback open_callback,
|
|
|
|
MetaCloseDeviceCallback close_callback,
|
|
|
|
gpointer user_data)
|
2013-07-15 12:24:35 -04:00
|
|
|
{
|
2014-03-01 13:06:25 -05:00
|
|
|
device_open_callback = open_callback;
|
|
|
|
device_close_callback = close_callback;
|
|
|
|
device_callback_data = user_data;
|
2013-07-15 12:24:35 -04:00
|
|
|
}
|
2013-08-09 11:06:39 -04:00
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_keyboard_map: (skip)
|
2013-08-09 11:06:39 -04:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
* @keymap: the new keymap
|
|
|
|
*
|
|
|
|
* Instructs @evdev to use the speficied keyboard map. This will cause
|
2014-01-20 07:50:08 -05:00
|
|
|
* the backend to drop the state and create a new one with the new
|
|
|
|
* map. To avoid state being lost, callers should ensure that no key
|
|
|
|
* is pressed when calling this function.
|
2014-02-27 05:22:50 -05:00
|
|
|
*
|
|
|
|
* Since: 1.16
|
|
|
|
* Stability: unstable
|
2013-08-09 11:06:39 -04:00
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_keyboard_map (ClutterDeviceManager *evdev,
|
|
|
|
struct xkb_keymap *xkb_keymap)
|
2013-08-09 11:06:39 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2019-01-10 10:13:20 -05:00
|
|
|
ClutterKeymap *keymap;
|
2013-08-09 11:06:39 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2013-08-09 11:06:39 -04:00
|
|
|
|
2019-01-10 10:13:20 -05:00
|
|
|
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_keymap_native_set_keyboard_map (META_KEYMAP_NATIVE (keymap),
|
|
|
|
xkb_keymap);
|
2013-08-09 11:06:39 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
|
|
|
update_xkb_state (manager_evdev);
|
2013-08-09 11:06:39 -04:00
|
|
|
}
|
2013-08-23 06:15:40 -04:00
|
|
|
|
2014-01-15 11:54:25 -05:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_get_keyboard_map: (skip)
|
2014-01-15 11:54:25 -05:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
*
|
|
|
|
* Retrieves the #xkb_keymap in use by the evdev backend.
|
|
|
|
*
|
|
|
|
* Return value: the #xkb_keymap.
|
2014-02-27 05:22:50 -05:00
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
* Stability: unstable
|
2014-01-15 11:54:25 -05:00
|
|
|
*/
|
|
|
|
struct xkb_keymap *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_keyboard_map (ClutterDeviceManager *evdev)
|
2014-01-15 11:54:25 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2014-01-15 11:54:25 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_val_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev), NULL);
|
2014-01-15 11:54:25 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2014-01-15 11:54:25 -05:00
|
|
|
|
|
|
|
return xkb_state_get_keymap (manager_evdev->priv->main_seat->xkb);
|
|
|
|
}
|
|
|
|
|
2014-07-06 11:43:14 -04:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_set_keyboard_layout_index: (skip)
|
2014-07-06 11:43:14 -04:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
* @idx: the xkb layout index to set
|
|
|
|
*
|
|
|
|
* Sets the xkb layout index on the backend's #xkb_state .
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
|
|
|
xkb_layout_index_t idx)
|
2014-07-06 11:43:14 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2014-07-06 11:43:14 -04:00
|
|
|
xkb_mod_mask_t depressed_mods;
|
|
|
|
xkb_mod_mask_t latched_mods;
|
|
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
struct xkb_state *state;
|
2017-12-19 10:32:32 -05:00
|
|
|
GSList *l;
|
2014-07-06 11:43:14 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2014-07-06 11:43:14 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2014-07-06 11:43:14 -04:00
|
|
|
state = manager_evdev->priv->main_seat->xkb;
|
|
|
|
|
|
|
|
depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED);
|
|
|
|
latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED);
|
|
|
|
locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
|
|
|
|
|
|
|
|
xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
|
2017-12-19 10:32:32 -05:00
|
|
|
for (l = manager_evdev->priv->seats; l; l = l->next)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat = l->data;
|
2017-12-19 10:32:32 -05:00
|
|
|
|
|
|
|
seat->layout_idx = idx;
|
|
|
|
}
|
2014-07-06 11:43:14 -04:00
|
|
|
}
|
|
|
|
|
2017-08-17 04:17:45 -04:00
|
|
|
/**
|
|
|
|
* clutter_evdev_get_keyboard_layout_index: (skip)
|
|
|
|
*/
|
|
|
|
xkb_layout_index_t
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_keyboard_layout_index (ClutterDeviceManager *evdev)
|
2017-08-17 04:17:45 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2017-08-17 04:17:45 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2017-12-19 10:32:32 -05:00
|
|
|
return manager_evdev->priv->main_seat->layout_idx;
|
2017-08-17 04:17:45 -04:00
|
|
|
}
|
|
|
|
|
2016-09-08 03:55:44 -04:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_keyboard_numlock: (skip)
|
2016-09-08 03:55:44 -04:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
* @numlock_set: TRUE to set NumLock ON, FALSE otherwise.
|
|
|
|
*
|
|
|
|
* Sets the NumLock state on the backend's #xkb_state .
|
|
|
|
*
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_keyboard_numlock (ClutterDeviceManager *evdev,
|
|
|
|
gboolean numlock_state)
|
2016-09-08 03:55:44 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2016-09-08 03:55:44 -04:00
|
|
|
GSList *iter;
|
|
|
|
xkb_mod_mask_t numlock;
|
2019-01-10 10:13:20 -05:00
|
|
|
struct xkb_keymap *xkb_keymap;
|
|
|
|
ClutterKeymap *keymap;
|
2016-09-08 03:55:44 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2016-09-08 03:55:44 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2016-09-08 03:55:44 -04:00
|
|
|
priv = manager_evdev->priv;
|
2019-01-10 10:13:20 -05:00
|
|
|
|
|
|
|
keymap = clutter_backend_get_keymap (clutter_get_default_backend ());
|
2019-03-29 17:03:27 -04:00
|
|
|
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
2019-01-10 10:13:20 -05:00
|
|
|
|
|
|
|
numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2"));
|
2016-09-08 03:55:44 -04:00
|
|
|
|
|
|
|
for (iter = priv->seats; iter; iter = iter->next)
|
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaSeatNative *seat = iter->data;
|
2016-09-08 03:55:44 -04:00
|
|
|
xkb_mod_mask_t depressed_mods;
|
|
|
|
xkb_mod_mask_t latched_mods;
|
|
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
xkb_mod_mask_t group_mods;
|
|
|
|
|
|
|
|
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
|
|
|
latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED);
|
|
|
|
locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED);
|
|
|
|
group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE);
|
|
|
|
|
|
|
|
if (numlock_state)
|
|
|
|
locked_mods |= numlock;
|
|
|
|
else
|
|
|
|
locked_mods &= ~numlock;
|
|
|
|
|
|
|
|
xkb_state_update_mask (seat->xkb,
|
|
|
|
depressed_mods,
|
|
|
|
latched_mods,
|
|
|
|
locked_mods,
|
|
|
|
0, 0,
|
|
|
|
group_mods);
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_seat_native_sync_leds (seat);
|
2016-09-08 03:55:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-23 06:15:40 -04:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_pointer_constrain_callback:
|
2013-08-23 06:15:40 -04:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
* @callback: the callback
|
2015-03-03 10:53:04 -05:00
|
|
|
* @user_data: data to pass to the callback
|
|
|
|
* @user_data_notify: function to be called when removing the callback
|
2013-08-23 06:15:40 -04:00
|
|
|
*
|
|
|
|
* Sets a callback to be invoked for every pointer motion. The callback
|
|
|
|
* can then modify the new pointer coordinates to constrain movement within
|
|
|
|
* a specific region.
|
2014-02-27 05:22:50 -05:00
|
|
|
*
|
|
|
|
* Since: 1.16
|
|
|
|
* Stability: unstable
|
2013-08-23 06:15:40 -04:00
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_pointer_constrain_callback (ClutterDeviceManager *evdev,
|
|
|
|
MetaPointerConstrainCallback callback,
|
|
|
|
gpointer user_data,
|
|
|
|
GDestroyNotify user_data_notify)
|
2013-08-23 06:15:40 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2013-08-23 06:15:40 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2013-08-23 06:15:40 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2013-08-23 06:15:40 -04:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
|
|
|
if (priv->constrain_data_notify)
|
|
|
|
priv->constrain_data_notify (priv->constrain_data);
|
|
|
|
|
|
|
|
priv->constrain_callback = callback;
|
|
|
|
priv->constrain_data = user_data;
|
|
|
|
priv->constrain_data_notify = user_data_notify;
|
|
|
|
}
|
2014-01-13 10:05:57 -05:00
|
|
|
|
2017-02-03 00:02:50 -05:00
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
|
|
|
MetaRelativeMotionFilter filter,
|
|
|
|
gpointer user_data)
|
2017-02-03 00:02:50 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaDeviceManagerNativePrivate *priv;
|
2017-02-03 00:02:50 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2017-02-03 00:02:50 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2017-02-03 00:02:50 -05:00
|
|
|
priv = manager_evdev->priv;
|
|
|
|
|
|
|
|
priv->relative_motion_filter = filter;
|
|
|
|
priv->relative_motion_filter_user_data = user_data;
|
|
|
|
}
|
|
|
|
|
2014-01-13 10:05:57 -05:00
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_keyboard_repeat:
|
2014-01-13 10:05:57 -05:00
|
|
|
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
|
|
|
* @repeat: whether to enable or disable keyboard repeat events
|
|
|
|
* @delay: the delay in ms between the hardware key press event and
|
|
|
|
* the first synthetic event
|
|
|
|
* @interval: the period in ms between consecutive synthetic key
|
|
|
|
* press events
|
|
|
|
*
|
|
|
|
* Enables or disables sythetic key press events, allowing for initial
|
|
|
|
* delay and interval period to be specified.
|
2014-02-27 05:22:50 -05:00
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
* Stability: unstable
|
2014-01-13 10:05:57 -05:00
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_keyboard_repeat (ClutterDeviceManager *evdev,
|
|
|
|
gboolean repeat,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t delay,
|
|
|
|
uint32_t interval)
|
2014-01-13 10:05:57 -05:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
|
|
|
MetaSeatNative *seat;
|
2014-01-13 10:05:57 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
g_return_if_fail (META_IS_DEVICE_MANAGER_NATIVE (evdev));
|
2014-01-13 10:05:57 -05:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (evdev);
|
2014-01-13 10:05:57 -05:00
|
|
|
seat = manager_evdev->priv->main_seat;
|
|
|
|
|
|
|
|
seat->repeat = repeat;
|
|
|
|
seat->repeat_delay = delay;
|
|
|
|
seat->repeat_interval = interval;
|
|
|
|
}
|
2014-04-25 13:54:35 -04:00
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_add_filter: (skip)
|
2014-04-25 13:54:35 -04:00
|
|
|
* @func: (closure data): a filter function
|
|
|
|
* @data: (allow-none): user data to be passed to the filter function, or %NULL
|
|
|
|
* @destroy_notify: (allow-none): function to call on @data when the filter is removed, or %NULL
|
|
|
|
*
|
|
|
|
* Adds an event filter function.
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_add_filter (MetaEvdevFilterFunc func,
|
|
|
|
gpointer data,
|
|
|
|
GDestroyNotify destroy_notify)
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2014-04-25 13:54:35 -04:00
|
|
|
ClutterDeviceManager *manager;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventFilter *filter;
|
2014-04-25 13:54:35 -04:00
|
|
|
|
|
|
|
g_return_if_fail (func != NULL);
|
|
|
|
|
|
|
|
manager = clutter_device_manager_get_default ();
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
if (!META_IS_DEVICE_MANAGER_NATIVE (manager))
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
|
|
|
g_critical ("The Clutter input backend is not a evdev backend");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2014-04-25 13:54:35 -04:00
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
filter = g_new0 (MetaEventFilter, 1);
|
2014-04-25 13:54:35 -04:00
|
|
|
filter->func = func;
|
|
|
|
filter->data = data;
|
|
|
|
filter->destroy_notify = destroy_notify;
|
|
|
|
|
|
|
|
manager_evdev->priv->event_filters =
|
|
|
|
g_slist_append (manager_evdev->priv->event_filters, filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_remove_filter: (skip)
|
2014-04-25 13:54:35 -04:00
|
|
|
* @func: a filter function
|
|
|
|
* @data: (allow-none): user data to be passed to the filter function, or %NULL
|
|
|
|
*
|
|
|
|
* Removes the given filter function.
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_remove_filter (MetaEvdevFilterFunc func,
|
|
|
|
gpointer data)
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaDeviceManagerNative *manager_evdev;
|
2014-04-25 13:54:35 -04:00
|
|
|
ClutterDeviceManager *manager;
|
2019-03-29 17:03:27 -04:00
|
|
|
MetaEventFilter *filter;
|
2014-04-25 13:54:35 -04:00
|
|
|
GSList *tmp_list;
|
|
|
|
|
|
|
|
g_return_if_fail (func != NULL);
|
|
|
|
|
|
|
|
manager = clutter_device_manager_get_default ();
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
if (!META_IS_DEVICE_MANAGER_NATIVE (manager))
|
2014-04-25 13:54:35 -04:00
|
|
|
{
|
|
|
|
g_critical ("The Clutter input backend is not a evdev backend");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:03:27 -04:00
|
|
|
manager_evdev = META_DEVICE_MANAGER_NATIVE (manager);
|
2014-04-25 13:54:35 -04:00
|
|
|
tmp_list = manager_evdev->priv->event_filters;
|
|
|
|
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
filter = tmp_list->data;
|
|
|
|
|
|
|
|
if (filter->func == func && filter->data == data)
|
|
|
|
{
|
|
|
|
if (filter->destroy_notify)
|
|
|
|
filter->destroy_notify (filter->data);
|
|
|
|
g_free (filter);
|
|
|
|
manager_evdev->priv->event_filters =
|
|
|
|
g_slist_delete_link (manager_evdev->priv->event_filters, tmp_list);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 14:03:09 -04:00
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_warp_pointer:
|
2014-05-27 14:03:09 -04:00
|
|
|
* @pointer_device: the pointer device to warp
|
|
|
|
* @time: the timestamp for the warp event
|
|
|
|
* @x: the new X position of the pointer
|
|
|
|
* @y: the new Y position of the pointer
|
|
|
|
*
|
|
|
|
* Warps the pointer to a new location. Technically, this is
|
|
|
|
* processed the same way as an absolute motion event from
|
|
|
|
* libinput: it simply generates an absolute motion event that
|
|
|
|
* will be processed on the next iteration of the mainloop.
|
|
|
|
*
|
|
|
|
* The intended use for this is for display servers that need
|
|
|
|
* to warp cursor the cursor to a new location.
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
* Stability: unstable
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_warp_pointer (ClutterInputDevice *pointer_device,
|
2019-08-16 13:33:43 -04:00
|
|
|
uint32_t time_,
|
2019-03-29 17:03:27 -04:00
|
|
|
int x,
|
|
|
|
int y)
|
2014-05-27 14:03:09 -04:00
|
|
|
{
|
2015-01-09 11:10:11 -05:00
|
|
|
notify_absolute_motion (pointer_device, ms2us(time_), x, y, NULL);
|
2014-05-27 14:03:09 -04:00
|
|
|
}
|
2017-02-02 13:01:25 -05:00
|
|
|
|
|
|
|
/**
|
2019-03-29 17:03:27 -04:00
|
|
|
* meta_device_manager_native_set_seat_id:
|
2017-02-02 13:01:25 -05:00
|
|
|
* @seat_id: The seat ID
|
|
|
|
*
|
|
|
|
* Sets the seat to assign to the libinput context.
|
|
|
|
*
|
|
|
|
* For reliable effects, this function must be called before clutter_init().
|
|
|
|
*/
|
|
|
|
void
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_set_seat_id (const gchar *seat_id)
|
2017-02-02 13:01:25 -05:00
|
|
|
{
|
|
|
|
g_free (evdev_seat_id);
|
|
|
|
evdev_seat_id = g_strdup (seat_id);
|
|
|
|
}
|
2019-01-10 10:13:20 -05:00
|
|
|
|
|
|
|
struct xkb_state *
|
2019-03-29 17:03:27 -04:00
|
|
|
meta_device_manager_native_get_xkb_state (MetaDeviceManagerNative *manager_evdev)
|
2019-01-10 10:13:20 -05:00
|
|
|
{
|
|
|
|
return manager_evdev->priv->main_seat->xkb;
|
|
|
|
}
|