[gtk+/xi2: 318/1239] Add initial XI2 GdkDeviceManager implementation.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 318/1239] Add initial XI2 GdkDeviceManager implementation.
- Date: Tue, 29 Sep 2009 10:46:24 +0000 (UTC)
commit 1ca43e353c8c31bf2b2033b0d3b83f9a5084f9a3
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Jun 14 19:14:14 2009 +0200
Add initial XI2 GdkDeviceManager implementation.
configure.in | 6 +-
gdk/x11/Makefile.am | 7 +-
gdk/x11/gdkdevicemanager-x11.c | 38 ++++++
gdk/x11/gdkdevicemanager-xi2.c | 273 ++++++++++++++++++++++++++++++++++++++++
gdk/x11/gdkdevicemanager-xi2.h | 59 +++++++++
5 files changed, 381 insertions(+), 2 deletions(-)
---
diff --git a/configure.in b/configure.in
index faf9496..55defa5 100644
--- a/configure.in
+++ b/configure.in
@@ -1560,9 +1560,12 @@ if test "x$gdktarget" = "xx11"; then
if test "x$with_xinput" = "xxfree" || test "x$with_xinput" = "xyes"; then
AC_DEFINE(XINPUT_XFREE, 1,
[Define to 1 if XFree XInput should be used])
-
+
if $PKG_CONFIG --exists xi ; then
X_PACKAGES="$X_PACKAGES xi"
+
+ AC_CHECK_HEADER(X11/extensions/XInput2.h,
+ have_xinput2=yes; AC_DEFINE(XINPUT_2, 1, [Define to 1 if XInput 2.0 is available]))
else
GTK_ADD_LIB(x_extra_libs, Xi)
fi
@@ -1572,6 +1575,7 @@ if test "x$gdktarget" = "xx11"; then
fi
AM_CONDITIONAL(XINPUT_XFREE, test x$with_xinput = xxfree || test x$with_xinput = xyes)
+ AM_CONDITIONAL(XINPUT_2, test "x$have_xinput2" = "xyes")
# Check for the RANDR extension
if $PKG_CONFIG --exists "xrandr >= 1.2.99" ; then
diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am
index 93b18cf..4cd9e2c 100644
--- a/gdk/x11/Makefile.am
+++ b/gdk/x11/Makefile.am
@@ -23,6 +23,7 @@ libgdk_x11_la_SOURCES = \
gdkasync.h \
gdkcolor-x11.c \
gdkcursor-x11.c \
+ gdkdevicemanager-core.c \
gdkdevicemanager-x11.c \
gdkdisplay-x11.c \
gdkdisplay-x11.h \
@@ -64,10 +65,14 @@ libgdk_x11_la_SOURCES = \
xsettings-common.h \
xsettings-common.c
+if XINPUT_2
+libgdk_x11_la_SOURCES += gdkinput-x11.c gdkinput-xfree.c gdkdevicemanager-xi2.c
+else
if XINPUT_XFREE
libgdk_x11_la_SOURCES += gdkinput-x11.c gdkinput-xfree.c
else
-libgdk_x11_la_SOURCES += gdkinput-none.c gdkdevicemanager-core.c
+libgdk_x11_la_SOURCES += gdkinput-none.c
+endif
endif
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c
index 5ad9512..47dc4a7 100644
--- a/gdk/x11/gdkdevicemanager-x11.c
+++ b/gdk/x11/gdkdevicemanager-x11.c
@@ -18,11 +18,49 @@
*/
#include "config.h"
+#include "gdkx.h"
#include "gdkdevicemanager-core.h"
+#ifdef XINPUT_2
+#include "gdkdevicemanager-xi2.h"
+#endif /* XINPUT_2 */
+
GdkDeviceManager *
_gdk_device_manager_new (GdkDisplay *display)
{
+ GdkDeviceManager *device_manager;
+ int opcode, firstevent, firsterror;
+ int major, minor;
+ Display *xdisplay;
+
+#if defined (XINPUT_2) || defined (XINPUT_XFREE)
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ if (XQueryExtension (xdisplay, "XInputExtension",
+ &opcode, &firstevent, &firsterror))
+ {
+#if defined (XINPUT_2)
+ major = 2;
+ minor = 0;
+
+ if (XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
+ {
+ GdkDeviceManagerXI2 *device_manager_xi2;
+
+ device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_XI2,
+ "display", display,
+ NULL);
+
+ device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (device_manager);
+ device_manager_xi2->opcode = opcode;
+
+ return device_manager;
+ }
+#endif
+ }
+
+#endif /* XINPUT_2 || XINPUT_XFREE */
+
return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
"display", display,
NULL);
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
new file mode 100644
index 0000000..704a859
--- /dev/null
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -0,0 +1,273 @@
+/* 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 "gdkdevicemanager-xi2.h"
+#include "gdkeventtranslator.h"
+#include "gdkinputprivate.h"
+#include "gdkx.h"
+
+static void gdk_device_manager_xi2_constructed (GObject *object);
+
+static GList * gdk_device_manager_xi2_get_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type);
+static void gdk_device_manager_xi2_set_window_events (GdkDeviceManager *device_manager,
+ GdkWindow *window,
+ GdkEventMask event_mask);
+
+static void gdk_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface);
+
+static gboolean gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
+ GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent);
+
+
+G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI2, gdk_device_manager_xi2, GDK_TYPE_DEVICE_MANAGER,
+ G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
+ gdk_device_manager_xi2_event_translator_init))
+
+
+static void
+gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
+{
+ GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = gdk_device_manager_xi2_constructed;
+
+ device_manager_class->get_devices = gdk_device_manager_xi2_get_devices;
+ device_manager_class->set_window_events = gdk_device_manager_xi2_set_window_events;
+}
+
+static void
+gdk_device_manager_xi2_init (GdkDeviceManagerXI2 *device_manager)
+{
+}
+
+static void
+translate_event_mask (GdkEventMask event_mask,
+ unsigned char *mask)
+{
+ if (event_mask & GDK_POINTER_MOTION_MASK ||
+ event_mask & GDK_POINTER_MOTION_HINT_MASK)
+ XISetMask (mask, XI_Motion);
+
+ if (event_mask & GDK_BUTTON_MOTION_MASK ||
+ event_mask & GDK_BUTTON1_MOTION_MASK ||
+ event_mask & GDK_BUTTON2_MOTION_MASK ||
+ event_mask & GDK_BUTTON3_MOTION_MASK)
+ {
+ XISetMask (mask, XI_ButtonPress);
+ XISetMask (mask, XI_ButtonRelease);
+ XISetMask (mask, XI_Motion);
+ }
+
+ if (event_mask & GDK_SCROLL_MASK)
+ {
+ XISetMask (mask, XI_ButtonPress);
+ XISetMask (mask, XI_ButtonRelease);
+ }
+
+ if (event_mask & GDK_BUTTON_PRESS_MASK)
+ XISetMask (mask, XI_ButtonPress);
+
+ if (event_mask & GDK_BUTTON_RELEASE_MASK)
+ XISetMask (mask, XI_ButtonRelease);
+
+ if (event_mask & GDK_KEY_PRESS_MASK)
+ XISetMask (mask, XI_KeyPress);
+
+ if (event_mask & GDK_KEY_RELEASE_MASK)
+ XISetMask (mask, XI_KeyRelease);
+
+ if (event_mask & GDK_ENTER_NOTIFY_MASK)
+ XISetMask (mask, XI_Enter);
+
+ if (event_mask & GDK_LEAVE_NOTIFY_MASK)
+ XISetMask (mask, XI_Leave);
+
+ if (event_mask & GDK_FOCUS_CHANGE_MASK)
+ {
+ XISetMask (mask, XI_FocusIn);
+ XISetMask (mask, XI_FocusOut);
+ }
+
+ /* FIXME: Proximity in/out mask */
+}
+
+static void
+_gdk_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
+ GdkWindow *window,
+ int device_id,
+ unsigned char *mask)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ Window xwindow;
+ XIEventMask event_mask;
+
+ display = gdk_device_manager_get_display (device_manager);
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ xwindow = GDK_WINDOW_XWINDOW (window);
+
+ event_mask.deviceid = device_id;
+ event_mask.mask_len = sizeof (mask);
+ event_mask.mask = mask;
+
+ XISelectEvents (xdisplay, xwindow, &event_mask, 1);
+}
+
+static void
+gdk_device_manager_xi2_constructed (GObject *object)
+{
+ GdkDeviceManagerXI2 *device_manager_xi2;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ Display *xdisplay;
+ XIDeviceInfo *info, *dev;
+ int ndevices, i;
+ unsigned char mask[2] = { 0 };
+
+ device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (object);
+ display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ info = XIQueryDevice(xdisplay, XIAllDevices, &ndevices);
+
+ /* Initialize devices list */
+ for (i = 0; i < ndevices; i++)
+ {
+ GdkDevice *device;
+ GdkDevicePrivate *private;
+
+ dev = &info[i];
+
+ device = g_object_new (GDK_TYPE_DEVICE, NULL);
+ private = (GdkDevicePrivate *) device;
+
+ device->name = g_strdup (dev->name);
+ device->source = GDK_SOURCE_MOUSE;
+ device->mode = GDK_MODE_SCREEN;
+ device->has_cursor = TRUE;
+ device->num_axes = 0;
+ device->axes = NULL;
+ device->num_keys = 0;
+ device->keys = NULL;
+
+ private->display = display;
+
+ if (dev->use == XIMasterPointer)
+ device_manager_xi2->master_devices = g_list_prepend (device_manager_xi2->master_devices, device);
+ else if (dev->use == XISlavePointer)
+ device_manager_xi2->slave_devices = g_list_prepend (device_manager_xi2->slave_devices, device);
+ else if (dev->use == XIFloatingSlave)
+ device_manager_xi2->floating_devices = g_list_prepend (device_manager_xi2->floating_devices, device);
+ else
+ {
+ g_warning ("Unhandled device: %s\n", device->name);
+ g_object_unref (device);
+ }
+ }
+
+ XIFreeDeviceInfo(info);
+
+ /* Connect to hierarchy change events */
+ screen = gdk_display_get_default_screen (display);
+ XISetMask (mask, XI_HierarchyChanged);
+
+ _gdk_device_manager_xi2_select_events (GDK_DEVICE_MANAGER (object),
+ gdk_screen_get_root_window (screen),
+ XIAllDevices,
+ mask);
+}
+
+static GList *
+gdk_device_manager_xi2_get_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type)
+{
+ GdkDeviceManagerXI2 *device_manager_xi2;
+ GList *list = NULL;
+
+ device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (device_manager);
+
+ switch (type)
+ {
+ case GDK_DEVICE_TYPE_MASTER:
+ list = device_manager_xi2->master_devices;
+ break;
+ case GDK_DEVICE_TYPE_SLAVE:
+ list = device_manager_xi2->slave_devices;
+ break;
+ case GDK_DEVICE_TYPE_FLOATING:
+ list = device_manager_xi2->floating_devices;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return g_list_copy (list);;
+}
+
+static void
+gdk_device_manager_xi2_set_window_events (GdkDeviceManager *device_manager,
+ GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ unsigned char mask[2] = { 0 };
+
+ translate_event_mask (event_mask, mask);
+
+ _gdk_device_manager_xi2_select_events (device_manager, window,
+ XIAllMasterDevices,
+ mask);
+}
+
+static void
+gdk_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface)
+{
+ iface->translate_event = gdk_device_manager_xi2_translate_event;
+}
+
+static gboolean
+gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
+ GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkDeviceManagerXI2 *device_manager;
+ XIEvent *ev;
+ gboolean return_val = TRUE;
+
+ ev = (XIEvent *) xevent;
+ device_manager = (GdkDeviceManagerXI2 *) translator;
+
+ if (ev->type != GenericEvent || ev->extension != device_manager->opcode)
+ return FALSE;
+
+ switch (ev->evtype)
+ {
+ default:
+ return_val = FALSE;
+ break;
+ }
+
+ XIFreeEventData (ev);
+
+ return return_val;
+}
diff --git a/gdk/x11/gdkdevicemanager-xi2.h b/gdk/x11/gdkdevicemanager-xi2.h
new file mode 100644
index 0000000..b033c65
--- /dev/null
+++ b/gdk/x11/gdkdevicemanager-xi2.h
@@ -0,0 +1,59 @@
+/* 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.
+ */
+
+#ifndef __GDK_DEVICE_MANAGER_XI2_H__
+#define __GDK_DEVICE_MANAGER_XI2_H__
+
+#include <gdk/gdkdevicemanager.h>
+#include <X11/extensions/XInput2.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_DEVICE_MANAGER_XI2 (gdk_device_manager_xi2_get_type ())
+#define GDK_DEVICE_MANAGER_XI2(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_XI2, GdkDeviceManagerXI2))
+#define GDK_DEVICE_MANAGER_XI2_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_XI2, GdkDeviceManagerXI2Class))
+#define GDK_IS_DEVICE_MANAGER_XI2(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_XI2))
+#define GDK_IS_DEVICE_MANAGER_XI2_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_XI2))
+#define GDK_DEVICE_MANAGER_XI2_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_XI2, GdkDeviceManagerXI2Class))
+
+typedef struct _GdkDeviceManagerXI2 GdkDeviceManagerXI2;
+typedef struct _GdkDeviceManagerXI2Class GdkDeviceManagerXI2Class;
+
+struct _GdkDeviceManagerXI2
+{
+ GdkDeviceManager parent_object;
+
+ GList *master_devices;
+ GList *slave_devices;
+ GList *floating_devices;
+
+ int opcode;
+};
+
+struct _GdkDeviceManagerXI2Class
+{
+ GdkDeviceManagerClass parent_class;
+};
+
+GType gdk_device_manager_xi2_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]