device: Make InputDevice an object and subclass it for X11

ClutterInputDevice should be a type that we can subclass per-backend
to add functionality.
This commit is contained in:
Emmanuele Bassi 2009-11-23 16:07:16 +00:00
parent d5331bfb57
commit d23dd9af6b
11 changed files with 484 additions and 165 deletions

View File

@ -92,6 +92,7 @@ source_h = \
$(srcdir)/clutter-flow-layout.h \
$(srcdir)/clutter-frame-source.h \
$(srcdir)/clutter-group.h \
$(srcdir)/clutter-input-device.h \
$(srcdir)/clutter-interval.h \
$(srcdir)/clutter-keysyms.h \
$(srcdir)/clutter-layout-manager.h \
@ -164,6 +165,7 @@ source_c = \
$(srcdir)/clutter-flow-layout.c \
$(srcdir)/clutter-frame-source.c \
$(srcdir)/clutter-group.c \
$(srcdir)/clutter-input-device.c \
$(srcdir)/clutter-interval.c \
$(srcdir)/clutter-layout-manager.c \
$(srcdir)/clutter-layout-meta.c \

View File

@ -29,6 +29,7 @@
#define __CLUTTER_EVENT_H__
#include <glib-object.h>
#include <clutter/clutter-input-device.h>
#include <clutter/clutter-types.h>
#define CLUTTER_TYPE_EVENT (clutter_event_get_type ())
@ -201,37 +202,6 @@ typedef struct _ClutterScrollEvent ClutterScrollEvent;
typedef struct _ClutterStageStateEvent ClutterStageStateEvent;
typedef struct _ClutterCrossingEvent ClutterCrossingEvent;
/**
* ClutterInputDevice:
*
* Generic representation of an input device. The
* actual contents of this structure depend on the
* backend used.
*/
typedef struct _ClutterInputDevice ClutterInputDevice;
/**
* ClutterInputDeviceType:
* @CLUTTER_POINTER_DEVICE: A pointer device
* @CLUTTER_KEYBOARD_DEVICE: A keyboard device
* @CLUTTER_EXTENSION_DEVICE: A generic extension device
* @CLUTTER_N_DEVICE_TYPES: The number of device types
*
* The types of input devices available.
*
* The #ClutterInputDeviceType enumeration can be extended at later
* date; not every platform supports every input device type.
*
* Since: 1.0
*/
typedef enum {
CLUTTER_POINTER_DEVICE,
CLUTTER_KEYBOARD_DEVICE,
CLUTTER_EXTENSION_DEVICE,
CLUTTER_N_DEVICE_TYPES
} ClutterInputDeviceType;
/**
* ClutterAnyEvent:
* @type: event type
@ -509,9 +479,6 @@ guint32 clutter_keysym_to_unicode (guint k
guint32 clutter_get_current_event_time (void);
G_CONST_RETURN ClutterEvent *clutter_get_current_event (void);
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
gint clutter_input_device_get_device_id (ClutterInputDevice *device);
G_END_DECLS
#endif /* __CLUTTER_EVENT_H__ */

View File

@ -0,0 +1,175 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-input-device.h"
#include "clutter-private.h"
enum
{
PROP_0,
PROP_ID,
PROP_DEVICE_TYPE
};
G_DEFINE_TYPE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT);
static void
clutter_input_device_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject);
switch (prop_id)
{
case PROP_ID:
self->id = g_value_get_int (value);
break;
case PROP_DEVICE_TYPE:
self->device_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_input_device_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject);
switch (prop_id)
{
case PROP_ID:
g_value_set_int (value, self->id);
break;
case PROP_DEVICE_TYPE:
g_value_set_enum (value, self->device_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_input_device_class_init (ClutterInputDeviceClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = clutter_input_device_set_property;
gobject_class->get_property = clutter_input_device_get_property;
pspec = g_param_spec_int ("id",
"Id",
"Unique identifier of the device",
-1, G_MAXINT,
0,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class, PROP_ID, pspec);
pspec = g_param_spec_enum ("device-type",
"Device Type",
"The type of the device",
CLUTTER_TYPE_INPUT_DEVICE_TYPE,
CLUTTER_POINTER_DEVICE,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class, PROP_DEVICE_TYPE, pspec);
}
static void
clutter_input_device_init (ClutterInputDevice *self)
{
self->id = -1;
self->device_type = CLUTTER_POINTER_DEVICE;
self->click_count = 0;
self->previous_time = CLUTTER_CURRENT_TIME;
self->previous_x = -1;
self->previous_y = -1;
self->previous_button_number = -1;
self->previous_state = 0;
}
void
_clutter_input_device_set_coords (ClutterInputDevice *device,
gfloat x,
gfloat y)
{
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
device->previous_x = floorf (x) + 0.5;
device->previous_y = floorf (y) + 0.5;
}
void
_clutter_input_device_set_state (ClutterInputDevice *device,
ClutterModifierType state)
{
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
device->previous_state = state;
}
void
_clutter_input_device_set_time (ClutterInputDevice *device,
guint32 time_)
{
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
device->previous_time = time_;
}
/**
* clutter_input_device_get_device_type:
* @device: a #ClutterInputDevice
*
* Retrieves the type of @device
*
* Return value: the type of the device
*
* Since: 1.0
*/
ClutterInputDeviceType
clutter_input_device_get_device_type (ClutterInputDevice *device)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
CLUTTER_POINTER_DEVICE);
return device->device_type;
}
/**
* clutter_input_device_get_device_id:
* @device: a #ClutterInputDevice
*
* Retrieves the unique identifier of @device
*
* Return value: the identifier of the device
*
* Since: 1.0
*/
gint
clutter_input_device_get_device_id (ClutterInputDevice *device)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), -1);
return device->id;
}

