[gtk+/events-refactor: 1084/1085] Add initial GdkDeviceManagerXI implementation



commit 347065e57f6fd31e7379b496607be05f4f4db46e
Author: Carlos Garnacho <carlos gnome org>
Date:   Sat Sep 26 13:41:29 2009 +0200

    Add initial GdkDeviceManagerXI implementation
    
    GdkDeviceManagerXI and GdkDeviceXI were added to deal with XInput 1, They're
    pretty barebones, but already handle event translation.

 gdk/x11/Makefile.am            |    2 +-
 gdk/x11/gdkdevice-xi.c         |  123 +++++++
 gdk/x11/gdkdevice-xi.h         |   69 ++++
 gdk/x11/gdkdevicemanager-x11.c |   26 ++
 gdk/x11/gdkdevicemanager-xi.c  |  684 ++++++++++++++++++++++++++++++++++++++++
 gdk/x11/gdkdevicemanager-xi.h  |   53 +++
 gdk/x11/gdkinput-x11.c         |   99 ++++---
 gdk/x11/gdkinput-xfree.c       |  120 ++++----
 gdk/x11/gdkinputprivate.h      |   56 +---
 9 files changed, 1086 insertions(+), 146 deletions(-)
---
diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am
index 3dbcbb3..e23e793 100644
--- a/gdk/x11/Makefile.am
+++ b/gdk/x11/Makefile.am
@@ -64,7 +64,7 @@ libgdk_x11_la_SOURCES =    	\
 	xsettings-common.c
 
 if XINPUT_XFREE
-libgdk_x11_la_SOURCES += gdkinput-x11.c gdkinput-xfree.c
+libgdk_x11_la_SOURCES += gdkdevicemanager-xi.c gdkdevice-xi.c gdkinput-x11.c gdkinput-xfree.c
 else
 libgdk_x11_la_SOURCES += gdkinput-none.c
 endif
diff --git a/gdk/x11/gdkdevice-xi.c b/gdk/x11/gdkdevice-xi.c
new file mode 100644
index 0000000..43c56b4
--- /dev/null
+++ b/gdk/x11/gdkdevice-xi.c
@@ -0,0 +1,123 @@
+/* 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 <gdk/gdkwindow.h>
+#include "gdkdevice-xi.h"
+#include "gdkprivate-x11.h"
+#include "gdkintl.h"
+#include "gdkx.h"
+
+static void gdk_device_xi_constructed  (GObject *object);
+static void gdk_device_xi_set_property (GObject      *object,
+                                        guint         prop_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec);
+static void gdk_device_xi_get_property (GObject      *object,
+                                        guint         prop_id,
+                                        GValue       *value,
+                                        GParamSpec   *pspec);
+
+
+G_DEFINE_TYPE (GdkDeviceXI, gdk_device_xi, GDK_TYPE_DEVICE)
+
+enum {
+  PROP_0,
+  PROP_DEVICE_ID
+};
+
+static void
+gdk_device_xi_class_init (GdkDeviceXIClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed = gdk_device_xi_constructed;
+  object_class->set_property = gdk_device_xi_set_property;
+  object_class->get_property = gdk_device_xi_get_property;
+
+  g_object_class_install_property (object_class,
+				   PROP_DEVICE_ID,
+				   g_param_spec_int ("device-id",
+                                                     P_("Device ID"),
+                                                     P_("Device ID"),
+                                                     0, G_MAXINT, 0,
+                                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gdk_device_xi_init (GdkDeviceXI *device)
+{
+}
+
+static void
+gdk_device_xi_constructed (GObject *object)
+{
+  GdkDeviceXI *device;
+  GdkDisplay *display;
+
+  device = GDK_DEVICE_XI (object);
+  display = gdk_device_get_display (GDK_DEVICE (object));
+
+  gdk_error_trap_push ();
+  device->xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (display),
+                                 device->device_id);
+
+  if (gdk_error_trap_pop ())
+    g_warning ("Device %s can't be opened", GDK_DEVICE (device)->name);
+
+  if (G_OBJECT_CLASS (gdk_device_xi_parent_class)->constructed)
+    G_OBJECT_CLASS (gdk_device_xi_parent_class)->constructed (object);
+}
+
+static void
+gdk_device_xi_set_property (GObject      *object,
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GdkDeviceXI *device = GDK_DEVICE_XI (object);
+
+  switch (prop_id)
+    {
+    case PROP_DEVICE_ID:
+      device->device_id = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gdk_device_xi_get_property (GObject    *object,
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  GdkDeviceXI *device = GDK_DEVICE_XI (object);
+
+  switch (prop_id)
+    {
+    case PROP_DEVICE_ID:
+      g_value_set_int (value, device->device_id);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
diff --git a/gdk/x11/gdkdevice-xi.h b/gdk/x11/gdkdevice-xi.h
new file mode 100644
index 0000000..98389bd
--- /dev/null
+++ b/gdk/x11/gdkdevice-xi.h
@@ -0,0 +1,69 @@
+/* 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_XI_H__
+#define __GDK_DEVICE_XI_H__
+
+#include <gdk/gdkdeviceprivate.h>
+#include <X11/extensions/XInput.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_DEVICE_XI         (gdk_device_xi_get_type ())
+#define GDK_DEVICE_XI(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_XI, GdkDeviceXI))
+#define GDK_DEVICE_XI_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_XI, GdkDeviceXIClass))
+#define GDK_IS_DEVICE_XI(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_XI))
+#define GDK_IS_DEVICE_XI_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_XI))
+#define GDK_DEVICE_XI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_XI, GdkDeviceXIClass))
+
+typedef struct _GdkDeviceXI GdkDeviceXI;
+typedef struct _GdkDeviceXIClass GdkDeviceXIClass;
+
+struct _GdkDeviceXI
+{
+  GdkDevice parent_instance;
+
+  guint32 device_id;
+  XDevice *xdevice;
+
+  gint button_press_type;
+  gint button_release_type;
+  gint key_press_type;
+  gint key_release_type;
+  gint motion_notify_type;
+  gint proximity_in_type;
+  gint proximity_out_type;
+
+  /* minimum key code for device */
+  gint min_keycode;
+
+  /* Mask of buttons (used for button grabs) */
+  gint button_state;
+};
+
+struct _GdkDeviceXIClass
+{
+  GdkDeviceClass parent_class;
+};
+
+GType gdk_device_xi_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_XI_H__ */
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c
index 5ad9512..3f8e800 100644
--- a/gdk/x11/gdkdevicemanager-x11.c
+++ b/gdk/x11/gdkdevicemanager-x11.c
@@ -18,11 +18,37 @@
  */
 
 #include "config.h"
