forked from AuroraMiddleware/gtk
de9a082ddb
Previously we weren't installing the device headers when compiling without XINPUT support. But we would include them from gdkx.h, so essentially the build was broken. With this patch the types will exist but not do anything.
688 lines
22 KiB
C
688 lines
22 KiB
C
/* GDK - The GIMP Drawing Kit
|
|
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gdkx11devicemanager-xi.h"
|
|
#include "gdkdevicemanagerprivate-core.h"
|
|
#include "gdkdeviceprivate-xi.h"
|
|
|
|
#include "gdkdevicemanagerprivate.h"
|
|
#include "gdkeventtranslator.h"
|
|
#include "gdkintl.h"
|
|
#include "gdkprivate-x11.h"
|
|
|
|
#ifdef XINPUT_XFREE
|
|
|
|
#include <X11/extensions/XInput.h>
|
|
|
|
#endif /* XINPUT_XFREE */
|
|
|
|
struct _GdkX11DeviceManagerXI
|
|
{
|
|
GdkX11DeviceManagerCore parent_object;
|
|
|
|
GHashTable *id_table;
|
|
gint event_base;
|
|
GList *devices;
|
|
gboolean ignore_core_events;
|
|
};
|
|
|
|
struct _GdkX11DeviceManagerXIClass
|
|
{
|
|
GdkX11DeviceManagerCoreClass parent_class;
|
|
};
|
|
|
|
static void gdk_x11_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface);
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerXI, gdk_x11_device_manager_xi, GDK_TYPE_X11_DEVICE_MANAGER_CORE,
|
|
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
|
|
gdk_x11_device_manager_xi_event_translator_init))
|
|
|
|
#ifdef XINPUT_XFREE
|
|
|
|
static void gdk_x11_device_manager_xi_constructed (GObject *object);
|
|
static void gdk_x11_device_manager_xi_dispose (GObject *object);
|
|
static void gdk_x11_device_manager_xi_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec);
|
|
static void gdk_x11_device_manager_xi_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec);
|
|
|
|
static gboolean gdk_x11_device_manager_xi_translate_event (GdkEventTranslator *translator,
|
|
GdkDisplay *display,
|
|
GdkEvent *event,
|
|
XEvent *xevent);
|
|
static GList * gdk_x11_device_manager_xi_list_devices (GdkDeviceManager *device_manager,
|
|
GdkDeviceType type);
|
|
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_EVENT_BASE
|
|
};
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_class_init (GdkX11DeviceManagerXIClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
|
|
|
|
object_class->constructed = gdk_x11_device_manager_xi_constructed;
|
|
object_class->dispose = gdk_x11_device_manager_xi_dispose;
|
|
object_class->set_property = gdk_x11_device_manager_xi_set_property;
|
|
object_class->get_property = gdk_x11_device_manager_xi_get_property;
|
|
|
|
device_manager_class->list_devices = gdk_x11_device_manager_xi_list_devices;
|
|
|
|
g_object_class_install_property (object_class,
|
|
PROP_EVENT_BASE,
|
|
g_param_spec_int ("event-base",
|
|
P_("Event base"),
|
|
P_("Event base for XInput events"),
|
|
0, G_MAXINT, 0,
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
}
|
|
|
|
static GdkFilterReturn
|
|
window_input_info_filter (GdkXEvent *xevent,
|
|
GdkEvent *event,
|
|
gpointer user_data)
|
|
{
|
|
GdkDeviceManager *device_manager;
|
|
GdkDisplay *display;
|
|
GdkWindow *window;
|
|
XEvent *xev;
|
|
|
|
device_manager = user_data;
|
|
xev = (XEvent *) xevent;
|
|
|
|
display = gdk_device_manager_get_display (device_manager);
|
|
window = gdk_x11_window_lookup_for_display (display, xev->xany.window);
|
|
|
|
if (window && xev->type == ConfigureNotify)
|
|
_gdk_x11_device_xi_update_window_info (window);
|
|
|
|
return GDK_FILTER_CONTINUE;
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_init (GdkX11DeviceManagerXI *device_manager)
|
|
{
|
|
device_manager->id_table = g_hash_table_new_full (NULL, NULL, NULL,
|
|
(GDestroyNotify) g_object_unref);
|
|
|
|
gdk_window_add_filter (NULL, window_input_info_filter, device_manager);
|
|
}
|
|
|
|
static void
|
|
translate_class_info (GdkDevice *device,
|
|
XDeviceInfo *info)
|
|
{
|
|
GdkX11DeviceXI *device_xi;
|
|
XAnyClassPtr class;
|
|
gint i, j;
|
|
|
|
device_xi = GDK_X11_DEVICE_XI (device);
|
|
class = info->inputclassinfo;
|
|
|
|
for (i = 0; i < info->num_classes; i++)
|
|
{
|
|
switch (class->class)
|
|
{
|
|
case ButtonClass:
|
|
break;
|
|
case KeyClass:
|
|
{
|
|
XKeyInfo *xki = (XKeyInfo *)class;
|
|
guint num_keys;
|
|
|
|
num_keys = xki->max_keycode - xki->min_keycode + 1;
|
|
_gdk_device_set_keys (device, num_keys);
|
|
|
|
device_xi->min_keycode = xki->min_keycode;
|
|
|
|
break;
|
|
}
|
|
case ValuatorClass:
|
|
{
|
|
XValuatorInfo *xvi = (XValuatorInfo *)class;
|
|
|
|
for (j = 0; j < xvi->num_axes; j++)
|
|
{
|
|
GdkAxisUse use;
|
|
|
|
switch (j)
|
|
{
|
|
case 0:
|
|
use = GDK_AXIS_X;
|
|
break;
|
|
case 1:
|
|
use = GDK_AXIS_Y;
|
|
break;
|
|
case 2:
|
|
use = GDK_AXIS_PRESSURE;
|
|
break;
|
|
case 3:
|
|
use = GDK_AXIS_XTILT;
|
|
break;
|
|
case 4:
|
|
use = GDK_AXIS_YTILT;
|
|
break;
|
|
case 5:
|
|
use = GDK_AXIS_WHEEL;
|
|
break;
|
|
default:
|
|
use = GDK_AXIS_IGNORE;
|
|
}
|
|
|
|
_gdk_device_add_axis (device,
|
|
GDK_NONE,
|
|
use,
|
|
xvi->axes[j].min_value,
|
|
xvi->axes[j].max_value,
|
|
xvi->axes[j].resolution);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
class = (XAnyClassPtr) (((char *) class) + class->length);
|
|
}
|
|
}
|
|
|
|
/* old versions of XI.h don't define these */
|
|
#ifndef IsXExtensionKeyboard
|
|
#define IsXExtensionKeyboard 3
|
|
#define IsXExtensionPointer 4
|
|
#endif
|
|
|
|
static GdkDevice *
|
|
create_device (GdkDeviceManager *device_manager,
|
|
GdkDisplay *display,
|
|
XDeviceInfo *info)
|
|
{
|
|
GdkInputSource input_source;
|
|
GdkDevice *device;
|
|
|
|
if (info->use != IsXExtensionPointer &&
|
|
info->use != IsXExtensionKeyboard)
|
|
return NULL;
|
|
|
|
if (info->use == IsXExtensionKeyboard)
|
|
input_source = GDK_SOURCE_KEYBOARD;
|
|
else
|
|
{
|
|
gchar *tmp_name;
|
|
|
|
tmp_name = g_ascii_strdown (info->name, -1);
|
|
|
|
if (strstr (tmp_name, "eraser"))
|
|
input_source = GDK_SOURCE_ERASER;
|
|
else if (strstr (tmp_name, "cursor"))
|
|
input_source = GDK_SOURCE_CURSOR;
|
|
else if (strstr (tmp_name, "wacom") ||
|
|
strstr (tmp_name, "pen"))
|
|
input_source = GDK_SOURCE_PEN;
|
|
else
|
|
input_source = GDK_SOURCE_MOUSE;
|
|
|
|
g_free (tmp_name);
|
|
}
|
|
|
|
device = g_object_new (GDK_TYPE_X11_DEVICE_XI,
|
|
"name", info->name,
|
|
"type", GDK_DEVICE_TYPE_FLOATING,
|
|
"input-source", input_source,
|
|
"input-mode", GDK_MODE_DISABLED,
|
|
"has-cursor", FALSE,
|
|
"display", display,
|
|
"device-manager", device_manager,
|
|
"device-id", info->id,
|
|
NULL);
|
|
translate_class_info (device, info);
|
|
|
|
return device;
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_constructed (GObject *object)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
XDeviceInfo *devices;
|
|
gint i, num_devices;
|
|
GdkDisplay *display;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (object);
|
|
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
|
devices = XListInputDevices (GDK_DISPLAY_XDISPLAY (display), &num_devices);
|
|
|
|
for(i = 0; i < num_devices; i++)
|
|
{
|
|
GdkDevice *device;
|
|
|
|
device = create_device (GDK_DEVICE_MANAGER (object),
|
|
display, &devices[i]);
|
|
if (device)
|
|
{
|
|
device_manager->devices = g_list_prepend (device_manager->devices, device);
|
|
g_hash_table_insert (device_manager->id_table,
|
|
GINT_TO_POINTER (devices[i].id),
|
|
g_object_ref (device));
|
|
}
|
|
}
|
|
|
|
XFreeDeviceList (devices);
|
|
|
|
gdk_x11_register_standard_event_type (display,
|
|
device_manager->event_base,
|
|
15 /* Number of events */);
|
|
|
|
if (G_OBJECT_CLASS (gdk_x11_device_manager_xi_parent_class)->constructed)
|
|
G_OBJECT_CLASS (gdk_x11_device_manager_xi_parent_class)->constructed (object);
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_dispose (GObject *object)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (object);
|
|
g_list_foreach (device_manager->devices, (GFunc) g_object_unref, NULL);
|
|
g_list_free (device_manager->devices);
|
|
device_manager->devices = NULL;
|
|
|
|
if (device_manager->id_table != NULL)
|
|
{
|
|
g_hash_table_destroy (device_manager->id_table);
|
|
device_manager->id_table = NULL;
|
|
}
|
|
|
|
gdk_window_remove_filter (NULL, window_input_info_filter, object);
|
|
|
|
G_OBJECT_CLASS (gdk_x11_device_manager_xi_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_EVENT_BASE:
|
|
device_manager->event_base = g_value_get_int (value);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_EVENT_BASE:
|
|
g_value_set_int (value, device_manager->event_base);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface)
|
|
{
|
|
iface->translate_event = gdk_x11_device_manager_xi_translate_event;
|
|
}
|
|
|
|
/* combine the state of the core device and the device state
|
|
* into one - for now we do this in a simple-minded manner -
|
|
* we just take the keyboard portion of the core device and
|
|
* the button portion (all of?) the device state.
|
|
* Any button remapping should go on here.
|
|
*/
|
|
static guint
|
|
translate_state (guint state, guint device_state)
|
|
{
|
|
return device_state | (state & 0xFF);
|
|
}
|
|
|
|
static GdkDevice *
|
|
lookup_device (GdkX11DeviceManagerXI *manager,
|
|
XEvent *xevent)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
guint32 device_id;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (manager);
|
|
|
|
/* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
|
|
but it's potentially faster than scanning through the types of
|
|
every device. If we were deceived, then it won't match any of
|
|
the types for the device anyways */
|
|
device_id = ((XDeviceButtonEvent *)xevent)->deviceid;
|
|
|
|
return g_hash_table_lookup (device_manager->id_table, GINT_TO_POINTER (device_id));
|
|
}
|
|
|
|
static gboolean
|
|
gdk_x11_device_manager_xi_translate_event (GdkEventTranslator *translator,
|
|
GdkDisplay *display,
|
|
GdkEvent *event,
|
|
XEvent *xevent)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
GdkEventTranslatorIface *parent_iface;
|
|
GdkX11DeviceXI *device_xi;
|
|
GdkDevice *device;
|
|
GdkWindow *window;
|
|
|
|
parent_iface = g_type_interface_peek_parent (GDK_EVENT_TRANSLATOR_GET_IFACE (translator));
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (translator);
|
|
|
|
if (!device_manager->ignore_core_events &&
|
|
parent_iface->translate_event (translator, display, event, xevent))
|
|
return TRUE;
|
|
|
|
device = lookup_device (device_manager, xevent);
|
|
device_xi = GDK_X11_DEVICE_XI (device);
|
|
|
|
if (!device)
|
|
return FALSE;
|
|
|
|
window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
|
|
|
|
if (!window)
|
|
return FALSE;
|
|
|
|
if ((xevent->type == device_xi->button_press_type) ||
|
|
(xevent->type == device_xi->button_release_type))
|
|
{
|
|
XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *) xevent;
|
|
|
|
event->button.type = (xdbe->type == device_xi->button_press_type) ?
|
|
GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
|
|
|
event->button.device = device;
|
|
event->button.window = g_object_ref (window);
|
|
event->button.time = xdbe->time;
|
|
|
|
event->button.x_root = (gdouble) xdbe->x_root;
|
|
event->button.y_root = (gdouble) xdbe->y_root;
|
|
|
|
event->button.axes = g_new0 (gdouble, gdk_device_get_n_axes (device));
|
|
_gdk_x11_device_xi_update_axes (device, xdbe->axes_count,
|
|
xdbe->first_axis, xdbe->axis_data);
|
|
_gdk_x11_device_xi_translate_axes (device, window,
|
|
device_xi->axis_data,
|
|
event->button.axes,
|
|
&event->button.x,
|
|
&event->button.y);
|
|
|
|
event->button.state = translate_state (xdbe->state, xdbe->device_state);
|
|
event->button.button = xdbe->button;
|
|
|
|
if (event->button.type == GDK_BUTTON_PRESS)
|
|
_gdk_event_button_generate (gdk_window_get_display (event->button.window),
|
|
event);
|
|
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("button %s:\t\twindow: %ld device: %ld x,y: %f %f button: %d\n",
|
|
(event->button.type == GDK_BUTTON_PRESS) ? "press" : "release",
|
|
xdbe->window,
|
|
xdbe->deviceid,
|
|
event->button.x, event->button.y,
|
|
xdbe->button));
|
|
|
|
/* Update the timestamp of the latest user interaction, if the event has
|
|
* a valid timestamp.
|
|
*/
|
|
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
|
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
|
gdk_event_get_time (event));
|
|
return TRUE;
|
|
}
|
|
|
|
if ((xevent->type == device_xi->key_press_type) ||
|
|
(xevent->type == device_xi->key_release_type))
|
|
{
|
|
XDeviceKeyEvent *xdke = (XDeviceKeyEvent *) xevent;
|
|
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("device key %s:\twindow: %ld device: %ld keycode: %d\n",
|
|
(event->key.type == GDK_KEY_PRESS) ? "press" : "release",
|
|
xdke->window,
|
|
xdke->deviceid,
|
|
xdke->keycode));
|
|
|
|
if (xdke->keycode < device_xi->min_keycode ||
|
|
xdke->keycode >= device_xi->min_keycode + gdk_device_get_n_keys (device))
|
|
{
|
|
g_warning ("Invalid device key code received");
|
|
return FALSE;
|
|
}
|
|
|
|
gdk_device_get_key (device, xdke->keycode - device_xi->min_keycode,
|
|
&event->key.keyval,
|
|
&event->key.state);
|
|
|
|
if (event->key.keyval == 0)
|
|
{
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("\t\ttranslation - NONE\n"));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
event->key.type = (xdke->type == device_xi->key_press_type) ?
|
|
GDK_KEY_PRESS : GDK_KEY_RELEASE;
|
|
|
|
event->key.window = g_object_ref (window);
|
|
event->key.time = xdke->time;
|
|
|
|
event->key.state |= translate_state (xdke->state, xdke->device_state);
|
|
|
|
/* Add a string translation for the key event */
|
|
if ((event->key.keyval >= 0x20) && (event->key.keyval <= 0xFF))
|
|
{
|
|
event->key.length = 1;
|
|
event->key.string = g_new (gchar, 2);
|
|
event->key.string[0] = (gchar) event->key.keyval;
|
|
event->key.string[1] = 0;
|
|
}
|
|
else
|
|
{
|
|
event->key.length = 0;
|
|
event->key.string = g_new0 (gchar, 1);
|
|
}
|
|
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("\t\ttranslation - keyval: %d modifiers: %#x\n",
|
|
event->key.keyval,
|
|
event->key.state));
|
|
|
|
/* Update the timestamp of the latest user interaction, if the event has
|
|
* a valid timestamp.
|
|
*/
|
|
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
|
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
|
gdk_event_get_time (event));
|
|
return TRUE;
|
|
}
|
|
|
|
if (xevent->type == device_xi->motion_notify_type)
|
|
{
|
|
XDeviceMotionEvent *xdme = (XDeviceMotionEvent *) xevent;
|
|
|
|
event->motion.device = device;
|
|
|
|
if (device_xi->in_proximity)
|
|
device_manager->ignore_core_events = TRUE;
|
|
|
|
event->motion.x_root = (gdouble) xdme->x_root;
|
|
event->motion.y_root = (gdouble) xdme->y_root;
|
|
|
|
event->motion.axes = g_new0 (gdouble, gdk_device_get_n_axes (device));
|
|
_gdk_x11_device_xi_update_axes (device, xdme->axes_count,
|
|
xdme->first_axis, xdme->axis_data);
|
|
_gdk_x11_device_xi_translate_axes (device, window,
|
|
device_xi->axis_data,
|
|
event->motion.axes,
|
|
&event->motion.x,
|
|
&event->motion.y);
|
|
|
|
event->motion.type = GDK_MOTION_NOTIFY;
|
|
event->motion.window = g_object_ref (window);
|
|
event->motion.time = xdme->time;
|
|
event->motion.state = translate_state (xdme->state,
|
|
xdme->device_state);
|
|
event->motion.is_hint = xdme->is_hint;
|
|
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("motion notify:\t\twindow: %ld device: %ld x,y: %f %f state %#4x hint: %s\n",
|
|
xdme->window,
|
|
xdme->deviceid,
|
|
event->motion.x, event->motion.y,
|
|
event->motion.state,
|
|
(xdme->is_hint) ? "true" : "false"));
|
|
|
|
|
|
/* Update the timestamp of the latest user interaction, if the event has
|
|
* a valid timestamp.
|
|
*/
|
|
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
|
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
|
gdk_event_get_time (event));
|
|
return TRUE;
|
|
}
|
|
|
|
if (xevent->type == device_xi->proximity_in_type ||
|
|
xevent->type == device_xi->proximity_out_type)
|
|
{
|
|
XProximityNotifyEvent *xpne = (XProximityNotifyEvent *) xevent;
|
|
|
|
if (xevent->type == device_xi->proximity_in_type)
|
|
{
|
|
event->proximity.type = GDK_PROXIMITY_IN;
|
|
device_xi->in_proximity = TRUE;
|
|
device_manager->ignore_core_events = TRUE;
|
|
}
|
|
else
|
|
{
|
|
event->proximity.type = GDK_PROXIMITY_OUT;
|
|
device_xi->in_proximity = FALSE;
|
|
device_manager->ignore_core_events = FALSE;
|
|
}
|
|
|
|
event->proximity.device = device;
|
|
event->proximity.window = g_object_ref (window);
|
|
event->proximity.time = xpne->time;
|
|
|
|
/* Update the timestamp of the latest user interaction, if the event has
|
|
* a valid timestamp.
|
|
*/
|
|
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
|
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
|
gdk_event_get_time (event));
|
|
return TRUE;
|
|
}
|
|
|
|
if (xevent->type == device_xi->state_notify_type)
|
|
{
|
|
XDeviceStateNotifyEvent *xdse = (XDeviceStateNotifyEvent *) xevent;
|
|
XInputClass *input_class = (XInputClass *) xdse->data;
|
|
int i;
|
|
|
|
for (i = 0; i < xdse->num_classes; i++)
|
|
{
|
|
if (input_class->class == ValuatorClass)
|
|
_gdk_x11_device_xi_update_axes (device, gdk_device_get_n_axes (device), 0,
|
|
((XValuatorState *)input_class)->valuators);
|
|
|
|
input_class = (XInputClass *)(((char *)input_class)+input_class->length);
|
|
}
|
|
|
|
GDK_NOTE (EVENTS,
|
|
g_print ("device state notify:\t\twindow: %ld device: %ld\n",
|
|
xdse->window,
|
|
xdse->deviceid));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static GList *
|
|
gdk_x11_device_manager_xi_list_devices (GdkDeviceManager *manager,
|
|
GdkDeviceType type)
|
|
{
|
|
GdkX11DeviceManagerXI *device_manager;
|
|
|
|
device_manager = GDK_X11_DEVICE_MANAGER_XI (manager);
|
|
|
|
if (type == GDK_DEVICE_TYPE_MASTER)
|
|
return GDK_DEVICE_MANAGER_CLASS (gdk_x11_device_manager_xi_parent_class)->list_devices (manager, type);
|
|
else if (type == GDK_DEVICE_TYPE_FLOATING)
|
|
{
|
|
return g_list_copy (device_manager->devices);
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
#else /* XINPUT_XFREE */
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_class_init (GdkX11DeviceManagerXIClass *klass)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_init (GdkX11DeviceManagerXI *device_manager)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gdk_x11_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface)
|
|
{
|
|
}
|
|
|
|
#endif /* XINPUT_XFREE */
|