View File

@ -0,0 +1,64 @@
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_INPUT_DEVICE_H__
#define __CLUTTER_INPUT_DEVICE_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ())
#define CLUTTER_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDevice))
#define CLUTTER_IS_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE))
#define CLUTTER_INPUT_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDeviceClass))
#define CLUTTER_IS_INPUT_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_INPUT_DEVICE))
#define CLUTTER_INPUT_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDeviceClass))
/**
* ClutterInputDevice:
*
* Generic representation of an input device. The
* actual contents of this structure depend on the
* backend used.
*/
typedef struct _ClutterInputDevice ClutterInputDevice;
typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass;
/**
* ClutterInputDeviceType:
* @CLUTTER_POINTER_DEVICE: A pointer device
* @CLUTTER_KEYBOARD_DEVICE: A keyboard device
* @CLUTTER_EXTENSION_DEVICE: A generic extension device
* @CLUTTER_N_DEVICE_TYPES: The number of device types
*
* The types of input devices available.
*
* The #ClutterInputDeviceType enumeration can be extended at later
* date; not every platform supports every input device type.
*
* Since: 1.0
*/
typedef enum {
CLUTTER_POINTER_DEVICE,
CLUTTER_KEYBOARD_DEVICE,
CLUTTER_EXTENSION_DEVICE,
CLUTTER_N_DEVICE_TYPES
} ClutterInputDeviceType;
struct _ClutterInputDeviceClass
{
/*< private >*/
GObjectClass parent_class;
};
GType clutter_input_device_get_type (void) G_GNUC_CONST;
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
gint clutter_input_device_get_device_id (ClutterInputDevice *device);
G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_H__ */

View File