+#include "gdkx.h"
 #include "gdkdevicemanager-core.h"
 
+#ifdef XINPUT_XFREE
+#include "gdkdevicemanager-xi.h"
+#endif
+
 GdkDeviceManager *
 _gdk_device_manager_new (GdkDisplay *display)
 {
+  GdkDeviceManager *device_manager;
+  int opcode, firstevent, firsterror;
+  int major, minor;
+  Display *xdisplay;
+
+  if (G_UNLIKELY (!g_getenv ("GDK_CORE_DEVICE_EVENTS")))
+    {
+#ifdef XINPUT_XFREE
+      xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+      if (XQueryExtension (xdisplay, "XInputExtension",
+                           &opcode, &firstevent, &firsterror))
+        {
+          return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
+                               "display", display,
+                               "event-base", firstevent,
+                               NULL);
+        }
+#endif /* XINPUT_XFREE */
+    }
+
   return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
                        "display", display,
                        NULL);
diff --git a/gdk/x11/gdkdevicemanager-xi.c b/gdk/x11/gdkdevicemanager-xi.c
new file mode 100644
index 0000000..249cfbd
--- /dev/null
+++ b/gdk/x11/gdkdevicemanager-xi.c
@@ -0,0 +1,684 @@
+/* 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-xi.h"
+#include "gdkeventtranslator.h"
+#include "gdkdevice-xi.h"
+#include "gdkintl.h"
+#include "gdkx.h"
+
+#include <X11/extensions/XInput.h>
+
+#define GDK_DEVICE_MANAGER_XI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIPrivate))
+
+typedef struct GdkDeviceManagerXIPrivate GdkDeviceManagerXIPrivate;
+
+struct GdkDeviceManagerXIPrivate
+{
+  GHashTable *id_table;
+  gint event_base;
+  GList *devices;
+};
+
+static void gdk_device_manager_xi_constructed  (GObject      *object);
+static void gdk_device_manager_xi_finalize     (GObject      *object);
+static void gdk_device_manager_xi_set_property (GObject      *object,
+                                                guint         prop_id,
+                                                const GValue *value,
+                                                GParamSpec   *pspec);
+static void gdk_device_manager_xi_get_property (GObject      *object,
+                                                guint         prop_id,
+                                                GValue       *value,
+                                                GParamSpec   *pspec);
+
+static void     gdk_device_manager_xi_event_translator_init  (GdkEventTranslatorIface *iface);
+static gboolean gdk_device_manager_xi_translate_event (GdkEventTranslator *translator,
+                                                       GdkDisplay         *display,
+                                                       GdkEvent           *event,
+                                                       XEvent             *xevent);
+static GList *  gdk_device_manager_xi_get_devices     (GdkDeviceManager  *device_manager,
+                                                       GdkDeviceType      type);
+
+
+G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_DEVICE_MANAGER_CORE,
+                         G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
+                                                gdk_device_manager_xi_event_translator_init))
+
+enum {
+  PROP_0,
+  PROP_EVENT_BASE
+};
+
+static void
+gdk_device_manager_xi_class_init (GdkDeviceManagerXIClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+
+  object_class->constructed = gdk_device_manager_xi_constructed;
+  object_class->finalize = gdk_device_manager_xi_finalize;
+  object_class->set_property = gdk_device_manager_xi_set_property;
+  object_class->get_property = gdk_device_manager_xi_get_property;
+
+  device_manager_class->get_devices = gdk_device_manager_xi_get_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));
+
+  g_type_class_add_private (object_class, sizeof (GdkDeviceManagerXIPrivate));
+}
+
+static void
+gdk_device_manager_xi_init (GdkDeviceManagerXI *device_manager)
+{
+  GdkDeviceManagerXIPrivate *priv;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_manager);
+  priv->id_table = g_hash_table_new_full (NULL, NULL, NULL,
+                                          (GDestroyNotify) g_object_unref);
+}
+
+static void
+translate_class_info (GdkDevice   *device,
+                      XDeviceInfo *info)
+{
+  XAnyClassPtr class;
+  gint i, j;
+
+  class = info->inputclassinfo;
+
+  for (i = 0; i < info->num_classes; i++)
+    {
+      switch (class->class) {
+      case ButtonClass:
+	break;
+      case KeyClass:
+	{
+#if 0
+	  XKeyInfo *xki = (XKeyInfo *)class;
+	  /* Hack to catch XFree86 3.3.1 bug. Other devices better
+	   * not have exactly 25 keys...
+	   */
+	  if ((xki->min_keycode == 8) && (xki->max_keycode == 32))
+	    {
+	      gdkdev->info.num_keys = 32;
+	      gdkdev->min_keycode = 1;
+	    }
+	  else
+	    {
+	      gdkdev->info.num_keys = xki->max_keycode - xki->min_keycode + 1;
+	      gdkdev->min_keycode = xki->min_keycode;
+	    }
+	  gdkdev->info.keys = g_new (GdkDeviceKey, gdkdev->info.num_keys);
+
+	  for (j=0; j<gdkdev->info.num_keys; j++)
+	    {
+	      gdkdev->info.keys[j].keyval = 0;
+	      gdkdev->info.keys[j].modifiers = 0;
+	    }
+#endif
+
+	  break;
+	}
+      case ValuatorClass:
+	{
+	  XValuatorInfo *xvi = (XValuatorInfo *)class;
+
+          device->num_axes = xvi->num_axes;
+	  device->axes = g_new0 (GdkDeviceAxis, xvi->num_axes);
+#if 0
+	  gdkdev->axes = g_new (GdkAxisInfo, xvi->num_axes);
+
+          for (j = 0; j < xvi->num_axes; j++)
+	    {
+	      gdkdev->axes[j].resolution =
+		gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
+	      gdkdev->axes[j].min_value =
+		gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
+	      gdkdev->axes[j].max_value =
+		gdkdev->axes[j].xmax_value = xvi->axes[j].max_value;
+	      gdkdev->info.axes[j].use = GDK_AXIS_IGNORE;
+	    }
+#endif
+	  j=0;
+
+          if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_X);
+	  if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_Y);
+	  if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_PRESSURE);
+	  if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_XTILT);
+	  if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_YTILT);
+	  if (j < xvi->num_axes)
+	    gdk_device_set_axis_use (device, j++, GDK_AXIS_WHEEL);
+
+	  break;
+	}
+      }
+
+      class = (XAnyClassPtr) (((char *) class) + class->length);
+    }
+}
+
+static GdkDevice *
+create_device (GdkDisplay  *display,
+               XDeviceInfo *info)
+{
+  GdkDevice *device;
+
+  device = g_object_new (GDK_TYPE_DEVICE_XI,
+                         "name", info->name,
+                         "input-source", GDK_SOURCE_MOUSE,
+                         "input-mode", GDK_MODE_DISABLED,
+                         "has-cursor", FALSE,
+                         "display", display,
+                         "device-id", info->id,
+                         NULL);
+  translate_class_info (device, info);
+
+  return device;
+}
+
+static void
+gdk_device_manager_xi_constructed (GObject *object)
+{
+  GdkDeviceManagerXIPrivate *priv;
+  XDeviceInfo *devices;
+  gint i, num_devices;
+  GdkDisplay *display;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (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 (display, &devices[i]);
+      priv->devices = g_list_prepend (priv->devices, device);
+
+      g_hash_table_insert (priv->id_table,
+                           GINT_TO_POINTER (devices[i].id),
+                           device);
+    }
+
+  XFreeDeviceList(devices);
+
+  gdk_x11_register_standard_event_type (display,
+                                        priv->event_base,
+                                        15 /* Number of events */);
+
+  if (G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->constructed)
+    G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->constructed (object);
+}
+
+static void
+gdk_device_manager_xi_finalize (GObject *object)
+{
+  GdkDeviceManagerXIPrivate *priv;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
+
+  g_list_foreach (priv->devices, (GFunc) g_object_unref, NULL);
+  g_list_free (priv->devices);
+
+  G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->finalize (object);
+}
+
+static void
+gdk_device_manager_xi_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GdkDeviceManagerXIPrivate *priv;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_EVENT_BASE:
+      priv->event_base = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gdk_device_manager_xi_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  GdkDeviceManagerXIPrivate *priv;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_EVENT_BASE:
+      g_value_set_int (value, priv->event_base);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gdk_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface)
+{
+  iface->translate_event = gdk_device_manager_xi_translate_event;
+}
+
+static void
+gdk_input_translate_coordinates (GdkDevice *device,
+				 GdkWindow *window,
+				 gint      *axis_data,
+				 gdouble   *axis_out,
+				 gdouble   *x_out,
+				 gdouble   *y_out)
+{
+#if 0
+  GdkWindowObject *priv, *impl_window;
+
+  int i;
+  int x_axis = 0;
+  int y_axis = 0;
+
+  double device_width, device_height;
+  double x_offset, y_offset, x_scale, y_scale;
+
+  priv = (GdkWindowObject *) window;
+  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
+
+  for (i = 0; i < device->num_axes; i++)
+    {
+      switch (device->axes[i].use)
+	{
+	case GDK_AXIS_X:
+	  x_axis = i;
+	  break;
+	case GDK_AXIS_Y:
+	  y_axis = i;
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
+  device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
+
+  if (device->mode == GDK_MODE_SCREEN)
+    {
+      x_scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / device_width;
+      y_scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / device_height;
+
+      x_offset = - impl_window->input_window->root_x - priv->abs_x;
+      y_offset = - impl_window->input_window->root_y - priv->abs_y;
+    }
+  else				/* GDK_MODE_WINDOW */
+    {
+      double x_resolution = gdkdev->axes[x_axis].resolution;
+      double y_resolution = gdkdev->axes[y_axis].resolution;
+      double device_aspect;
+      /*
+       * Some drivers incorrectly report the resolution of the device
+       * as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
+       * This causes the device_aspect to become NaN and totally
+       * breaks windowed mode.  If this is the case, the best we can
+       * do is to assume the resolution is non-zero is equal in both
+       * directions (which is true for many devices).  The absolute
+       * value of the resolution doesn't matter since we only use the
+       * ratio.
+       */
+      if ((x_resolution == 0) || (y_resolution == 0))
+	{
+	  x_resolution = 1;
+	  y_resolution = 1;
+	}
+      device_aspect = (device_height * y_resolution) /
+	(device_width * x_resolution);
+      if (device_aspect * priv->width >= priv->height)
+	{
+	  /* device taller than window */
+	  x_scale = priv->width / device_width;
+	  y_scale = (x_scale * x_resolution) / y_resolution;
+
+	  x_offset = 0;
+	  y_offset = - (device_height * y_scale - priv->height) / 2;
+	}
+      else
+	{
+	  /* window taller than device */
+	  y_scale = priv->height / device_height;
+	  x_scale = (y_scale * y_resolution) / x_resolution;
+
+	  y_offset = 0;
+	  x_offset = - (device_width * x_scale - priv->width) / 2;
+	}
+    }
+
+  for (i=0; i<gdkdev->info.num_axes; i++)
+    {
+      switch (gdkdev->info.axes[i].use)
+	{
+	case GDK_AXIS_X:
+	  axis_out[i] = x_offset + x_scale * (axis_data[x_axis] -
+	    gdkdev->axes[x_axis].min_value);
+	  if (x_out)
+	    *x_out = axis_out[i];
+	  break;
+	case GDK_AXIS_Y:
+	  axis_out[i] = y_offset + y_scale * (axis_data[y_axis] -
+	    gdkdev->axes[y_axis].min_value);
+	  if (y_out)
+	    *y_out = axis_out[i];
+	  break;
+	default:
+	  axis_out[i] =
+	    (device->axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
+	     device->axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
+	    (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
+	  break;
+	}
+    }
+#endif
+}
+
+/* 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
+gdk_input_translate_state (guint state, guint device_state)
+{
+  return device_state | (state & 0xFF);
+}
+
+static GdkDevice *
+lookup_device (GdkDeviceManagerXI *device_manager,
+               XEvent             *xevent)
+{
+  GdkDeviceManagerXIPrivate *priv;
+  guint32 device_id;
+
+  priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_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 (priv->id_table, GINT_TO_POINTER (device_id));
+}
+
+static gboolean
+gdk_device_manager_xi_translate_event (GdkEventTranslator *translator,
+                                       GdkDisplay         *display,
+                                       GdkEvent           *event,
+                                       XEvent             *xevent)
+{
+  GdkEventTranslatorIface *parent_iface;
+  GdkWindowObject *priv, *impl_window;
+  GdkInputWindow *input_window;
+  GdkDeviceXI *device_xi;
+  GdkDevice *device;
+  GdkWindow *window;
+
+  parent_iface = g_type_interface_peek_parent (GDK_EVENT_TRANSLATOR_GET_IFACE (translator));
+
+  if (parent_iface->translate_event (translator, display, event, xevent))
+    return TRUE;
+
+  device = lookup_device (GDK_DEVICE_MANAGER_XI (translator), xevent);
+  device_xi = GDK_DEVICE_XI (device);
+
+  if (!device)
+    return FALSE;
+
+  window = gdk_window_lookup_for_display (display, xevent->xany.window);
+  priv = (GdkWindowObject *) window;
+
+  if (!window)
+    return FALSE;
+
+  impl_window = (GdkWindowObject *) _gdk_window_get_impl_window (window);
+  input_window = impl_window->input_window;
+
+  if ((xevent->type == device_xi->button_press_type) ||
+      (xevent->type == device_xi->button_release_type))
+    {
+      XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *) xevent;
+
+      if (xdbe->type == device_xi->button_press_type)
+	{
+	  event->button.type = GDK_BUTTON_PRESS;
+#if 0
+	  gdkdev->button_state |= 1 << xdbe->button;
+#endif
+	}
+      else
+	{
+	  event->button.type = GDK_BUTTON_RELEASE;
+#if 0
+	  gdkdev->button_state &= ~(1 << xdbe->button);
+#endif
+	}
+
+      event->button.device = device;
+      event->button.window = window;
+      event->button.time = xdbe->time;
+
+      event->button.axes = g_new (gdouble, device->num_axes);
+      gdk_input_translate_coordinates (device, window, xdbe->axis_data,
+				       event->button.axes,
+				       &event->button.x, &event->button.y);
+#if 0
+      event->button.x_root = event->button.x + priv->abs_x + input_window->root_x;
+      event->button.y_root = event->button.y + priv->abs_y + input_window->root_y;
+#endif
+      event->button.state = gdk_input_translate_state (xdbe->state, xdbe->device_state);
+      event->button.button = xdbe->button;
+
+      if (event->button.type == GDK_BUTTON_PRESS)
+	_gdk_event_button_generate (gdk_drawable_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 0
+      if (xdke->keycode < gdkdev->min_keycode ||
+	  xdke->keycode >= gdkdev->min_keycode + gdkdev->info.num_keys)
+	{
+	  g_warning ("Invalid device key code received");
+	  return FALSE;
+	}
+
+      event->key.keyval = device->keys[xdke->keycode - gdkdev->min_keycode].keyval;
+#endif
+
+      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 = window;
+      event->key.time = xdke->time;
+
+#if 0
+      event->key.state = gdk_input_translate_state (xdke->state, xdke->device_state)
+	| device->keys[xdke->keycode - device_xi->min_keycode].modifiers;
+#endif
+
+      /* 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;
+
+      event->motion.axes = g_new (gdouble, device->num_axes);
+      gdk_input_translate_coordinates (device, window, xdme->axis_data,
+                                       event->motion.axes,
+                                       &event->motion.x, &event->motion.y);
+#if 0
+      event->motion.x_root = event->motion.x + priv->abs_x + input_window->root_x;
+      event->motion.y_root = event->motion.y + priv->abs_y + input_window->root_y;
+#endif
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = window;
+      event->motion.time = xdme->time;
+      event->motion.state = gdk_input_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;
+
+      event->proximity.device = device;
+      event->proximity.type = (xevent->type == device_xi->proximity_in_type) ?
+	GDK_PROXIMITY_IN : GDK_PROXIMITY_OUT;
+      event->proximity.window = 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;
+  }
+
+  return FALSE;
+}
+
+static GList *
+gdk_device_manager_xi_get_devices (GdkDeviceManager *device_manager,
+                                   GdkDeviceType     type)
+{
+  GdkDeviceManagerXIPrivate *priv;
+
+  if (type == GDK_DEVICE_TYPE_MASTER)
+    return GDK_DEVICE_MANAGER_CLASS (gdk_device_manager_xi_parent_class)->get_devices (device_manager, type);
+  else if (type == GDK_DEVICE_TYPE_FLOATING)
+    {
+      priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_manager);
+      return g_list_copy (priv->devices);
+    }
+  else
+    return NULL;
+}
diff --git a/gdk/x11/gdkdevicemanager-xi.h b/gdk/x11/gdkdevicemanager-xi.h
new file mode 100644
index 0000000..3b0e976
--- /dev/null
+++ b/gdk/x11/gdkdevicemanager-xi.h
@@ -0,0 +1,53 @@
+/* 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_XI_H__
+#define __GDK_DEVICE_MANAGER_XI_H__
+
+#include "gdkdevicemanager-core.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_DEVICE_MANAGER_XI         (gdk_device_manager_xi_get_type ())
+#define GDK_DEVICE_MANAGER_XI(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXI))
+#define GDK_DEVICE_MANAGER_XI_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIClass))
+#define GDK_IS_DEVICE_MANAGER_XI(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_XI))
+#define GDK_IS_DEVICE_MANAGER_XI_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_XI))
+#define GDK_DEVICE_MANAGER_XI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIClass))
+
+typedef struct _GdkDeviceManagerXI GdkDeviceManagerXI;
+typedef struct _GdkDeviceManagerXIClass GdkDeviceManagerXIClass;
+
+struct _GdkDeviceManagerXI
+{
+  GdkDeviceManagerCore parent_object;
+  GdkDevice *core_pointer;
+  GdkDevice *core_keyboard;
+};
+
+struct _GdkDeviceManagerXIClass
+{
+  GdkDeviceManagerCoreClass parent_class;
+};
+
+GType gdk_device_manager_xi_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_MANAGER_XI_H__ */
diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c
index fffc0c8..e3e889b 100644
--- a/gdk/x11/gdkinput-x11.c
+++ b/gdk/x11/gdkinput-x11.c
@@ -31,14 +31,17 @@
 #include "gdk.h"		/* For gdk_error_trap_push()/pop() */
 #include "gdkdisplay-x11.h"
 #include "gdkalias.h"
+#include "gdkdevice-xi.h"
 
 #include <string.h>
 
 /* Forward declarations */
+#if 0
 static GdkDevicePrivate *gdk_input_device_new            (GdkDisplay       *display,
 							  XDeviceInfo      *device,
 							  gint              include_core);
-static void              gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
+#endif
+static void              gdk_input_translate_coordinates (GdkDevice        *device,
 							  GdkWindow        *window,
 							  gint             *axis_data,
 							  gdouble          *axis_out,
@@ -47,19 +50,22 @@ static void              gdk_input_translate_coordinates (GdkDevicePrivate *gdkd
 static guint             gdk_input_translate_state       (guint             state,
 							  guint             device_state);
 
-GdkDevicePrivate *
+GdkDevice *
 _gdk_input_find_device (GdkDisplay *display,
 			guint32     id)
 {
   GList *tmp_list = GDK_DISPLAY_X11 (display)->input_devices;
-  GdkDevicePrivate *gdkdev;
+  GdkDevice *device;
+
   while (tmp_list)
     {
-      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
-      if (gdkdev->deviceid == id)
-	return gdkdev;
+      device = tmp_list->data;
       tmp_list = tmp_list->next;
+
+      if (GDK_DEVICE_XI (device)->device_id == id)
+	return device;
     }
+
   return NULL;
 }
 
@@ -81,6 +87,7 @@ _gdk_input_get_root_relative_geometry (GdkWindow *window,
     *y_ret = y;
 }
 
+#if 0
 static GdkDevicePrivate *
 gdk_input_device_new (GdkDisplay  *display,
 		      XDeviceInfo *device,
@@ -239,37 +246,40 @@ gdk_input_device_new (GdkDisplay  *display,
 
   return NULL;
 }
+#endif
 
 void
-_gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
+_gdk_input_common_find_events (GdkDevice *device,
 			       gint mask,
 			       XEventClass *classes,
 			       int *num_classes)
 {
+  GdkDeviceXI *device_xi;
   gint i;
   XEventClass class;
 
+  device_xi = GDK_DEVICE_XI (device);
   i = 0;
   if (mask & GDK_BUTTON_PRESS_MASK)
     {
-      DeviceButtonPress (gdkdev->xdevice, gdkdev->buttonpress_type,
+      DeviceButtonPress (device_xi->xdevice, device_xi->button_press_type,
 			     class);
       if (class != 0)
 	  classes[i++] = class;
-      DeviceButtonPressGrab (gdkdev->xdevice, 0, class);
+      DeviceButtonPressGrab (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_BUTTON_RELEASE_MASK)
     {
-      DeviceButtonRelease (gdkdev->xdevice, gdkdev->buttonrelease_type,
+      DeviceButtonRelease (device_xi->xdevice, device_xi->button_release_type,
 			   class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_POINTER_MOTION_MASK)
     {
-      DeviceMotionNotify  (gdkdev->xdevice, gdkdev->motionnotify_type, class);
+      DeviceMotionNotify  (device_xi->xdevice, device_xi->motion_notify_type, class);
       if (class != 0)
 	  classes[i++] = class;
     }
@@ -279,29 +289,29 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
 		GDK_POINTER_MOTION_HINT_MASK))
       {
 	/* Make sure gdkdev->motionnotify_type is set */
-	DeviceMotionNotify  (gdkdev->xdevice, gdkdev->motionnotify_type, class);
+	DeviceMotionNotify  (device_xi->xdevice, device_xi->motion_notify_type, class);
       }
   if (mask & GDK_BUTTON1_MOTION_MASK)
     {
-      DeviceButton1Motion  (gdkdev->xdevice, 0, class);
+      DeviceButton1Motion  (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_BUTTON2_MOTION_MASK)
     {
-      DeviceButton2Motion  (gdkdev->xdevice, 0, class);
+      DeviceButton2Motion  (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_BUTTON3_MOTION_MASK)
     {
-      DeviceButton3Motion  (gdkdev->xdevice, 0, class);
+      DeviceButton3Motion  (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_BUTTON_MOTION_MASK)
     {
-      DeviceButtonMotion  (gdkdev->xdevice, 0, class);
+      DeviceButtonMotion  (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
@@ -309,31 +319,31 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
     {
       /* We'll get into trouble if the macros change, but at least we'll
 	 know about it, and we avoid warnings now */
-      DevicePointerMotionHint (gdkdev->xdevice, 0, class);
+      DevicePointerMotionHint (device_xi->xdevice, 0, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_KEY_PRESS_MASK)
     {
-      DeviceKeyPress (gdkdev->xdevice, gdkdev->keypress_type, class);
+      DeviceKeyPress (device_xi->xdevice, device_xi->key_press_type, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_KEY_RELEASE_MASK)
     {
-      DeviceKeyRelease (gdkdev->xdevice, gdkdev->keyrelease_type, class);
+      DeviceKeyRelease (device_xi->xdevice, device_xi->key_release_type, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_PROXIMITY_IN_MASK)
     {
-      ProximityIn   (gdkdev->xdevice, gdkdev->proximityin_type, class);
+      ProximityIn   (device_xi->xdevice, device_xi->proximity_in_type, class);
       if (class != 0)
 	  classes[i++] = class;
     }
   if (mask & GDK_PROXIMITY_OUT_MASK)
     {
-      ProximityOut  (gdkdev->xdevice, gdkdev->proximityout_type, class);
+      ProximityOut  (device_xi->xdevice, device_xi->proximity_out_type, class);
       if (class != 0)
 	  classes[i++] = class;
     }
@@ -343,7 +353,7 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
 
 void
 _gdk_input_select_events (GdkWindow *impl_window,
-			  GdkDevicePrivate *gdkdev)
+                          GdkDevice *device)
 {
   XEventClass classes[GDK_MAX_DEVICE_CLASSES];
   gint num_classes;
@@ -355,13 +365,13 @@ _gdk_input_select_events (GdkWindow *impl_window,
   event_mask = 0;
   iw = ((GdkWindowObject *)impl_window)->input_window;
 
-  if (gdkdev->info.mode != GDK_MODE_DISABLED &&
+  if (device->mode != GDK_MODE_DISABLED &&
       iw != NULL)
     {
       for (l = iw->windows; l != NULL; l = l->next)
 	{
 	  w = l->data;
-	  if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
+	  if (device->has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
 	    event_mask |= w->extension_events;
 	}
     }
@@ -370,7 +380,7 @@ _gdk_input_select_events (GdkWindow *impl_window,
   if (event_mask)
     event_mask |= GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
 
-  _gdk_input_common_find_events (gdkdev, event_mask,
+  _gdk_input_common_find_events (device, event_mask,
 				 classes, &num_classes);
   XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (impl_window),
 			 GDK_WINDOW_XWINDOW (impl_window),
@@ -381,6 +391,7 @@ gint
 _gdk_input_common_init (GdkDisplay *display,
 			gint        include_core)
 {
+#if 0
   XDeviceInfo   *devices;
   int num_devices, loop;
   int ignore, event_base;
@@ -409,12 +420,13 @@ _gdk_input_common_init (GdkDisplay *display,
     }
 
   display_x11->input_devices = g_list_append (display_x11->input_devices, display->core_pointer);
+#endif
 
   return TRUE;
 }
 
 static void
-gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
+gdk_input_translate_coordinates (GdkDevice        *device,
 				 GdkWindow        *window,
 				 gint             *axis_data,
 				 gdouble          *axis_out,
@@ -433,9 +445,9 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
   priv = (GdkWindowObject *) window;
   impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
 
-  for (i=0; i<gdkdev->info.num_axes; i++)
+  for (i=0; i< device->num_axes; i++)
     {
-      switch (gdkdev->info.axes[i].use)
+      switch (device->axes[i].use)
 	{
 	case GDK_AXIS_X:
 	  x_axis = i;
@@ -448,6 +460,7 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
 	}
     }
 
+#if 0
   device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
   device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
 
@@ -525,8 +538,11 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
 	  break;
 	}
     }
+#endif
 }
 
+#if 0
+
 /* 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
@@ -544,21 +560,23 @@ gboolean
 _gdk_input_common_other_event (GdkEvent         *event,
 			       XEvent           *xevent,
 			       GdkWindow        *window,
-			       GdkDevicePrivate *gdkdev)
+                               GdkDevice        *device)
 {
   GdkWindowObject *priv, *impl_window;
   GdkInputWindow *input_window;
+  GdkDeviceXI *device_xi;
 
+  device_xi = GDK_DEVICE_XI (device);
   priv = (GdkWindowObject *) window;
   impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
   input_window = impl_window->input_window;
 
-  if ((xevent->type == gdkdev->buttonpress_type) ||
-      (xevent->type == gdkdev->buttonrelease_type))
+  if ((xevent->type == device_xi->button_press_type) ||
+      (xevent->type == device_xi->button_release_type))
     {
       XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
 
-      if (xdbe->type == gdkdev->buttonpress_type)
+      if (xdbe->type == device_xi->button_press_type)
 	{
 	  event->button.type = GDK_BUTTON_PRESS;
 	  gdkdev->button_state |= 1 << xdbe->button;
@@ -728,6 +746,7 @@ _gdk_input_common_other_event (GdkEvent         *event,
 
   return FALSE;			/* wasn't one of our event types */
 }
+#endif
 
 static GdkTimeCoord **
 _gdk_device_allocate_history (GdkDevice *device,
@@ -754,17 +773,17 @@ _gdk_device_get_history (GdkDevice         *device,
   GdkTimeCoord **coords;
   XDeviceTimeCoord *device_coords;
   GdkWindow *impl_window;
-  GdkDevicePrivate *gdkdev;
+  GdkDeviceXI *device_xi;
   gint mode_return;
   gint axis_count_return;
   gint i;
 
-  gdkdev = (GdkDevicePrivate *)device;
+  device_xi = (GdkDeviceXI *) device;
 
   impl_window = _gdk_window_get_impl_window (window);
 
   device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (impl_window),
-					  gdkdev->xdevice,
+					  device_xi->xdevice,
 					  start, stop,
 					  n_events, &mode_return,
 					  &axis_count_return);
@@ -777,7 +796,7 @@ _gdk_device_get_history (GdkDevice         *device,
 	{
 	  coords[i]->time = device_coords[i].time;
 
-	  gdk_input_translate_coordinates (gdkdev, window,
+	  gdk_input_translate_coordinates (device, window,
 					   device_coords[i].data,
 					   coords[i]->axes, NULL, NULL);
 	}
@@ -817,17 +836,17 @@ gdk_device_get_state (GdkDevice       *device,
     }
   else
     {
-      GdkDevicePrivate *gdkdev;
+      GdkDeviceXI *device_xi;
       XDeviceState *state;
       XInputClass *input_class;
 
       if (mask)
 	gdk_window_get_pointer (window, NULL, NULL, mask);
 
-      gdkdev = (GdkDevicePrivate *)device;
+      device_xi = (GdkDeviceXI *) device;
 
       state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window),
-				 gdkdev->xdevice);
+				 device_xi->xdevice);
       input_class = state->data;
       for (i=0; i<state->num_classes; i++)
 	{
@@ -835,7 +854,7 @@ gdk_device_get_state (GdkDevice       *device,
 	    {
 	    case ValuatorClass:
 	      if (axes)
-		gdk_input_translate_coordinates (gdkdev, window,
+		gdk_input_translate_coordinates (device, window,
 						 ((XValuatorState *)input_class)->valuators,
 						 axes, NULL, NULL);
 	      break;
diff --git a/gdk/x11/gdkinput-xfree.c b/gdk/x11/gdkinput-xfree.c
index e89b3a4..db7e3a4 100644
--- a/gdk/x11/gdkinput-xfree.c
+++ b/gdk/x11/gdkinput-xfree.c
@@ -21,6 +21,7 @@
 #include "gdkinputprivate.h"
 #include "gdkdisplay-x11.h"
 #include "gdkalias.h"
+#include "gdkdevice-xi.h"
 
 /*
  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
@@ -38,15 +39,12 @@ gdk_device_set_mode (GdkDevice      *device,
 		     GdkInputMode    mode)
 {
   GList *tmp_list;
-  GdkDevicePrivate *gdkdev;
   GdkInputWindow *input_window;
   GdkDisplayX11 *display_impl;
 
   if (GDK_IS_CORE (device))
     return FALSE;
 
-  gdkdev = (GdkDevicePrivate *)device;
-
   if (device->mode == mode)
     return TRUE;
 
@@ -57,11 +55,11 @@ gdk_device_set_mode (GdkDevice      *device,
   else if (mode == GDK_MODE_SCREEN)
     device->has_cursor = TRUE;
 
-  display_impl = GDK_DISPLAY_X11 (gdkdev->display);
+  display_impl = GDK_DISPLAY_X11 (gdk_device_get_display (device));
   for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
     {
       input_window = (GdkInputWindow *)tmp_list->data;
-      _gdk_input_select_events (input_window->impl_window, gdkdev);
+      _gdk_input_select_events (input_window->impl_window, device);
     }
 
   return TRUE;
@@ -76,34 +74,40 @@ gdk_input_check_proximity (GdkDisplay *display)
 
   while (tmp_list && !new_proximity)
     {
-      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      GdkDevice *device = tmp_list->data;
 
-      if (gdkdev->info.mode != GDK_MODE_DISABLED
-	  && !GDK_IS_CORE (gdkdev)
-	  && gdkdev->xdevice)
+      if (device->mode != GDK_MODE_DISABLED &&
+	  !GDK_IS_CORE (device) &&
+          GDK_IS_DEVICE_XI (device))
 	{
-	  XDeviceState *state = XQueryDeviceState(display_impl->xdisplay,
-						  gdkdev->xdevice);
-	  XInputClass *xic;
-	  int i;
-
-	  xic = state->data;
-	  for (i=0; i<state->num_classes; i++)
-	    {
-	      if (xic->class == ValuatorClass)
-		{
-		  XValuatorState *xvs = (XValuatorState *)xic;
-		  if ((xvs->mode & ProximityState) == InProximity)
-		    {
-		      new_proximity = TRUE;
-		    }
-		  break;
-		}
-	      xic = (XInputClass *)((char *)xic + xic->length);
-	    }
-
-	  XFreeDeviceState (state);
+          GdkDeviceXI *device_xi = GDK_DEVICE_XI (device);
+
+          if (device_xi->xdevice)
+            {
+              XDeviceState *state = XQueryDeviceState(display_impl->xdisplay,
+                                                      device_xi->xdevice);
+              XInputClass *xic;
+              int i;
+
+              xic = state->data;
+              for (i = 0; i < state->num_classes; i++)
+                {
+                  if (xic->class == ValuatorClass)
+                    {
+                      XValuatorState *xvs = (XValuatorState *)xic;
+                      if ((xvs->mode & ProximityState) == InProximity)
+                        {
+                          new_proximity = TRUE;
+                        }
+                      break;
+                    }
+                  xic = (XInputClass *) ((char *) xic + xic->length);
+                }
+
+              XFreeDeviceState (state);
+            }
 	}
+
       tmp_list = tmp_list->next;
     }
 
@@ -132,7 +136,6 @@ _gdk_input_crossing_event (GdkWindow *window,
 			   gboolean enter)
 {
   GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
-  GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
   GdkWindowObject *priv = (GdkWindowObject *)window;
   GdkInputWindow *input_window;
   gint root_x, root_y;
@@ -153,12 +156,13 @@ _gdk_input_crossing_event (GdkWindow *window,
     display->ignore_core_events = FALSE;
 }
 
+#if 0
 static GdkEventType
-get_input_event_type (GdkDevicePrivate *gdkdev,
-		      XEvent *xevent,
+get_input_event_type (GdkDeviceXI *device,
+                      XEvent *xevent,
 		      int *core_x, int *core_y)
 {
-  if (xevent->type == gdkdev->buttonpress_type)
+  if (xevent->type == device->button_press_type)
     {
       XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
       *core_x = xie->x;
@@ -166,7 +170,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_BUTTON_PRESS;
     }
 
-  if (xevent->type == gdkdev->buttonrelease_type)
+  if (xevent->type == device->button_release_type)
     {
       XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
       *core_x = xie->x;
@@ -174,7 +178,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_BUTTON_RELEASE;
     }
 
-  if (xevent->type == gdkdev->keypress_type)
+  if (xevent->type == device->key_press_type)
     {
       XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
       *core_x = xie->x;
@@ -182,7 +186,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_KEY_PRESS;
     }
 
-  if (xevent->type == gdkdev->keyrelease_type)
+  if (xevent->type == device->key_release_type)
     {
       XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
       *core_x = xie->x;
@@ -190,7 +194,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_KEY_RELEASE;
     }
 
-  if (xevent->type == gdkdev->motionnotify_type)
+  if (xevent->type == device->motion_notify_type)
     {
       XDeviceMotionEvent *xie = (XDeviceMotionEvent *)(xevent);
       *core_x = xie->x;
@@ -198,7 +202,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_MOTION_NOTIFY;
     }
 
-  if (xevent->type == gdkdev->proximityin_type)
+  if (xevent->type == device->proximity_in_type)
     {
       XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
       *core_x = xie->x;
@@ -206,7 +210,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
       return GDK_PROXIMITY_IN;
     }
 
-  if (xevent->type == gdkdev->proximityout_type)
+  if (xevent->type == device->proximity_out_type)
     {
       XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
       *core_x = xie->x;
@@ -219,7 +223,6 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
   return GDK_NOTHING;
 }
 
-
 gboolean
 _gdk_input_other_event (GdkEvent *event,
 			XEvent *xevent,
@@ -244,7 +247,7 @@ _gdk_input_other_event (GdkEvent *event,
   if (!gdkdev)
     return FALSE;			/* we don't handle it - not an XInput event */
 
-  event_type = get_input_event_type (gdkdev, xevent, &x, &y);
+  event_type = get_input_event_type (device, xevent, &x, &y);
   if (event_type == GDK_NOTHING)
     return FALSE;
 
@@ -286,6 +289,8 @@ _gdk_input_other_event (GdkEvent *event,
   return return_val;
 }
 
+#endif
+
 gint
 _gdk_input_grab_pointer (GdkWindow      *window,
 			 GdkWindow      *native_window, /* This is the toplevel */
@@ -297,7 +302,7 @@ _gdk_input_grab_pointer (GdkWindow      *window,
   GdkInputWindow *input_window;
   GdkWindowObject *priv, *impl_window;
   gboolean need_ungrab;
-  GdkDevicePrivate *gdkdev;
+  GdkDeviceXI *device;
   GList *tmp_list;
   XEventClass event_classes[GDK_MAX_DEVICE_CLASSES];
   gint num_classes;
@@ -331,17 +336,18 @@ _gdk_input_grab_pointer (GdkWindow      *window,
       tmp_list = display_impl->input_devices;
       while (tmp_list)
 	{
-	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
-	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
+          device = tmp_list->data;
+
+	  if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice)
 	    {
-	      _gdk_input_common_find_events (gdkdev, event_mask,
+	      _gdk_input_common_find_events (GDK_DEVICE (device), event_mask,
 					     event_classes, &num_classes);
 #ifdef G_ENABLE_DEBUG
 	      if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
 		result = GrabSuccess;
 	      else
 #endif
-		result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
+		result = XGrabDevice (display_impl->xdisplay, device->xdevice,
 				      GDK_WINDOW_XWINDOW (native_window),
 				      owner_events, num_classes, event_classes,
 				      GrabModeAsync, GrabModeAsync, time);
@@ -359,12 +365,13 @@ _gdk_input_grab_pointer (GdkWindow      *window,
       tmp_list = display_impl->input_devices;
       while (tmp_list)
 	{
-	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
-	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice &&
-	      ((gdkdev->button_state != 0) || need_ungrab))
+          device = tmp_list->data;
+
+	  if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice &&
+	      ((device->button_state != 0) || need_ungrab))
 	    {
-	      XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
-	      gdkdev->button_state = 0;
+	      XUngrabDevice (display_impl->xdisplay, device->xdevice, time);
+	      device->button_state = 0;
 	    }
 
 	  tmp_list = tmp_list->next;
@@ -379,7 +386,7 @@ _gdk_input_ungrab_pointer (GdkDisplay *display,
 			   guint32 time)
 {
   GdkInputWindow *input_window = NULL; /* Quiet GCC */
-  GdkDevicePrivate *gdkdev;
+  GdkDeviceXI *device;
   GList *tmp_list;
   GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
 
@@ -399,9 +406,10 @@ _gdk_input_ungrab_pointer (GdkDisplay *display,
       tmp_list = display_impl->input_devices;
       while (tmp_list)
 	{
-	  gdkdev = (GdkDevicePrivate *)tmp_list->data;
-	  if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
-	    XUngrabDevice( display_impl->xdisplay, gdkdev->xdevice, time);
+          device = tmp_list->data;
+
+	  if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice)
+	    XUngrabDevice (display_impl->xdisplay, device->xdevice, time);
 
 	  tmp_list = tmp_list->next;
 	}
diff --git a/gdk/x11/gdkinputprivate.h b/gdk/x11/gdkinputprivate.h
index 71b806f..a2b60eb 100644
--- a/gdk/x11/gdkinputprivate.h
+++ b/gdk/x11/gdkinputprivate.h
@@ -38,9 +38,7 @@
 #include <X11/extensions/XInput.h>
 #endif
 
-
 typedef struct _GdkAxisInfo    GdkAxisInfo;
-typedef struct _GdkDevicePrivate GdkDevicePrivate;
 
 /* information about a device axis */
 struct _GdkAxisInfo
@@ -61,48 +59,6 @@ struct _GdkAxisInfo
 
 #define GDK_INPUT_NUM_EVENTC 6
 
-struct _GdkDevicePrivate
-{
-  GdkDevice info;
-
-  guint32 deviceid;
-
-  GdkDisplay *display;
-  
-
-#ifndef XINPUT_NONE
-  /* information about the axes */
-  GdkAxisInfo *axes;
-
-  /* Information about XInput device */
-  XDevice       *xdevice;
-
-  /* minimum key code for device */
-  gint min_keycode;	       
-
-  int buttonpress_type, buttonrelease_type, keypress_type,
-      keyrelease_type, motionnotify_type, proximityin_type, 
-      proximityout_type, changenotify_type;
-
-  /* true if we need to select a different set of events, but
-     can't because this is the core pointer */
-  gint needs_update;
-
-  /* Mask of buttons (used for button grabs) */
-  gint button_state;
-
-  /* true if we've claimed the device as active. (used only for XINPUT_GXI) */
-  gint claimed;
-#endif /* !XINPUT_NONE */
-};
-
-#if 0
-struct _GdkDeviceClass
-{
-  GObjectClass parent_class;
-};
-#endif
-
 /* Addition used for extension_events mask */
 #define GDK_ALL_DEVICES_MASK (1<<30)
 
@@ -124,7 +80,7 @@ struct _GdkInputWindow
 
 /* Global data */
 
-#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == ((GdkDevicePrivate *)(d))->display->core_pointer)
+#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == gdk_device_get_display (d)->core_pointer)
 
 /* Function declarations */
 
@@ -163,21 +119,23 @@ gboolean         _gdk_device_get_history     (GdkDevice         *device,
 
 gint               _gdk_input_common_init               (GdkDisplay	  *display,
 							 gint              include_core);
-GdkDevicePrivate * _gdk_input_find_device               (GdkDisplay	  *display,
+GdkDevice *        _gdk_input_find_device               (GdkDisplay	  *display,
 							 guint32           id);
 void               _gdk_input_get_root_relative_geometry(GdkWindow        *window,
 							 int              *x_ret,
 							 int              *y_ret);
-void               _gdk_input_common_find_events        (GdkDevicePrivate *gdkdev,
+void               _gdk_input_common_find_events        (GdkDevice        *device,
 							 gint              mask,
 							 XEventClass      *classes,
 							 int              *num_classes);
 void               _gdk_input_select_events             (GdkWindow        *impl_window,
-							 GdkDevicePrivate *gdkdev);
+                                                         GdkDevice        *device);
+#if 0
 gint               _gdk_input_common_other_event        (GdkEvent         *event,
 							 XEvent           *xevent,
 							 GdkWindow        *window,
-							 GdkDevicePrivate *gdkdev);
+                                                         GdkDevice        *device);
+#endif
 
 #endif /* !XINPUT_NONE */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]