]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkinput.c
Change FSF Address
[~andy/gtk] / gdk / win32 / gdkinput.c
index e6369c73e4d42205a9e7868c50ddf7421352cddc..31b7d41d3e10908836f05c60eb9269a70348aded 100644 (file)
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Copyright (C) 1999 Tor Lillqvist
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * 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
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library 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.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
- * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GTK+ Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-#include <gdk/gdk.h>
-#include "gdkx.h"
-#include "gdkinput.h"
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-/* If USE_SYSCONTEXT is on, we open the Wintab device (hmm, what if
- * there are several?) as a system pointing device, i.e. it controls
- * the normal Windows cursor. This seems much more natural.
+/* This file should really be one level up, in the backend-independent
+ * GDK, and the x11/gdkinput.c could also be removed.
+ * 
+ * That stuff in x11/gdkinput.c which really *is* X11-dependent should
+ * be in x11/gdkinput-x11.c.
  */
-#define USE_SYSCONTEXT 1       /* The code for the other choice is not
-                                * good at all.
-                                */
-
-#define TWOPI (2.*M_PI)
-
-#define PING() g_print("%s: %d\n",__FILE__,__LINE__)
-
-/* Forward declarations */
-
-static gint gdk_input_win32_set_mode (guint32      deviceid,
-                                     GdkInputMode mode);
-static void gdk_input_win32_get_pointer (GdkWindow       *window,
-                                        guint32            deviceid,
-                                        gdouble         *x,
-                                        gdouble         *y,
-                                        gdouble         *pressure,
-                                        gdouble         *xtilt,
-                                        gdouble         *ytilt,
-                                        GdkModifierType *mask);
-static void gdk_input_none_get_pointer (GdkWindow       *window,
-                                       guint32          deviceid,
-                                       gdouble         *x,
-                                       gdouble         *y,
-                                       gdouble         *pressure,
-                                       gdouble         *xtilt,
-                                       gdouble         *ytilt,
-                                       GdkModifierType *mask);
-static gint gdk_input_win32_grab_pointer (GdkWindow *     window,
-                                         gint            owner_events,
-                                         GdkEventMask    event_mask,
-                                         GdkWindow      *confine_to,
-                                         guint32         time);
-static void gdk_input_win32_ungrab_pointer (guint32 time);
-static void gdk_input_win32_configure_event (GdkEventConfigure *event, 
-                                            GdkWindow         *window);
-static void gdk_input_win32_enter_event (GdkEventCrossing  *xevent, 
-                                        GdkWindow         *window);
-static gint gdk_input_win32_other_event (GdkEvent  *event, 
-                                        MSG       *xevent);
-static gint gdk_input_win32_enable_window (GdkWindow        *window,
-                                          GdkDevicePrivate *gdkdev);
-static gint gdk_input_win32_disable_window (GdkWindow        *window,
-                                           GdkDevicePrivate *gdkdev);
-
-static GdkInputWindow *gdk_input_window_find (GdkWindow *window);
-static GdkInputWindow *gdk_input_window_find_within (GdkWindow *window);
-static GdkDevicePrivate *gdk_input_find_device (guint32 deviceid);
-static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
-                                                     UINT id);
-
-/* Local variables */
-
-static GList     *gdk_input_devices;
-static GList     *gdk_input_windows;
-static GList     *wintab_contexts;
-
-static gint gdk_input_root_width;
-static gint gdk_input_root_height;
-
-static GdkWindow *wintab_window;
-
-static guint32 last_moved_cursor_id;
-
-static GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
-
-static GdkDeviceInfo gdk_input_core_info =
-{
-  GDK_CORE_POINTER,
-  "Core Pointer",
-  GDK_SOURCE_MOUSE,
-  GDK_MODE_SCREEN,
-  TRUE,
-  2,
-  gdk_input_core_axes
-};
-
-/* Global variables  */
-
-GdkInputVTable    gdk_input_vtable;
-gint              gdk_input_ignore_core;
-gint             gdk_input_ignore_wintab = FALSE;
-
-#if 0
-
-static void
-print_lc(LOGCONTEXT *lc)
-{
-  g_print ("lcName = %s\n", lc->lcName);
-  g_print ("lcOptions =");
-  if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
-  if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
-  if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
-  if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
-  if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
-  if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
-  if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
-  g_print ("\n");
-  g_print ("lcStatus =");
-  if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
-  if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
-  if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
-  g_print ("\n");
-  g_print ("lcLocks =");
-  if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
-  if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
-  if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
-  if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
-  g_print ("\n");
-  g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
-         lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
-  g_print ("lcPktData =");
-  if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
-  if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
-  if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
-  if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
-  if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
-  if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
-  if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
-  if (lc->lcPktData & PK_X) g_print (" PK_X");
-  if (lc->lcPktData & PK_Y) g_print (" PK_Y");
-  if (lc->lcPktData & PK_Z) g_print (" PK_Z");
-  if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
-  if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
-  if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
-  if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
-  g_print ("\n");
-  g_print ("lcPktMode =");
-  if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
-  if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
-  if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
-  if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
-  if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
-  if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
-  if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
-  if (lc->lcPktMode & PK_X) g_print (" PK_X");
-  if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
-  if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
-  if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
-  if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
-  if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
-  if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
-  g_print ("\n");
-  g_print ("lcMoveMask =");
-  if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
-  if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
-  if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
-  if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
-  if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
-  if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
-  if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
-  if (lc->lcMoveMask & PK_X) g_print (" PK_X");
-  if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
-  if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
-  if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
-  if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
-  if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
-  if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
-  g_print ("\n");
-  g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
-         lc->lcBtnDnMask, lc->lcBtnUpMask);
-  g_print ("lcInOrgX = %d, lcInOrgY = %d, lcInOrgZ = %d\n",
-         lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
-  g_print ("lcInExtX = %d, lcInExtY = %d, lcInExtZ = %d\n",
-         lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
-  g_print ("lcOutOrgX = %d, lcOutOrgY = %d, lcOutOrgZ = %d\n",
-         lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
-  g_print ("lcOutExtX = %d, lcOutExtY = %d, lcOutExtZ = %d\n",
-         lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
-  g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
-         lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
-  g_print ("lcSysMode = %d\n", lc->lcSysMode);
-  g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
-         lc->lcSysOrgX, lc->lcSysOrgY);
-  g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
-         lc->lcSysExtX, lc->lcSysExtY);
-  g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
-         lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
-}
-
-#endif
-
-void 
-gdk_input_init (void)
-{
-  GdkDevicePrivate *gdkdev;
-  GdkWindowPrivate *window_private;
-  GdkWindowAttr wa;
-  WORD specversion;
-  LOGCONTEXT defcontext;
-  HCTX *hctx;
-  UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
-  AXIS axis_x, axis_y, axis_npressure, axis_orientation[3];
-  int i, j, k;
-  char devname[100], csrname[100];
-  guint32 deviceid_counter = 0;
-
-  gdk_input_devices = NULL;
-  wintab_contexts = NULL;
-
-  if (!gdk_input_ignore_wintab &&
-      WTInfo (0, 0, NULL))
-    {
-      WTInfo (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
-
-#if USE_SYSCONTEXT
-      WTInfo (WTI_DEFSYSCTX, 0, &defcontext);
-#else
-      WTInfo (WTI_DEFCONTEXT, 0, &defcontext);
-#endif
-#if 0
-      g_print("DEFCONTEXT:\n"); print_lc(&defcontext);
-#endif
-      WTInfo (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
-      WTInfo (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
-
-      /* Create a dummy window to receive wintab events */
-      wa.wclass = GDK_INPUT_OUTPUT;
-      wa.event_mask = GDK_ALL_EVENTS_MASK;
-      wa.width = 2;
-      wa.height = 2;
-      wa.x = -100;
-      wa.y = -100;
-      wa.window_type = GDK_WINDOW_TOPLEVEL;
-      if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
-       {
-         g_warning ("gdk_input_init: gdk_window_new failed");
-         return;
-       }
-      gdk_window_ref (wintab_window);
-      window_private = (GdkWindowPrivate *) wintab_window;
-      
-      for (i = 0; i < ndevices; i++)
-       {
-         LOGCONTEXT lc;
-
-         WTInfo (WTI_DEVICES + i, DVC_NAME, devname);
-      
-         WTInfo (WTI_DEVICES + i, DVC_NCSRTYPES, &ncsrtypes);
-         WTInfo (WTI_DEVICES + i, DVC_FIRSTCSR, &firstcsr);
-         WTInfo (WTI_DEVICES + i, DVC_HARDWARE, &hardware);
-         WTInfo (WTI_DEVICES + i, DVC_X, &axis_x);
-         WTInfo (WTI_DEVICES + i, DVC_Y, &axis_y);
-         WTInfo (WTI_DEVICES + i, DVC_NPRESSURE, &axis_npressure);
-         WTInfo (WTI_DEVICES + i, DVC_ORIENTATION, axis_orientation);
-
-         if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
-           {
-             WTInfo (WTI_DDCTXS + i, CTX_NAME, lc.lcName);
-             WTInfo (WTI_DDCTXS + i, CTX_OPTIONS, &lc.lcOptions);
-             lc.lcOptions |= CXO_MESSAGES;
-             lc.lcStatus = 0;
-             WTInfo (WTI_DDCTXS + i, CTX_LOCKS, &lc.lcLocks);
-             lc.lcMsgBase = WT_DEFBASE;
-             lc.lcDevice = i;
-             lc.lcPktRate = 20;
-             lc.lcPktData = PACKETDATA;
-             lc.lcPktMode = PK_BUTTONS; /* We want buttons in relative mode */
-             lc.lcMoveMask = PACKETDATA;
-             lc.lcBtnDnMask = lc.lcBtnUpMask = ~0;
-             WTInfo (WTI_DDCTXS + i, CTX_INORGX, &lc.lcInOrgX);
-             WTInfo (WTI_DDCTXS + i, CTX_INORGY, &lc.lcInOrgY);
-             WTInfo (WTI_DDCTXS + i, CTX_INORGZ, &lc.lcInOrgZ);
-             WTInfo (WTI_DDCTXS + i, CTX_INEXTX, &lc.lcInExtX);
-             WTInfo (WTI_DDCTXS + i, CTX_INEXTY, &lc.lcInExtY);
-             WTInfo (WTI_DDCTXS + i, CTX_INEXTZ, &lc.lcInExtZ);
-             lc.lcOutOrgX = axis_x.axMin;
-             lc.lcOutOrgY = axis_y.axMin;
-             lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
-             lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
-             lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
-             WTInfo (WTI_DDCTXS + i, CTX_SENSX, &lc.lcSensX);
-             WTInfo (WTI_DDCTXS + i, CTX_SENSY, &lc.lcSensY);
-             WTInfo (WTI_DDCTXS + i, CTX_SENSZ, &lc.lcSensZ);
-             WTInfo (WTI_DDCTXS + i, CTX_SYSMODE, &lc.lcSysMode);
-             lc.lcSysOrgX = lc.lcSysOrgY = 0;
-             WTInfo (WTI_DDCTXS + i, CTX_SYSEXTX, &lc.lcSysExtX);
-             WTInfo (WTI_DDCTXS + i, CTX_SYSEXTY, &lc.lcSysExtY);
-             WTInfo (WTI_DDCTXS + i, CTX_SYSSENSX, &lc.lcSysSensX);
-             WTInfo (WTI_DDCTXS + i, CTX_SYSSENSY, &lc.lcSysSensY);
-           }
-         else
-           {
-             lc = defcontext;
-             lc.lcOptions |= CXO_MESSAGES;
-             lc.lcMsgBase = WT_DEFBASE;
-             lc.lcPktRate = 20; /* Slow down the packets a bit */
-             lc.lcPktData = PACKETDATA;
-             lc.lcPktMode = PACKETMODE;
-             lc.lcMoveMask = PACKETDATA;
-             lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
-#if 0
-             lc.lcOutExtY = -lc.lcOutExtY; /* Y grows downward */
-#else
-             lc.lcOutOrgX = axis_x.axMin;
-             lc.lcOutOrgY = axis_y.axMin;
-             lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
-             lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
-             lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
-#endif
-           }
-#if 0
-         g_print("context for device %d:\n", i); print_lc(&lc);
-#endif
-         hctx = g_new (HCTX, 1);
-          if ((*hctx = WTOpen (window_private->xwindow, &lc, TRUE)) == NULL)
-           {
-             g_warning ("gdk_input_init: WTOpen failed");
-             return;
-           }
-         GDK_NOTE (MISC, g_print ("gdk_input_init: opened Wintab device %d %#x\n",
-                                  i, *hctx));
-
-         wintab_contexts = g_list_append (wintab_contexts, hctx);
-#if 0
-         WTEnable (*hctx, TRUE);
-#endif
-         WTOverlap (*hctx, TRUE);
-
-#if 0
-         g_print("context for device %d after WTOpen:\n", i); print_lc(&lc);
-#endif
-         for (j = firstcsr; j < firstcsr + ncsrtypes; j++)
-           {
-             gdkdev = g_new (GdkDevicePrivate, 1);
-             WTInfo (WTI_CURSORS + j, CSR_NAME, csrname);
-             gdkdev->info.name = g_strconcat (devname, " ", csrname, NULL);
-             gdkdev->info.deviceid = deviceid_counter++;
-             gdkdev->info.source = GDK_SOURCE_PEN;
-             gdkdev->info.mode = GDK_MODE_SCREEN;
-#if USE_SYSCONTEXT
-             gdkdev->info.has_cursor = TRUE;
-#else
-             gdkdev->info.has_cursor = FALSE;
-#endif
-             gdkdev->hctx = *hctx;
-             gdkdev->cursor = j;
-             WTInfo (WTI_CURSORS + j, CSR_PKTDATA, &gdkdev->pktdata);
-             gdkdev->info.num_axes = 0;
-             if (gdkdev->pktdata & PK_X)
-               gdkdev->info.num_axes++;
-             if (gdkdev->pktdata & PK_Y)
-               gdkdev->info.num_axes++;
-             if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
-               gdkdev->info.num_axes++;
-             if (gdkdev->pktdata & PK_ORIENTATION)
-               gdkdev->info.num_axes += 2; /* x and y tilt */
-             WTInfo (WTI_CURSORS + j, CSR_NPBTNMARKS, &gdkdev->npbtnmarks);
-             gdkdev->axes = g_new (GdkAxisInfo, gdkdev->info.num_axes);
-             gdkdev->info.axes = g_new (GdkAxisUse, gdkdev->info.num_axes);
-             gdkdev->last_axis_data = g_new (gint, gdkdev->info.num_axes);
-             
-             for (k = 0; k < GDK_AXIS_LAST; k++)
-               gdkdev->axis_for_use[k] = -1;
-
-             k = 0;
-             if (gdkdev->pktdata & PK_X)
-               {
-                 gdkdev->axes[k].xresolution =
-                   gdkdev->axes[k].resolution = axis_x.axResolution / 65535.;
-                 gdkdev->axes[k].xmin_value =
-                   gdkdev->axes[k].min_value = axis_x.axMin;
-                 gdkdev->axes[k].xmax_value =
-                   gdkdev->axes[k].max_value = axis_x.axMax;
-                 gdkdev->info.axes[k] = GDK_AXIS_X;
-                 gdkdev->axis_for_use[GDK_AXIS_X] = k;
-                 k++;
-               }
-             if (gdkdev->pktdata & PK_Y)
-               {
-                 gdkdev->axes[k].xresolution =
-                   gdkdev->axes[k].resolution = axis_y.axResolution / 65535.;
-                 gdkdev->axes[k].xmin_value =
-                   gdkdev->axes[k].min_value = axis_y.axMin;
-                 gdkdev->axes[k].xmax_value =
-                   gdkdev->axes[k].max_value = axis_y.axMax;
-                 gdkdev->info.axes[k] = GDK_AXIS_Y;
-                 gdkdev->axis_for_use[GDK_AXIS_Y] = k;
-                 k++;
-               }
-             if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
-               {
-                 gdkdev->axes[k].xresolution =
-                   gdkdev->axes[k].resolution = axis_npressure.axResolution / 65535.;
-                 gdkdev->axes[k].xmin_value =
-                   gdkdev->axes[k].min_value = axis_npressure.axMin;
-                 gdkdev->axes[k].xmax_value =
-                   gdkdev->axes[k].max_value = axis_npressure.axMax;
-                 gdkdev->info.axes[k] = GDK_AXIS_PRESSURE;
-                 gdkdev->axis_for_use[GDK_AXIS_PRESSURE] = k;
-                 k++;
-               }
-             if (gdkdev->pktdata & PK_ORIENTATION)
-               {
-                 GdkAxisUse axis;
-
-                 gdkdev->orientation_axes[0] = axis_orientation[0];
-                 gdkdev->orientation_axes[1] = axis_orientation[1];
-                 for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++)
-                   {
-                     gdkdev->axes[k].xresolution =
-                       gdkdev->axes[k].resolution = 1000;
-                     gdkdev->axes[k].xmin_value =
-                       gdkdev->axes[k].min_value = -1000;
-                     gdkdev->axes[k].xmax_value =
-                       gdkdev->axes[k].max_value = 1000;
-                     gdkdev->info.axes[k] = axis;
-                     gdkdev->axis_for_use[axis] = k;
-                     k++;
-                   }
-               }
-             gdkdev->info.num_keys = 0;
-             gdkdev->info.keys = NULL;
-             GDK_NOTE (EVENTS,
-                       g_print ("gdk_input_init: device: %d axes: %d\n",
-                                gdkdev->info.deviceid,
-                                gdkdev->info.num_axes));
-             gdk_input_devices = g_list_append (gdk_input_devices,
-                                                gdkdev);
-           }
-       }
-      gdk_input_vtable.set_mode           = gdk_input_win32_set_mode;
-      gdk_input_vtable.set_axes           = NULL;
-      gdk_input_vtable.set_key            = NULL;
-      gdk_input_vtable.motion_events      = NULL;
-      gdk_input_vtable.get_pointer       = gdk_input_win32_get_pointer;
-      gdk_input_vtable.grab_pointer      = gdk_input_win32_grab_pointer;
-      gdk_input_vtable.ungrab_pointer     = gdk_input_win32_ungrab_pointer;
-      gdk_input_vtable.configure_event    = gdk_input_win32_configure_event;
-      gdk_input_vtable.enter_event        = gdk_input_win32_enter_event;
-      gdk_input_vtable.other_event        = gdk_input_win32_other_event;
-      gdk_input_vtable.enable_window      = gdk_input_win32_enable_window;
-      gdk_input_vtable.disable_window     = gdk_input_win32_disable_window;
-
-      gdk_input_root_width = gdk_screen_width ();
-      gdk_input_root_height = gdk_screen_height ();
-      gdk_input_ignore_core = FALSE;
-    }
-  else
-    {
-      gdk_input_vtable.set_mode           = NULL;
-      gdk_input_vtable.set_axes           = NULL;
-      gdk_input_vtable.set_key            = NULL;
-      gdk_input_vtable.motion_events      = NULL;
-      gdk_input_vtable.get_pointer       = gdk_input_none_get_pointer;
-      gdk_input_vtable.grab_pointer      = NULL;
-      gdk_input_vtable.ungrab_pointer     = NULL;
-      gdk_input_vtable.configure_event    = NULL;
-      gdk_input_vtable.enter_event        = NULL;
-      gdk_input_vtable.other_event        = NULL;
-      gdk_input_vtable.enable_window      = NULL;
-      gdk_input_vtable.disable_window     = NULL;
-      gdk_input_ignore_core = FALSE;
-    }
-  
-  gdk_input_devices = g_list_append (gdk_input_devices, &gdk_input_core_info);
-}
-
-static void
-gdk_input_get_root_relative_geometry (HWND w,
-                                     int  *x_ret,
-                                     int  *y_ret)
-{
-  RECT rect;
-
-  GetWindowRect (w, &rect);
-
-  if (x_ret)
-    *x_ret = rect.left;
-  if (y_ret)
-    *y_ret = rect.top;
-}
-
-static void
-gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
-                                GdkInputWindow   *input_window,
-                                gint             *axis_data,
-                                gdouble          *x,
-                                gdouble          *y,
-                                gdouble          *pressure,
-                                gdouble          *xtilt,
-                                gdouble          *ytilt)
-{
-  GdkWindowPrivate *window_private;
-  gint x_axis, y_axis, pressure_axis, xtilt_axis, ytilt_axis;
-  gdouble device_width, device_height;
-  gdouble x_offset, y_offset, x_scale, y_scale;
-
-  window_private = (GdkWindowPrivate *) input_window->window;
-
-  x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
-  y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
-  pressure_axis = gdkdev->axis_for_use[GDK_AXIS_PRESSURE];
-  xtilt_axis = gdkdev->axis_for_use[GDK_AXIS_XTILT];
-  ytilt_axis = gdkdev->axis_for_use[GDK_AXIS_YTILT];
-
-  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 (gdkdev->info.mode == GDK_MODE_SCREEN) 
-    {
-      x_scale = gdk_input_root_width / device_width;
-      y_scale = gdk_input_root_height / device_height;
-
-      x_offset = -input_window->root_x;
-      y_offset = -input_window->root_y;
-    }
-  else                         /* GDK_MODE_WINDOW */
-    {
-      double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
-       (device_width*gdkdev->axes[x_axis].resolution);
-
-      if (device_aspect * window_private->width >= window_private->height)
-       {
-         /* device taller than window */
-         x_scale = window_private->width / device_width;
-         y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
-           / gdkdev->axes[y_axis].resolution;
-
-         x_offset = 0;
-         y_offset = -(device_height * y_scale - 
-                              window_private->height)/2;
-       }
-      else
-       {
-         /* window taller than device */
-         y_scale = window_private->height / device_height;
-         x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
-           / gdkdev->axes[x_axis].resolution;
-
-         y_offset = 0;
-         x_offset = -(device_width * x_scale - window_private->width)/2;
-       }
-    }
-  
-  if (x)
-    *x = x_offset + x_scale*axis_data[x_axis];
-  if (y)
-    *y = y_offset + y_scale*axis_data[y_axis];
-
-  if (pressure)
-    {
-      if (pressure_axis != -1)
-       *pressure = ((double)axis_data[pressure_axis] 
-                    - gdkdev->axes[pressure_axis].min_value) 
-         / (gdkdev->axes[pressure_axis].max_value 
-            - gdkdev->axes[pressure_axis].min_value);
-      else
-       *pressure = 0.5;
-    }
-
-  if (xtilt)
-    {
-      if (xtilt_axis != -1)
-       {
-         *xtilt = 2. * (double)(axis_data[xtilt_axis] - 
-                                (gdkdev->axes[xtilt_axis].min_value +
-                                 gdkdev->axes[xtilt_axis].max_value)/2) /
-           (gdkdev->axes[xtilt_axis].max_value -
-            gdkdev->axes[xtilt_axis].min_value);
-       }
-      else
-       *xtilt = 0;
-    }
-  
-  if (ytilt)
-    {
-      if (ytilt_axis != -1)
-       {
-         *ytilt = 2. * (double)(axis_data[ytilt_axis] - 
-                                (gdkdev->axes[ytilt_axis].min_value +
-                                 gdkdev->axes[ytilt_axis].max_value)/2) /
-           (gdkdev->axes[ytilt_axis].max_value -
-            gdkdev->axes[ytilt_axis].min_value);
-       }
-      else
-       *ytilt = 0;
-    }
-}
-
-gint
-gdk_input_set_mode (guint32      deviceid,
-                   GdkInputMode mode)
-{
-  if (deviceid == GDK_CORE_POINTER)
-    return FALSE;
-
-  if (gdk_input_vtable.set_mode)
-    return gdk_input_vtable.set_mode (deviceid, mode);
-  else
-    return FALSE;
-}
-
-void
-gdk_input_set_axes (guint32     deviceid,
-                   GdkAxisUse *axes)
-{
-  int i;
-  GdkDevicePrivate *gdkdev = gdk_input_find_device (deviceid);
-  g_return_if_fail (gdkdev != NULL);
-
-  if (deviceid == GDK_CORE_POINTER)
-    return;
-
-  for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
-    {
-      gdkdev->axis_for_use[i] = -1;
-    }
-
-  for (i = 0; i < gdkdev->info.num_axes; i++)
-    {
-      gdkdev->info.axes[i] = axes[i];
-      gdkdev->axis_for_use[axes[i]] = i;
-    }
-}
-
-static void 
-gdk_input_win32_get_pointer (GdkWindow       *window,
-                            guint32          deviceid,
-                            gdouble         *x,
-                            gdouble         *y,
-                            gdouble         *pressure,
-                            gdouble         *xtilt,
-                            gdouble         *ytilt,
-                            GdkModifierType *mask)
-{
-  GdkDevicePrivate *gdkdev;
-  GdkInputWindow *input_window;
-  gint x_int, y_int;
-  gint i;
-
-  if (deviceid == GDK_CORE_POINTER)
-    {
-      gdk_window_get_pointer (window, &x_int, &y_int, mask);
-      if (x)
-       *x = x_int;
-      if (y)
-       *y = y_int;
-      if (pressure)
-       *pressure = 0.5;
-      if (xtilt)
-       *xtilt = 0;
-      if (ytilt)
-       *ytilt = 0;
-    }
-  else
-    {
-      if (mask)
-       gdk_window_get_pointer (window, NULL, NULL, mask);
-      
-      gdkdev = gdk_input_find_device (deviceid);
-      g_return_if_fail (gdkdev != NULL);
-
-      input_window = gdk_input_window_find (window);
-      g_return_if_fail (input_window != NULL);
-
-      gdk_input_translate_coordinates (gdkdev, input_window,
-                                      gdkdev->last_axis_data,
-                                      x, y, pressure,
-                                      xtilt, ytilt);
-      if (mask)
-       {
-         *mask &= 0xFF;
-         *mask |= ((gdkdev->last_buttons & 0x1F) << 8);
-       }
-    }
-}
-
-static void
-gdk_input_none_get_pointer (GdkWindow       *window,
-                           guint32          deviceid,
-                           gdouble         *x,
-                           gdouble         *y,
-                           gdouble         *pressure,
-                           gdouble         *xtilt,
-                           gdouble         *ytilt,
-                           GdkModifierType *mask)
-{
-  gint x_int, y_int;
-
-  gdk_window_get_pointer (window, &x_int, &y_int, mask);
-
-  if (x)
-    *x = x_int;
-  if (y)
-    *y = y_int;
-  if (pressure)
-    *pressure = 0.5;
-  if (xtilt)
-    *xtilt = 0;
-  if (ytilt)
-    *ytilt = 0;
-}
-
-static gint
-gdk_input_win32_set_mode (guint32      deviceid,
-                         GdkInputMode mode)
-{
-  GList *tmp_list;
-  GdkDevicePrivate *gdkdev;
-  GdkInputMode old_mode;
-  GdkInputWindow *input_window;
-
-  if (deviceid == GDK_CORE_POINTER)
-    return FALSE;
-
-  gdkdev = gdk_input_find_device (deviceid);
-  g_return_val_if_fail (gdkdev != NULL, FALSE);
-  old_mode = gdkdev->info.mode;
-
-  if (old_mode == mode)
-    return TRUE;
-
-  gdkdev->info.mode = mode;
-
-  if (mode == GDK_MODE_WINDOW)
-    {
-      gdkdev->info.has_cursor = FALSE;
-      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
-       {
-         input_window = (GdkInputWindow *)tmp_list->data;
-         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
-           gdk_input_win32_enable_window (input_window->window, gdkdev);
-         else
-           if (old_mode != GDK_MODE_DISABLED)
-             gdk_input_win32_disable_window (input_window->window, gdkdev);
-       }
-    }
-  else if (mode == GDK_MODE_SCREEN)
-    {
-      gdkdev->info.has_cursor = TRUE;
-      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
-       gdk_input_win32_enable_window (((GdkInputWindow *)tmp_list->data)->window,
-                                      gdkdev);
-    }
-  else  /* mode == GDK_MODE_DISABLED */
-    {
-      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
-       {
-         input_window = (GdkInputWindow *)tmp_list->data;
-         if (old_mode != GDK_MODE_WINDOW ||
-             input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
-           gdk_input_win32_disable_window (input_window->window, gdkdev);
-       }
-    }
-
-  return TRUE;
-}
-
-static void
-gdk_input_win32_configure_event (GdkEventConfigure *event,
-                                GdkWindow         *window)
-{
-  GdkInputWindow *input_window;
-  gint root_x, root_y;
-
-  input_window = gdk_input_window_find (window);
-  g_return_if_fail (window != NULL);
-
-  gdk_input_get_root_relative_geometry (GDK_WINDOW_XWINDOW (window),
-                                       &root_x, &root_y);
-
-  input_window->root_x = root_x;
-  input_window->root_y = root_y;
-}
-
-static void 
-gdk_input_win32_enter_event (GdkEventCrossing *event, 
-                            GdkWindow        *window)
-{
-  GdkInputWindow *input_window;
-  gint root_x, root_y;
-
-  input_window = gdk_input_window_find (window);
-  g_return_if_fail (window != NULL);
-
-  gdk_input_get_root_relative_geometry (GDK_WINDOW_XWINDOW (window),
-                                       &root_x, &root_y);
 
-  input_window->root_x = root_x;
-  input_window->root_y = root_y;
-}
-
-static void
-decode_tilt (gint   *axis_data,
-            AXIS   *axes,
-            PACKET *packet)
-{
-  /* As I don't have a tilt-sensing tablet,
-   * I cannot test this code.
-   */
-  
-  double az, el;
-
-  az = TWOPI * packet->pkOrientation.orAzimuth /
-    (axes[0].axResolution / 65536.);
-  el = TWOPI * packet->pkOrientation.orAltitude /
-    (axes[1].axResolution / 65536.);
-  
-  /* X tilt */
-  axis_data[0] = cos (az) * cos (el) * 1000;
-  /* Y tilt */
-  axis_data[1] = sin (az) * cos (el) * 1000;
-}
-
-static gint 
-gdk_input_win32_other_event (GdkEvent  *event,
-                            MSG       *xevent)
-{
-  GdkWindow *current_window;
-  GdkInputWindow *input_window;
-  GdkWindow *window;
-  GdkWindowPrivate *window_private;
-  GdkDevicePrivate *gdkdev;
-  GdkEventMask masktest;
-  POINT pt;
-  PACKET packet;
-  gint return_val;
-  gint k;
-  gint x, y;
-
-  if (event->any.window != wintab_window)
-    g_warning ("gdk_input_win32_other_event: not wintab_window?");
-
-#if USE_SYSCONTEXT
-  window = gdk_window_at_pointer (&x, &y);
-  if (window == NULL)
-    window = (GdkWindow *) &gdk_root_parent;
-
-  gdk_window_ref (window);
-
-  window_private = (GdkWindowPrivate *) window;
-
-  GDK_NOTE (EVENTS, g_print ("gdk_input_win32_other_event: window=%#x (%d,%d)\n", window_private->xwindow, x, y));
-  
-#else
-  /* ??? This code is pretty bogus */
-  current_window = gdk_window_lookup (GetActiveWindow ());
-  if (current_window == NULL)
-    return FALSE;
-  
-  input_window = gdk_input_window_find_within (current_window);
-  if (input_window == NULL)
-    return FALSE;
-#endif
-
-  if (xevent->message == WT_PACKET)
-    {
-      if (!WTPacket ((HCTX) xevent->lParam, xevent->wParam, &packet))
-       return FALSE;
-    }
-
-  switch (xevent->message)
-    {
-    case WT_PACKET:
-      if (window_private == &gdk_root_parent)
-       {
-         GDK_NOTE (EVENTS, g_print ("...is root\n"));
-         return FALSE;
-       }
-
-      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) xevent->lParam,
-                                                packet.pkCursor)) == NULL)
-       return FALSE;
-
-      if (gdkdev->info.mode == GDK_MODE_DISABLED)
-       return FALSE;
-      
-      k = 0;
-      if (gdkdev->pktdata & PK_X)
-       gdkdev->last_axis_data[k++] = packet.pkX;
-      if (gdkdev->pktdata & PK_Y)
-       gdkdev->last_axis_data[k++] = packet.pkY;
-      if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
-       gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
-      if (gdkdev->pktdata & PK_ORIENTATION)
-       {
-         decode_tilt (gdkdev->last_axis_data + k,
-                      gdkdev->orientation_axes, &packet);
-         k += 2;
-       }
-
-      g_assert (k == gdkdev->info.num_axes);
-
-      if (HIWORD (packet.pkButtons) != TBN_NONE)
-       {
-         /* Gdk buttons are numbered 1.. */
-         event->button.button = 1 + LOWORD (packet.pkButtons);
-
-         if (HIWORD (packet.pkButtons) == TBN_UP)
-           {
-             event->any.type = GDK_BUTTON_RELEASE;
-             masktest = GDK_BUTTON_RELEASE_MASK;
-             gdkdev->button_state &= ~(1 << LOWORD (packet.pkButtons));
-           }
-         else
-           {
-             event->any.type = GDK_BUTTON_PRESS;
-             masktest = GDK_BUTTON_PRESS_MASK;
-             gdkdev->button_state |= 1 << LOWORD (packet.pkButtons);
-           }
-       }
-      else
-       {
-         event->any.type = GDK_MOTION_NOTIFY;
-         masktest = GDK_POINTER_MOTION_MASK;
-         if (gdkdev->button_state & (1 << 0))
-           masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
-         if (gdkdev->button_state & (1 << 1))
-           masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
-         if (gdkdev->button_state & (1 << 2))
-           masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
-       }
-
-      /* Now we can check if the window wants the event, and
-       * propagate if necessary.
-       */
-    dijkstra:
-      if (!window_private->extension_events_selected
-         || !(window_private->extension_events & masktest))
-       {
-         GDK_NOTE (EVENTS, g_print ("...not selected\n"));
-
-         if (window_private->parent == (GdkWindow *) &gdk_root_parent)
-           return FALSE;
-         
-         pt.x = x;
-         pt.y = y;
-         ClientToScreen (window_private->xwindow, &pt);
-         gdk_window_unref (window);
-         window = window_private->parent;
-         gdk_window_ref (window);
-         window_private = (GdkWindowPrivate *) window;
-         ScreenToClient (window_private->xwindow, &pt);
-         x = pt.x;
-         y = pt.y;
-         GDK_NOTE (EVENTS, g_print ("...propagating to %#x, (%d,%d)\n", window_private->xwindow, x, y));
-         goto dijkstra;
-       }
-
-      input_window = gdk_input_window_find (window);
-
-      g_assert (input_window != NULL);
-
-      if (gdkdev->info.mode == GDK_MODE_WINDOW
-         && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
-       return FALSE;
-
-      event->any.window = window;
-
-      if (event->any.type == GDK_BUTTON_PRESS
-         || event->any.type == GDK_BUTTON_RELEASE)
-       {
-         event->button.time = xevent->time;
-         event->button.source = gdkdev->info.source;
-         last_moved_cursor_id = 
-           event->button.deviceid = gdkdev->info.deviceid;
-         
-#if 0
-#if USE_SYSCONTEXT
-         /* Buttons 1 to 3 will come in as WM_[LMR]BUTTON{DOWN,UP} */
-         if (event->button.button <= 3)
-           return FALSE;
-#endif
-#endif
-         gdk_input_translate_coordinates (gdkdev, input_window,
-                                          gdkdev->last_axis_data,
-                                          &event->button.x, &event->button.y,
-                                          &event->button.pressure,
-                                          &event->button.xtilt, 
-                                          &event->button.ytilt);
-
-         event->button.state = ((gdkdev->button_state << 8)
-                                & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
-                                   | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
-                                   | GDK_BUTTON5_MASK));
-         GDK_NOTE (EVENTS, g_print ("WINTAB button %s: %d %d %g,%g %g\n",
-                                    (event->button.type == GDK_BUTTON_PRESS ?
-                                     "press" : "release"),
-                                    event->button.deviceid,
-                                    event->button.button,
-                                    event->button.x, event->button.y,
-                                    event->button.pressure));
-       }
-      else
-       {
-         event->motion.time = xevent->time;
-         last_moved_cursor_id =
-           event->motion.deviceid = gdkdev->info.deviceid;
-         event->motion.is_hint = FALSE;
-         event->motion.source = gdkdev->info.source;
-
-         gdk_input_translate_coordinates (gdkdev, input_window,
-                                          gdkdev->last_axis_data,
-                                          &event->motion.x, &event->motion.y,
-                                          &event->motion.pressure,
-                                          &event->motion.xtilt, 
-                                          &event->motion.ytilt);
-
-         event->motion.state = ((gdkdev->button_state << 8)
-                                & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
-                                   | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
-                                   | GDK_BUTTON5_MASK));
-
-         GDK_NOTE (EVENTS, g_print ("WINTAB motion: %d %g,%g %g\n",
-                                    event->motion.deviceid,
-                                    event->motion.x, event->motion.y,
-                                    event->motion.pressure));
-
-         /* Check for missing release or press events for the normal
-          * pressure button. At least on my ArtPadII I sometimes miss a
-          * release event?
-          */
-         if ((gdkdev->pktdata & PK_NORMAL_PRESSURE
-              && (event->motion.state & GDK_BUTTON1_MASK)
-              && packet.pkNormalPressure <= MAX (0, gdkdev->npbtnmarks[0] - 2))
-             || (gdkdev->pktdata & PK_NORMAL_PRESSURE
-                 && !(event->motion.state & GDK_BUTTON1_MASK)
-                 && packet.pkNormalPressure > gdkdev->npbtnmarks[1] + 2))
-           {
-             GdkEvent *event2 = gdk_event_copy (event);
-             if (event->motion.state & GDK_BUTTON1_MASK)
-               {
-                 event2->button.type = GDK_BUTTON_RELEASE;
-                 gdkdev->button_state &= ~1;
-               }
-             else
-               {
-                 event2->button.type = GDK_BUTTON_PRESS;
-                 gdkdev->button_state |= 1;
-               }
-             event2->button.state = ((gdkdev->button_state << 8)
-                                     & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
-                                        | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
-                                        | GDK_BUTTON5_MASK));
-             event2->button.button = 1;
-             GDK_NOTE (EVENTS, g_print ("WINTAB synthesized button %s: %d %d %g,%g %g\n",
-                                        (event2->button.type == GDK_BUTTON_PRESS ?
-                                         "press" : "release"),
-                                        event2->button.deviceid,
-                                        event2->button.button,
-                                        event2->button.x, event2->button.y,
-                                        event2->button.pressure));
-             gdk_event_queue_append (event2);
-           }
-       }
-      return TRUE;
-
-    case WT_PROXIMITY:
-      if (LOWORD (xevent->lParam) == 0)
-       {
-         event->proximity.type = GDK_PROXIMITY_OUT;
-         gdk_input_ignore_core = FALSE;
-       }
-      else
-       {
-         event->proximity.type = GDK_PROXIMITY_IN;
-         gdk_input_ignore_core = TRUE;
-       }
-      event->proximity.time = xevent->time;
-      event->proximity.source = GDK_SOURCE_PEN;
-      event->proximity.deviceid = last_moved_cursor_id;
-
-      GDK_NOTE (EVENTS, g_print ("WINTAB proximity %s: %d\n",
-                                (event->proximity.type == GDK_PROXIMITY_IN ?
-                                 "in" : "out"),
-                                event->proximity.deviceid));
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-static gint
-gdk_input_win32_enable_window (GdkWindow        *window,
-                              GdkDevicePrivate *gdkdev)
-{
-  GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
-
-  window_private->extension_events_selected = TRUE;
-  return TRUE;
-}
-
-static gint
-gdk_input_win32_disable_window (GdkWindow        *window,
-                               GdkDevicePrivate *gdkdev)
-{
-  GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
-
-  window_private->extension_events_selected = FALSE;
-  return TRUE;
-}
-
-static gint
-gdk_input_win32_grab_pointer (GdkWindow    *window,
-                             gint          owner_events,
-                             GdkEventMask  event_mask,
-                             GdkWindow    *confine_to,
-                             guint32       time)
-{
-  GdkInputWindow *input_window, *new_window;
-  gboolean need_ungrab;
-  GdkDevicePrivate *gdkdev;
-  GList *tmp_list;
-  gint result;
-
-  tmp_list = gdk_input_windows;
-  new_window = NULL;
-  need_ungrab = FALSE;
-
-  GDK_NOTE (MISC, g_print ("gdk_input_win32_grab_pointer: %#x %d %#x\n",
-                          ((GdkWindowPrivate *) window)->xwindow,
-                          owner_events,
-                          (confine_to ?
-                           ((GdkWindowPrivate *) confine_to)->xwindow :
-                           0)));
-
-  while (tmp_list)
-    {
-      input_window = (GdkInputWindow *)tmp_list->data;
-
-      if (input_window->window == window)
-       new_window = input_window;
-      else if (input_window->grabbed)
-       {
-         input_window->grabbed = FALSE;
-         need_ungrab = TRUE;
-       }
-
-      tmp_list = tmp_list->next;
-    }
-
-  if (new_window)
-    {
-      new_window->grabbed = TRUE;
-      
-      tmp_list = gdk_input_devices;
-      while (tmp_list)
-       {
-         gdkdev = (GdkDevicePrivate *)tmp_list->data;
-         if (gdkdev->info.deviceid != GDK_CORE_POINTER)
-           {
-#if 0        
-             gdk_input_find_events (window, gdkdev,
-                                    event_mask,
-                                    event_classes, &num_classes);
-             result = XGrabDevice (GDK_DISPLAY(), gdkdev->xdevice,
-                                   GDK_WINDOW_XWINDOW (window),
-                                   owner_events, num_classes, event_classes,
-                                   GrabModeAsync, GrabModeAsync, time);
-             
-             /* FIXME: if failure occurs on something other than the first
-                device, things will be badly inconsistent */
-             if (result != Success)
-               return result;
-#endif
-           }
-         tmp_list = tmp_list->next;
-       }
-    }
-  else
-    { 
-      tmp_list = gdk_input_devices;
-      while (tmp_list)
-       {
-         gdkdev = (GdkDevicePrivate *)tmp_list->data;
-         if (gdkdev->info.deviceid != GDK_CORE_POINTER && 
-             ((gdkdev->button_state != 0) || need_ungrab))
-           {
-#if 0
-             XUngrabDevice (gdk_display, gdkdev->xdevice, time);
-#endif
-             gdkdev->button_state = 0;
-           }
-         
-         tmp_list = tmp_list->next;
-       }
-    }
-
-  return Success;
-      
-}
-
-static void 
-gdk_input_win32_ungrab_pointer (guint32 time)
-{
-  GdkInputWindow *input_window;
-  GdkDevicePrivate *gdkdev;
-  GList *tmp_list;
+#include "config.h"
 
-  GDK_NOTE (MISC, g_print ("gdk_input_win32_ungrab_pointer\n"));
+#include "gdkdisplay.h"
+#include "gdkdevice.h"
+#include "gdkdisplayprivate.h"
 
-  tmp_list = gdk_input_windows;
-  while (tmp_list)
-    {
-      input_window = (GdkInputWindow *)tmp_list->data;
-      if (input_window->grabbed)
-       break;
-      tmp_list = tmp_list->next;
-    }
+#include "gdkprivate-win32.h"
+#include "gdkdevicemanager-win32.h"
 
-  if (tmp_list)                        /* we found a grabbed window */
-    {
-      input_window->grabbed = FALSE;
+gint              _gdk_input_ignore_core;
 
-      tmp_list = gdk_input_devices;
-      while (tmp_list)
-       {
-         gdkdev = (GdkDevicePrivate *)tmp_list->data;
-#if 0
-         if (gdkdev->info.deviceid != GDK_CORE_POINTER && gdkdev->xdevice)
-           XUngrabDevice (gdk_display, gdkdev->xdevice, time);
-#endif
-         tmp_list = tmp_list->next;
-       }
-    }
-}
+GList            *_gdk_input_devices;
+GList            *_gdk_input_windows;
 
 GList *
