Compare commits
	
		
			15 Commits
		
	
	
		
			3.22.1
			...
			wip/garnac
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7e3f96d972 | ||
| 
						 | 
					5f91d34f88 | ||
| 
						 | 
					d0a708b42c | ||
| 
						 | 
					d940d5e581 | ||
| 
						 | 
					70f69e5de4 | ||
| 
						 | 
					c2ce0e6795 | ||
| 
						 | 
					adbd566f83 | ||
| 
						 | 
					f511f65a14 | ||
| 
						 | 
					0942d68f1a | ||
| 
						 | 
					73d5d837db | ||
| 
						 | 
					ea5b691ac6 | ||
| 
						 | 
					53d1b11386 | ||
| 
						 | 
					85e8feca67 | ||
| 
						 | 
					fb47374629 | ||
| 
						 | 
					9a92d5fe89 | 
@@ -123,6 +123,7 @@ source_h =					\
 | 
			
		||||
	clutter-transition.h		\
 | 
			
		||||
	clutter-types.h		\
 | 
			
		||||
	clutter-units.h 		\
 | 
			
		||||
	clutter-virtual-input-device.h	\
 | 
			
		||||
	clutter-zoom-action.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
@@ -168,6 +169,7 @@ source_c = \
 | 
			
		||||
	clutter-image.c		\
 | 
			
		||||
	clutter-input-device.c	\
 | 
			
		||||
	clutter-input-device-tool.c	\
 | 
			
		||||
	clutter-virtual-input-device.c	\
 | 
			
		||||
	clutter-interval.c            \
 | 
			
		||||
	clutter-keyframe-transition.c	\
 | 
			
		||||
	clutter-keysyms-table.c	\
 | 
			
		||||
@@ -418,6 +420,14 @@ x11_source_h_priv += \
 | 
			
		||||
	x11/clutter-input-device-xi2.h	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
x11_source_c += \
 | 
			
		||||
	x11/clutter-virtual-input-device-x11.c	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
x11_source_h_priv += \
 | 
			
		||||
	x11/clutter-virtual-input-device-x11.h	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
backend_source_h += $(x11_source_h)
 | 
			
		||||
backend_source_c += $(x11_source_c)
 | 
			
		||||
backend_source_h_priv += $(x11_source_h_priv)
 | 
			
		||||
@@ -458,13 +468,17 @@ backend_source_c += $(glx_source_c)
 | 
			
		||||
evdev_c_priv = \
 | 
			
		||||
	evdev/clutter-device-manager-evdev.c	\
 | 
			
		||||
	evdev/clutter-input-device-evdev.c	\
 | 
			
		||||
	evdev/clutter-seat-evdev.c		\
 | 
			
		||||
	evdev/clutter-virtual-input-device-evdev.c	\
 | 
			
		||||
	evdev/clutter-event-evdev.c		\
 | 
			
		||||
	evdev/clutter-input-device-tool-evdev.c	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
evdev_h_priv = \
 | 
			
		||||
	evdev/clutter-device-manager-evdev.h	\
 | 
			
		||||
	evdev/clutter-input-device-evdev.h	\
 | 
			
		||||
	evdev/clutter-seat-evdev.h		\
 | 
			
		||||
	evdev/clutter-input-device-tool-evdev.h	\
 | 
			
		||||
	evdev/clutter-virtual-input-device-evdev.h	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
evdev_h = evdev/clutter-evdev.h
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@
 | 
			
		||||
#include "clutter-marshal.h"
 | 
			
		||||
#include "clutter-private.h"
 | 
			
		||||
#include "clutter-stage-private.h"
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
 | 
			
		||||
struct _ClutterDeviceManagerPrivate
 | 
			
		||||
{
 | 
			
		||||
@@ -435,3 +436,25 @@ _clutter_device_manager_get_backend (ClutterDeviceManager *manager)
 | 
			
		||||
 | 
			
		||||
  return manager->priv->backend;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_device_manager_create_virtual_device:
 | 
			
		||||
 * @device_manager: a #ClutterDeviceManager
 | 
			
		||||
 * @device_type: the type of the virtual device
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a virtual input device.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): a newly created virtual device
 | 
			
		||||
 **/
 | 
			
		||||
ClutterVirtualInputDevice *
 | 
			
		||||
clutter_device_manager_create_virtual_device (ClutterDeviceManager   *device_manager,
 | 
			
		||||
                                              ClutterInputDeviceType  device_type)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManagerClass *manager_class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
 | 
			
		||||
 | 
			
		||||
  manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
 | 
			
		||||
  return manager_class->create_virtual_device (device_manager,
 | 
			
		||||
                                               device_type);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -83,6 +83,8 @@ struct _ClutterDeviceManagerClass
 | 
			
		||||
                                           ClutterInputDevice     *device);
 | 
			
		||||
  void                (* select_stage_events) (ClutterDeviceManager *manager,
 | 
			
		||||
                                               ClutterStage       *stage);
 | 
			
		||||
  ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager  *manager,
 | 
			
		||||
                                                        ClutterInputDeviceType device_type);
 | 
			
		||||
 | 
			
		||||
  /* padding */
 | 
			
		||||
  gpointer _padding[7];
 | 
			
		||||
@@ -105,6 +107,10 @@ CLUTTER_AVAILABLE_IN_1_2
 | 
			
		||||
ClutterInputDevice *  clutter_device_manager_get_core_device (ClutterDeviceManager   *device_manager,
 | 
			
		||||
                                                              ClutterInputDeviceType  device_type);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
ClutterVirtualInputDevice *clutter_device_manager_create_virtual_device (ClutterDeviceManager  *device_manager,
 | 
			
		||||
                                                                         ClutterInputDeviceType device_type);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,7 @@ typedef struct _ClutterState            	ClutterState;
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterInputDeviceTool          ClutterInputDeviceTool;
 | 
			
		||||
typedef struct _ClutterInputDevice              ClutterInputDevice;
 | 
			
		||||
typedef struct _ClutterVirtualInputDevice       ClutterVirtualInputDevice;
 | 
			
		||||
 | 
			
		||||
typedef CoglMatrix                              ClutterMatrix;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										222
									
								
								clutter/clutter/clutter-virtual-input-device.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								clutter/clutter/clutter-virtual-input-device.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,222 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-device-manager.h"
 | 
			
		||||
#include "clutter-private.h"
 | 
			
		||||
