diff --git a/clutter/Makefile.am b/clutter/Makefile.am index c61aea192..d8fb48fd0 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -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 \ diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h index 03d91549c..947536461 100644 --- a/clutter/clutter-event.h +++ b/clutter/clutter-event.h @@ -29,6 +29,7 @@ #define __CLUTTER_EVENT_H__ #include +#include #include #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__ */ diff --git a/clutter/clutter-input-device.c b/clutter/clutter-input-device.c new file mode 100644 index 000000000..dae5e92e2 --- /dev/null +++ b/clutter/clutter-input-device.c @@ -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; +} diff --git a/clutter/clutter-input-device.h b/clutter/clutter-input-device.h new file mode 100644 index 000000000..1d36278bc --- /dev/null +++ b/clutter/clutter-input-device.h @@ -0,0 +1,64 @@ +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __CLUTTER_INPUT_DEVICE_H__ +#define __CLUTTER_INPUT_DEVICE_H__ + +#include + +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__ */ diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 7d69fb8a0..d0438bbf2 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -2046,10 +2046,10 @@ event_click_count_generate (ClutterEvent *event) static gint previous_button_number = -1; ClutterBackend *backend; - guint double_click_time; - guint double_click_distance; + 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,11 +2074,11 @@ 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*/ { - click_count=1; + click_count = 1; previous_button_number = event->button.button; } @@ -2086,13 +2086,14 @@ event_click_count_generate (ClutterEvent *event) * next event */ previous_time = event->button.time; - previous_x = event->button.x; - previous_y = event->button.y; + previous_x = event->button.x; + previous_y = event->button.y; /* fallthrough */ case CLUTTER_BUTTON_RELEASE: - event->button.click_count=click_count; + 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,8 +2232,8 @@ static void set_motion_last_actor (ClutterActor *motion_current_actor, ClutterInputDevice *device) { - ClutterMainContext *context = ClutterCntx; - ClutterActor *last_actor = context->motion_last_actor; + ClutterMainContext *context = _clutter_context_get_default (); + ClutterActor *last_actor = context->motion_last_actor; if (device != NULL) last_actor = device->motion_last_actor; @@ -2262,10 +2262,10 @@ set_motion_last_actor (ClutterActor *motion_current_actor, static inline void generate_enter_leave_events (ClutterEvent *event) { - ClutterMainContext *context = ClutterCntx; - ClutterActor *motion_current_actor = event->motion.source; - ClutterActor *last_actor = context->motion_last_actor; - ClutterInputDevice *device = clutter_event_get_device (event); + 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); if (device != NULL) last_actor = device->motion_last_actor; diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index e2d5e2132..4f16bc33b 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -53,7 +53,7 @@ G_BEGIN_DECLS -typedef struct _ClutterMainContext ClutterMainContext; +typedef struct _ClutterMainContext ClutterMainContext; typedef enum { CLUTTER_ACTOR_UNUSED_FLAG = 0, @@ -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); diff --git a/clutter/clutter.h b/clutter/clutter.h index 971910976..fac430ae2 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -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" diff --git a/clutter/x11/Makefile.am b/clutter/x11/Makefile.am index 175f65d8b..820c700f4 100644 --- a/clutter/x11/Makefile.am +++ b/clutter/x11/Makefile.am @@ -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 \ diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c index c67963d1e..d8f026f05 100644 --- a/clutter/x11/clutter-backend-x11.c +++ b/clutter/x11/clutter-backend-x11.c @@ -37,6 +37,7 @@ #include #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 */ } diff --git a/clutter/x11/clutter-input-device-x11.c b/clutter/x11/clutter-input-device-x11.c new file mode 100644 index 000000000..e0edfd1e9 --- /dev/null +++ b/clutter/x11/clutter-input-device-x11.c @@ -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 +#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 */ +} diff --git a/clutter/x11/clutter-input-device-x11.h b/clutter/x11/clutter-input-device-x11.h new file mode 100644 index 000000000..b8d60ac46 --- /dev/null +++ b/clutter/x11/clutter-input-device-x11.h @@ -0,0 +1,25 @@ +#ifndef __CLUTTER_INPUT_DEVICE_X11_H__ +#define __CLUTTER_INPUT_DEVICE_X11_H__ + +#include +#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__ */