@ -2049,7 +2049,7 @@ event_click_count_generate (ClutterEvent *event)
guint double_click_time;
guint double_click_distance;
backend = _clutter_context_get_default ()->backend;
backend = clutter_get_default_backend ();
double_click_distance = clutter_backend_get_double_click_distance (backend);
double_click_time = clutter_backend_get_double_click_time (backend);
@ -2074,7 +2074,7 @@ event_click_count_generate (ClutterEvent *event)
(ABS (event->button.y - previous_y) <= double_click_distance)
&& event->button.button == previous_button_number)
{
click_count ++;
click_count += 1;
}
else /* start a new click count*/
{
@ -2093,6 +2093,7 @@ event_click_count_generate (ClutterEvent *event)
case CLUTTER_BUTTON_RELEASE:
event->button.click_count = click_count;
break;
default:
g_assert (NULL);
}
@ -2107,7 +2108,6 @@ event_click_count_generate (ClutterEvent *event)
}
}
static inline void
emit_event (ClutterEvent *event,
gboolean is_key_event)
@ -2209,7 +2209,7 @@ emit_pointer_event (ClutterEvent *event,
static inline void
emit_keyboard_event (ClutterEvent *event)
{
ClutterMainContext *context = ClutterCntx;
ClutterMainContext *context = _clutter_context_get_default ();
if (G_UNLIKELY (context->keyboard_grab_actor != NULL))
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
@ -2220,7 +2220,7 @@ emit_keyboard_event (ClutterEvent *event)
static void
unset_motion_last_actor (ClutterActor *actor, ClutterInputDevice *dev)
{
ClutterMainContext *context = ClutterCntx;
ClutterMainContext *context = _clutter_context_get_default ();
if (dev == NULL)
context->motion_last_actor = NULL;
@ -2232,7 +2232,7 @@ static void
set_motion_last_actor (ClutterActor *motion_current_actor,
ClutterInputDevice *device)
{
ClutterMainContext *context = ClutterCntx;
ClutterMainContext *context = _clutter_context_get_default ();
ClutterActor *last_actor = context->motion_last_actor;
if (device != NULL)
@ -2262,7 +2262,7 @@ set_motion_last_actor (ClutterActor *motion_current_actor,
static inline void
generate_enter_leave_events (ClutterEvent *event)
{
ClutterMainContext *context = ClutterCntx;
ClutterMainContext *context = _clutter_context_get_default ();
ClutterActor *motion_current_actor = event->motion.source;
ClutterActor *last_actor = context->motion_last_actor;
ClutterInputDevice *device = clutter_event_get_device (event);

View File

@ -85,6 +85,8 @@ typedef enum {
struct _ClutterInputDevice
{
GObject parent_instance;
gint id;
ClutterInputDeviceType device_type;
@ -93,10 +95,12 @@ struct _ClutterInputDevice
ClutterActor *motion_last_actor;
gint click_count;
gint previous_x;
gint previous_y;
gfloat previous_x;
gfloat previous_y;
guint32 previous_time;
gint previous_button_number;
ClutterModifierType previous_state;
guint is_default : 1;
};
@ -190,6 +194,15 @@ void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager
void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager,
ClutterInputDevice *device);
/* input device */
void _clutter_input_device_set_coords (ClutterInputDevice *device,
gfloat x,
gfloat y);
void _clutter_input_device_set_state (ClutterInputDevice *device,
ClutterModifierType state);
void _clutter_input_device_set_time (ClutterInputDevice *device,
guint32 time_);
/* stage manager */
void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager,
ClutterStage *stage);

View File

@ -58,6 +58,7 @@
#include "clutter-flow-layout.h"
#include "clutter-frame-source.h"
#include "clutter-group.h"
#include "clutter-input-device.h"
#include "clutter-interval.h"
#include "clutter-keysyms.h"
#include "clutter-layout-manager.h"

View File

@ -43,6 +43,8 @@ libclutter_x11_la_SOURCES = \
clutter-backend-x11.h \
clutter-backend-x11.c \
clutter-event-x11.c \
clutter-input-device-x11.h \
clutter-input-device-x11.c \
clutter-stage-x11.h \
clutter-stage-x11.c \
clutter-x11-enum-types.h \

View File

@ -37,6 +37,7 @@
#include <errno.h>
#include "clutter-backend-x11.h"
#include "clutter-input-device-x11.h"
#include "clutter-stage-x11.h"
#include "clutter-x11.h"
@ -56,18 +57,6 @@
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND);
/* a specific X11 input device */
struct _ClutterX11XInputDevice
{
ClutterInputDevice device;
#ifdef HAVE_XINPUT
XDevice *xdevice;
XEventClass xevent_list[5]; /* MAX 5 event types */
int num_events;
#endif
};
/* atoms; remember to add the code that assigns the atom value to
* the member of the ClutterBackendX11 structure if you add an
* atom name here. do not change the order!
@ -159,108 +148,43 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
/* info->use == IsXExtensionKeyboard || XInput1 is broken */
info->use == IsXExtensionDevice)
{
ClutterInputDeviceType device_type;
ClutterInputDevice *device;
XDevice *x_device;
int n_events = 0;
int j;
clutter_x11_trap_x_errors ();
x_device = XOpenDevice (backend->xdpy, info->id);
if (clutter_x11_untrap_x_errors () || x_device == NULL)
{
CLUTTER_NOTE (BACKEND, "Unable to open device %li", info->id);
continue;
}
device = g_slice_new0 (ClutterX11XInputDevice);
device->device.id = info->id;
device->device.click_count = 0;
device->device.previous_time = CLUTTER_CURRENT_TIME;
device->device.previous_x = -1;
device->device.previous_y = -1;
device->device.previous_button_number = -1;
gint n_events = 0;
switch (info->use)
{
case IsXExtensionPointer:
device->device.device_type = CLUTTER_POINTER_DEVICE;
device_type = CLUTTER_POINTER_DEVICE;
have_an_xpointer = TRUE;
break;
#if 0
/* XInput1 is broken for keyboards */
case IsXExtensionKeyboard:
device->device.device_type = CLUTTER_KEYBOARD_DEVICE;
device_type = CLUTTER_KEYBOARD_DEVICE;
break;
#endif
case IsXExtensionDevice:
device->device.device_type = CLUTTER_EXTENSION_DEVICE;
device_type = CLUTTER_EXTENSION_DEVICE;
break;
}
device->xdevice = x_device;
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
"id", info->id,
"device-type", device_type,
NULL);
n_events = _clutter_input_device_x11_construct (device, backend);
CLUTTER_NOTE (BACKEND, "Registering XINPUT device with XID: %li",
x_device->device_id);
/* We must go through all the classes supported by this device and
* register the appropriate events we want. Each class only appears
* once. We need to store the types with the stage since they are
* created dynamically by the server. They are not device specific.
*/
for (j = 0; j < xdevice->num_classes; j++)
{
XInputClassInfo *xclass_info = xdevice->classes + j;
switch (xclass_info->input_class)
{
#if 0
/* XInput 1.x is broken for keyboards: */
case KeyClass:
DeviceKeyPress (xdevice,
x11b->event_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT],
device->xevent_list [num_events]);
n_events++;
DeviceKeyRelease (xdevice,
x11b->event_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT],
device->xevent_list [num_events]);
n_events++;
break;
#endif
case ButtonClass:
DeviceButtonPress (xdevice,
x11b->event_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT],
device->xevent_list [num_events]);
n_events++;
DeviceButtonRelease (xdevice,
x11b->event_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT],
device->xevent_list [num_events]);
n_events++;
break;
case ValuatorClass:
DeviceMotionNotify (xdevice,
x11b->event_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT],
device->xevent_list [num_events]);
n_events++;
break;
}
}
if (info->use == IsXExtensionPointer && num_events > 0)
if (info->use == IsXExtensionPointer && n_events > 0)
{
/* mark it as a default */
device->device.is_default = TRUE;
device->is_default = TRUE;
have_an_xpointer = TRUE;
}
device->num_events = n_events;
/* add it to a temporary list; we don't add the device
* straight to the device manager because the XInput
* initialization might still fail
@ -279,20 +203,19 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
for (l = devices; l != NULL; l = l->next)
_clutter_device_manager_add_device (manager, l->data);
backend->have_xinput = TRUE;
}
else
{
GSList *l;
g_warning ("No usable XInput pointer devices found");
for (l = devices; l != NULL; l = l->next)
g_slice_free (ClutterX11XInputDevice, l->data);
g_slist_foreach (devices, (GFunc) g_object_unref, NULL);
backend->have_xinput = FALSE;
}
g_slist_free (devices);
backend->have_xinput = TRUE;
#endif /* HAVE_XINPUT */
default_device:
@ -310,21 +233,20 @@ default_device:
{
ClutterInputDevice *d;
d = g_slice_new0 (ClutterInputDevice);
d->id = 0;
d->device_type = CLUTTER_POINTER_DEVICE;
d->click_count = 0;
d->previous_time = CLUTTER_CURRENT_TIME;
d->previous_x = -1;
d->previous_y = -1;
d->previous_button_number = -1;
d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
"id", 0,
"device-type", CLUTTER_POINTER_DEVICE,
NULL);
d->is_default = TRUE;
CLUTTER_NOTE (BACKEND, "Added default pointer device %d", d->id);
_clutter_device_manager_add_device (manager, d);
d = g_slice_new0 (ClutterInputDevice);
d->id = 1;
d->device_type = CLUTTER_KEYBOARD_DEVICE;
d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
"id", 1,
"device-type", CLUTTER_KEYBOARD_DEVICE,
NULL);
d->is_default = TRUE;
CLUTTER_NOTE (BACKEND, "Added default keyboard device %d", d->id);
_clutter_device_manager_add_device (manager, d);
}
}
@ -883,12 +805,9 @@ _clutter_x11_select_events (Window xwin)
l != NULL;
l = l->next)
{
ClutterX11XInputDevice *device = l->data;
ClutterInputDevice *device = l->data;
XSelectExtensionEvent (backend_singleton->xdpy,
xwin,
device->xevent_list,
device->num_events);
_clutter_input_device_x11_select_events (device, backend_singleton, xwin);
}
#endif /* HAVE_XINPUT */
}