-gdk_input_list_devices (void)
-{
-  return gdk_input_devices;
-}
-
-void
-gdk_input_set_source (guint32        deviceid,
-                     GdkInputSource source)
-{
-  GdkDevicePrivate *gdkdev = gdk_input_find_device (deviceid);
-  g_return_if_fail (gdkdev != NULL);
-
-  gdkdev->info.source = source;
-}
-
-void gdk_input_set_key (guint32 deviceid,
-                       guint   index,
-                       guint   keyval,
-                       GdkModifierType modifiers)
-{
-  if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key)
-    gdk_input_vtable.set_key (deviceid, index, keyval, modifiers);
-}
-
-GdkTimeCoord *
-gdk_input_motion_events (GdkWindow *window,
-                        guint32    deviceid,
-                        guint32    start,
-                        guint32    stop,
-                        gint      *nevents_return)
-{
-  GdkWindowPrivate *window_private;
-  GdkTimeCoord *coords;
-  int i;
-
-  g_return_val_if_fail (window != NULL, NULL);
-  window_private = (GdkWindowPrivate *) window;
-  if (window_private->destroyed)
-    return NULL;
-
-  *nevents_return = 0;
-  return NULL;         /* ??? */
-}
-
-static GdkInputWindow *
-gdk_input_window_find (GdkWindow *window)
+gdk_devices_list (void)
 {
-  GList *tmp_list;
-
-  for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
-    if (((GdkInputWindow *)(tmp_list->data))->window == window)
-      return (GdkInputWindow *)(tmp_list->data);
-
-  return NULL;      /* Not found */
+  return _gdk_win32_display_list_devices (_gdk_display);
 }
 