#include "clutter-enum-types.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_DEVICE_MANAGER,
 | 
			
		||||
  PROP_DEVICE_TYPE,
 | 
			
		||||
 | 
			
		||||
  PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GParamSpec *obj_props[PROP_LAST];
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterVirtualInputDevicePrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManager *manager;
 | 
			
		||||
  ClutterInputDeviceType device_type;
 | 
			
		||||
} ClutterVirtualInputDevicePrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterVirtualInputDevice,
 | 
			
		||||
                            clutter_virtual_input_device,
 | 
			
		||||
                            G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_virtual_input_device_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                     uint64_t                   time_us,
 | 
			
		||||
                                                     double                     dx,
 | 
			
		||||
                                                     double                     dy)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *klass =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
 | 
			
		||||
 | 
			
		||||
  klass->notify_relative_motion (virtual_device, time_us, dx, dy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_virtual_input_device_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                     uint64_t                   time_us,
 | 
			
		||||
                                                     double                     x,
 | 
			
		||||
                                                     double                     y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *klass =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
 | 
			
		||||
 | 
			
		||||
  klass->notify_absolute_motion (virtual_device, time_us, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_virtual_input_device_notify_button (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                            uint64_t                   time_us,
 | 
			
		||||
                                            uint32_t                   button,
 | 
			
		||||
                                            ClutterButtonState         button_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *klass =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
 | 
			
		||||
 | 
			
		||||
  klass->notify_button (virtual_device, time_us, button, button_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_virtual_input_device_notify_key (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                         uint64_t                   time_us,
 | 
			
		||||
                                         uint32_t                   key,
 | 
			
		||||
                                         ClutterKeyState            key_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *klass =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
 | 
			
		||||
 | 
			
		||||
  klass->notify_key (virtual_device, time_us, key, key_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                            uint64_t                   time_us,
 | 
			
		||||
                                            uint32_t                   keyval,
 | 
			
		||||
                                            ClutterKeyState            key_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *klass =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
 | 
			
		||||
 | 
			
		||||
  klass->notify_keyval (virtual_device, time_us, keyval, key_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_virtual_input_device_get_manager:
 | 
			
		||||
 * @virtual_device: a virtual device
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the device manager of this virtual device.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): The #ClutterDeviceManager of this virtual device
 | 
			
		||||
 **/
 | 
			
		||||
ClutterDeviceManager *
 | 
			
		||||
clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevicePrivate *priv =
 | 
			
		||||
    clutter_virtual_input_device_get_instance_private (virtual_device);
 | 
			
		||||
 | 
			
		||||
  return priv->manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevicePrivate *priv =
 | 
			
		||||
    clutter_virtual_input_device_get_instance_private (virtual_device);
 | 
			
		||||
 | 
			
		||||
  return priv->device_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_get_property (GObject    *object,
 | 
			
		||||
                                           guint       prop_id,
 | 
			
		||||
                                           GValue     *value,
 | 
			
		||||
                                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice *virtual_device =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE (object);
 | 
			
		||||
  ClutterVirtualInputDevicePrivate *priv =
 | 
			
		||||
    clutter_virtual_input_device_get_instance_private (virtual_device);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_DEVICE_MANAGER:
 | 
			
		||||
      g_value_set_object (value, priv->manager);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DEVICE_TYPE:
 | 
			
		||||
      g_value_set_enum (value, priv->device_type);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_set_property (GObject      *object,
 | 
			
		||||
                                           guint         prop_id,
 | 
			
		||||
                                           const GValue *value,
 | 
			
		||||
                                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice *virtual_device =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE (object);
 | 
			
		||||
  ClutterVirtualInputDevicePrivate *priv =
 | 
			
		||||
    clutter_virtual_input_device_get_instance_private (virtual_device);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_DEVICE_MANAGER:
 | 
			
		||||
      priv->manager = g_value_get_object (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DEVICE_TYPE:
 | 
			
		||||
      priv->device_type = g_value_get_enum (value);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_init (ClutterVirtualInputDevice *virtual_device)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_class_init (ClutterVirtualInputDeviceClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = clutter_virtual_input_device_get_property;
 | 
			
		||||
  object_class->set_property = clutter_virtual_input_device_set_property;
 | 
			
		||||
 | 
			
		||||
  obj_props[PROP_DEVICE_MANAGER] =
 | 
			
		||||
    g_param_spec_object ("device-manager",
 | 
			
		||||
                         P_("Device Manager"),
 | 
			
		||||
                         P_("The device manager instance"),
 | 
			
		||||
                         CLUTTER_TYPE_DEVICE_MANAGER,
 | 
			
		||||
                         CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
  obj_props[PROP_DEVICE_TYPE] =
 | 
			
		||||
    g_param_spec_enum ("device-type",
 | 
			
		||||
                       P_("Device type"),
 | 
			
		||||
                       P_("Device type"),
 | 
			
		||||
                       CLUTTER_TYPE_INPUT_DEVICE_TYPE,
 | 
			
		||||
                       CLUTTER_POINTER_DEVICE,
 | 
			
		||||
                       CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								clutter/clutter/clutter-virtual-input-device.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								clutter/clutter/clutter-virtual-input-device.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_H__
 | 
			
		||||
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-device-manager.h"
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE (clutter_virtual_input_device_get_type ())
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (ClutterVirtualInputDevice,
 | 
			
		||||
                          clutter_virtual_input_device,
 | 
			
		||||
                          CLUTTER, VIRTUAL_INPUT_DEVICE,
 | 
			
		||||
                          GObject)
 | 
			
		||||
 | 
			
		||||
typedef enum _ClutterButtonState
 | 
			
		||||
{
 | 
			
		||||
  CLUTTER_BUTTON_STATE_RELEASED,
 | 
			
		||||
  CLUTTER_BUTTON_STATE_PRESSED
 | 
			
		||||
} ClutterButtonState;
 | 
			
		||||
 | 
			
		||||
typedef enum _ClutterKeyState
 | 
			
		||||
{
 | 
			
		||||
  CLUTTER_KEY_STATE_RELEASED,
 | 
			
		||||
  CLUTTER_KEY_STATE_PRESSED
 | 
			
		||||
} ClutterKeyState;
 | 
			
		||||
 | 
			
		||||
struct _ClutterVirtualInputDeviceClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (*notify_relative_motion) (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                  uint64_t                   time_us,
 | 
			
		||||
                                  double                     dx,
 | 
			
		||||
                                  double                     dy);
 | 
			
		||||
 | 
			
		||||
  void (*notify_absolute_motion) (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                  uint64_t                   time_us,
 | 
			
		||||
                                  double                     x,
 | 
			
		||||
                                  double                     y);
 | 
			
		||||
 | 
			
		||||
  void (*notify_button) (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                         uint64_t                   time_us,
 | 
			
		||||
                         uint32_t                   button,
 | 
			
		||||
                         ClutterButtonState         button_state);
 | 
			
		||||
 | 
			
		||||
  void (*notify_key) (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                      uint64_t                   time_us,
 | 
			
		||||
                      uint32_t                   key,
 | 
			
		||||
                      ClutterKeyState            key_state);
 | 
			
		||||
  void (*notify_keyval) (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                         uint64_t                   time_us,
 | 
			
		||||
                         uint32_t                   keyval,
 | 
			
		||||
                         ClutterKeyState            key_state);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
void clutter_virtual_input_device_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                          uint64_t                   time_us,
 | 
			
		||||
                                                          double                     dx,
 | 
			
		||||
                                                          double                     dy);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
void clutter_virtual_input_device_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                          uint64_t                   time_us,
 | 
			
		||||
                                                          double                     x,
 | 
			
		||||
                                                          double                     y);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
void clutter_virtual_input_device_notify_button (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                 uint64_t                   time_us,
 | 
			
		||||
                                                 uint32_t                   button,
 | 
			
		||||
                                                 ClutterButtonState         button_state);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
void clutter_virtual_input_device_notify_key (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                              uint64_t                   time_us,
 | 
			
		||||
                                              uint32_t                   key,
 | 
			
		||||
                                              ClutterKeyState            key_state);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
void clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                 uint64_t                   time_us,
 | 
			
		||||
                                                 uint32_t                   keyval,
 | 
			
		||||
                                                 ClutterKeyState            key_state);
 | 
			
		||||
 | 
			
		||||
CLUTTER_AVAILABLE_IN_ALL
 | 
			
		||||
ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device);
 | 
			
		||||
 | 
			
		||||
int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device);
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_H__ */
 | 
			
		||||
@@ -107,6 +107,7 @@
 | 
			
		||||
#include "clutter-transition.h"
 | 
			
		||||
#include "clutter-units.h"
 | 
			
		||||
#include "clutter-version.h"
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
#include "clutter-zoom-action.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-deprecated.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,8 @@
 | 
			
		||||
#include "clutter-device-manager-private.h"
 | 
			
		||||
#include "clutter-event-private.h"
 | 
			
		||||
#include "clutter-input-device-evdev.h"
 | 
			
		||||
#include "clutter-seat-evdev.h"
 | 
			
		||||
#include "clutter-virtual-input-device-evdev.h"
 | 
			
		||||
#include "clutter-main.h"
 | 
			
		||||
#include "clutter-private.h"
 | 
			
		||||
#include "clutter-stage-manager.h"
 | 
			
		||||
@@ -59,12 +61,6 @@
 | 
			
		||||
 | 
			
		||||
#define DISCRETE_SCROLL_STEP 10.0
 | 
			
		||||
 | 
			
		||||
#define AUTOREPEAT_VALUE 2
 | 
			
		||||
 | 
			
		||||
/* Try to keep the pointer inside the stage. Hopefully no one is using
 | 
			
		||||
 * this backend with stages smaller than this. */
 | 
			
		||||
#define INITIAL_POINTER_X 16
 | 
			
		||||
#define INITIAL_POINTER_Y 16
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter makes the assumption that two core devices have ID's 2 and 3 (core
 | 
			
		||||
@@ -76,50 +72,8 @@
 | 
			
		||||
 */
 | 
			
		||||
#define INITIAL_DEVICE_ID 2
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterTouchState ClutterTouchState;
 | 
			
		||||
typedef struct _ClutterEventFilter ClutterEventFilter;
 | 
			
		||||
 | 
			
		||||
struct _ClutterTouchState
 | 
			
		||||
{
 | 
			
		||||
  guint32 id;
 | 
			
		||||
  ClutterPoint coords;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ClutterSeatEvdev
 | 
			
		||||
{
 | 
			
		||||
  struct libinput_seat *libinput_seat;
 | 
			
		||||
  ClutterDeviceManagerEvdev *manager_evdev;
 | 
			
		||||
 | 
			
		||||
  GSList *devices;
 | 
			
		||||
 | 
			
		||||
  ClutterInputDevice *core_pointer;
 | 
			
		||||
  ClutterInputDevice *core_keyboard;
 | 
			
		||||
 | 
			
		||||
  GHashTable *touches;
 | 
			
		||||
 | 
			
		||||
  struct xkb_state *xkb;
 | 
			
		||||
  xkb_led_index_t caps_lock_led;
 | 
			
		||||
  xkb_led_index_t num_lock_led;
 | 
			
		||||
  xkb_led_index_t scroll_lock_led;
 | 
			
		||||
  uint32_t button_state;
 | 
			
		||||
 | 
			
		||||
  /* keyboard repeat */
 | 
			
		||||
  gboolean repeat;
 | 
			
		||||
  guint32 repeat_delay;
 | 
			
		||||
  guint32 repeat_interval;
 | 
			
		||||
  guint32 repeat_key;
 | 
			
		||||
  guint32 repeat_count;
 | 
			
		||||
  guint32 repeat_timer;
 | 
			
		||||
  ClutterInputDevice *repeat_device;
 | 
			
		||||
 | 
			
		||||
  gfloat pointer_x;
 | 
			
		||||
  gfloat pointer_y;
 | 
			
		||||
 | 
			
		||||
  /* Emulation of discrete scroll events out of smooth ones */
 | 
			
		||||
  gfloat accum_scroll_dx;
 | 
			
		||||
  gfloat accum_scroll_dy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ClutterEventFilter
 | 
			
		||||
{
 | 
			
		||||
  ClutterEvdevFilterFunc func;
 | 
			
		||||
@@ -198,24 +152,6 @@ static const char *option_xkb_layout = "us";
 | 
			
		||||
static const char *option_xkb_variant = "";
 | 
			
		||||
static const char *option_xkb_options = "";
 | 
			
		||||
 | 
			
		||||
static inline guint64
 | 
			
		||||
us (guint64 us)
 | 
			
		||||
{
 | 
			
		||||
  return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline guint64
 | 
			
		||||
ms2us (guint64 ms)
 | 
			
		||||
{
 | 
			
		||||
  return us (ms * 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline guint32
 | 
			
		||||
us2ms (guint64 us)
 | 
			
		||||
{
 | 
			
		||||
  return (guint32) (us / 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender,
 | 
			
		||||
                                              const ClutterEvent   *src,
 | 
			
		||||
@@ -299,134 +235,34 @@ queue_event (ClutterEvent *event)
 | 
			
		||||
  _clutter_event_push (event, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clear_repeat_timer (ClutterSeatEvdev *seat)
 | 
			
		||||
void
 | 
			
		||||
_clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                                                 ClutterInputDevice        *core_pointer,
 | 
			
		||||
                                                 uint64_t                   time_us,
 | 
			
		||||
                                                 float                      x,
 | 
			
		||||
                                                 float                      y,
 | 
			
		||||
                                                 float                     *new_x,
 | 
			
		||||
                                                 float                     *new_y)
 | 
			
		||||
{
 | 
			
		||||
  if (seat->repeat_timer)
 | 
			
		||||
  if (manager_evdev->priv->constrain_callback)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (seat->repeat_timer);
 | 
			
		||||
      seat->repeat_timer = 0;
 | 
			
		||||
      g_clear_object (&seat->repeat_device);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
keyboard_repeat (gpointer data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notify_key_device (ClutterInputDevice *input_device,
 | 
			
		||||
		   guint64             time_us,
 | 
			
		||||
		   guint32             key,
 | 
			
		||||
		   guint32             state,
 | 
			
		||||
		   gboolean            update_keys)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
    CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
  ClutterEvent *event = NULL;
 | 
			
		||||
  enum xkb_state_component changed_state;
 | 
			
		||||
 | 
			
		||||
  /* 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)
 | 
			
		||||
    {
 | 
			
		||||
      clear_repeat_timer (seat);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  event = _clutter_key_event_new_from_evdev (input_device,
 | 
			
		||||
					     seat->core_keyboard,
 | 
			
		||||
					     stage,
 | 
			
		||||
					     seat->xkb,
 | 
			
		||||
					     seat->button_state,
 | 
			
		||||
					     us2ms (time_us), key, state);
 | 
			
		||||
  _clutter_evdev_event_set_event_code (event, key);
 | 
			
		||||
 | 
			
		||||
  /* We must be careful and not pass multiple releases to xkb, otherwise it gets
 | 
			
		||||
     confused and locks the modifiers */
 | 
			
		||||
  if (state != AUTOREPEAT_VALUE)
 | 
			
		||||
    {
 | 
			
		||||
      changed_state = xkb_state_update_key (seat->xkb,
 | 
			
		||||
                                            event->key.hardware_keycode,
 | 
			
		||||
                                            state ? XKB_KEY_DOWN : XKB_KEY_UP);
 | 
			
		||||
      manager_evdev->priv->constrain_callback (core_pointer,
 | 
			
		||||
                                               us2ms (time_us),
 | 
			
		||||
                                               x, y,
 | 
			
		||||
                                               new_x, new_y,
 | 
			
		||||
					       manager_evdev->priv->constrain_data);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      changed_state = 0;
 | 
			
		||||
      clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
 | 
			
		||||
    }
 | 
			
		||||
      ClutterActor *stage = CLUTTER_ACTOR (manager_evdev->priv->stage);
 | 
			
		||||
      float stage_width = clutter_actor_get_width (stage);
 | 
			
		||||
      float stage_height = clutter_actor_get_height (stage);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
 | 
			
		||||
  if (update_keys && (changed_state & XKB_STATE_LEDS))
 | 
			
		||||
    clutter_seat_evdev_sync_leds (seat);
 | 
			
		||||
 | 
			
		||||
  if (state == 0 ||             /* key release */
 | 
			
		||||
      !seat->repeat ||
 | 
			
		||||
      !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), event->key.hardware_keycode))
 | 
			
		||||
    {
 | 
			
		||||
      clear_repeat_timer (seat);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (state == 1)               /* key press */
 | 
			
		||||
    seat->repeat_count = 0;
 | 
			
		||||
 | 
			
		||||
  seat->repeat_count += 1;
 | 
			
		||||
  seat->repeat_key = key;
 | 
			
		||||
 | 
			
		||||
  switch (seat->repeat_count)
 | 
			
		||||
    {
 | 
			
		||||
    case 1:
 | 
			
		||||
    case 2:
 | 
			
		||||
      {
 | 
			
		||||
        guint32 interval;
 | 
			
		||||
 | 
			
		||||
        clear_repeat_timer (seat);
 | 
			
		||||
        seat->repeat_device = g_object_ref (input_device);
 | 
			
		||||
 | 
			
		||||
        if (seat->repeat_count == 1)
 | 
			
		||||
          interval = seat->repeat_delay;
 | 
			
		||||
        else
 | 
			
		||||
          interval = seat->repeat_interval;
 | 
			
		||||
 | 
			
		||||
        seat->repeat_timer =
 | 
			
		||||
          clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
 | 
			
		||||
                                            interval,
 | 
			
		||||
                                            keyboard_repeat,
 | 
			
		||||
                                            seat,
 | 
			
		||||
                                            NULL);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    default:
 | 
			
		||||
      return;
 | 
			
		||||
      x = CLAMP (x, 0.f, stage_width - 1);
 | 
			
		||||
      y = CLAMP (y, 0.f, stage_height - 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
keyboard_repeat (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterSeatEvdev *seat = data;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  guint32 time_ms;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
 | 
			
		||||
  source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
 | 
			
		||||
  time_ms = g_source_get_time (source) / 1000;
 | 
			
		||||
 | 
			
		||||
  notify_key_device (seat->repeat_device,
 | 
			
		||||
                     ms2us (time_ms),
 | 
			
		||||
                     seat->repeat_key,
 | 
			
		||||
                     AUTOREPEAT_VALUE,
 | 
			
		||||
                     FALSE);
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_CONTINUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterEvent *
 | 
			
		||||
new_absolute_motion_event (ClutterInputDevice *input_device,
 | 
			
		||||
@@ -511,45 +347,6 @@ notify_absolute_motion (ClutterInputDevice *input_device,
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notify_relative_motion (ClutterInputDevice *input_device,
 | 
			
		||||
                        struct libinput_event_pointer *pointer_event)
 | 
			
		||||
{
 | 
			
		||||
  guint64 time_us;
 | 
			
		||||
  double dx;
 | 
			
		||||
  double dy;
 | 
			
		||||
  double dx_unaccel;
 | 
			
		||||
  double dy_unaccel;
 | 
			
		||||
  gfloat new_x, new_y;
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev;
 | 
			
		||||
  ClutterSeatEvdev *seat;
 | 
			
		||||
  ClutterEvent *event;
 | 
			
		||||
 | 
			
		||||
  /* We can drop the event on the floor if no stage has been
 | 
			
		||||
   * associated with the device yet. */
 | 
			
		||||
  if (!_clutter_input_device_get_stage (input_device))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
 | 
			
		||||
  dx = libinput_event_pointer_get_dx (pointer_event);
 | 
			
		||||
  dy = libinput_event_pointer_get_dy (pointer_event);
 | 
			
		||||
  new_x = seat->pointer_x + dx;
 | 
			
		||||
  new_y = seat->pointer_y + dy;
 | 
			
		||||
 | 
			
		||||
  time_us = libinput_event_pointer_get_time_usec (pointer_event);
 | 
			
		||||
  event = new_absolute_motion_event (input_device, time_us, new_x, new_y, NULL);
 | 
			
		||||
 | 
			
		||||
  dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event);
 | 
			
		||||
  dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event);
 | 
			
		||||
  _clutter_evdev_event_set_relative_motion (event,
 | 
			
		||||
                                            dx, dy,
 | 
			
		||||
                                            dx_unaccel, dy_unaccel);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notify_relative_tool_motion (ClutterInputDevice *input_device,
 | 
			
		||||
                             guint64             time_us,
 | 
			
		||||
@@ -682,118 +479,6 @@ notify_scroll (ClutterInputDevice       *input_device,
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notify_button (ClutterInputDevice *input_device,
 | 
			
		||||
               guint64             time_us,
 | 
			
		||||
               guint32             button,
 | 
			
		||||
               guint32             state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev;
 | 
			
		||||
  ClutterSeatEvdev *seat;
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
  ClutterEvent *event = NULL;
 | 
			
		||||
  gint button_nr;
 | 
			
		||||
  static gint maskmap[8] =
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
 | 
			
		||||
      CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  /* We can drop the event on the floor if no stage has been
 | 
			
		||||
   * associated with the device yet. */
 | 
			
		||||
  stage = _clutter_input_device_get_stage (input_device);
 | 
			
		||||
  if (stage == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
 | 
			
		||||
  /* The evdev button numbers don't map sequentially to clutter button
 | 
			
		||||
   * numbers (the right and middle mouse buttons are in the opposite
 | 
			
		||||
   * order) so we'll map them directly with a switch statement */
 | 
			
		||||
  switch (button)
 | 
			
		||||
    {
 | 
			
		||||
    case BTN_LEFT:
 | 
			
		||||
    case BTN_TOUCH:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_PRIMARY;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case BTN_RIGHT:
 | 
			
		||||
    case BTN_STYLUS:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_SECONDARY;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case BTN_MIDDLE:
 | 
			
		||||
    case BTN_STYLUS2:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_MIDDLE;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
 | 
			
		||||
      if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
        button_nr = button - BTN_TOOL_PEN + 4;
 | 
			
		||||
      else
 | 
			
		||||
        button_nr = button - (BTN_LEFT - 1) + 4;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (button_nr < 1 || button_nr > 12)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unhandled button event 0x%x", button);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (state)
 | 
			
		||||
    event = clutter_event_new (CLUTTER_BUTTON_PRESS);
 | 
			
		||||
  else
 | 
			
		||||
    event = clutter_event_new (CLUTTER_BUTTON_RELEASE);
 | 
			
		||||
 | 
			
		||||
  if (button_nr < G_N_ELEMENTS (maskmap))
 | 
			
		||||
    {
 | 
			
		||||
      /* Update the modifiers */
 | 
			
		||||
      if (state)
 | 
			
		||||
        seat->button_state |= maskmap[button_nr - 1];
 | 
			
		||||
      else
 | 
			
		||||
        seat->button_state &= ~maskmap[button_nr - 1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_time_usec (event, time_us);
 | 
			
		||||
  event->button.time = us2ms (time_us);
 | 
			
		||||
  event->button.stage = CLUTTER_STAGE (stage);
 | 
			
		||||
  _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
 | 
			
		||||
  event->button.button = button_nr;
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterPoint point;
 | 
			
		||||
 | 
			
		||||
      clutter_input_device_get_coords (input_device, NULL, &point);
 | 
			
		||||
      event->button.x = point.x;
 | 
			
		||||
      event->button.y = point.y;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      event->button.x = seat->pointer_x;
 | 
			
		||||
      event->button.y = seat->pointer_y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_event_set_source_device (event, input_device);
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_event_code (event, button);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_event_set_device_tool (event, device_evdev->last_tool);
 | 
			
		||||
      clutter_event_set_device (event, input_device);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    clutter_event_set_device (event, seat->core_pointer);
 | 
			
		||||
 | 
			
		||||
  _clutter_input_device_set_stage (seat->core_pointer, stage);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
notify_touch_event (ClutterInputDevice *input_device,
 | 
			
		||||
		    ClutterEventType    evtype,
 | 
			
		||||
@@ -1205,128 +890,6 @@ clutter_event_source_free (ClutterEventSource *source)
 | 
			
		||||
  g_source_unref (g_source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_touch_state_free (ClutterTouchState *touch_state)
 | 
			
		||||
{
 | 
			
		||||
  g_slice_free (ClutterTouchState, touch_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
 | 
			
		||||
                                      struct libinput_seat *libinput_seat)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (seat->libinput_seat == NULL);
 | 
			
		||||
 | 
			
		||||
  libinput_seat_ref (libinput_seat);
 | 
			
		||||
  libinput_seat_set_user_data (libinput_seat, seat);
 | 
			
		||||
  seat->libinput_seat = libinput_seat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterSeatEvdev *
 | 
			
		||||
clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
 | 
			
		||||
  ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
 | 
			
		||||
  ClutterSeatEvdev *seat;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  struct xkb_context *ctx;
 | 
			
		||||
  struct xkb_rule_names names;
 | 
			
		||||
  struct xkb_keymap *keymap;
 | 
			
		||||
 | 
			
		||||
  seat = g_new0 (ClutterSeatEvdev, 1);
 | 
			
		||||
  if (!seat)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  device = _clutter_input_device_evdev_new_virtual (
 | 
			
		||||
    manager, seat, CLUTTER_POINTER_DEVICE);
 | 
			
		||||
  _clutter_input_device_set_stage (device, priv->stage);
 | 
			
		||||
  seat->pointer_x = INITIAL_POINTER_X;
 | 
			
		||||
  seat->pointer_y = INITIAL_POINTER_Y;
 | 
			
		||||
  _clutter_input_device_set_coords (device, NULL,
 | 
			
		||||
                                    seat->pointer_x, seat->pointer_y,
 | 
			
		||||
                                    NULL);
 | 
			
		||||
  _clutter_device_manager_add_device (manager, device);
 | 
			
		||||
  seat->core_pointer = device;
 | 
			
		||||
 | 
			
		||||
  device = _clutter_input_device_evdev_new_virtual (
 | 
			
		||||
    manager, seat, CLUTTER_KEYBOARD_DEVICE);
 | 
			
		||||
  _clutter_input_device_set_stage (device, priv->stage);
 | 
			
		||||
  _clutter_device_manager_add_device (manager, device);
 | 
			
		||||
  seat->core_keyboard = device;
 | 
			
		||||
 | 
			
		||||
  seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
 | 
			
		||||
                                         (GDestroyNotify) clutter_touch_state_free);
 | 
			
		||||
 | 
			
		||||
  ctx = xkb_context_new(0);
 | 
			
		||||
  g_assert (ctx);
 | 
			
		||||
 | 
			
		||||
  names.rules = "evdev";
 | 
			
		||||
  names.model = "pc105";
 | 
			
		||||
  names.layout = option_xkb_layout;
 | 
			
		||||
  names.variant = option_xkb_variant;
 | 
			
		||||
  names.options = option_xkb_options;
 | 
			
		||||
 | 
			
		||||
  keymap = xkb_keymap_new_from_names (ctx, &names, 0);
 | 
			
		||||
  xkb_context_unref(ctx);
 | 
			
		||||
  if (keymap)
 | 
			
		||||
    {
 | 
			
		||||
      seat->xkb = xkb_state_new (keymap);
 | 
			
		||||
 | 
			
		||||
      seat->caps_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS);
 | 
			
		||||
      seat->num_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM);
 | 
			
		||||
      seat->scroll_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL);
 | 
			
		||||
 | 
			
		||||
      priv->keymap = keymap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  seat->repeat = TRUE;
 | 
			
		||||
  seat->repeat_delay = 250;     /* ms */
 | 
			
		||||
  seat->repeat_interval = 33;   /* ms */
 | 
			
		||||
 | 
			
		||||
  priv->seats = g_slist_append (priv->seats, seat);
 | 
			
		||||
  return seat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
 | 
			
		||||
{
 | 
			
		||||
  GSList *iter;
 | 
			
		||||
 | 
			
		||||
  for (iter = seat->devices; iter; iter = g_slist_next (iter))
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = iter->data;
 | 
			
		||||
 | 
			
		||||
      g_object_unref (device);
 | 
			
		||||
    }
 | 
			
		||||
  g_slist_free (seat->devices);
 | 
			
		||||
  g_hash_table_unref (seat->touches);
 | 
			
		||||
 | 
			
		||||
  xkb_state_unref (seat->xkb);
 | 
			
		||||
 | 
			
		||||
  clear_repeat_timer (seat);
 | 
			
		||||
 | 
			
		||||
  if (seat->libinput_seat)
 | 
			
		||||
    libinput_seat_unref (seat->libinput_seat);
 | 
			
		||||
 | 
			
		||||
  g_free (seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat, ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  GSList *l;
 | 
			
		||||
 | 
			
		||||
  for (l = seat->devices; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = l->data;
 | 
			
		||||
 | 
			
		||||
      _clutter_input_device_set_stage (device, stage);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                  struct libinput_device    *libinput_device)
 | 
			
		||||
@@ -1346,11 +909,16 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
       * 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;
 | 
			
		||||
        {
 | 
			
		||||
          seat = priv->main_seat;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        seat = clutter_seat_evdev_new (manager_evdev);
 | 
			
		||||
        {
 | 
			
		||||
          seat = clutter_seat_evdev_new (manager_evdev);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      clutter_seat_evdev_set_libinput_seat (seat, libinput_seat);
 | 
			
		||||
      priv->seats = g_slist_append (priv->seats, seat);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  device = _clutter_input_device_evdev_new (manager, seat, libinput_device);
 | 
			
		||||
@@ -1429,7 +997,7 @@ clutter_device_manager_evdev_remove_device (ClutterDeviceManager *manager,
 | 
			
		||||
  priv->devices = g_slist_remove (priv->devices, device);
 | 
			
		||||
 | 
			
		||||
  if (seat->repeat_timer && seat->repeat_device == device)
 | 
			
		||||
    clear_repeat_timer (seat);
 | 
			
		||||
    clutter_seat_evdev_clear_repeat_timer (seat);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (device);
 | 
			
		||||
}
 | 
			
		||||
@@ -1494,32 +1062,6 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat)
 | 
			
		||||
{
 | 
			
		||||
  GSList *iter;
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev;
 | 
			
		||||
  int caps_lock, num_lock, scroll_lock;
 | 
			
		||||
  enum libinput_led leds = 0;
 | 
			
		||||
 | 
			
		||||
  caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led);
 | 
			
		||||
  num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led);
 | 
			
		||||
  scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led);
 | 
			
		||||
 | 
			
		||||
  if (caps_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_CAPS_LOCK;
 | 
			
		||||
  if (num_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_NUM_LOCK;
 | 
			
		||||
  if (scroll_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_SCROLL_LOCK;
 | 
			
		||||
 | 
			
		||||
  for (iter = seat->devices; iter; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      device_evdev = iter->data;
 | 
			
		||||
      _clutter_input_device_evdev_update_leds (device_evdev, leds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
flush_event_queue (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -1568,45 +1110,6 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
  return handled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterTouchState *
 | 
			
		||||
_device_seat_add_touch (ClutterInputDevice *input_device,
 | 
			
		||||
                        guint32             id)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
    CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
  ClutterTouchState *touch;
 | 
			
		||||
 | 
			
		||||
  touch = g_slice_new0 (ClutterTouchState);
 | 
			
		||||
  touch->id = id;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
 | 
			
		||||
 | 
			
		||||
  return touch;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_device_seat_remove_touch (ClutterInputDevice *input_device,
 | 
			
		||||
                           guint32             id)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
    CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterTouchState *
 | 
			
		||||
_device_seat_get_touch (ClutterInputDevice *input_device,
 | 
			
		||||
                        guint32             id)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
    CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
  ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
 | 
			
		||||
  return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_notify_discrete_scroll (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                              ClutterInputDevice        *device,
 | 
			
		||||
@@ -1773,6 +1276,14 @@ translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event)
 | 
			
		||||
    return (gdouble *) g_array_free (axes, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterSeatEvdev *
 | 
			
		||||
seat_from_device (ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
 | 
			
		||||
 | 
			
		||||
  return _clutter_input_device_evdev_get_seat (device_evdev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                      struct libinput_event *event)
 | 
			
		||||
@@ -1789,8 +1300,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        struct libinput_event_keyboard *key_event =
 | 
			
		||||
          libinput_event_get_keyboard_event (event);
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        time_us = libinput_event_keyboard_get_time_usec (key_event);
 | 
			
		||||
        key = libinput_event_keyboard_get_key (key_event);
 | 
			
		||||
        key_state = libinput_event_keyboard_get_key_state (key_event) ==
 | 
			
		||||
@@ -1805,18 +1316,35 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
	     seat_key_count != 0))
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        notify_key_device (device, time_us, key, key_state, TRUE);
 | 
			
		||||
        clutter_seat_evdev_notify_key (seat_from_device (device),
 | 
			
		||||
                                       device,
 | 
			
		||||
                                       time_us, key, key_state, TRUE);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    case LIBINPUT_EVENT_POINTER_MOTION:
 | 
			
		||||
      {
 | 
			
		||||
        struct libinput_event_pointer *motion_event =
 | 
			
		||||
        struct libinput_event_pointer *pointer_event =
 | 
			
		||||
          libinput_event_get_pointer_event (event);
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        uint64_t time_us;
 | 
			
		||||
        double dx;
 | 
			
		||||
        double dy;
 | 
			
		||||
        double dx_unaccel;
 | 
			
		||||
        double dy_unaccel;
 | 
			
		||||
 | 
			
		||||
        notify_relative_motion (device, motion_event);
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_notify_relative_motion (seat_from_device (device),
 | 
			
		||||
                                                   device,
 | 
			
		||||
                                                   time_us,
 | 
			
		||||
                                                   dx, dy,
 | 
			
		||||
                                                   dx_unaccel, dy_unaccel);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
@@ -1843,7 +1371,12 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                                                               stage_width);
 | 
			
		||||
        y = libinput_event_pointer_get_absolute_y_transformed (motion_event,
 | 
			
		||||
                                                               stage_height);
 | 
			
		||||
        notify_absolute_motion (device, time_us, x, y, NULL);
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_notify_absolute_motion (seat_from_device (device),
 | 
			
		||||
                                                   device,
 | 
			
		||||
                                                   time_us,
 | 
			
		||||
                                                   x, y,
 | 
			
		||||
                                                   NULL);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
@@ -1870,8 +1403,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
             seat_button_count != 0))
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        notify_button (device, time_us, button, button_state);
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_notify_button (seat_from_device (device), device,
 | 
			
		||||
                                          time_us, button, button_state);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -1966,11 +1499,14 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        double x, y;
 | 
			
		||||
        gfloat stage_width, stage_height;
 | 
			
		||||
        ClutterSeatEvdev *seat;
 | 
			
		||||
        ClutterStage *stage;
 | 
			
		||||
        ClutterTouchState *touch_state;
 | 
			
		||||
        struct libinput_event_touch *touch_event =
 | 
			
		||||
          libinput_event_get_touch_event (event);
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
 | 
			
		||||
 | 
			
		||||
        stage = _clutter_input_device_get_stage (device);
 | 
			
		||||
        if (stage == NULL)
 | 
			
		||||
@@ -1986,7 +1522,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
        y = libinput_event_touch_get_y_transformed (touch_event,
 | 
			
		||||
                                                    stage_height);
 | 
			
		||||
 | 
			
		||||
        touch_state = _device_seat_add_touch (device, slot);
 | 
			
		||||
        touch_state = clutter_seat_evdev_add_touch (seat, slot);
 | 
			
		||||
        touch_state->coords.x = x;
 | 
			
		||||
        touch_state->coords.y = y;
 | 
			
		||||
 | 
			
		||||
@@ -1999,18 +1535,21 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
      {
 | 
			
		||||
        gint32 slot;
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        ClutterSeatEvdev *seat;
 | 
			
		||||
        ClutterTouchState *touch_state;
 | 
			
		||||
        struct libinput_event_touch *touch_event =
 | 
			
		||||
          libinput_event_get_touch_event (event);
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
 | 
			
		||||
 | 
			
		||||
        slot = libinput_event_touch_get_slot (touch_event);
 | 
			
		||||
        time_us = libinput_event_touch_get_time_usec (touch_event);
 | 
			
		||||
        touch_state = _device_seat_get_touch (device, slot);
 | 
			
		||||
        touch_state = clutter_seat_evdev_get_touch (seat, slot);
 | 
			
		||||
 | 
			
		||||
        notify_touch_event (device, CLUTTER_TOUCH_END, time_us, slot,
 | 
			
		||||
			    touch_state->coords.x, touch_state->coords.y);
 | 
			
		||||
        _device_seat_remove_touch (device, slot);
 | 
			
		||||
        clutter_seat_evdev_remove_touch (seat, slot);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
@@ -2021,11 +1560,14 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        double x, y;
 | 
			
		||||
        gfloat stage_width, stage_height;
 | 
			
		||||
        ClutterSeatEvdev *seat;
 | 
			
		||||
        ClutterStage *stage;
 | 
			
		||||
        ClutterTouchState *touch_state;
 | 
			
		||||
        struct libinput_event_touch *touch_event =
 | 
			
		||||
          libinput_event_get_touch_event (event);
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
 | 
			
		||||
 | 
			
		||||
        stage = _clutter_input_device_get_stage (device);
 | 
			
		||||
        if (stage == NULL)
 | 
			
		||||
@@ -2041,7 +1583,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
        y = libinput_event_touch_get_y_transformed (touch_event,
 | 
			
		||||
                                                    stage_height);
 | 
			
		||||
 | 
			
		||||
        touch_state = _device_seat_get_touch (device, slot);
 | 
			
		||||
        touch_state = clutter_seat_evdev_get_touch (seat, slot);
 | 
			
		||||
        touch_state->coords.x = x;
 | 
			
		||||
        touch_state->coords.y = y;
 | 
			
		||||
 | 
			
		||||
@@ -2215,34 +1757,38 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
      }
 | 
			
		||||
    case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
 | 
			
		||||
      {
 | 
			
		||||
        guint64 time;
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        guint32 button_state;
 | 
			
		||||
        struct libinput_event_tablet_tool *tablet_event =
 | 
			
		||||
          libinput_event_get_tablet_tool_event (event);
 | 
			
		||||
        guint tablet_button;
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        time = libinput_event_tablet_tool_get_time_usec (tablet_event);
 | 
			
		||||
        time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
 | 
			
		||||
        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;
 | 
			
		||||
        notify_button (device, time, tablet_button, button_state);
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_notify_button (seat_from_device (device), device,
 | 
			
		||||
                                          time_us, tablet_button, button_state);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    case LIBINPUT_EVENT_TABLET_TOOL_TIP:
 | 
			
		||||
      {
 | 
			
		||||
        guint64 time;
 | 
			
		||||
        guint64 time_us;
 | 
			
		||||
        guint32 button_state;
 | 
			
		||||
        struct libinput_event_tablet_tool *tablet_event =
 | 
			
		||||
          libinput_event_get_tablet_tool_event (event);
 | 
			
		||||
 | 
			
		||||
        device = libinput_device_get_user_data (libinput_device);
 | 
			
		||||
        time = libinput_event_tablet_tool_get_time_usec (tablet_event);
 | 
			
		||||
        time_us = libinput_event_tablet_tool_get_time_usec (tablet_event);
 | 
			
		||||
 | 
			
		||||
        button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) ==
 | 
			
		||||
                       LIBINPUT_TABLET_TOOL_TIP_DOWN;
 | 
			
		||||
        notify_button (device, time, BTN_TOUCH, button_state);
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_notify_button (seat_from_device (device), device,
 | 
			
		||||
                                          time_us, BTN_TOUCH, button_state);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
 | 
			
		||||
@@ -2413,6 +1959,21 @@ static const struct libinput_interface libinput_interface = {
 | 
			
		||||
  close_restricted
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ClutterVirtualInputDevice *
 | 
			
		||||
clutter_device_manager_evdev_create_virtual_device (ClutterDeviceManager  *manager,
 | 
			
		||||
                                                    ClutterInputDeviceType device_type)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManagerEvdev *manager_evdev =
 | 
			
		||||
    CLUTTER_DEVICE_MANAGER_EVDEV (manager);
 | 
			
		||||
  ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
 | 
			
		||||
 | 
			
		||||
  return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_EVDEV,
 | 
			
		||||
                       "device-manager", manager,
 | 
			
		||||
                       "seat", priv->main_seat,
 | 
			
		||||
                       "device-type", device_type,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * GObject implementation
 | 
			
		||||
 */
 | 
			
		||||
@@ -2424,6 +1985,8 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
 | 
			
		||||
  ClutterDeviceManagerEvdevPrivate *priv;
 | 
			
		||||
  ClutterEventSource *source;
 | 
			
		||||
  struct udev *udev;
 | 
			
		||||
  struct xkb_context *ctx;
 | 
			
		||||
  struct xkb_rule_names names;
 | 
			
		||||
 | 
			
		||||
  udev = udev_new ();
 | 
			
		||||
  if (G_UNLIKELY (udev == NULL))
 | 
			
		||||
@@ -2454,6 +2017,17 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
 | 
			
		||||
 | 
			
		||||
  udev_unref (udev);
 | 
			
		||||
 | 
			
		||||
  names.rules = "evdev";
 | 
			
		||||
  names.model = "pc105";
 | 
			
		||||
  names.layout = option_xkb_layout;
 | 
			
		||||
  names.variant = option_xkb_variant;
 | 
			
		||||
  names.options = option_xkb_options;
 | 
			
		||||
 | 
			
		||||
  ctx = xkb_context_new (0);
 | 
			
		||||
  g_assert (ctx);
 | 
			
		||||
  priv->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
 | 
			
		||||
  xkb_context_unref (ctx);
 | 
			
		||||
 | 
			
		||||
  priv->main_seat = clutter_seat_evdev_new (manager_evdev);
 | 
			
		||||
 | 
			
		||||
  dispatch_libinput (manager_evdev);
 | 
			
		||||
@@ -2539,6 +2113,7 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
 | 
			
		||||
  manager_class->get_devices = clutter_device_manager_evdev_get_devices;
 | 
			
		||||
  manager_class->get_core_device = clutter_device_manager_evdev_get_core_device;
 | 
			
		||||
  manager_class->get_device = clutter_device_manager_evdev_get_device;
 | 
			
		||||
  manager_class->create_virtual_device = clutter_device_manager_evdev_create_virtual_device;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -2684,6 +2259,22 @@ _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *mana
 | 
			
		||||
                                                compare_ids);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct xkb_keymap *
 | 
			
		||||
_clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->keymap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterStage *
 | 
			
		||||
_clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->stage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_evdev_release_devices:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#ifndef __CLUTTER_DEVICE_MANAGER_EVDEV_H__
 | 
			
		||||
#define __CLUTTER_DEVICE_MANAGER_EVDEV_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter-backend.h>
 | 
			
		||||
#include <clutter/clutter-device-manager.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
@@ -39,6 +40,8 @@ typedef struct _ClutterDeviceManagerEvdev         ClutterDeviceManagerEvdev;
 | 
			
		||||
typedef struct _ClutterDeviceManagerEvdevClass    ClutterDeviceManagerEvdevClass;
 | 
			
		||||
typedef struct _ClutterDeviceManagerEvdevPrivate  ClutterDeviceManagerEvdevPrivate;
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterSeatEvdev ClutterSeatEvdev;
 | 
			
		||||
 | 
			
		||||
struct _ClutterDeviceManagerEvdev
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManager parent_instance;
 | 
			
		||||
@@ -61,6 +64,36 @@ gint  _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev
 | 
			
		||||
void  _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                                                       ClutterInputDevice        *device);
 | 
			
		||||
 | 
			
		||||
struct xkb_keymap * _clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev);
 | 
			
		||||
 | 
			
		||||
ClutterStage * _clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev);
 | 
			
		||||
 | 
			
		||||
void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev,
 | 
			
		||||
                                                      ClutterInputDevice        *core_pointer,
 | 
			
		||||
                                                      uint64_t                   time_us,
 | 
			
		||||
                                                      float                      x,
 | 
			
		||||
                                                      float                      y,
 | 
			
		||||
                                                      float                     *new_x,
 | 
			
		||||
                                                      float                     *new_y);
 | 
			
		||||
 | 
			
		||||
static inline guint64
 | 
			
		||||
us (guint64 us)
 | 
			
		||||
{
 | 
			
		||||
  return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline guint64
 | 
			
		||||
ms2us (guint64 ms)
 | 
			
		||||
{
 | 
			
		||||
  return us (ms * 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline guint32
 | 
			
		||||
us2ms (guint64 us)
 | 
			
		||||
{
 | 
			
		||||
  return (guint32) (us / 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,8 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager,
 | 
			
		||||
ClutterInputDevice *
 | 
			
		||||
_clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager,
 | 
			
		||||
                                         ClutterSeatEvdev *seat,
 | 
			
		||||
                                         ClutterInputDeviceType type)
 | 
			
		||||
                                         ClutterInputDeviceType type,
 | 
			
		||||
                                         ClutterInputMode mode)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceEvdev *device;
 | 
			
		||||
  ClutterDeviceManagerEvdev *manager_evdev;
 | 
			
		||||
@@ -223,7 +224,7 @@ _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager,
 | 
			
		||||
                         "name", name,
 | 
			
		||||
                         "device-manager", manager,
 | 
			
		||||
                         "device-type", type,
 | 
			
		||||
                         "device-mode", CLUTTER_INPUT_MODE_MASTER,
 | 
			
		||||
                         "device-mode", mode,
 | 
			
		||||
                         "enabled", TRUE,
 | 
			
		||||
                         NULL);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,8 @@
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <libinput.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter-input-device.h>
 | 
			
		||||
#include "clutter/clutter-device-manager-private.h"
 | 
			
		||||
#include "evdev/clutter-seat-evdev.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +57,6 @@ G_BEGIN_DECLS
 | 
			
		||||
  CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterInputDeviceEvdev ClutterInputDeviceEvdev;
 | 
			
		||||
typedef struct _ClutterSeatEvdev ClutterSeatEvdev;
 | 
			
		||||
typedef struct _ClutterEventEvdev ClutterEventEvdev;
 | 
			
		||||
 | 
			
		||||
struct _ClutterInputDeviceEvdev
 | 
			
		||||
@@ -76,7 +76,8 @@ ClutterInputDevice *      _clutter_input_device_evdev_new             (ClutterDe
 | 
			
		||||
 | 
			
		||||
ClutterInputDevice *      _clutter_input_device_evdev_new_virtual     (ClutterDeviceManager    *manager,
 | 
			
		||||
                                                                       ClutterSeatEvdev        *seat,
 | 
			
		||||
                                                                       ClutterInputDeviceType   type);
 | 
			
		||||
                                                                       ClutterInputDeviceType   type,
 | 
			
		||||
                                                                       ClutterInputMode         mode);
 | 
			
		||||
 | 
			
		||||
ClutterSeatEvdev *        _clutter_input_device_evdev_get_seat        (ClutterInputDeviceEvdev *device);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										590
									
								
								clutter/clutter/evdev/clutter-seat-evdev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										590
									
								
								clutter/clutter/evdev/clutter-seat-evdev.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,590 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010  Intel Corp.
 | 
			
		||||
 * Copyright (C) 2014  Jonas Ådahl
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Damien Lespiau <damien.lespiau@intel.com>
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-seat-evdev.h"
 | 
			
		||||
 | 
			
		||||
#include <linux/input.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-event-private.h"
 | 
			
		||||
#include "clutter-input-device-evdev.h"
 | 
			
		||||
#include "clutter-main.h"
 | 
			
		||||
 | 
			
		||||
/* Try to keep the pointer inside the stage. Hopefully no one is using
 | 
			
		||||
 * this backend with stages smaller than this. */
 | 
			
		||||
#define INITIAL_POINTER_X 16
 | 
			
		||||
#define INITIAL_POINTER_Y 16
 | 
			
		||||
 | 
			
		||||
#define AUTOREPEAT_VALUE 2
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev     *seat,
 | 
			
		||||
                                      struct libinput_seat *libinput_seat)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (seat->libinput_seat == NULL);
 | 
			
		||||
 | 
			
		||||
  libinput_seat_ref (libinput_seat);
 | 
			
		||||
  libinput_seat_set_user_data (libinput_seat, seat);
 | 
			
		||||
  seat->libinput_seat = libinput_seat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat)
 | 
			
		||||
{
 | 
			
		||||
  GSList *iter;
 | 
			
		||||
  ClutterInputDeviceEvdev *device_evdev;
 | 
			
		||||
  int caps_lock, num_lock, scroll_lock;
 | 
			
		||||
  enum libinput_led leds = 0;
 | 
			
		||||
 | 
			
		||||
  caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led);
 | 
			
		||||
  num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led);
 | 
			
		||||
  scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led);
 | 
			
		||||
 | 
			
		||||
  if (caps_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_CAPS_LOCK;
 | 
			
		||||
  if (num_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_NUM_LOCK;
 | 
			
		||||
  if (scroll_lock)
 | 
			
		||||
    leds |= LIBINPUT_LED_SCROLL_LOCK;
 | 
			
		||||
 | 
			
		||||
  for (iter = seat->devices; iter; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      device_evdev = iter->data;
 | 
			
		||||
      _clutter_input_device_evdev_update_leds (device_evdev, leds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_touch_state_free (ClutterTouchState *touch_state)
 | 
			
		||||
{
 | 
			
		||||
  g_slice_free (ClutterTouchState, touch_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterTouchState *
 | 
			
		||||
clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                              guint32           id)
 | 
			
		||||
{
 | 
			
		||||
  ClutterTouchState *touch;
 | 
			
		||||
 | 
			
		||||
  touch = g_slice_new0 (ClutterTouchState);
 | 
			
		||||
  touch->id = id;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
 | 
			
		||||
 | 
			
		||||
  return touch;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                                 guint32           id)
 | 
			
		||||
{
 | 
			
		||||
  g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterTouchState *
 | 
			
		||||
clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                              guint32           id)
 | 
			
		||||
{
 | 
			
		||||
  return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterSeatEvdev *
 | 
			
		||||
clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
 | 
			
		||||
  ClutterSeatEvdev *seat;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
  struct xkb_keymap *keymap;
 | 
			
		||||
 | 
			
		||||
  seat = g_new0 (ClutterSeatEvdev, 1);
 | 
			
		||||
  if (!seat)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  seat->manager_evdev = manager_evdev;
 | 
			
		||||
  device = _clutter_input_device_evdev_new_virtual (
 | 
			
		||||
      manager, seat, CLUTTER_POINTER_DEVICE,
 | 
			
		||||
      CLUTTER_INPUT_MODE_MASTER);
 | 
			
		||||
  stage = _clutter_device_manager_evdev_get_stage (manager_evdev);
 | 
			
		||||
  _clutter_input_device_set_stage (device, stage);
 | 
			
		||||
  seat->pointer_x = INITIAL_POINTER_X;
 | 
			
		||||
  seat->pointer_y = INITIAL_POINTER_Y;
 | 
			
		||||
  _clutter_input_device_set_coords (device, NULL,
 | 
			
		||||
                                    seat->pointer_x, seat->pointer_y,
 | 
			
		||||
                                    NULL);
 | 
			
		||||
  _clutter_device_manager_add_device (manager, device);
 | 
			
		||||
  seat->core_pointer = device;
 | 
			
		||||
 | 
			
		||||
  device = _clutter_input_device_evdev_new_virtual (
 | 
			
		||||
      manager, seat, CLUTTER_KEYBOARD_DEVICE,
 | 
			
		||||
      CLUTTER_INPUT_MODE_MASTER);
 | 
			
		||||
  _clutter_input_device_set_stage (device, stage);
 | 
			
		||||
  _clutter_device_manager_add_device (manager, device);
 | 
			
		||||
  seat->core_keyboard = device;
 | 
			
		||||
 | 
			
		||||
  seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
 | 
			
		||||
                                         (GDestroyNotify) clutter_touch_state_free);
 | 
			
		||||
 | 
			
		||||
  seat->repeat = TRUE;
 | 
			
		||||
  seat->repeat_delay = 250;     /* ms */
 | 
			
		||||
  seat->repeat_interval = 33;   /* ms */
 | 
			
		||||
 | 
			
		||||
  keymap = _clutter_device_manager_evdev_get_keymap (manager_evdev);
 | 
			
		||||
  if (keymap)
 | 
			
		||||
    {
 | 
			
		||||
      seat->xkb = xkb_state_new (keymap);
 | 
			
		||||
 | 
			
		||||
      seat->caps_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS);
 | 
			
		||||
      seat->num_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM);
 | 
			
		||||
      seat->scroll_lock_led =
 | 
			
		||||
        xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return seat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat)
 | 
			
		||||
{
 | 
			
		||||
  if (seat->repeat_timer)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (seat->repeat_timer);
 | 
			
		||||
      seat->repeat_timer = 0;
 | 
			
		||||
      g_clear_object (&seat->repeat_device);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
keyboard_repeat (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterSeatEvdev *seat = data;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  guint32 time_ms;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
 | 
			
		||||
  source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);
 | 
			
		||||
  time_ms = g_source_get_time (source) / 1000;
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_key (seat,
 | 
			
		||||
                                 seat->repeat_device,
 | 
			
		||||
                                 ms2us (time_ms),
 | 
			
		||||
                                 seat->repeat_key,
 | 
			
		||||
                                 AUTOREPEAT_VALUE,
 | 
			
		||||
                                 FALSE);
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_CONTINUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
queue_event (ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  _clutter_event_push (event, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
update_button_count (ClutterSeatEvdev *seat,
 | 
			
		||||
                     uint32_t          button,
 | 
			
		||||
                     uint32_t          state)
 | 
			
		||||
{
 | 
			
		||||
  if (state)
 | 
			
		||||
    {
 | 
			
		||||
      return ++seat->button_count[button];
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Handle cases where we newer saw the initial pressed event. */
 | 
			
		||||
      if (seat->button_count[button] == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
      return --seat->button_count[button];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_notify_key (ClutterSeatEvdev   *seat,
 | 
			
		||||
                               ClutterInputDevice *device,
 | 
			
		||||
                               uint64_t            time_us,
 | 
			
		||||
                               uint32_t            key,
 | 
			
		||||
                               uint32_t            state,
 | 
			
		||||
                               gboolean            update_keys)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
  ClutterEvent *event = NULL;
 | 
			
		||||
  enum xkb_state_component changed_state;
 | 
			
		||||
 | 
			
		||||
  if (state != AUTOREPEAT_VALUE)
 | 
			
		||||
    {
 | 
			
		||||
      /* Drop any repeated button press (for example from virtual devices. */
 | 
			
		||||
      int count = update_button_count (seat, key, state);
 | 
			
		||||
      if (state && count > 1)
 | 
			
		||||
        return;
 | 
			
		||||
      if (!state && count != 0)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* We can drop the event on the floor if no stage has been
 | 
			
		||||
   * associated with the device yet. */
 | 
			
		||||
  stage = _clutter_input_device_get_stage (device);
 | 
			
		||||
  if (stage == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_seat_evdev_clear_repeat_timer (seat);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  event = _clutter_key_event_new_from_evdev (device,
 | 
			
		||||
					     seat->core_keyboard,
 | 
			
		||||
					     stage,
 | 
			
		||||
					     seat->xkb,
 | 
			
		||||
					     seat->button_state,
 | 
			
		||||
					     us2ms (time_us), key, state);
 | 
			
		||||
  _clutter_evdev_event_set_event_code (event, key);
 | 
			
		||||
 | 
			
		||||
  /* We must be careful and not pass multiple releases to xkb, otherwise it gets
 | 
			
		||||
     confused and locks the modifiers */
 | 
			
		||||
  if (state != AUTOREPEAT_VALUE)
 | 
			
		||||
    {
 | 
			
		||||
      changed_state = xkb_state_update_key (seat->xkb,
 | 
			
		||||
                                            event->key.hardware_keycode,
 | 
			
		||||
                                            state ? XKB_KEY_DOWN : XKB_KEY_UP);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      changed_state = 0;
 | 
			
		||||
      clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
 | 
			
		||||
  if (update_keys && (changed_state & XKB_STATE_LEDS))
 | 
			
		||||
    clutter_seat_evdev_sync_leds (seat);
 | 
			
		||||
 | 
			
		||||
  if (state == 0 ||             /* key release */
 | 
			
		||||
      !seat->repeat ||
 | 
			
		||||
      !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb),
 | 
			
		||||
                               event->key.hardware_keycode))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_seat_evdev_clear_repeat_timer (seat);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (state == 1)               /* key press */
 | 
			
		||||
    seat->repeat_count = 0;
 | 
			
		||||
 | 
			
		||||
  seat->repeat_count += 1;
 | 
			
		||||
  seat->repeat_key = key;
 | 
			
		||||
 | 
			
		||||
  switch (seat->repeat_count)
 | 
			
		||||
    {
 | 
			
		||||
    case 1:
 | 
			
		||||
    case 2:
 | 
			
		||||
      {
 | 
			
		||||
        guint32 interval;
 | 
			
		||||
 | 
			
		||||
        clutter_seat_evdev_clear_repeat_timer (seat);
 | 
			
		||||
        seat->repeat_device = g_object_ref (device);
 | 
			
		||||
 | 
			
		||||
        if (seat->repeat_count == 1)
 | 
			
		||||
          interval = seat->repeat_delay;
 | 
			
		||||
        else
 | 
			
		||||
          interval = seat->repeat_interval;
 | 
			
		||||
 | 
			
		||||
        seat->repeat_timer =
 | 
			
		||||
          clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS,
 | 
			
		||||
                                            interval,
 | 
			
		||||
                                            keyboard_repeat,
 | 
			
		||||
                                            seat,
 | 
			
		||||
                                            NULL);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    default:
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterEvent *
 | 
			
		||||
new_absolute_motion_event (ClutterSeatEvdev   *seat,
 | 
			
		||||
                           ClutterInputDevice *input_device,
 | 
			
		||||
                           guint64             time_us,
 | 
			
		||||
                           gfloat              x,
 | 
			
		||||
                           gfloat              y,
 | 
			
		||||
                           gdouble            *axes)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStage *stage = _clutter_input_device_get_stage (input_device);
 | 
			
		||||
  ClutterEvent *event;
 | 
			
		||||
 | 
			
		||||
  event = clutter_event_new (CLUTTER_MOTION);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    _clutter_device_manager_evdev_constrain_pointer (seat->manager_evdev,
 | 
			
		||||
                                                     seat->core_pointer,
 | 
			
		||||
                                                     time_us,
 | 
			
		||||
                                                     seat->pointer_x,
 | 
			
		||||
                                                     seat->pointer_y,
 | 
			
		||||
                                                     &x, &y);
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_time_usec (event, time_us);
 | 
			
		||||
  event->motion.time = us2ms (time_us);
 | 
			
		||||
  event->motion.stage = stage;
 | 
			
		||||
  event->motion.device = seat->core_pointer;
 | 
			
		||||
  _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
 | 
			
		||||
  event->motion.x = x;
 | 
			
		||||
  event->motion.y = y;
 | 
			
		||||
  event->motion.axes = axes;
 | 
			
		||||
  clutter_event_set_device (event, seat->core_pointer);
 | 
			
		||||
  clutter_event_set_source_device (event, input_device);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
        CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
 | 
			
		||||
      clutter_event_set_device_tool (event, device_evdev->last_tool);
 | 
			
		||||
      clutter_event_set_device (event, input_device);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_event_set_device (event, seat->core_pointer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_input_device_set_stage (seat->core_pointer, stage);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      seat->pointer_x = x;
 | 
			
		||||
      seat->pointer_y = y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return event;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev   *seat,
 | 
			
		||||
                                           ClutterInputDevice *input_device,
 | 
			
		||||
                                           uint64_t            time_us,
 | 
			
		||||
                                           float               dx,
 | 
			
		||||
                                           float               dy,
 | 
			
		||||
                                           float               dx_unaccel,
 | 
			
		||||
                                           float               dy_unaccel)
 | 
			
		||||
{
 | 
			
		||||
  gfloat new_x, new_y;
 | 
			
		||||
  ClutterEvent *event;
 | 
			
		||||
 | 
			
		||||
  /* We can drop the event on the floor if no stage has been
 | 
			
		||||
   * associated with the device yet. */
 | 
			
		||||
  if (!_clutter_input_device_get_stage (input_device))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  new_x = seat->pointer_x + dx;
 | 
			
		||||
  new_y = seat->pointer_y + dy;
 | 
			
		||||
  event = new_absolute_motion_event (seat, input_device,
 | 
			
		||||
                                     time_us, new_x, new_y, NULL);
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_relative_motion (event,
 | 
			
		||||
                                            dx, dy,
 | 
			
		||||
                                            dx_unaccel, dy_unaccel);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev   *seat,
 | 
			
		||||
                                                ClutterInputDevice *input_device,
 | 
			
		||||
                                                uint64_t            time_us,
 | 
			
		||||
                                                float               x,
 | 
			
		||||
                                                float               y,
 | 
			
		||||
                                                double             *axes)
 | 
			
		||||
{
 | 
			
		||||
  ClutterEvent *event;
 | 
			
		||||
 | 
			
		||||
  event = new_absolute_motion_event (seat, input_device, time_us, x, x, axes);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_notify_button (ClutterSeatEvdev   *seat,
 | 
			
		||||
                                  ClutterInputDevice *input_device,
 | 
			
		||||
                                  uint64_t            time_us,
 | 
			
		||||
                                  uint32_t            button,
 | 
			
		||||
                                  uint32_t            state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
  ClutterEvent *event = NULL;
 | 
			
		||||
  gint button_nr;
 | 
			
		||||
  static gint maskmap[8] =
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK,
 | 
			
		||||
      CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0
 | 
			
		||||
    };
 | 
			
		||||
  int button_count;
 | 
			
		||||
 | 
			
		||||
  /* Drop any repeated button press (for example from virtual devices. */
 | 
			
		||||
  button_count = update_button_count (seat, button, state);
 | 
			
		||||
  if (state && button_count > 1)
 | 
			
		||||
    return;
 | 
			
		||||
  if (!state && button_count != 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* We can drop the event on the floor if no stage has been
 | 
			
		||||
   * associated with the device yet. */
 | 
			
		||||
  stage = _clutter_input_device_get_stage (input_device);
 | 
			
		||||
  if (stage == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* The evdev button numbers don't map sequentially to clutter button
 | 
			
		||||
   * numbers (the right and middle mouse buttons are in the opposite
 | 
			
		||||
   * order) so we'll map them directly with a switch statement */
 | 
			
		||||
  switch (button)
 | 
			
		||||
    {
 | 
			
		||||
    case BTN_LEFT:
 | 
			
		||||
    case BTN_TOUCH:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_PRIMARY;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case BTN_RIGHT:
 | 
			
		||||
    case BTN_STYLUS:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_SECONDARY;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case BTN_MIDDLE:
 | 
			
		||||
    case BTN_STYLUS2:
 | 
			
		||||
      button_nr = CLUTTER_BUTTON_MIDDLE;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
 | 
			
		||||
      if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
        button_nr = button - BTN_TOOL_PEN + 4;
 | 
			
		||||
      else
 | 
			
		||||
        button_nr = button - (BTN_LEFT - 1) + 4;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (button_nr < 1 || button_nr > 12)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unhandled button event 0x%x", button);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (state)
 | 
			
		||||
    event = clutter_event_new (CLUTTER_BUTTON_PRESS);
 | 
			
		||||
  else
 | 
			
		||||
    event = clutter_event_new (CLUTTER_BUTTON_RELEASE);
 | 
			
		||||
 | 
			
		||||
  if (button_nr < G_N_ELEMENTS (maskmap))
 | 
			
		||||
    {
 | 
			
		||||
      /* Update the modifiers */
 | 
			
		||||
      if (state)
 | 
			
		||||
        seat->button_state |= maskmap[button_nr - 1];
 | 
			
		||||
      else
 | 
			
		||||
        seat->button_state &= ~maskmap[button_nr - 1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_time_usec (event, time_us);
 | 
			
		||||
  event->button.time = us2ms (time_us);
 | 
			
		||||
  event->button.stage = CLUTTER_STAGE (stage);
 | 
			
		||||
  _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
 | 
			
		||||
  event->button.button = button_nr;
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterPoint point;
 | 
			
		||||
 | 
			
		||||
      clutter_input_device_get_coords (input_device, NULL, &point);
 | 
			
		||||
      event->button.x = point.x;
 | 
			
		||||
      event->button.y = point.y;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      event->button.x = seat->pointer_x;
 | 
			
		||||
      event->button.y = seat->pointer_y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_event_set_device (event, seat->core_pointer);
 | 
			
		||||
  clutter_event_set_source_device (event, input_device);
 | 
			
		||||
 | 
			
		||||
  _clutter_evdev_event_set_event_code (event, button);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDeviceEvdev *device_evdev =
 | 
			
		||||
        CLUTTER_INPUT_DEVICE_EVDEV (input_device);
 | 
			
		||||
 | 
			
		||||
      clutter_event_set_device_tool (event, device_evdev->last_tool);
 | 
			
		||||
      clutter_event_set_device (event, input_device);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_event_set_device (event, seat->core_pointer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_input_device_set_stage (seat->core_pointer, stage);
 | 
			
		||||
 | 
			
		||||
  queue_event (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
 | 
			
		||||
{
 | 
			
		||||
  GSList *iter;
 | 
			
		||||
 | 
			
		||||
  for (iter = seat->devices; iter; iter = g_slist_next (iter))
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = iter->data;
 | 
			
		||||
 | 
			
		||||
      g_object_unref (device);
 | 
			
		||||
    }
 | 
			
		||||
  g_slist_free (seat->devices);
 | 
			
		||||
  g_hash_table_unref (seat->touches);
 | 
			
		||||
 | 
			
		||||
  xkb_state_unref (seat->xkb);
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_clear_repeat_timer (seat);
 | 
			
		||||
 | 
			
		||||
  if (seat->libinput_seat)
 | 
			
		||||
    libinput_seat_unref (seat->libinput_seat);
 | 
			
		||||
 | 
			
		||||
  g_free (seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
 | 
			
		||||
                              ClutterStage     *stage)
 | 
			
		||||
{
 | 
			
		||||
  GSList *l;
 | 
			
		||||
 | 
			
		||||
  _clutter_input_device_set_stage (seat->core_pointer, stage);
 | 
			
		||||
  _clutter_input_device_set_stage (seat->core_keyboard, stage);
 | 
			
		||||
 | 
			
		||||
  for (l = seat->devices; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = l->data;
 | 
			
		||||
 | 
			
		||||
      _clutter_input_device_set_stage (device, stage);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								clutter/clutter/evdev/clutter-seat-evdev.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								clutter/clutter/evdev/clutter-seat-evdev.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010  Intel Corp.
 | 
			
		||||
 * Copyright (C) 2014  Jonas Ådahl
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Damien Lespiau <damien.lespiau@intel.com>
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_SEAT_EVDEV_H__
 | 
			
		||||
#define __CLUTTER_SEAT_EVDEV_H__
 | 
			
		||||
 | 
			
		||||
#include <libinput.h>
 | 
			
		||||
#include <linux/input.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-input-device.h"
 | 
			
		||||
#include "clutter-device-manager-evdev.h"
 | 
			
		||||
#include "clutter-xkb-utils.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterTouchState ClutterTouchState;
 | 
			
		||||
 | 
			
		||||
struct _ClutterTouchState
 | 
			
		||||
{
 | 
			
		||||
  guint32 id;
 | 
			
		||||
  ClutterPoint coords;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ClutterSeatEvdev
 | 
			
		||||
{
 | 
			
		||||
  struct libinput_seat *libinput_seat;
 | 
			
		||||
  ClutterDeviceManagerEvdev *manager_evdev;
 | 
			
		||||
 | 
			
		||||
  GSList *devices;
 | 
			
		||||
 | 
			
		||||
  ClutterInputDevice *core_pointer;
 | 
			
		||||
  ClutterInputDevice *core_keyboard;
 | 
			
		||||
 | 
			
		||||
  GHashTable *touches;
 | 
			
		||||
 | 
			
		||||
  struct xkb_state *xkb;
 | 
			
		||||
  xkb_led_index_t caps_lock_led;
 | 
			
		||||
  xkb_led_index_t num_lock_led;
 | 
			
		||||
  xkb_led_index_t scroll_lock_led;
 | 
			
		||||
  uint32_t button_state;
 | 
			
		||||
  int button_count[KEY_CNT];
 | 
			
		||||
 | 
			
		||||
  /* keyboard repeat */
 | 
			
		||||
  gboolean repeat;
 | 
			
		||||
  guint32 repeat_delay;
 | 
			
		||||
  guint32 repeat_interval;
 | 
			
		||||
  guint32 repeat_key;
 | 
			
		||||
  guint32 repeat_count;
 | 
			
		||||
  guint32 repeat_timer;
 | 
			
		||||
  ClutterInputDevice *repeat_device;
 | 
			
		||||
 | 
			
		||||
  gfloat pointer_x;
 | 
			
		||||
  gfloat pointer_y;
 | 
			
		||||
 | 
			
		||||
  /* Emulation of discrete scroll events out of smooth ones */
 | 
			
		||||
  gfloat accum_scroll_dx;
 | 
			
		||||
  gfloat accum_scroll_dy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_notify_key (ClutterSeatEvdev   *seat,
 | 
			
		||||
                                    ClutterInputDevice *device,
 | 
			
		||||
                                    uint64_t            time_us,
 | 
			
		||||
                                    uint32_t            key,
 | 
			
		||||
                                    uint32_t            state,
 | 
			
		||||
                                    gboolean            update_keys);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev   *seat_evdev,
 | 
			
		||||
                                                ClutterInputDevice *input_device,
 | 
			
		||||
                                                uint64_t            time_us,
 | 
			
		||||
                                                float               dx,
 | 
			
		||||
                                                float               dy,
 | 
			
		||||
                                                float               dx_unaccel,
 | 
			
		||||
                                                float               dy_unaccel);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev   *seat_evdev,
 | 
			
		||||
                                                ClutterInputDevice *input_device,
 | 
			
		||||
                                                uint64_t            time_us,
 | 
			
		||||
                                                float               x,
 | 
			
		||||
                                                float               y,
 | 
			
		||||
                                                double             *axes);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_notify_button (ClutterSeatEvdev   *seat,
 | 
			
		||||
                                       ClutterInputDevice *input_device,
 | 
			
		||||
                                       uint64_t            time_us,
 | 
			
		||||
                                       uint32_t            button,
 | 
			
		||||
                                       uint32_t            state);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev     *seat,
 | 
			
		||||
                                           struct libinput_seat *libinput_seat);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
 | 
			
		||||
 | 
			
		||||
ClutterTouchState * clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                                                  guint32           id);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                                      guint32           id);
 | 
			
		||||
 | 
			
		||||
ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
 | 
			
		||||
                                                  guint32           id);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
 | 
			
		||||
                                   ClutterStage     *stage);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat);
 | 
			
		||||
 | 
			
		||||
ClutterSeatEvdev * clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev);
 | 
			
		||||
 | 
			
		||||
void clutter_seat_evdev_free (ClutterSeatEvdev *seat);
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_SEAT_EVDEV_H__ */
 | 
			
		||||
							
								
								
									
										497
									
								
								clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										497
									
								
								clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,497 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <linux/input.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-private.h"
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
#include "evdev/clutter-input-device-evdev.h"
 | 
			
		||||
#include "evdev/clutter-seat-evdev.h"
 | 
			
		||||
#include "evdev/clutter-virtual-input-device-evdev.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_SEAT,
 | 
			
		||||
 | 
			
		||||
  PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GParamSpec *obj_props[PROP_LAST];
 | 
			
		||||
 | 
			
		||||
struct _ClutterVirtualInputDeviceEvdev
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice parent;
 | 
			
		||||
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  ClutterSeatEvdev *seat;
 | 
			
		||||
  int button_count[KEY_CNT];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ClutterVirtualInputDeviceEvdev,
 | 
			
		||||
               clutter_virtual_input_device_evdev,
 | 
			
		||||
               CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
 | 
			
		||||
 | 
			
		||||
typedef enum _EvdevButtonType
 | 
			
		||||
{
 | 
			
		||||
  EVDEV_BUTTON_TYPE_NONE,
 | 
			
		||||
  EVDEV_BUTTON_TYPE_KEY,
 | 
			
		||||
  EVDEV_BUTTON_TYPE_BUTTON,
 | 
			
		||||
} EvdevButtonType;
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
update_button_count (ClutterVirtualInputDeviceEvdev *virtual_evdev,
 | 
			
		||||
                     uint32_t                        button,
 | 
			
		||||
                     uint32_t                        state)
 | 
			
		||||
{
 | 
			
		||||
  if (state)
 | 
			
		||||
    {
 | 
			
		||||
      return ++virtual_evdev->button_count[button];
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Handle cases where we newer saw the initial pressed event. */
 | 
			
		||||
      if (virtual_evdev->button_count[button] == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
      return --virtual_evdev->button_count[button];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EvdevButtonType
 | 
			
		||||
get_button_type (uint16_t code)
 | 
			
		||||
{
 | 
			
		||||
  switch (code)
 | 
			
		||||
    {
 | 
			
		||||
    case BTN_TOOL_PEN:
 | 
			
		||||
    case BTN_TOOL_RUBBER:
 | 
			
		||||
    case BTN_TOOL_BRUSH:
 | 
			
		||||
    case BTN_TOOL_PENCIL:
 | 
			
		||||
    case BTN_TOOL_AIRBRUSH:
 | 
			
		||||
    case BTN_TOOL_MOUSE:
 | 
			
		||||
    case BTN_TOOL_LENS:
 | 
			
		||||
    case BTN_TOOL_QUINTTAP:
 | 
			
		||||
    case BTN_TOOL_DOUBLETAP:
 | 
			
		||||
    case BTN_TOOL_TRIPLETAP:
 | 
			
		||||
    case BTN_TOOL_QUADTAP:
 | 
			
		||||
    case BTN_TOOL_FINGER:
 | 
			
		||||
    case BTN_TOUCH:
 | 
			
		||||
      return EVDEV_BUTTON_TYPE_NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (code >= KEY_ESC && code <= KEY_MICMUTE)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_KEY;
 | 
			
		||||
  if (code >= BTN_MISC && code <= BTN_GEAR_UP)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_BUTTON;
 | 
			
		||||
  if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_KEY;
 | 
			
		||||
  if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_BUTTON;
 | 
			
		||||
  if (code >= KEY_ALS_TOGGLE && code <= KEY_KBDINPUTASSIST_CANCEL)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_KEY;
 | 
			
		||||
  if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40)
 | 
			
		||||
    return EVDEV_BUTTON_TYPE_BUTTON;
 | 
			
		||||
  return EVDEV_BUTTON_TYPE_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  int code;
 | 
			
		||||
  uint64_t time_us;
 | 
			
		||||
 | 
			
		||||
  time_us = g_get_monotonic_time ();
 | 
			
		||||
 | 
			
		||||
  for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++)
 | 
			
		||||
    {
 | 
			
		||||
      switch (get_button_type (code))
 | 
			
		||||
        {
 | 
			
		||||
        case EVDEV_BUTTON_TYPE_KEY:
 | 
			
		||||
          clutter_virtual_input_device_notify_key (virtual_device,
 | 
			
		||||
                                                   time_us,
 | 
			
		||||
                                                   code,
 | 
			
		||||
                                                   CLUTTER_KEY_STATE_RELEASED);
 | 
			
		||||
          break;
 | 
			
		||||
        case EVDEV_BUTTON_TYPE_BUTTON:
 | 
			
		||||
          clutter_virtual_input_device_notify_button (virtual_device,
 | 
			
		||||
                                                      time_us,
 | 
			
		||||
                                                      code,
 | 
			
		||||
                                                      CLUTTER_BUTTON_STATE_RELEASED);
 | 
			
		||||
          break;
 | 
			
		||||
        case EVDEV_BUTTON_TYPE_NONE:
 | 
			
		||||
          g_assert_not_reached ();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                           uint64_t                   time_us,
 | 
			
		||||
                                                           double                     dx,
 | 
			
		||||
                                                           double                     dy)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_relative_motion (virtual_evdev->seat,
 | 
			
		||||
                                             virtual_evdev->device,
 | 
			
		||||
                                             time_us,
 | 
			
		||||
                                             dx, dy,
 | 
			
		||||
                                             dx, dy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                           uint64_t                   time_us,
 | 
			
		||||
                                                           double                     x,
 | 
			
		||||
                                                           double                     y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_absolute_motion (virtual_evdev->seat,
 | 
			
		||||
                                             virtual_evdev->device,
 | 
			
		||||
                                             time_us,
 | 
			
		||||
                                             x, y,
 | 
			
		||||
                                             NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                  uint64_t                   time_us,
 | 
			
		||||
                                                  uint32_t                   button,
 | 
			
		||||
                                                  ClutterButtonState         button_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  int button_count;
 | 
			
		||||
 | 
			
		||||
  if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unknown/invalid virtual device button 0x%x pressed",
 | 
			
		||||
                 button);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  button_count = update_button_count (virtual_evdev, button, button_state);
 | 
			
		||||
  if (button_count > 1)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Received multiple virtual 0x%x button presses (ignoring)",
 | 
			
		||||
                 button);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_button (virtual_evdev->seat,
 | 
			
		||||
                                    virtual_evdev->device,
 | 
			
		||||
                                    time_us,
 | 
			
		||||
                                    button,
 | 
			
		||||
                                    button_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                               uint64_t                   time_us,
 | 
			
		||||
                                               uint32_t                   key,
 | 
			
		||||
                                               ClutterKeyState            key_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  int key_count;
 | 
			
		||||
 | 
			
		||||
  if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  key_count = update_button_count (virtual_evdev, key, key_state);
 | 
			
		||||
  if (key_count > 1)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Received multiple virtual 0x%x key presses (ignoring)",
 | 
			
		||||
                 key);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_key (virtual_evdev->seat,
 | 
			
		||||
                                 virtual_evdev->device,
 | 
			
		||||
                                 time_us,
 | 
			
		||||
                                 key,
 | 
			
		||||
                                 key_state,
 | 
			
		||||
                                 TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                          guint                      keyval,
 | 
			
		||||
                                          guint                     *keycode_out,
 | 
			
		||||
                                          guint                     *level_out)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  ClutterDeviceManager *manager;
 | 
			
		||||
  struct xkb_keymap *xkb_keymap;
 | 
			
		||||
  struct xkb_state  *state;
 | 
			
		||||
  guint keycode, layout;
 | 
			
		||||
  xkb_keycode_t min_keycode, max_keycode;
 | 
			
		||||
 | 
			
		||||
  manager = clutter_virtual_input_device_get_manager (virtual_device);
 | 
			
		||||
  xkb_keymap = _clutter_device_manager_evdev_get_keymap (CLUTTER_DEVICE_MANAGER_EVDEV (manager));
 | 
			
		||||
  state = virtual_evdev->seat->xkb;
 | 
			
		||||
 | 
			
		||||
  layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
 | 
			
		||||
  min_keycode = xkb_keymap_min_keycode (xkb_keymap);
 | 
			
		||||
  max_keycode = xkb_keymap_max_keycode (xkb_keymap);
 | 
			
		||||
  for (keycode = min_keycode; keycode < max_keycode; keycode++)
 | 
			
		||||
    {
 | 
			
		||||
      gint num_levels, level;
 | 
			
		||||
      num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
 | 
			
		||||
      for (level = 0; level < num_levels; level++)
 | 
			
		||||
        {
 | 
			
		||||
          const xkb_keysym_t *syms;
 | 
			
		||||
          gint num_syms, sym;
 | 
			
		||||
          num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
 | 
			
		||||
          for (sym = 0; sym < num_syms; sym++)
 | 
			
		||||
            {
 | 
			
		||||
              if (syms[sym] == keyval)
 | 
			
		||||
                {
 | 
			
		||||
                  *keycode_out = keycode;
 | 
			
		||||
                  if (level_out)
 | 
			
		||||
                    *level_out = level;
 | 
			
		||||
                  return TRUE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
apply_level_modifiers (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                       uint64_t                   time_us,
 | 
			
		||||
                       uint32_t                   level,
 | 
			
		||||
                       uint32_t                   key_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  guint keysym, keycode, evcode;
 | 
			
		||||
 | 
			
		||||
  if (level == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (level == 1)
 | 
			
		||||
    {
 | 
			
		||||
      keysym = XKB_KEY_Shift_L;
 | 
			
		||||
    }
 | 
			
		||||
  else if (level == 2)
 | 
			
		||||
    {
 | 
			
		||||
      keysym = XKB_KEY_ISO_Level3_Shift;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unhandled level: %d\n", level);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!pick_keycode_for_keyval_in_current_group (virtual_device, keysym,
 | 
			
		||||
                                                 &keycode, NULL))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_keycode_to_evdev (virtual_evdev->device,
 | 
			
		||||
                                         keycode, &evcode);
 | 
			
		||||
  clutter_seat_evdev_notify_key (virtual_evdev->seat,
 | 
			
		||||
                                 virtual_evdev->device,
 | 
			
		||||
                                 time_us,
 | 
			
		||||
                                 evcode,
 | 
			
		||||
                                 key_state,
 | 
			
		||||
                                 TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                  uint64_t                   time_us,
 | 
			
		||||
                                                  uint32_t                   keyval,
 | 
			
		||||
                                                  ClutterKeyState            key_state)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
 | 
			
		||||
  int key_count;
 | 
			
		||||
  guint keycode = 0, level = 0, evcode = 0;
 | 
			
		||||
 | 
			
		||||
  if (!pick_keycode_for_keyval_in_current_group (virtual_device,
 | 
			
		||||
                                                 keyval, &keycode, &level))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("No keycode found for keyval %x in current group", keyval);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_keycode_to_evdev (virtual_evdev->device,
 | 
			
		||||
                                         keycode, &evcode);
 | 
			
		||||
 | 
			
		||||
  if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  key_count = update_button_count (virtual_evdev, evcode, key_state);
 | 
			
		||||
  if (key_count > 1)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Received multiple virtual 0x%x key presses (ignoring)",
 | 
			
		||||
                 keycode);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (key_state)
 | 
			
		||||
    apply_level_modifiers (virtual_device, time_us, level, key_state);
 | 
			
		||||
 | 
			
		||||
  clutter_seat_evdev_notify_key (virtual_evdev->seat,
 | 
			
		||||
                                 virtual_evdev->device,
 | 
			
		||||
                                 time_us,
 | 
			
		||||
                                 evcode,
 | 
			
		||||
                                 key_state,
 | 
			
		||||
                                 TRUE);
 | 
			
		||||
 | 
			
		||||
  if (!key_state)
 | 
			
		||||
    apply_level_modifiers (virtual_device, time_us, level, key_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_get_property (GObject    *object,
 | 
			
		||||
                                                 guint       prop_id,
 | 
			
		||||
                                                 GValue     *value,
 | 
			
		||||
                                                 GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_SEAT:
 | 
			
		||||
      g_value_set_pointer (value, virtual_evdev->seat);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_set_property (GObject      *object,
 | 
			
		||||
                                                 guint         prop_id,
 | 
			
		||||
                                                 const GValue *value,
 | 
			
		||||
                                                 GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_SEAT:
 | 
			
		||||
      virtual_evdev->seat = g_value_get_pointer (value);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice *virtual_device =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE (object);
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
 | 
			
		||||
  ClutterDeviceManager *manager;
 | 
			
		||||
  ClutterInputDeviceType device_type;
 | 
			
		||||
  ClutterStage *stage;
 | 
			
		||||
 | 
			
		||||
  manager = clutter_virtual_input_device_get_manager (virtual_device);
 | 
			
		||||
  device_type = clutter_virtual_input_device_get_device_type (virtual_device);
 | 
			
		||||
 | 
			
		||||
  virtual_evdev->device =
 | 
			
		||||
    _clutter_input_device_evdev_new_virtual (manager,
 | 
			
		||||
                                             virtual_evdev->seat,
 | 
			
		||||
                                             device_type,
 | 
			
		||||
                                             CLUTTER_INPUT_MODE_SLAVE);
 | 
			
		||||
 | 
			
		||||
  stage = _clutter_device_manager_evdev_get_stage (CLUTTER_DEVICE_MANAGER_EVDEV (manager));
 | 
			
		||||
  _clutter_input_device_set_stage (virtual_evdev->device, stage);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice *virtual_device =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE (object);
 | 
			
		||||
  ClutterVirtualInputDeviceEvdev *virtual_evdev =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
 | 
			
		||||
  release_pressed_buttons (virtual_device);
 | 
			
		||||
  g_clear_object (&virtual_evdev->device);
 | 
			
		||||
 | 
			
		||||
  object_class =
 | 
			
		||||
    G_OBJECT_CLASS (clutter_virtual_input_device_evdev_parent_class);
 | 
			
		||||
  object_class->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_init (ClutterVirtualInputDeviceEvdev *virtual_device_evdev)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_evdev_class_init (ClutterVirtualInputDeviceEvdevClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterVirtualInputDeviceClass *virtual_input_device_class =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = clutter_virtual_input_device_evdev_get_property;
 | 
			
		||||
  object_class->set_property = clutter_virtual_input_device_evdev_set_property;
 | 
			
		||||
  object_class->constructed = clutter_virtual_input_device_evdev_constructed;
 | 
			
		||||
  object_class->finalize = clutter_virtual_input_device_evdev_finalize;
 | 
			
		||||
 | 
			
		||||
  virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_evdev_notify_relative_motion;
 | 
			
		||||
  virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_evdev_notify_absolute_motion;
 | 
			
		||||
  virtual_input_device_class->notify_button = clutter_virtual_input_device_evdev_notify_button;
 | 
			
		||||
  virtual_input_device_class->notify_key = clutter_virtual_input_device_evdev_notify_key;
 | 
			
		||||
  virtual_input_device_class->notify_keyval = clutter_virtual_input_device_evdev_notify_keyval;
 | 
			
		||||
 | 
			
		||||
  obj_props[PROP_SEAT] = g_param_spec_pointer ("seat",
 | 
			
		||||
                                               P_("ClutterSeatEvdev"),
 | 
			
		||||
                                               P_("ClutterSeatEvdev"),
 | 
			
		||||
                                               CLUTTER_PARAM_READWRITE |
 | 
			
		||||
                                               G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								clutter/clutter/evdev/clutter-virtual-input-device-evdev.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								clutter/clutter/evdev/clutter-virtual-input-device-evdev.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__
 | 
			
		||||
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__
 | 
			
		||||
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_EVDEV (clutter_virtual_input_device_evdev_get_type ())
 | 
			
		||||
G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceEvdev,
 | 
			
		||||
                      clutter_virtual_input_device_evdev,
 | 
			
		||||
                      CLUTTER, VIRTUAL_INPUT_DEVICE_EVDEV,
 | 
			
		||||
                      ClutterVirtualInputDevice)
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ */
 | 
			
		||||
@@ -28,6 +28,7 @@
 | 
			
		||||
#include "clutter-backend-x11.h"
 | 
			
		||||
#include "clutter-input-device-core-x11.h"
 | 
			
		||||
#include "clutter-stage-x11.h"
 | 
			
		||||
#include "clutter-virtual-input-device-x11.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-backend.h"
 | 
			
		||||
#include "clutter-debug.h"
 | 
			
		||||
@@ -480,6 +481,13 @@ clutter_device_manager_x11_get_device (ClutterDeviceManager *manager,
 | 
			
		||||
                              GINT_TO_POINTER (id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterVirtualInputDevice *
 | 
			
		||||
clutter_device_manager_x11_create_virtual_device (ClutterDeviceManager  *device_manager,
 | 
			
		||||
                                                  ClutterInputDeviceType device_type)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_device_manager_x11_set_property (GObject      *gobject,
 | 
			
		||||
                                         guint         prop_id,
 | 
			
		||||
@@ -526,6 +534,7 @@ clutter_device_manager_x11_class_init (ClutterDeviceManagerX11Class *klass)
 | 
			
		||||
  manager_class->get_devices = clutter_device_manager_x11_get_devices;
 | 
			
		||||
  manager_class->get_core_device = clutter_device_manager_x11_get_core_device;
 | 
			
		||||
  manager_class->get_device = clutter_device_manager_x11_get_device;
 | 
			
		||||
  manager_class->create_virtual_device = clutter_device_manager_x11_create_virtual_device;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								clutter/clutter/x11/clutter-virtual-input-device-x11.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								clutter/clutter/x11/clutter-virtual-input-device-x11.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
#include "x11/clutter-virtual-input-device-x11.h"
 | 
			
		||||
 | 
			
		||||
struct _ClutterVirtualInputDeviceX11
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDevice parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ClutterVirtualInputDeviceX11,
 | 
			
		||||
               clutter_virtual_input_device_x11,
 | 
			
		||||
               CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                         uint64_t                   time_us,
 | 
			
		||||
                                                         double                     dx,
 | 
			
		||||
                                                         double                     dy)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                         uint64_t                   time_us,
 | 
			
		||||
                                                         double                     x,
 | 
			
		||||
                                                         double                     y)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                                uint64_t                   time_us,
 | 
			
		||||
                                                uint32_t                   button,
 | 
			
		||||
                                                ClutterButtonState         button_state)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_device,
 | 
			
		||||
                                             uint64_t                   time_us,
 | 
			
		||||
                                             uint32_t                   key,
 | 
			
		||||
                                             ClutterKeyState            key_state)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_init (ClutterVirtualInputDeviceX11 *virtual_device_x11)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_virtual_input_device_x11_class_init (ClutterVirtualInputDeviceX11Class *klass)
 | 
			
		||||
{
 | 
			
		||||
  ClutterVirtualInputDeviceClass *virtual_input_device_class =
 | 
			
		||||
    CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_x11_notify_relative_motion;
 | 
			
		||||
  virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_x11_notify_absolute_motion;
 | 
			
		||||
  virtual_input_device_class->notify_button = clutter_virtual_input_device_x11_notify_button;
 | 
			
		||||
  virtual_input_device_class->notify_key = clutter_virtual_input_device_x11_notify_key;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								clutter/clutter/x11/clutter-virtual-input-device-x11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								clutter/clutter/x11/clutter-virtual-input-device-x11.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016  Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__
 | 
			
		||||
#define __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__
 | 
			
		||||
 | 
			
		||||
#include "clutter-virtual-input-device.h"
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11 (clutter_virtual_input_device_x11_get_type ())
 | 
			
		||||
G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceX11,
 | 
			
		||||
                      clutter_virtual_input_device_x11,
 | 
			
		||||
                      CLUTTER, VIRTUAL_INPUT_DEVICE_X11,
 | 
			
		||||
                      ClutterVirtualInputDevice)
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__ */
 | 
			
		||||
@@ -54,6 +54,8 @@ meta_input_settings_native_set_send_events (MetaInputSettings        *settings,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
  libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -65,6 +67,8 @@ meta_input_settings_native_set_matrix (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (libinput_device_config_calibration_has_matrix (libinput_device) > 0)
 | 
			
		||||
    libinput_device_config_calibration_set_matrix (libinput_device, matrix);
 | 
			
		||||
@@ -78,6 +82,8 @@ meta_input_settings_native_set_speed (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
  libinput_device_config_accel_set_speed (libinput_device,
 | 
			
		||||
                                          CLAMP (speed, -1, 1));
 | 
			
		||||
}
 | 
			
		||||
@@ -90,6 +96,8 @@ meta_input_settings_native_set_left_handed (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (libinput_device_config_left_handed_is_available (libinput_device))
 | 
			
		||||
    libinput_device_config_left_handed_set (libinput_device, enabled);
 | 
			
		||||
@@ -103,6 +111,8 @@ meta_input_settings_native_set_tap_enabled (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (libinput_device_config_tap_get_finger_count (libinput_device) > 0)
 | 
			
		||||
    libinput_device_config_tap_set_enabled (libinput_device,
 | 
			
		||||
@@ -119,6 +129,8 @@ meta_input_settings_native_set_invert_scroll (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (libinput_device_config_scroll_has_natural_scroll (libinput_device))
 | 
			
		||||
    libinput_device_config_scroll_set_natural_scroll_enabled (libinput_device,
 | 
			
		||||
@@ -163,6 +175,8 @@ meta_input_settings_native_set_edge_scroll (MetaInputSettings            *settin
 | 
			
		||||
  enum libinput_config_scroll_method supported;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
  supported = libinput_device_config_scroll_get_methods (libinput_device);
 | 
			
		||||
 | 
			
		||||
  if (supported & LIBINPUT_CONFIG_SCROLL_2FG)
 | 
			
		||||
@@ -190,6 +204,8 @@ meta_input_settings_native_set_scroll_button (MetaInputSettings  *settings,
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!device_set_scroll_method (libinput_device,
 | 
			
		||||
                                 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN))
 | 
			
		||||
@@ -207,6 +223,8 @@ meta_input_settings_native_set_click_method (MetaInputSettings           *settin
 | 
			
		||||
  struct libinput_device *libinput_device;
 | 
			
		||||
 | 
			
		||||
  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
 | 
			
		||||
  if (!libinput_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user