mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +00: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-flow-layout.h \
|
||||||
$(srcdir)/clutter-frame-source.h \
|
$(srcdir)/clutter-frame-source.h \
|
||||||
$(srcdir)/clutter-group.h \
|
$(srcdir)/clutter-group.h \
|
||||||
|
$(srcdir)/clutter-input-device.h \
|
||||||
$(srcdir)/clutter-interval.h \
|
$(srcdir)/clutter-interval.h \
|
||||||
$(srcdir)/clutter-keysyms.h \
|
$(srcdir)/clutter-keysyms.h \
|
||||||
$(srcdir)/clutter-layout-manager.h \
|
$(srcdir)/clutter-layout-manager.h \
|
||||||
@ -164,6 +165,7 @@ source_c = \
|
|||||||
$(srcdir)/clutter-flow-layout.c \
|
$(srcdir)/clutter-flow-layout.c \
|
||||||
$(srcdir)/clutter-frame-source.c \
|
$(srcdir)/clutter-frame-source.c \
|
||||||
$(srcdir)/clutter-group.c \
|
$(srcdir)/clutter-group.c \
|
||||||
|
$(srcdir)/clutter-input-device.c \
|
||||||
$(srcdir)/clutter-interval.c \
|
$(srcdir)/clutter-interval.c \
|
||||||
$(srcdir)/clutter-layout-manager.c \
|
$(srcdir)/clutter-layout-manager.c \
|
||||||
$(srcdir)/clutter-layout-meta.c \
|
$(srcdir)/clutter-layout-meta.c \
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define __CLUTTER_EVENT_H__
|
#define __CLUTTER_EVENT_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-input-device.h>
|
||||||
#include <clutter/clutter-types.h>
|
#include <clutter/clutter-types.h>
|
||||||
|
|
||||||
#define CLUTTER_TYPE_EVENT (clutter_event_get_type ())
|
#define CLUTTER_TYPE_EVENT (clutter_event_get_type ())
|
||||||
@ -201,37 +202,6 @@ typedef struct _ClutterScrollEvent ClutterScrollEvent;
|
|||||||
typedef struct _ClutterStageStateEvent ClutterStageStateEvent;
|
typedef struct _ClutterStageStateEvent ClutterStageStateEvent;
|
||||||
typedef struct _ClutterCrossingEvent ClutterCrossingEvent;
|
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:
|
* ClutterAnyEvent:
|
||||||
* @type: event type
|
* @type: event type
|
||||||
@ -509,9 +479,6 @@ guint32 clutter_keysym_to_unicode (guint k
|
|||||||
guint32 clutter_get_current_event_time (void);
|
guint32 clutter_get_current_event_time (void);
|
||||||
G_CONST_RETURN ClutterEvent *clutter_get_current_event (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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_EVENT_H__ */
|
#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__ */
|
@ -2046,10 +2046,10 @@ event_click_count_generate (ClutterEvent *event)
|
|||||||
static gint previous_button_number = -1;
|
static gint previous_button_number = -1;
|
||||||
|
|
||||||
ClutterBackend *backend;
|
ClutterBackend *backend;
|
||||||
guint double_click_time;
|
guint double_click_time;
|
||||||
guint double_click_distance;
|
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_distance = clutter_backend_get_double_click_distance (backend);
|
||||||
double_click_time = clutter_backend_get_double_click_time (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)
|
(ABS (event->button.y - previous_y) <= double_click_distance)
|
||||||
&& event->button.button == previous_button_number)
|
&& event->button.button == previous_button_number)
|
||||||
{
|
{
|
||||||
click_count ++;
|
click_count += 1;
|
||||||
}
|
}
|
||||||
else /* start a new click count*/
|
else /* start a new click count*/
|
||||||
{
|
{
|
||||||
click_count=1;
|
click_count = 1;
|
||||||
previous_button_number = event->button.button;
|
previous_button_number = event->button.button;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2086,13 +2086,14 @@ event_click_count_generate (ClutterEvent *event)
|
|||||||
* next event
|
* next event
|
||||||
*/
|
*/
|
||||||
previous_time = event->button.time;
|
previous_time = event->button.time;
|
||||||
previous_x = event->button.x;
|
previous_x = event->button.x;
|
||||||
previous_y = event->button.y;
|
previous_y = event->button.y;
|
||||||
|
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
event->button.click_count=click_count;
|
event->button.click_count = click_count;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert (NULL);
|
g_assert (NULL);
|
||||||
}
|
}
|
||||||
@ -2107,7 +2108,6 @@ event_click_count_generate (ClutterEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
emit_event (ClutterEvent *event,
|
emit_event (ClutterEvent *event,
|
||||||
gboolean is_key_event)
|
gboolean is_key_event)
|
||||||
@ -2209,7 +2209,7 @@ emit_pointer_event (ClutterEvent *event,
|
|||||||
static inline void
|
static inline void
|
||||||
emit_keyboard_event (ClutterEvent *event)
|
emit_keyboard_event (ClutterEvent *event)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = ClutterCntx;
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
|
|
||||||
if (G_UNLIKELY (context->keyboard_grab_actor != NULL))
|
if (G_UNLIKELY (context->keyboard_grab_actor != NULL))
|
||||||
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
||||||
@ -2220,7 +2220,7 @@ emit_keyboard_event (ClutterEvent *event)
|
|||||||
static void
|
static void
|
||||||
unset_motion_last_actor (ClutterActor *actor, ClutterInputDevice *dev)
|
unset_motion_last_actor (ClutterActor *actor, ClutterInputDevice *dev)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = ClutterCntx;
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
|
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
context->motion_last_actor = NULL;
|
context->motion_last_actor = NULL;
|
||||||
@ -2232,8 +2232,8 @@ static void
|
|||||||
set_motion_last_actor (ClutterActor *motion_current_actor,
|
set_motion_last_actor (ClutterActor *motion_current_actor,
|
||||||
ClutterInputDevice *device)
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = ClutterCntx;
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
ClutterActor *last_actor = context->motion_last_actor;
|
ClutterActor *last_actor = context->motion_last_actor;
|
||||||
|
|
||||||
if (device != NULL)
|
if (device != NULL)
|
||||||
last_actor = device->motion_last_actor;
|
last_actor = device->motion_last_actor;
|
||||||
@ -2262,10 +2262,10 @@ set_motion_last_actor (ClutterActor *motion_current_actor,
|
|||||||
static inline void
|
static inline void
|
||||||
generate_enter_leave_events (ClutterEvent *event)
|
generate_enter_leave_events (ClutterEvent *event)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = ClutterCntx;
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
ClutterActor *motion_current_actor = event->motion.source;
|
ClutterActor *motion_current_actor = event->motion.source;
|
||||||
ClutterActor *last_actor = context->motion_last_actor;
|
ClutterActor *last_actor = context->motion_last_actor;
|
||||||
ClutterInputDevice *device = clutter_event_get_device (event);
|
ClutterInputDevice *device = clutter_event_get_device (event);
|
||||||
|
|
||||||
if (device != NULL)
|
if (device != NULL)
|
||||||
last_actor = device->motion_last_actor;
|
last_actor = device->motion_last_actor;
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _ClutterMainContext ClutterMainContext;
|
typedef struct _ClutterMainContext ClutterMainContext;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CLUTTER_ACTOR_UNUSED_FLAG = 0,
|
CLUTTER_ACTOR_UNUSED_FLAG = 0,
|
||||||
@ -85,6 +85,8 @@ typedef enum {
|
|||||||
|
|
||||||
struct _ClutterInputDevice
|
struct _ClutterInputDevice
|
||||||
{
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
gint id;
|
gint id;
|
||||||
|
|
||||||
ClutterInputDeviceType device_type;
|
ClutterInputDeviceType device_type;
|
||||||
@ -93,10 +95,12 @@ struct _ClutterInputDevice
|
|||||||
ClutterActor *motion_last_actor;
|
ClutterActor *motion_last_actor;
|
||||||
|
|
||||||
gint click_count;
|
gint click_count;
|
||||||
gint previous_x;
|
|
||||||
gint previous_y;
|
gfloat previous_x;
|
||||||
|
gfloat previous_y;
|
||||||
guint32 previous_time;
|
guint32 previous_time;
|
||||||
gint previous_button_number;
|
gint previous_button_number;
|
||||||
|
ClutterModifierType previous_state;
|
||||||
|
|
||||||
guint is_default : 1;
|
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,
|
void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager,
|
||||||
ClutterInputDevice *device);
|
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 */
|
/* stage manager */
|
||||||
void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager,
|
void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager,
|
||||||
ClutterStage *stage);
|
ClutterStage *stage);
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include "clutter-flow-layout.h"
|
#include "clutter-flow-layout.h"
|
||||||
#include "clutter-frame-source.h"
|
#include "clutter-frame-source.h"
|
||||||
#include "clutter-group.h"
|
#include "clutter-group.h"
|
||||||
|
#include "clutter-input-device.h"
|
||||||
#include "clutter-interval.h"
|
#include "clutter-interval.h"
|
||||||
#include "clutter-keysyms.h"
|
#include "clutter-keysyms.h"
|
||||||
#include "clutter-layout-manager.h"
|
#include "clutter-layout-manager.h"
|
||||||
|
@ -43,6 +43,8 @@ libclutter_x11_la_SOURCES = \
|
|||||||
clutter-backend-x11.h \
|
clutter-backend-x11.h \
|
||||||
clutter-backend-x11.c \
|
clutter-backend-x11.c \
|
||||||
clutter-event-x11.c \
|
clutter-event-x11.c \
|
||||||
|
clutter-input-device-x11.h \
|
||||||
|
clutter-input-device-x11.c \
|
||||||
clutter-stage-x11.h \
|
clutter-stage-x11.h \
|
||||||
clutter-stage-x11.c \
|
clutter-stage-x11.c \
|
||||||
clutter-x11-enum-types.h \
|
clutter-x11-enum-types.h \
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "clutter-backend-x11.h"
|
#include "clutter-backend-x11.h"
|
||||||
|
#include "clutter-input-device-x11.h"
|
||||||
#include "clutter-stage-x11.h"
|
#include "clutter-stage-x11.h"
|
||||||
#include "clutter-x11.h"
|
#include "clutter-x11.h"
|
||||||
|
|
||||||
@ -56,18 +57,6 @@
|
|||||||
|
|
||||||
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND);
|
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
|
/* atoms; remember to add the code that assigns the atom value to
|
||||||
* the member of the ClutterBackendX11 structure if you add an
|
* the member of the ClutterBackendX11 structure if you add an
|
||||||
* atom name here. do not change the order!
|
* 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 == IsXExtensionKeyboard || XInput1 is broken */
|
||||||
info->use == IsXExtensionDevice)
|
info->use == IsXExtensionDevice)
|
||||||
{
|
{
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
XDevice *x_device;
|
gint n_events = 0;
|
||||||
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;
|
|
||||||
|
|
||||||
switch (info->use)
|
switch (info->use)
|
||||||
{
|
{
|
||||||
case IsXExtensionPointer:
|
case IsXExtensionPointer:
|
||||||
device->device.device_type = CLUTTER_POINTER_DEVICE;
|
device_type = CLUTTER_POINTER_DEVICE;
|
||||||
have_an_xpointer = TRUE;
|
have_an_xpointer = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* XInput1 is broken for keyboards */
|
/* XInput1 is broken for keyboards */
|
||||||
case IsXExtensionKeyboard:
|
case IsXExtensionKeyboard:
|
||||||
device->device.device_type = CLUTTER_KEYBOARD_DEVICE;
|
device_type = CLUTTER_KEYBOARD_DEVICE;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case IsXExtensionDevice:
|
case IsXExtensionDevice:
|
||||||
device->device.device_type = CLUTTER_EXTENSION_DEVICE;
|
device_type = CLUTTER_EXTENSION_DEVICE;
|
||||||
break;
|
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",
|
if (info->use == IsXExtensionPointer && n_events > 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
/* mark it as a default */
|
/* mark it as a default */
|
||||||
device->device.is_default = TRUE;
|
device->is_default = TRUE;
|
||||||
|
|
||||||
have_an_xpointer = TRUE;
|
have_an_xpointer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->num_events = n_events;
|
|
||||||
|
|
||||||
/* add it to a temporary list; we don't add the device
|
/* add it to a temporary list; we don't add the device
|
||||||
* straight to the device manager because the XInput
|
* straight to the device manager because the XInput
|
||||||
* initialization might still fail
|
* initialization might still fail
|
||||||
@ -279,20 +203,19 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend)
|
|||||||
|
|
||||||
for (l = devices; l != NULL; l = l->next)
|
for (l = devices; l != NULL; l = l->next)
|
||||||
_clutter_device_manager_add_device (manager, l->data);
|
_clutter_device_manager_add_device (manager, l->data);
|
||||||
|
|
||||||
|
backend->have_xinput = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
g_warning ("No usable XInput pointer devices found");
|
g_warning ("No usable XInput pointer devices found");
|
||||||
|
|
||||||
for (l = devices; l != NULL; l = l->next)
|
g_slist_foreach (devices, (GFunc) g_object_unref, NULL);
|
||||||
g_slice_free (ClutterX11XInputDevice, l->data);
|
|
||||||
|
backend->have_xinput = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free (devices);
|
g_slist_free (devices);
|
||||||
|
|
||||||
backend->have_xinput = TRUE;
|
|
||||||
#endif /* HAVE_XINPUT */
|
#endif /* HAVE_XINPUT */
|
||||||
|
|
||||||
default_device:
|
default_device:
|
||||||
@ -310,21 +233,20 @@ default_device:
|
|||||||
{
|
{
|
||||||
ClutterInputDevice *d;
|
ClutterInputDevice *d;
|
||||||
|
|
||||||
d = g_slice_new0 (ClutterInputDevice);
|
d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
|
||||||
d->id = 0;
|
"id", 0,
|
||||||
d->device_type = CLUTTER_POINTER_DEVICE;
|
"device-type", CLUTTER_POINTER_DEVICE,
|
||||||
d->click_count = 0;
|
NULL);
|
||||||
d->previous_time = CLUTTER_CURRENT_TIME;
|
|
||||||
d->previous_x = -1;
|
|
||||||
d->previous_y = -1;
|
|
||||||
d->previous_button_number = -1;
|
|
||||||
d->is_default = TRUE;
|
d->is_default = TRUE;
|
||||||
|
CLUTTER_NOTE (BACKEND, "Added default pointer device %d", d->id);
|
||||||
_clutter_device_manager_add_device (manager, d);
|
_clutter_device_manager_add_device (manager, d);
|
||||||
|
|
||||||
d = g_slice_new0 (ClutterInputDevice);
|
d = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11,
|
||||||
d->id = 1;
|
"id", 1,
|
||||||
d->device_type = CLUTTER_KEYBOARD_DEVICE;
|
"device-type", CLUTTER_KEYBOARD_DEVICE,
|
||||||
|
NULL);
|
||||||
d->is_default = TRUE;
|
d->is_default = TRUE;
|
||||||
|
CLUTTER_NOTE (BACKEND, "Added default keyboard device %d", d->id);
|
||||||
_clutter_device_manager_add_device (manager, d);
|
_clutter_device_manager_add_device (manager, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,12 +805,9 @@ _clutter_x11_select_events (Window xwin)
|
|||||||
l != NULL;
|
l != NULL;
|
||||||
l = l->next)
|
l = l->next)
|
||||||
{
|
{
|
||||||
ClutterX11XInputDevice *device = l->data;
|
ClutterInputDevice *device = l->data;
|
||||||
|
|
||||||
XSelectExtensionEvent (backend_singleton->xdpy,
|
_clutter_input_device_x11_select_events (device, backend_singleton, xwin);
|
||||||
xwin,
|
|
||||||
device->xevent_list,
|
|
||||||
device->num_events);
|
|
||||||
}
|
}
|
||||||
#endif /* HAVE_XINPUT */
|
#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…
x
Reference in New Issue
Block a user