mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
evdev: First stab at an evdev backend
This backend is a event backend that can be enabled for EGL (for now). It uses udev (gudev) to query input devices on a linux system, listens to keyboard events from input devices and xkbcommon to translate raw key codes into key keysyms. This commit only supports key events, more to follow.
This commit is contained in:
parent
9f5f62b4b5
commit
c6493885c3
@ -433,14 +433,34 @@ egl_source_c_priv =
|
|||||||
|
|
||||||
egl_tslib_c = $(srcdir)/egl/clutter-event-tslib.c
|
egl_tslib_c = $(srcdir)/egl/clutter-event-tslib.c
|
||||||
|
|
||||||
|
evdev_c_priv = \
|
||||||
|
$(srcdir)/evdev/clutter-xkb-utils.c \
|
||||||
|
$(srcdir)/evdev/clutter-device-manager-evdev.c \
|
||||||
|
$(srcdir)/evdev/clutter-input-device-evdev.c \
|
||||||
|
$(srcdir)/evdev/clutter-event-evdev.c \
|
||||||
|
$(NULL)
|
||||||
|
evdev_h_priv = \
|
||||||
|
$(srcdir)/evdev/clutter-xkb-utils.h \
|
||||||
|
$(srcdir)/evdev/clutter-device-manager-evdev.h \
|
||||||
|
$(srcdir)/evdev/clutter-input-device-evdev.h \
|
||||||
|
$(srcdir)/evdev/clutter-event-evdev.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
egl_cex_c_priv = $(srcdir)/egl/clutter-backend-cex100.c
|
egl_cex_c_priv = $(srcdir)/egl/clutter-backend-cex100.c
|
||||||
egl_cex_h_priv = $(srcdir)/egl/clutter-backend-cex100.h
|
egl_cex_h_priv = $(srcdir)/egl/clutter-backend-cex100.h
|
||||||
egl_cex_h = $(srcdir)/egl/clutter-cex100.h
|
egl_cex_h = $(srcdir)/egl/clutter-cex100.h
|
||||||
|
|
||||||
if SUPPORT_EGL
|
if SUPPORT_EGL
|
||||||
|
|
||||||
if USE_TSLIB
|
if USE_TSLIB
|
||||||
egl_source_c_priv += $(egl_tslib_c)
|
egl_source_c_priv += $(egl_tslib_c)
|
||||||
endif # SUPPORT_TSLIB
|
endif # SUPPORT_TSLIB
|
||||||
|
|
||||||
|
if SUPPORT_EVDEV
|
||||||
|
egl_source_c_priv += $(evdev_c_priv)
|
||||||
|
egl_source_h_priv += $(evdev_h_priv)
|
||||||
|
endif # SUPPORT_EVDEV
|
||||||
|
|
||||||
if SUPPORT_CEX100
|
if SUPPORT_CEX100
|
||||||
egl_source_c_priv += $(egl_cex_c_priv)
|
egl_source_c_priv += $(egl_cex_c_priv)
|
||||||
egl_source_h_priv += $(egl_cex_h_priv)
|
egl_source_h_priv += $(egl_cex_h_priv)
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define __CLUTTER_DEVICE_MANAGER_PRIVATE_H__
|
#define __CLUTTER_DEVICE_MANAGER_PRIVATE_H__
|
||||||
|
|
||||||
#include <clutter/clutter-device-manager.h>
|
#include <clutter/clutter-device-manager.h>
|
||||||
|
#include <clutter/clutter-event.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -53,6 +53,10 @@ typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass;
|
|||||||
* @CLUTTER_POINTER_DEVICE: A pointer device
|
* @CLUTTER_POINTER_DEVICE: A pointer device
|
||||||
* @CLUTTER_KEYBOARD_DEVICE: A keyboard device
|
* @CLUTTER_KEYBOARD_DEVICE: A keyboard device
|
||||||
* @CLUTTER_EXTENSION_DEVICE: A generic extension device
|
* @CLUTTER_EXTENSION_DEVICE: A generic extension device
|
||||||
|
* @CLUTTER_JOYSTICK_DEVICE: A joystick device
|
||||||
|
* @CLUTTER_TABLET_DEVICE: A tablet device
|
||||||
|
* @CLUTTER_TOUCHPAD_DEVICE: A touchpad device
|
||||||
|
* @CLUTTER_TOUCHSCREEN_DEVICE: A touch screen device
|
||||||
* @CLUTTER_N_DEVICE_TYPES: The number of device types
|
* @CLUTTER_N_DEVICE_TYPES: The number of device types
|
||||||
*
|
*
|
||||||
* The types of input devices available.
|
* The types of input devices available.
|
||||||
@ -66,6 +70,10 @@ typedef enum {
|
|||||||
CLUTTER_POINTER_DEVICE,
|
CLUTTER_POINTER_DEVICE,
|
||||||
CLUTTER_KEYBOARD_DEVICE,
|
CLUTTER_KEYBOARD_DEVICE,
|
||||||
CLUTTER_EXTENSION_DEVICE,
|
CLUTTER_EXTENSION_DEVICE,
|
||||||
|
CLUTTER_JOYSTICK_DEVICE,
|
||||||
|
CLUTTER_TABLET_DEVICE,
|
||||||
|
CLUTTER_TOUCHPAD_DEVICE,
|
||||||
|
CLUTTER_TOUCHSCREEN_DEVICE,
|
||||||
|
|
||||||
CLUTTER_N_DEVICE_TYPES
|
CLUTTER_N_DEVICE_TYPES
|
||||||
} ClutterInputDeviceType;
|
} ClutterInputDeviceType;
|
||||||
|
@ -40,6 +40,11 @@
|
|||||||
#include "clutter-stage-egl.h"
|
#include "clutter-stage-egl.h"
|
||||||
#include "clutter-egl.h"
|
#include "clutter-egl.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_EVDEV
|
||||||
|
#include "clutter-device-manager-evdev.h"
|
||||||
|
#include "clutter-event-evdev.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
@ -516,14 +521,35 @@ clutter_backend_egl_redraw (ClutterBackend *backend,
|
|||||||
_clutter_stage_egl_redraw (CLUTTER_STAGE_EGL (impl), stage);
|
_clutter_stage_egl_redraw (CLUTTER_STAGE_EGL (impl), stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TSLIB
|
static ClutterDeviceManager *
|
||||||
|
clutter_backend_egl_get_device_manager (ClutterBackend *backend)
|
||||||
|
{
|
||||||
|
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (backend_egl->device_manager == NULL))
|
||||||
|
{
|
||||||
|
#ifdef HAVE_EVDEV
|
||||||
|
backend_egl->device_manager =
|
||||||
|
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
|
||||||
|
"backend", backend_egl,
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return backend_egl->device_manager;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_egl_init_events (ClutterBackend *backend)
|
clutter_backend_egl_init_events (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_TSLIB
|
||||||
/* XXX: This should be renamed to _clutter_events_tslib_init */
|
/* XXX: This should be renamed to _clutter_events_tslib_init */
|
||||||
_clutter_events_egl_init (CLUTTER_BACKEND_EGL (backend));
|
_clutter_events_egl_init (CLUTTER_BACKEND_EGL (backend));
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_EVDEV
|
||||||
|
_clutter_events_evdev_init (CLUTTER_BACKEND (backend));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_egl_finalize (GObject *gobject)
|
clutter_backend_egl_finalize (GObject *gobject)
|
||||||
@ -827,16 +853,15 @@ _clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
|
|||||||
gobject_class->dispose = clutter_backend_egl_dispose;
|
gobject_class->dispose = clutter_backend_egl_dispose;
|
||||||
gobject_class->finalize = clutter_backend_egl_finalize;
|
gobject_class->finalize = clutter_backend_egl_finalize;
|
||||||
|
|
||||||
backend_class->pre_parse = clutter_backend_egl_pre_parse;
|
backend_class->pre_parse = clutter_backend_egl_pre_parse;
|
||||||
backend_class->post_parse = clutter_backend_egl_post_parse;
|
backend_class->post_parse = clutter_backend_egl_post_parse;
|
||||||
backend_class->get_features = clutter_backend_egl_get_features;
|
backend_class->get_features = clutter_backend_egl_get_features;
|
||||||
#ifdef HAVE_TSLIB
|
backend_class->get_device_manager = clutter_backend_egl_get_device_manager;
|
||||||
backend_class->init_events = clutter_backend_egl_init_events;
|
backend_class->init_events = clutter_backend_egl_init_events;
|
||||||
#endif
|
backend_class->create_stage = clutter_backend_egl_create_stage;
|
||||||
backend_class->create_stage = clutter_backend_egl_create_stage;
|
backend_class->create_context = clutter_backend_egl_create_context;
|
||||||
backend_class->create_context = clutter_backend_egl_create_context;
|
backend_class->ensure_context = clutter_backend_egl_ensure_context;
|
||||||
backend_class->ensure_context = clutter_backend_egl_ensure_context;
|
backend_class->redraw = clutter_backend_egl_redraw;
|
||||||
backend_class->redraw = clutter_backend_egl_redraw;
|
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
backendx11_class->get_visual_info = clutter_backend_egl_get_visual_info;
|
backendx11_class->get_visual_info = clutter_backend_egl_get_visual_info;
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <clutter/clutter-event.h>
|
#include <clutter/clutter-event.h>
|
||||||
|
#include <clutter/clutter-backend.h>
|
||||||
|
#include <clutter/clutter-device-manager.h>
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@ -103,6 +106,9 @@ struct _ClutterBackendEGL
|
|||||||
/* main stage singleton */
|
/* main stage singleton */
|
||||||
ClutterStageWindow *stage;
|
ClutterStageWindow *stage;
|
||||||
|
|
||||||
|
/* device manager (ie evdev) */
|
||||||
|
ClutterDeviceManager *device_manager;
|
||||||
|
|
||||||
/* event source */
|
/* event source */
|
||||||
GSource *event_source;
|
GSource *event_source;
|
||||||
|
|
||||||
|
276
clutter/evdev/clutter-device-manager-evdev.c
Normal file
276
clutter/evdev/clutter-device-manager-evdev.c
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
|
||||||
|
#include "clutter-backend.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-device-manager.h"
|
||||||
|
#include "clutter-device-manager-private.h"
|
||||||
|
#include "clutter-input-device-evdev.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
#include "clutter-device-manager-evdev.h"
|
||||||
|
|
||||||
|
#define CLUTTER_DEVICE_MANAGER_EVDEV_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
|
||||||
|
CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, \
|
||||||
|
ClutterDeviceManagerEvdevPrivate))
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterDeviceManagerEvdev,
|
||||||
|
clutter_device_manager_evdev,
|
||||||
|
CLUTTER_TYPE_DEVICE_MANAGER);
|
||||||
|
|
||||||
|
struct _ClutterDeviceManagerEvdevPrivate
|
||||||
|
{
|
||||||
|
GUdevClient *udev_client;
|
||||||
|
|
||||||
|
GSList *devices;
|
||||||
|
|
||||||
|
ClutterInputDevice *core_pointer;
|
||||||
|
ClutterInputDevice *core_keyboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gchar *subsystems[] = { "input", NULL };
|
||||||
|
|
||||||
|
static void
|
||||||
|
evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
|
||||||
|
GUdevDevice *udev_device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *manager = (ClutterDeviceManager *) manager_evdev;
|
||||||
|
ClutterInputDeviceType type = CLUTTER_EXTENSION_DEVICE;
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
const gchar *dev_file;
|
||||||
|
const gchar * const *keys;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
dev_file = g_udev_device_get_device_file (udev_device);
|
||||||
|
|
||||||
|
if (g_udev_device_get_property (udev_device, "ID_INPUT") == NULL)
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (EVENT, "Ignoring device %s without ID_INPUT set", dev_file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = g_udev_device_get_property_keys (udev_device);
|
||||||
|
for (i = 0; keys[i]; i++)
|
||||||
|
{
|
||||||
|
/* Clutter assumes that device types are exclusive in the
|
||||||
|
* ClutterInputDevice API */
|
||||||
|
if (strcmp (keys[i], "ID_INPUT_KEY") == 0)
|
||||||
|
type = CLUTTER_KEYBOARD_DEVICE;
|
||||||
|
else if (strcmp (keys[i], "ID_INPUT_MOUSE") == 0)
|
||||||
|
type = CLUTTER_POINTER_DEVICE;
|
||||||
|
else if (strcmp (keys[i], "ID_INPUT_JOYSTICK") == 0)
|
||||||
|
type = CLUTTER_JOYSTICK_DEVICE;
|
||||||
|
else if (strcmp (keys[i], "ID_INPUT_TABLET") == 0)
|
||||||
|
type = CLUTTER_TABLET_DEVICE;
|
||||||
|
else if (strcmp (keys[i], "ID_INPUT_TOUCHPAD") == 0)
|
||||||
|
type = CLUTTER_TOUCHPAD_DEVICE;
|
||||||
|
else if (strcmp (keys[i], "ID_INPUT_TOUCHSCREEN") == 0)
|
||||||
|
type = CLUTTER_TOUCHSCREEN_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV,
|
||||||
|
"id", 0,
|
||||||
|
"name", "Evdev device", /* FIXME */
|
||||||
|
"device-type", type,
|
||||||
|
"sysfs-path", sysfs_path,
|
||||||
|
"device-path", device_file,
|
||||||
|
NULL);
|
||||||
|
_clutter_device_manager_add_device (manager, device);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (EVENT, "Added device %s, type %d", dev_file, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterDeviceManager implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_add_device (ClutterDeviceManager *manager,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
|
gboolean is_pointer, is_keyboard;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
|
is_pointer = device_type == CLUTTER_POINTER_DEVICE;
|
||||||
|
is_keyboard = device_type == CLUTTER_KEYBOARD_DEVICE;
|
||||||
|
|
||||||
|
priv->devices = g_slist_prepend (priv->devices, device);
|
||||||
|
|
||||||
|
if (is_pointer && priv->core_pointer == NULL)
|
||||||
|
priv->core_pointer = device;
|
||||||
|
|
||||||
|
if (is_keyboard && priv->core_keyboard == NULL)
|
||||||
|
priv->core_keyboard = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_remove_device (ClutterDeviceManager *manager,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
priv->devices = g_slist_remove (priv->devices, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GSList *
|
||||||
|
clutter_device_manager_evdev_get_devices (ClutterDeviceManager *manager)
|
||||||
|
{
|
||||||
|
return CLUTTER_DEVICE_MANAGER_EVDEV (manager)->priv->devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterInputDevice *
|
||||||
|
clutter_device_manager_evdev_get_core_device (ClutterDeviceManager *manager,
|
||||||
|
ClutterInputDeviceType type)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CLUTTER_POINTER_DEVICE:
|
||||||
|
return priv->core_pointer;
|
||||||
|
|
||||||
|
case CLUTTER_KEYBOARD_DEVICE:
|
||||||
|
return priv->core_keyboard;
|
||||||
|
|
||||||
|
case CLUTTER_EXTENSION_DEVICE:
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterInputDevice *
|
||||||
|
clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
||||||
|
gint id)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
for (l = priv->devices; l; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *device = l->data;
|
||||||
|
|
||||||
|
if (clutter_input_device_get_device_id (device) == id)
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GObject implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_constructed (GObject *gobject)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
GList *devices, *l;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (gobject);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
priv->udev_client = g_udev_client_new (subsystems);
|
||||||
|
|
||||||
|
devices = g_udev_client_query_by_subsystem (priv->udev_client, subsystems[0]);
|
||||||
|
for (l = devices; l; l = g_list_next (l))
|
||||||
|
{
|
||||||
|
GUdevDevice *device = l->data;
|
||||||
|
|
||||||
|
evdev_add_device (manager_evdev, device);
|
||||||
|
g_object_unref (device);
|
||||||
|
}
|
||||||
|
g_list_free (devices);
|
||||||
|
|
||||||
|
/* subcribe for events on input devices */
|
||||||
|
g_signal_connect (priv->udev_client, "uevent",
|
||||||
|
G_CALLBACK (on_uevent), manager_evdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (object);
|
||||||
|
priv = manager_evdev->priv;
|
||||||
|
|
||||||
|
g_object_unref (priv->udev_client);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerClass *manager_class;
|
||||||
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterDeviceManagerEvdevPrivate));
|
||||||
|
|
||||||
|
gobject_class->constructed = clutter_device_manager_evdev_constructed;
|
||||||
|
gobject_class->finalize = clutter_device_manager_evdev_finalize;
|
||||||
|
|
||||||
|
manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass);
|
||||||
|
manager_class->add_device = clutter_device_manager_evdev_add_device;
|
||||||
|
manager_class->remove_device = clutter_device_manager_evdev_remove_device;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_device_manager_evdev_init (ClutterDeviceManagerEvdev *self)
|
||||||
|
{
|
||||||
|
self->priv = CLUTTER_DEVICE_MANAGER_EVDEV_GET_PRIVATE (self);
|
||||||
|
}
|
58
clutter/evdev/clutter-device-manager-evdev.h
Normal file
58
clutter/evdev/clutter-device-manager-evdev.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_DEVICE_MANAGER_EVDEV_H__
|
||||||
|
#define __CLUTTER_DEVICE_MANAGER_EVDEV_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-device-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_DEVICE_MANAGER_EVDEV (clutter_device_manager_evdev_get_type ())
|
||||||
|
#define CLUTTER_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdev))
|
||||||
|
#define CLUTTER_IS_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV))
|
||||||
|
#define CLUTTER_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass))
|
||||||
|
#define CLUTTER_IS_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV))
|
||||||
|
#define CLUTTER_DEVICE_MANAGER_EVDEV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterDeviceManagerEvdev ClutterDeviceManagerEvdev;
|
||||||
|
typedef struct _ClutterDeviceManagerEvdevClass ClutterDeviceManagerEvdevClass;
|
||||||
|
typedef struct _ClutterDeviceManagerEvdevPrivate ClutterDeviceManagerEvdevPrivate;
|
||||||
|
|
||||||
|
struct _ClutterDeviceManagerEvdev
|
||||||
|
{
|
||||||
|
ClutterDeviceManager parent_instance;
|
||||||
|
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterDeviceManagerEvdevClass
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_device_manager_evdev_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
|
318
clutter/evdev/clutter-event-evdev.c
Normal file
318
clutter/evdev/clutter-event-evdev.c
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2007 OpenedHand
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
|
||||||
|
#include "clutter-backend.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-device-manager.h"
|
||||||
|
#include "clutter-event.h"
|
||||||
|
#include "clutter-input-device-evdev.h"
|
||||||
|
#include "clutter-main.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
#include "clutter-xkb-utils.h"
|
||||||
|
|
||||||
|
/* List of all the event sources */
|
||||||
|
static GSList *event_sources = NULL;
|
||||||
|
|
||||||
|
const char *option_xkb_layout = "us";
|
||||||
|
const char *option_xkb_variant = "";
|
||||||
|
const char *option_xkb_options = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterEventSource for reading input devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _ClutterEventSource ClutterEventSource;
|
||||||
|
|
||||||
|
struct _ClutterEventSource
|
||||||
|
{
|
||||||
|
GSource source;
|
||||||
|
|
||||||
|
ClutterInputDeviceEvdev *device; /* back pointer to the evdev device */
|
||||||
|
GPollFD event_poll_fd; /* file descriptor of the /dev node */
|
||||||
|
struct xkb_desc *xkb; /* compiled xkb keymap */
|
||||||
|
uint32_t modifier_state; /* remember the modifier state */
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_event_prepare (GSource *source,
|
||||||
|
gint *timeout)
|
||||||
|
{
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
clutter_threads_enter ();
|
||||||
|
|
||||||
|
*timeout = -1;
|
||||||
|
retval = clutter_events_pending ();
|
||||||
|
|
||||||
|
clutter_threads_leave ();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_event_check (GSource *source)
|
||||||
|
{
|
||||||
|
ClutterEventSource *event_source = (ClutterEventSource *) source;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
clutter_threads_enter ();
|
||||||
|
|
||||||
|
retval = ((event_source->event_poll_fd.revents & G_IO_IN) ||
|
||||||
|
clutter_events_pending ());
|
||||||
|
|
||||||
|
clutter_threads_leave ();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_event_dispatch (GSource *g_source,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterEventSource *source = (ClutterEventSource *) g_source;
|
||||||
|
ClutterInputDevice *input_device = (ClutterInputDevice *) source->device;
|
||||||
|
ClutterMainContext *clutter_context;
|
||||||
|
struct input_event ev[8];
|
||||||
|
ClutterEvent *event = NULL;
|
||||||
|
ClutterStage *stage;
|
||||||
|
gint len, i;
|
||||||
|
|
||||||
|
clutter_threads_enter ();
|
||||||
|
|
||||||
|
clutter_context = _clutter_context_get_default ();
|
||||||
|
stage = CLUTTER_STAGE (clutter_stage_get_default ());
|
||||||
|
|
||||||
|
/* Don't queue more events if we haven't finished handling the previous batch
|
||||||
|
*/
|
||||||
|
if (!clutter_events_pending ())
|
||||||
|
{
|
||||||
|
len = read (source->event_poll_fd.fd, &ev, sizeof (ev));
|
||||||
|
if (len < 0 || len % sizeof (ev[0]) != 0)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
{
|
||||||
|
g_warning ("Could not read device (%d)", errno);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len / sizeof (ev[0]); i++)
|
||||||
|
{
|
||||||
|
struct input_event *e = &ev[i];
|
||||||
|
uint32_t _time;
|
||||||
|
|
||||||
|
_time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
|
||||||
|
|
||||||
|
switch (e->type)
|
||||||
|
{
|
||||||
|
case EV_KEY:
|
||||||
|
|
||||||
|
/* don't repeat mouse buttons */
|
||||||
|
if (e->code >= BTN_MOUSE && e->code < KEY_OK)
|
||||||
|
if (e->value == 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
event =
|
||||||
|
_clutter_key_event_new_from_evdev (input_device,
|
||||||
|
stage,
|
||||||
|
source->xkb,
|
||||||
|
_time, e->code, e->value,
|
||||||
|
&source->modifier_state);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EV_SYN:
|
||||||
|
/* Nothing to do here? */
|
||||||
|
break;
|
||||||
|
case EV_MSC:
|
||||||
|
/* Nothing to do here? */
|
||||||
|
break;
|
||||||
|
case EV_ABS:
|
||||||
|
case EV_REL:
|
||||||
|
default:
|
||||||
|
g_warning ("Unhandled event of type %d", e->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
g_queue_push_head (clutter_context->events_queue, event);
|
||||||
|
event = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pop an event off the queue if any */
|
||||||
|
event = clutter_event_get ();
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
/* forward the event into clutter for emission etc. */
|
||||||
|
clutter_do_event (event);
|
||||||
|
clutter_event_free (event);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
clutter_threads_leave ();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static GSourceFuncs event_funcs = {
|
||||||
|
clutter_event_prepare,
|
||||||
|
clutter_event_check,
|
||||||
|
clutter_event_dispatch,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static GSource *
|
||||||
|
clutter_event_source_new (ClutterInputDeviceEvdev *input_device)
|
||||||
|
{
|
||||||
|
GSource *source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
|
||||||
|
ClutterEventSource *event_source = (ClutterEventSource *) source;
|
||||||
|
const gchar *node_path;
|
||||||
|
gint fd;
|
||||||
|
|
||||||
|
/* grab the udev input device node and open it */
|
||||||
|
node_path = _clutter_input_device_evdev_get_device_path (input_device);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (EVENT, "Creating GSource for device %s", node_path);
|
||||||
|
|
||||||
|
fd = open (node_path, O_RDONLY | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
g_warning ("Could not open device %s: %s", node_path, strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup the source */
|
||||||
|
event_source->device = input_device;
|
||||||
|
event_source->event_poll_fd.fd = fd;
|
||||||
|
event_source->event_poll_fd.events = G_IO_IN;
|
||||||
|
|
||||||
|
/* create the xkb description */
|
||||||
|
event_source->xkb = _clutter_xkb_desc_new (NULL,
|
||||||
|
option_xkb_layout,
|
||||||
|
option_xkb_variant,
|
||||||
|
option_xkb_options);
|
||||||
|
if (G_UNLIKELY (event_source->xkb == NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Could not compile keymap %s:%s:%s", option_xkb_layout,
|
||||||
|
option_xkb_variant, option_xkb_options);
|
||||||
|
close (fd);
|
||||||
|
g_source_unref (source);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and finally configure and attach the GSource */
|
||||||
|
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
|
||||||
|
g_source_add_poll (source, &event_source->event_poll_fd);
|
||||||
|
g_source_set_can_recurse (source, TRUE);
|
||||||
|
g_source_attach (source, NULL);
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_event_source_free (ClutterEventSource *source)
|
||||||
|
{
|
||||||
|
GSource *g_source = (GSource *) source;
|
||||||
|
const gchar *node_path;
|
||||||
|
|
||||||
|
node_path = _clutter_input_device_evdev_get_device_path (source->device);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (EVENT, "Removing GSource for device %s", node_path);
|
||||||
|
|
||||||
|
/* ignore the return value of close, it's not like we can do something
|
||||||
|
* about it */
|
||||||
|
close (source->event_poll_fd.fd);
|
||||||
|
|
||||||
|
g_source_destroy (g_source);
|
||||||
|
g_source_unref (g_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_clutter_event_evdev_add_source (ClutterInputDeviceEvdev *input_device)
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
source = clutter_event_source_new (input_device);
|
||||||
|
if (G_LIKELY (source))
|
||||||
|
event_sources = g_slist_prepend (event_sources, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_clutter_event_evdev_remove_source (ClutterEventSource *source)
|
||||||
|
{
|
||||||
|
clutter_event_source_free (source);
|
||||||
|
event_sources = g_slist_remove (event_sources, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_events_evdev_init (ClutterBackend *backend)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *device_manager;
|
||||||
|
GSList *devices, *l;
|
||||||
|
|
||||||
|
CLUTTER_NOTE (EVENT, "Initializing evdev backend");
|
||||||
|
|
||||||
|
/* Of course, we assume that the singleton will be a
|
||||||
|
* ClutterDeviceManagerEvdev */
|
||||||
|
device_manager = clutter_device_manager_get_default ();
|
||||||
|
|
||||||
|
devices = clutter_device_manager_list_devices (device_manager);
|
||||||
|
for (l = devices; l; l = g_slist_next (l))
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *input_device = l->data;
|
||||||
|
|
||||||
|
_clutter_event_evdev_add_source (input_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_events_evdev_uninit (ClutterBackend *backend)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = event_sources; l; l = g_slist_next (l))
|
||||||
|
{
|
||||||
|
ClutterEventSource *source = l->data;
|
||||||
|
|
||||||
|
clutter_event_source_free (source);
|
||||||
|
}
|
||||||
|
g_slist_free (event_sources);
|
||||||
|
}
|
36
clutter/evdev/clutter-event-evdev.h
Normal file
36
clutter/evdev/clutter-event-evdev.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_EVENT_EVDEV_H__
|
||||||
|
#define __CLUTTER_EVENT_EVDEV_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter-backend.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void _clutter_events_evdev_init (ClutterBackend *backend);
|
||||||
|
void _clutter_events_evdev_uninit (ClutterBackend *backend);
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_EVENT_EVDEV_H__ */
|
197
clutter/evdev/clutter-input-device-evdev.c
Normal file
197
clutter/evdev/clutter-input-device-evdev.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "clutter/clutter-device-manager-private.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
#include "clutter-input-device-evdev.h"
|
||||||
|
|
||||||
|
typedef struct _ClutterInputDeviceClass ClutterInputDeviceEvdevClass;
|
||||||
|
typedef struct _ClutterInputDeviceEvdevPrivate ClutterInputDeviceEvdevPrivate;
|
||||||
|
|
||||||
|
#define INPUT_DEVICE_EVDEV_PRIVATE(o) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, \
|
||||||
|
ClutterInputDeviceEvdevPrivate))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_SYSFS_PATH,
|
||||||
|
PROP_DEVICE_PATH,
|
||||||
|
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterInputDeviceEvdevPrivate
|
||||||
|
{
|
||||||
|
gchar *sysfs_path;
|
||||||
|
gchar *device_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterInputDeviceEvdev
|
||||||
|
{
|
||||||
|
ClutterInputDevice parent;
|
||||||
|
|
||||||
|
ClutterInputDeviceEvdevPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterInputDeviceEvdev,
|
||||||
|
clutter_input_device_evdev,
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE)
|
||||||
|
|
||||||
|
static GParamSpec *obj_props[PROP_LAST];
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_input_device_evdev_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *input = CLUTTER_INPUT_DEVICE_EVDEV (object);
|
||||||
|
ClutterInputDeviceEvdevPrivate *priv = input->priv;
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_SYSFS_PATH:
|
||||||
|
g_value_set_string (value, priv->sysfs_path);
|
||||||
|
break;
|
||||||
|
case PROP_DEVICE_PATH:
|
||||||
|
g_value_set_string (value, priv->device_path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_input_device_evdev_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *input = CLUTTER_INPUT_DEVICE_EVDEV (object);
|
||||||
|
ClutterInputDeviceEvdevPrivate *priv = input->priv;
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_SYSFS_PATH:
|
||||||
|
priv->sysfs_path = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
case PROP_DEVICE_PATH:
|
||||||
|
priv->device_path = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_input_device_evdev_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *input = CLUTTER_INPUT_DEVICE_EVDEV (object);
|
||||||
|
ClutterInputDeviceEvdevPrivate *priv = input->priv;
|
||||||
|
|
||||||
|
g_free (priv->sysfs_path);
|
||||||
|
g_free (priv->device_path);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterInputDeviceEvdevPrivate));
|
||||||
|
|
||||||
|
object_class->get_property = clutter_input_device_evdev_get_property;
|
||||||
|
object_class->set_property = clutter_input_device_evdev_set_property;
|
||||||
|
object_class->finalize = clutter_input_device_evdev_finalize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterInputDeviceEvdev:udev-device:
|
||||||
|
*
|
||||||
|
* The Sysfs path of the device
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
pspec =
|
||||||
|
g_param_spec_string ("sysfs-path",
|
||||||
|
P_("sysfs Path"),
|
||||||
|
P_("Path of the device in sysfs"),
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE);
|
||||||
|
obj_props[PROP_SYSFS_PATH] = pspec;
|
||||||
|
g_object_class_install_property (object_class, PROP_SYSFS_PATH, pspec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterInputDeviceEvdev:device-path
|
||||||
|
*
|
||||||
|
* The path of the device file.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
pspec =
|
||||||
|
g_param_spec_string ("device-path",
|
||||||
|
P_("Device Path"),
|
||||||
|
P_("Path of the device node"),
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE);
|
||||||
|
obj_props[PROP_DEVICE_PATH] = pspec;
|
||||||
|
g_object_class_install_property (object_class, PROP_DEVICE_PATH, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self)
|
||||||
|
{
|
||||||
|
self->priv = INPUT_DEVICE_EVDEV_PRIVATE (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterInputDeviceEvdev *
|
||||||
|
_clutter_input_device_evdev_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
_clutter_input_device_evdev_get_sysfs_path (ClutterInputDeviceEvdev *device)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_EVDEV (device), NULL);
|
||||||
|
|
||||||
|
return device->priv->sysfs_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
_clutter_input_device_evdev_get_device_path (ClutterInputDeviceEvdev *device)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_EVDEV (device), NULL);
|
||||||
|
|
||||||
|
return device->priv->device_path;
|
||||||
|
}
|
66
clutter/evdev/clutter-input-device-evdev.h
Normal file
66
clutter/evdev/clutter-input-device-evdev.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_INPUT_DEVICE_EVDEV_H__
|
||||||
|
#define __CLUTTER_INPUT_DEVICE_EVDEV_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter-input-device.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_INPUT_DEVICE_EVDEV clutter_input_device_evdev_get_type()
|
||||||
|
|
||||||
|
#define CLUTTER_INPUT_DEVICE_EVDEV(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdev))
|
||||||
|
|
||||||
|
#define CLUTTER_INPUT_DEVICE_EVDEV_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
|
||||||
|
|
||||||
|
#define CLUTTER_IS_INPUT_DEVICE_EVDEV(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV))
|
||||||
|
|
||||||
|
#define CLUTTER_IS_INPUT_DEVICE_EVDEV_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV))
|
||||||
|
|
||||||
|
#define CLUTTER_INPUT_DEVICE_EVDEV_GET_CLASS(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterInputDeviceEvdev ClutterInputDeviceEvdev;
|
||||||
|
|
||||||
|
GType clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterInputDeviceEvdev * _clutter_input_device_evdev_new (void);
|
||||||
|
const gchar * _clutter_input_device_evdev_get_sysfs_path (ClutterInputDeviceEvdev *device);
|
||||||
|
const gchar * _clutter_input_device_evdev_get_device_path (ClutterInputDeviceEvdev *device);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */
|
12
configure.ac
12
configure.ac
@ -315,7 +315,16 @@ AS_CASE([$CLUTTER_FLAVOUR],
|
|||||||
|
|
||||||
AS_IF([test x"$found_gdl" = "xno"], [AC_MSG_ERROR([libgdl.h not found])])
|
AS_IF([test x"$found_gdl" = "xno"], [AC_MSG_ERROR([libgdl.h not found])])
|
||||||
|
|
||||||
FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl"
|
# evdev
|
||||||
|
PKG_CHECK_MODULES(EVDEV, [gudev-1.0 xkbcommon],
|
||||||
|
[have_evdev=yes], [have_evdev=no])
|
||||||
|
AS_IF([test "x$have_evdev" = "xyes"],
|
||||||
|
[AC_DEFINE([HAVE_EVDEV], 1,
|
||||||
|
[Have evdev support for input handling])]
|
||||||
|
)
|
||||||
|
|
||||||
|
FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $EVDEV_CFLAGS"
|
||||||
|
FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl $EVDEV_LIBS"
|
||||||
],
|
],
|
||||||
|
|
||||||
[fruity],
|
[fruity],
|
||||||
@ -580,6 +589,7 @@ AS_IF([test "x$COGL_DRIVER" = "xgles"],
|
|||||||
)
|
)
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_TSLIB, [test "x$have_tslib" = "xyes"])
|
AM_CONDITIONAL(USE_TSLIB, [test "x$have_tslib" = "xyes"])
|
||||||
|
AM_CONDITIONAL(SUPPORT_EVDEV, [test "x$have_evdev" = "xyes"])
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_GLES2_WRAPPER, [test "x$use_gles2_wrapper" = "xyes"])
|
AM_CONDITIONAL(USE_GLES2_WRAPPER, [test "x$use_gles2_wrapper" = "xyes"])
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user