-static GdkInputWindow *
-gdk_input_window_find_within (GdkWindow *window)
+GList *
+_gdk_win32_display_list_devices (GdkDisplay *dpy)
 {
-  GList *tmp_list;
-  GdkWindowPrivate *window_private;
-  GdkWindowPrivate *tmp_private;
-  GdkInputWindow *candidate = NULL;
-
-  window_private = (GdkWindowPrivate *) window;
-
-  for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
-    {
-      (GdkWindowPrivate *) tmp_private =
-       (GdkWindowPrivate *) (((GdkInputWindow *)(tmp_list->data))->window);
-      if (tmp_private == window_private
-         || IsChild (window_private->xwindow, tmp_private->xwindow))
-       {
-         if (candidate)
-           return NULL;                /* Multiple hits */
-         candidate = (GdkInputWindow *)(tmp_list->data);
-       }
-    }
+  g_return_val_if_fail (dpy == _gdk_display, NULL);
 
-  return candidate;
+  return _gdk_input_devices;
 }
 
 /* FIXME: this routine currently needs to be called between creation
@@ -1353,179 +64,62 @@ gdk_input_window_find_within (GdkWindow *window)
    cases */
 
 void
-gdk_input_set_extension_events (GdkWindow       *window,
-                               gint             mask,
-                               GdkExtensionMode mode)
+gdk_input_set_extension_events (GdkWindow *window, gint mask,
+                                GdkExtensionMode mode)
 {
-  GdkWindowPrivate *window_private;
-  GList *tmp_list;
-  GdkInputWindow *iw;
+  GdkDeviceManager *device_manager;
+  GList *devices, *d;
 
-  g_return_if_fail (window != NULL);
-  window_private = (GdkWindowPrivate *) window;
-  if (window_private->destroyed)
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
     return;
 
   if (mode == GDK_EXTENSION_EVENTS_NONE)
     mask = 0;
 
-  if (mask != 0)
-    {
-      iw = g_new (GdkInputWindow,1);
+  window->extension_events = mask;
 
-      iw->window = window;
-      iw->mode = mode;
+  device_manager = gdk_display_get_device_manager (_gdk_display);
+  devices = gdk_device_manager_list_devices (device_manager,
+                                             GDK_DEVICE_TYPE_FLOATING);
 
-      iw->grabbed = FALSE;
-
-      gdk_input_windows = g_list_append (gdk_input_windows, iw);
-      window_private->extension_events = mask;
-
-      /* Add enter window events to the event mask */
-      gdk_window_set_events (window,
-                            gdk_window_get_events (window) | 
-                            GDK_ENTER_NOTIFY_MASK);
-    }
-  else
+  for (d = devices; d; d = d->next)
     {
-      iw = gdk_input_window_find (window);
-      if (iw)
-       {
-         gdk_input_windows = g_list_remove (gdk_input_windows, iw);
-         g_free (iw);
-       }
+      GdkDevice *dev;
+      gint dev_mask;
 
-      window_private->extension_events = 0;
-    }
+      dev = d->data;
+      dev_mask = mask;
 
-  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
-    {
-      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdk_device_get_mode (dev) == GDK_MODE_DISABLED ||
+          (!gdk_device_get_has_cursor (dev) && mode == GDK_EXTENSION_EVENTS_CURSOR))
+        dev_mask = 0;
 
-      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
-       {
-         if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
-             && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
-           gdk_input_win32_enable_window (window, gdkdev);
-         else
-           gdk_input_win32_disable_window (window, gdkdev);
-       }
+      gdk_window_set_device_events (window, dev, mask);
     }
