mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
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:
parent
d5331bfb57
commit
d23dd9af6b
@ -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 \
|
||||
|
@ -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__ */
|
||||
|
175
clutter/clutter-input-device.c
Normal file
175
clutter/clutter-input-device.c
Normal 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;
|
||||
}
|
64
clutter/clutter-input-device.h
Normal file
64
clutter/clutter-input-device.h
Normal 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__ */
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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 \
|
||||
|
@ -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 */
|
||||
}
|
||||
|
151
clutter/x11/clutter-input-device-x11.c
Normal file
151
clutter/x11/clutter-input-device-x11.c
Normal 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 */
|
||||
}
|
25
clutter/x11/clutter-input-device-x11.h
Normal file
25
clutter/x11/clutter-input-device-x11.h
Normal 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__ */
|
Loading…
Reference in New Issue
Block a user