View File

@ -0,0 +1,151 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-input-device-x11.h"
#include "../clutter-debug.h"
#include "../clutter-private.h"
#ifdef HAVE_XINPUT
#include <X11/extensions/XInput.h>
#endif
typedef struct _ClutterInputDeviceClass ClutterInputDeviceX11Class;
/* a specific X11 input device */
struct _ClutterInputDeviceX11
{
ClutterInputDevice device;
#ifdef HAVE_XINPUT
XDevice *xdevice;
XEventClass xevent_list[5]; /* MAX 5 event types */
int num_events;
#endif
};
G_DEFINE_TYPE (ClutterInputDeviceX11,
clutter_input_device_x11,
CLUTTER_TYPE_INPUT_DEVICE);
static void
clutter_input_device_x11_class_init (ClutterInputDeviceX11Class *klass)
{
}
static void
clutter_input_device_x11_init (ClutterInputDeviceX11 *self)
{
}
gint
_clutter_input_device_x11_construct (ClutterInputDevice *device,
ClutterBackendX11 *backend)
{
int n_events = 0;
#ifdef HAVE_XINPUT
ClutterInputDeviceX11 *device_x11;
XDevice *x_device = NULL;
gint device_id;
int i;
device_x11 = CLUTTER_INPUT_DEVICE_X11 (device);
device_id = clutter_input_device_get_device_id (device);
clutter_x11_trap_x_errors ();
/* retrieve the X11 device */
x_device = XOpenDevice (backend->xdpy, device_id);
if (clutter_x11_untrap_x_errors () || x_device == NULL)
{
CLUTTER_NOTE (BACKEND, "Unable to open device %i", device_id);
return 0;
}
device_x11->xdevice = x_device;
CLUTTER_NOTE (BACKEND,
"Registering XINPUT device with XID: %li",
x_device->device_id);
/* We must go through all the classes supported by this device and
* register the appropriate events we want. Each class only appears
* once. We need to store the types with the stage since they are
* created dynamically by the server. They are not device specific.
*/
for (i = 0; i < x_device->num_classes; i++)
{
XInputClassInfo *xclass_info = x_device->classes + i;
int button_press, button_release, motion_notify;
button_press =
backend->event_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT];
button_release =
backend->event_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT];
motion_notify =
backend->event_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT];
switch (xclass_info->input_class)
{
#if 0
/* XInput 1.x is broken for keyboards: */
case KeyClass:
DeviceKeyPress (xdevice,
backend->event_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT],
device_x11->xevent_list[n_events]);
n_events++;
DeviceKeyRelease (xdevice,
backend->event_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT],
device_x11->xevent_list[n_events]);
n_events++;
break;
#endif
case ButtonClass:
DeviceButtonPress (x_device,
button_press,
device_x11->xevent_list[n_events]);
n_events++;
DeviceButtonRelease (x_device,
button_release,
device_x11->xevent_list[n_events]);
n_events++;
break;
case ValuatorClass:
DeviceMotionNotify (x_device,
motion_notify,
device_x11->xevent_list[n_events]);
n_events++;
break;
}
}
device_x11->num_events = n_events;
#endif /* HAVE_XINPUT */
return n_events;
}
void
_clutter_input_device_x11_select_events (ClutterInputDevice *device,
ClutterBackendX11 *backend_x11,
Window xwin)
{
#if HAVE_XINPUT
ClutterInputDeviceX11 *device_x11;
device_x11 = CLUTTER_INPUT_DEVICE_X11 (device);
if (device_x11->xdevice == None || device_x11->num_events == 0)
return;
XSelectExtensionEvent (backend_x11->xdpy, xwin,
device_x11->xevent_list,
device_x11->num_events);
#endif /* HAVE_XINPUT */
}

View File

@ -0,0 +1,25 @@
#ifndef __CLUTTER_INPUT_DEVICE_X11_H__
#define __CLUTTER_INPUT_DEVICE_X11_H__
#include <clutter/clutter-input-device.h>
#include "clutter-backend-x11.h"
G_BEGIN_DECLS
#define CLUTTER_TYPE_INPUT_DEVICE_X11 (clutter_input_device_x11_get_type ())
#define CLUTTER_INPUT_DEVICE_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE_X11, ClutterInputDeviceX11))
#define CLUTTER_IS_INPUT_DEVICE_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE_X11))
typedef struct _ClutterInputDeviceX11 ClutterInputDeviceX11;
GType clutter_input_device_x11_get_type (void) G_GNUC_CONST;
gint _clutter_input_device_x11_construct (ClutterInputDevice *device,
ClutterBackendX11 *backend);
void _clutter_input_device_x11_select_events (ClutterInputDevice *device,
ClutterBackendX11 *backend,
Window xwin);
G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_X11_H__ */