-}
-
-void
-gdk_input_window_destroy (GdkWindow *window)
-{
-  GdkInputWindow *input_window;
-
-  input_window = gdk_input_window_find (window);
-  g_return_if_fail (input_window != NULL);
 
-  gdk_input_windows = g_list_remove (gdk_input_windows,input_window);
-  g_free (input_window);
+  g_list_free (devices);
 }
 
 void
-gdk_input_exit (void)
+_gdk_input_init (GdkDisplay *display)
 {
-  GList *tmp_list;
-  GdkDevicePrivate *gdkdev;
+  GdkDeviceManagerWin32 *device_manager;
 
-  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
-    {
-      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
-      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
-       {
-         gdk_input_win32_set_mode (gdkdev->info.deviceid, GDK_MODE_DISABLED);
-         g_free (gdkdev->info.name);
-         g_free (gdkdev->last_axis_data);
-         g_free (gdkdev->info.axes);
-         g_free (gdkdev->info.keys);
-         g_free (gdkdev->axes);
-         g_free (gdkdev);
-       }
-    }
+  _gdk_input_ignore_core = FALSE;
 
-  g_list_free (gdk_input_devices);
+  device_manager = g_object_new (GDK_TYPE_DEVICE_MANAGER_WIN32,
+                                 "display", display,
+                                 NULL);
+  display->device_manager = GDK_DEVICE_MANAGER (device_manager);
 
-  for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
-    {
-      g_free (tmp_list->data);
-    }
-  g_list_free (gdk_input_windows);
+  display->core_pointer = device_manager->core_pointer;
 
-#if 1
-  for (tmp_list = wintab_contexts; tmp_list; tmp_list = tmp_list->next)
-    {
-      HCTX *hctx = (HCTX *) tmp_list->data;
-      BOOL result;
+  _gdk_input_devices = g_list_append (NULL, display->core_pointer);
+  _gdk_input_devices = g_list_concat (_gdk_input_devices,
+                                      g_list_copy (device_manager->wintab_devices));
 
-      /* For some reason WTEnable and/or WTClose tend to crash here.
-       * Protect with __try/__except to avoid a message box.
-       */
-      __try {
-#if 0
-        WTEnable (*hctx, FALSE);
-#endif
-       result = WTClose (*hctx);
-      }
-      __except (/* GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? */
-                EXCEPTION_EXECUTE_HANDLER /*: 
-                EXCEPTION_CONTINUE_SEARCH */) {
-       result = FALSE;
-      }
-      if (!result)
-       g_warning ("gdk_input_exit: Closing Wintab context %#x failed", *hctx);
-      g_free (hctx);
-    }
-#endif
-  g_list_free (wintab_contexts);
-}
-
-static GdkDevicePrivate *
-gdk_input_find_device (guint32 id)
-{
-  GList *tmp_list = gdk_input_devices;
-  GdkDevicePrivate *gdkdev;
-
-  while (tmp_list)
-    {
-      gdkdev = (GdkDevicePrivate *) (tmp_list->data);
-      if (gdkdev->info.deviceid == id)
-       return gdkdev;
-      tmp_list = tmp_list->next;
-    }
-  return NULL;
-}
+  _gdk_input_wintab_init_check (device_manager);
 
-static GdkDevicePrivate *
-gdk_input_find_dev_from_ctx (HCTX hctx,
-                            UINT cursor)
-{
-  GList *tmp_list = gdk_input_devices;
-  GdkDevicePrivate *gdkdev;
-
-  while (tmp_list)
-    {
-      gdkdev = (GdkDevicePrivate *) (tmp_list->data);
-      if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
-       return gdkdev;
-      tmp_list = tmp_list->next;
-    }
-  return NULL;
-}
-
-void
-gdk_input_window_get_pointer (GdkWindow       *window,
-                             guint32          deviceid,
-                             gdouble         *x,
-                             gdouble         *y,
-                             gdouble         *pressure,
-                             gdouble         *xtilt,
-                             gdouble         *ytilt,
-                             GdkModifierType *mask)
-{
-  if (gdk_input_vtable.get_pointer)
-    gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,
-                                 xtilt, ytilt, mask);
 }