]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkinput-win32.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / gdk / win32 / gdkinput-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-2002 Tor Lillqvist
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include <config.h>
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <math.h>
33
34 #include "gdk.h"
35 #include "gdkinput.h"
36 #include "gdkinternals.h"
37 #include "gdkprivate-win32.h"
38 #include "gdkinput-win32.h"
39
40 #ifdef HAVE_WINTAB
41
42 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y  | PK_NORMAL_PRESSURE | PK_ORIENTATION)
43 #define PACKETMODE (PK_BUTTONS)
44 #include <pktdef.h>
45
46 #define DEBUG_WINTAB 1          /* Verbose debug messages enabled */
47
48 #define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */
49
50 #endif
51
52 #if defined(HAVE_WINTAB) || defined(HAVE_WHATEVER_OTHER)
53 #define HAVE_SOME_XINPUT
54 #endif
55
56 #define TWOPI (2.*G_PI)
57
58 /* Forward declarations */
59
60 #ifdef HAVE_WINTAB
61
62 static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
63                                                       UINT id);
64 static GList     *wintab_contexts = NULL;
65
66 static GdkWindow *wintab_window = NULL;
67
68 #endif /* HAVE_WINTAB */
69
70 #ifdef HAVE_SOME_XINPUT
71
72 static GdkWindow *x_grab_window = NULL; /* Window that currently holds
73                                          * the extended inputs grab
74                                          */
75 static GdkEventMask x_grab_mask;
76 static gboolean x_grab_owner_events;
77
78 #endif /* HAVE_SOME_XINPUT */
79
80 #ifdef HAVE_WINTAB
81
82 static GdkDevicePrivate *
83 gdk_input_find_dev_from_ctx (HCTX hctx,
84                              UINT cursor)
85 {
86   GList *tmp_list = _gdk_input_devices;
87   GdkDevicePrivate *gdkdev;
88
89   while (tmp_list)
90     {
91       gdkdev = (GdkDevicePrivate *) (tmp_list->data);
92       if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
93         return gdkdev;
94       tmp_list = tmp_list->next;
95     }
96   return NULL;
97 }
98
99 #if DEBUG_WINTAB
100
101 static void
102 print_lc(LOGCONTEXT *lc)
103 {
104   g_print ("lcName = %s\n", lc->lcName);
105   g_print ("lcOptions =");
106   if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
107   if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
108   if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
109   if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
110   if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
111   if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
112   g_print ("\n");
113   g_print ("lcStatus =");
114   if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
115   if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
116   if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
117   g_print ("\n");
118   g_print ("lcLocks =");
119   if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
120   if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
121   if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
122   if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
123   g_print ("\n");
124   g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
125           lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
126   g_print ("lcPktData =");
127   if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
128   if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
129   if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
130   if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
131   if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
132   if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
133   if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
134   if (lc->lcPktData & PK_X) g_print (" PK_X");
135   if (lc->lcPktData & PK_Y) g_print (" PK_Y");
136   if (lc->lcPktData & PK_Z) g_print (" PK_Z");
137   if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
138   if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
139   if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
140   if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
141   g_print ("\n");
142   g_print ("lcPktMode =");
143   if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
144   if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
145   if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
146   if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
147   if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
148   if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
149   if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
150   if (lc->lcPktMode & PK_X) g_print (" PK_X");
151   if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
152   if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
153   if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
154   if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
155   if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
156   if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
157   g_print ("\n");
158   g_print ("lcMoveMask =");
159   if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
160   if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
161   if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
162   if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
163   if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
164   if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
165   if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
166   if (lc->lcMoveMask & PK_X) g_print (" PK_X");
167   if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
168   if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
169   if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
170   if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
171   if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
172   if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
173   g_print ("\n");
174   g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
175           (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
176   g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
177           lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
178   g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
179           lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
180   g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
181           lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
182   g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
183           lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
184   g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
185           lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
186   g_print ("lcSysMode = %d\n", lc->lcSysMode);
187   g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
188           lc->lcSysOrgX, lc->lcSysOrgY);
189   g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
190           lc->lcSysExtX, lc->lcSysExtY);
191   g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
192           lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
193 }
194
195 #endif
196
197 void
198 _gdk_input_wintab_init_check (void)
199 {
200   static gboolean wintab_initialized = FALSE;
201   GdkDevicePrivate *gdkdev;
202   GdkWindowAttr wa;
203   WORD specversion;
204   HCTX *hctx;
205   UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
206   BOOL active;
207   AXIS axis_x, axis_y, axis_npressure, axis_or[3];
208   int i, k;
209   int devix, cursorix;
210   char devname[100], csrname[100];
211   BOOL defcontext_done;
212
213   if (wintab_initialized)
214     return;
215   
216   wintab_initialized = TRUE;
217   
218   wintab_contexts = NULL;
219
220   if (!_gdk_input_ignore_wintab &&
221       WTInfo (0, 0, NULL))
222     {
223       WTInfo (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
224       GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
225                                HIBYTE (specversion), LOBYTE (specversion)));
226       WTInfo (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
227       WTInfo (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
228 #if DEBUG_WINTAB
229       GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
230                                ndevices, ncursors));
231 #endif
232       /* Create a dummy window to receive wintab events */
233       wa.wclass = GDK_INPUT_OUTPUT;
234       wa.event_mask = GDK_ALL_EVENTS_MASK;
235       wa.width = 2;
236       wa.height = 2;
237       wa.x = -100;
238       wa.y = -100;
239       wa.window_type = GDK_WINDOW_TOPLEVEL;
240       if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
241         {
242           g_warning ("gdk_input_wintab_init: gdk_window_new failed");
243           return;
244         }
245       g_object_ref (wintab_window);
246       
247       for (devix = 0; devix < ndevices; devix++)
248         {
249           LOGCONTEXT lc;
250           
251           /* We open the Wintab device (hmm, what if there are several?) as a
252            * system pointing device, i.e. it controls the normal Windows
253            * cursor. This seems much more natural.
254            */
255
256           WTInfo (WTI_DEVICES + devix, DVC_NAME, devname);
257       
258           WTInfo (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
259           WTInfo (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
260           WTInfo (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
261           WTInfo (WTI_DEVICES + devix, DVC_X, &axis_x);
262           WTInfo (WTI_DEVICES + devix, DVC_Y, &axis_y);
263           WTInfo (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
264           WTInfo (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
265
266           defcontext_done = FALSE;
267           if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
268             {
269               /* Try to get device-specific default context */
270               /* Some drivers, e.g. Aiptek, don't provide this info */
271               if (WTInfo (WTI_DSCTXS + devix, 0, &lc) > 0)
272                 defcontext_done = TRUE;
273 #if DEBUG_WINTAB
274               if (defcontext_done)
275                 GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
276               else
277                 GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
278 #endif
279             }
280
281           if (!defcontext_done)
282             WTInfo (WTI_DEFSYSCTX, 0, &lc);
283 #if DEBUG_WINTAB
284           GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
285 #endif
286           lc.lcOptions |= CXO_MESSAGES;
287           lc.lcStatus = 0;
288           lc.lcMsgBase = WT_DEFBASE;
289           lc.lcPktRate = 50;
290           lc.lcPktData = PACKETDATA;
291           lc.lcPktMode = PACKETMODE;
292           lc.lcMoveMask = PACKETDATA;
293           lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
294           lc.lcOutOrgX = axis_x.axMin;
295           lc.lcOutOrgY = axis_y.axMin;
296           lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
297           lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
298           lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
299 #if DEBUG_WINTAB
300           GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
301                            print_lc(&lc)));
302 #endif
303           hctx = g_new (HCTX, 1);
304           if ((*hctx = WTOpen (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
305             {
306               g_warning ("gdk_input_wintab_init: WTOpen failed");
307               return;
308             }
309           GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
310                                    devix, *hctx));
311
312           wintab_contexts = g_list_append (wintab_contexts, hctx);
313 #if 0
314           WTEnable (*hctx, TRUE);
315 #endif
316           WTOverlap (*hctx, TRUE);
317
318 #if DEBUG_WINTAB
319           GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
320                            print_lc(&lc)));
321 #endif
322           /* Increase packet queue size to reduce the risk of lost packets */
323           /* According to the specs, if the function fails we must try again */
324           /* with a smaller queue size */
325           GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
326           for (i = 128; i >= 1; i >>= 1)
327             {
328               if (WTQueueSizeSet(*hctx, i))
329                 {
330                   GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
331                   break;
332                 }
333             }
334           if (!i)
335             GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
336           for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
337             {
338               active = FALSE;
339               WTInfo (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
340               if (!active)
341                 continue;
342               gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
343               WTInfo (WTI_CURSORS + cursorix, CSR_NAME, csrname);
344               gdkdev->info.name = g_strconcat (devname, " ", csrname, NULL);
345               gdkdev->info.source = GDK_SOURCE_PEN;
346               gdkdev->info.mode = GDK_MODE_SCREEN;
347               gdkdev->info.has_cursor = TRUE;
348               gdkdev->hctx = *hctx;
349               gdkdev->cursor = cursorix;
350               WTInfo (WTI_CURSORS + cursorix, CSR_PKTDATA, &gdkdev->pktdata);
351               gdkdev->info.num_axes = 0;
352               if (gdkdev->pktdata & PK_X)
353                 gdkdev->info.num_axes++;
354               if (gdkdev->pktdata & PK_Y)
355                 gdkdev->info.num_axes++;
356               if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
357                 gdkdev->info.num_axes++;
358               /* The wintab driver for the Wacom ArtPad II reports
359                * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
360                * actually sense tilt. Catch this by noticing that the
361                * orientation axis's azimuth resolution is zero.
362                */
363               if ((gdkdev->pktdata & PK_ORIENTATION)
364                   && axis_or[0].axResolution == 0)
365                 gdkdev->pktdata &= ~PK_ORIENTATION;
366
367               if (gdkdev->pktdata & PK_ORIENTATION)
368                 gdkdev->info.num_axes += 2; /* x and y tilt */
369               WTInfo (WTI_CURSORS + cursorix, CSR_NPBTNMARKS, &gdkdev->npbtnmarks);
370               gdkdev->info.axes = g_new (GdkDeviceAxis, gdkdev->info.num_axes);
371               gdkdev->axes = g_new (GdkAxisInfo, gdkdev->info.num_axes);
372               gdkdev->last_axis_data = g_new (gint, gdkdev->info.num_axes);
373               
374               k = 0;
375               if (gdkdev->pktdata & PK_X)
376                 {
377                   gdkdev->axes[k].xresolution =
378                     gdkdev->axes[k].resolution = axis_x.axResolution / 65535.;
379                   gdkdev->axes[k].xmin_value =
380                     gdkdev->axes[k].min_value = axis_x.axMin;
381                   gdkdev->axes[k].xmax_value =
382                     gdkdev->axes[k].max_value = axis_x.axMax;
383                   gdkdev->info.axes[k].use = GDK_AXIS_X;
384                   gdkdev->info.axes[k].min = axis_x.axMin;
385                   gdkdev->info.axes[k].max = axis_x.axMax;
386                   k++;
387                 }
388               if (gdkdev->pktdata & PK_Y)
389                 {
390                   gdkdev->axes[k].xresolution =
391                     gdkdev->axes[k].resolution = axis_y.axResolution / 65535.;
392                   gdkdev->axes[k].xmin_value =
393                     gdkdev->axes[k].min_value = axis_y.axMin;
394                   gdkdev->axes[k].xmax_value =
395                     gdkdev->axes[k].max_value = axis_y.axMax;
396                   gdkdev->info.axes[k].use = GDK_AXIS_Y;
397                   gdkdev->info.axes[k].min = axis_y.axMin;
398                   gdkdev->info.axes[k].max = axis_y.axMax;
399                   k++;
400                 }
401               if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
402                 {
403                   gdkdev->axes[k].xresolution =
404                     gdkdev->axes[k].resolution = axis_npressure.axResolution / 65535.;
405                   gdkdev->axes[k].xmin_value =
406                     gdkdev->axes[k].min_value = axis_npressure.axMin;
407                   gdkdev->axes[k].xmax_value =
408                     gdkdev->axes[k].max_value = axis_npressure.axMax;
409                   gdkdev->info.axes[k].use = GDK_AXIS_PRESSURE;
410                   /* GIMP seems to expect values in the range 0-1 */
411                   gdkdev->info.axes[k].min = 0.0; /*axis_npressure.axMin;*/
412                   gdkdev->info.axes[k].max = 1.0; /*axis_npressure.axMax;*/
413                   k++;
414                 }
415               if (gdkdev->pktdata & PK_ORIENTATION)
416                 {
417                   GdkAxisUse axis;
418
419                   gdkdev->orientation_axes[0] = axis_or[0];
420                   gdkdev->orientation_axes[1] = axis_or[1];
421                   for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++)
422                     {
423                       /* Wintab gives us aximuth and altitude, which
424                        * we convert to x and y tilt in the -1000..1000 range
425                        */
426                       gdkdev->axes[k].xresolution =
427                         gdkdev->axes[k].resolution = 1000;
428                       gdkdev->axes[k].xmin_value =
429                         gdkdev->axes[k].min_value = -1000;
430                       gdkdev->axes[k].xmax_value =
431                         gdkdev->axes[k].max_value = 1000;
432                       gdkdev->info.axes[k].use = axis;
433                       gdkdev->info.axes[k].min = -1000;
434                       gdkdev->info.axes[k].max = 1000;
435                       k++;
436                     }
437                 }
438               gdkdev->info.num_keys = 0;
439               gdkdev->info.keys = NULL;
440               GDK_NOTE (INPUT,
441                         g_print ("device: (%d) %s axes: %d\n",
442                                  cursorix,
443                                  gdkdev->info.name,
444                                  gdkdev->info.num_axes));
445               for (i = 0; i < gdkdev->info.num_axes; i++)
446                 GDK_NOTE (INPUT,
447                           g_print ("... axis %d: %d--%d@%d (%d--%d@%d)\n",
448                                    i,
449                                    gdkdev->axes[i].xmin_value, 
450                                    gdkdev->axes[i].xmax_value, 
451                                    gdkdev->axes[i].xresolution, 
452                                    gdkdev->axes[i].min_value, 
453                                    gdkdev->axes[i].max_value, 
454                                    gdkdev->axes[i].resolution));
455               _gdk_input_devices = g_list_append (_gdk_input_devices,
456                                                  gdkdev);
457             }
458         }
459     }
460 }
461
462 static void
463 decode_tilt (gint   *axis_data,
464              AXIS   *axes,
465              PACKET *packet)
466 {
467   /* As I don't have a tilt-sensing tablet,
468    * I cannot test this code.
469    */
470   
471   double az, el;
472
473   az = TWOPI * packet->pkOrientation.orAzimuth /
474     (axes[0].axResolution / 65536.);
475   el = TWOPI * packet->pkOrientation.orAltitude /
476     (axes[1].axResolution / 65536.);
477   
478   /* X tilt */
479   axis_data[0] = cos (az) * cos (el) * 1000;
480   /* Y tilt */
481   axis_data[1] = sin (az) * cos (el) * 1000;
482 }
483
484 #endif /* HAVE_WINTAB */
485
486 static void
487 gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
488                                  GdkInputWindow   *input_window,
489                                  gint             *axis_data,
490                                  gdouble          *axis_out,
491                                  gdouble          *x_out,
492                                  gdouble          *y_out)
493 {
494   GdkWindowImplWin32 *impl, *root_impl;
495
496   int i;
497   int x_axis = 0;
498   int y_axis = 0;
499
500   double device_width, device_height;
501   double x_offset, y_offset, x_scale, y_scale;
502
503   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (input_window->window)->impl);
504
505   for (i=0; i<gdkdev->info.num_axes; i++)
506     {
507       switch (gdkdev->info.axes[i].use)
508         {
509         case GDK_AXIS_X:
510           x_axis = i;
511           break;
512         case GDK_AXIS_Y:
513           y_axis = i;
514           break;
515         default:
516           break;
517         }
518     }
519   
520   device_width = gdkdev->axes[x_axis].max_value - 
521                    gdkdev->axes[x_axis].min_value;
522   device_height = gdkdev->axes[y_axis].max_value - 
523                     gdkdev->axes[y_axis].min_value;
524
525   if (gdkdev->info.mode == GDK_MODE_SCREEN) 
526     {
527       root_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl);
528       x_scale = root_impl->width / device_width;
529       y_scale = root_impl->height / device_height;
530
531       x_offset = - input_window->root_x;
532       y_offset = - input_window->root_y;
533     }
534   else                          /* GDK_MODE_WINDOW */
535     {
536       double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
537         (device_width*gdkdev->axes[x_axis].resolution);
538
539       if (device_aspect * impl->width >= impl->height)
540         {
541           /* device taller than window */
542           x_scale = impl->width / device_width;
543           y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
544             / gdkdev->axes[y_axis].resolution;
545
546           x_offset = 0;
547           y_offset = -(device_height * y_scale - 
548                                impl->height)/2;
549         }
550       else
551         {
552           /* window taller than device */
553           y_scale = impl->height / device_height;
554           x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
555             / gdkdev->axes[x_axis].resolution;
556
557           y_offset = 0;
558           x_offset = - (device_width * x_scale - impl->width)/2;
559         }
560     }
561
562   for (i=0; i<gdkdev->info.num_axes; i++)
563     {
564       switch (gdkdev->info.axes[i].use)
565         {
566         case GDK_AXIS_X:
567           axis_out[i] = x_offset + x_scale*axis_data[x_axis];
568           if (x_out)
569             *x_out = axis_out[i];
570           break;
571         case GDK_AXIS_Y:
572           axis_out[i] = y_offset + y_scale*axis_data[y_axis];
573           if (y_out)
574             *y_out = axis_out[i];
575           break;
576         default:
577           axis_out[i] =
578             (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
579              gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
580             (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
581           break;
582         }
583     }
584 }
585
586 static void
587 gdk_input_get_root_relative_geometry (HWND w,
588                                       int  *x_ret,
589                                       int  *y_ret)
590 {
591   RECT rect;
592
593   GetWindowRect (w, &rect);
594
595   if (x_ret)
596     *x_ret = rect.left + _gdk_offset_x;
597   if (y_ret)
598     *y_ret = rect.top + _gdk_offset_y;
599 }
600
601 void
602 _gdk_input_configure_event (GdkWindow         *window)
603 {
604   GdkInputWindow *input_window;
605   int root_x, root_y;
606
607   input_window = _gdk_input_window_find (window);
608   g_return_if_fail (window != NULL);
609
610   gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
611                                         &root_x, &root_y);
612
613   input_window->root_x = root_x;
614   input_window->root_y = root_y;
615 }
616
617 void 
618 _gdk_input_enter_event (GdkWindow        *window)
619 {
620   GdkInputWindow *input_window;
621   int root_x, root_y;
622
623   input_window = _gdk_input_window_find (window);
624   g_return_if_fail (window != NULL);
625
626   gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &root_x, &root_y);
627
628   input_window->root_x = root_x;
629   input_window->root_y = root_y;
630 }
631
632 /*
633  * Get the currently active keyboard modifiers (ignoring the mouse buttons)
634  * We could use gdk_window_get_pointer but that function does a lot of other
635  * expensive things besides getting the modifiers. This code is somewhat based
636  * on build_pointer_event_state from gdkevents-win32.c
637  */
638 static guint
639 get_modifier_key_state (void)
640 {
641   guint state;
642   
643   state = 0;
644   /* High-order bit is up/down, low order bit is toggled/untoggled */
645   if (GetKeyState (VK_CONTROL) < 0)
646     state |= GDK_CONTROL_MASK;
647   if (GetKeyState (VK_SHIFT) < 0)
648     state |= GDK_SHIFT_MASK;
649   if (GetKeyState (VK_MENU) < 0)
650     state |= GDK_MOD1_MASK;
651   if (GetKeyState (VK_CAPITAL) & 0x1)
652     state |= GDK_LOCK_MASK;
653
654   return state;
655 }
656
657 #ifdef HAVE_WINTAB
658
659 static guint ignore_core_timer = 0;
660
661 static gboolean
662 ignore_core_timefunc (gpointer data)
663 {
664   /* The delay has passed */
665   _gdk_input_ignore_core = FALSE;
666   ignore_core_timer = 0;
667
668   return FALSE; /* remove timeout */
669 }
670
671 /*
672  * Set or unset the _gdk_input_ignore_core variable that tells GDK
673  * to ignore events for the core pointer when the tablet is in proximity
674  * The unsetting is delayed slightly so that if a tablet event arrives
675  * just after proximity out, it does not cause a core pointer event
676  * which e.g. causes GIMP to switch tools.
677  */
678 static void
679 set_ignore_core (gboolean ignore)
680 {
681   if (ignore)
682     {
683       _gdk_input_ignore_core = TRUE;
684       /* Remove any pending clear */
685       if (ignore_core_timer)
686         {
687           g_source_remove (ignore_core_timer);
688           ignore_core_timer = 0;
689         }
690     }
691   else
692     if (!ignore_core_timer)
693       ignore_core_timer = gdk_threads_add_timeout (PROXIMITY_OUT_DELAY,
694                                          ignore_core_timefunc, NULL);
695 }
696 #endif /* HAVE_WINTAB */
697
698 gboolean 
699 _gdk_input_other_event (GdkEvent  *event,
700                         MSG       *msg,
701                         GdkWindow *window)
702 {
703 #ifdef HAVE_WINTAB
704   GdkDisplay *display;
705   GdkWindowObject *obj, *grab_obj;
706   GdkInputWindow *input_window;
707   GdkDevicePrivate *gdkdev = NULL;
708   GdkEventMask masktest;
709   guint key_state;
710   POINT pt;
711
712   PACKET packet;
713   gint k;
714   gint x, y;
715
716   if (event->any.window != wintab_window)
717     {
718       g_warning ("_gdk_input_other_event: not wintab_window?");
719       return FALSE;
720     }
721
722   window = gdk_window_at_pointer (&x, &y);
723   if (window == NULL)
724     window = _gdk_root;
725
726   g_object_ref (window);
727   display = gdk_drawable_get_display (window);
728
729   GDK_NOTE (EVENTS_OR_INPUT,
730             g_print ("gdk_input_win32_other_event: window=%p %+d%+d\n",
731                      GDK_WINDOW_HWND (window), x, y));
732   
733   if (msg->message == WT_PACKET)
734     {
735       if (!WTPacket ((HCTX) msg->lParam, msg->wParam, &packet))
736         return FALSE;
737     }
738
739   obj = GDK_WINDOW_OBJECT (window);
740
741   switch (msg->message)
742     {
743     case WT_PACKET:
744       /* Don't produce any button or motion events while a window is being
745        * moved or resized, see bug #151090. */
746       if (_sizemove_in_progress)
747         {
748           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
749           return FALSE;
750         }
751       if (window == _gdk_root && x_grab_window == NULL)
752         {
753           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
754           return FALSE;
755         }
756
757       if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
758                                                  packet.pkCursor)) == NULL)
759         return FALSE;
760
761       if (gdkdev->info.mode == GDK_MODE_DISABLED)
762         return FALSE;
763       
764       k = 0;
765       if (gdkdev->pktdata & PK_X)
766         gdkdev->last_axis_data[k++] = packet.pkX;
767       if (gdkdev->pktdata & PK_Y)
768         gdkdev->last_axis_data[k++] = packet.pkY;
769       if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
770         gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
771       if (gdkdev->pktdata & PK_ORIENTATION)
772         {
773           decode_tilt (gdkdev->last_axis_data + k,
774                        gdkdev->orientation_axes, &packet);
775           k += 2;
776         }
777
778       g_assert (k == gdkdev->info.num_axes);
779
780       if (HIWORD (packet.pkButtons) != TBN_NONE)
781         {
782           /* Gdk buttons are numbered 1.. */
783           event->button.button = 1 + LOWORD (packet.pkButtons);
784
785           if (HIWORD (packet.pkButtons) == TBN_UP)
786             {
787               event->any.type = GDK_BUTTON_RELEASE;
788               masktest = GDK_BUTTON_RELEASE_MASK;
789               gdkdev->button_state &= ~(1 << LOWORD (packet.pkButtons));
790             }
791           else
792             {
793               event->any.type = GDK_BUTTON_PRESS;
794               masktest = GDK_BUTTON_PRESS_MASK;
795               gdkdev->button_state |= 1 << LOWORD (packet.pkButtons);
796             }
797         }
798       else
799         {
800           event->any.type = GDK_MOTION_NOTIFY;
801           masktest = GDK_POINTER_MOTION_MASK;
802           if (gdkdev->button_state & (1 << 0))
803             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
804           if (gdkdev->button_state & (1 << 1))
805             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
806           if (gdkdev->button_state & (1 << 2))
807             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
808         }
809
810       /* See if input is grabbed */
811       /* FIXME: x_grab_owner_events should probably be handled somehow */
812       if (x_grab_window != NULL)
813         {
814           grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
815           if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
816               || !(grab_obj->extension_events & masktest)
817               || !(x_grab_mask && masktest))
818             {
819               GDK_NOTE (EVENTS_OR_INPUT, 
820                         g_print ("... grabber doesn't want it\n"));
821               return FALSE;
822             }
823           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
824
825           g_object_ref(x_grab_window);
826           g_object_unref(window);
827           window = x_grab_window;
828           obj = grab_obj;
829         }
830       /* Now we can check if the window wants the event, and
831        * propagate if necessary.
832        */
833     dijkstra:
834       if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
835           || !(obj->extension_events & masktest))
836         {
837           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
838
839           if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
840             return FALSE;
841
842           /* It is not good to propagate the extended events up to the parent
843            * if this window wants normal (not extended) motion/button events */
844           if (obj->event_mask & masktest)
845             {
846               GDK_NOTE (EVENTS_OR_INPUT, 
847                         g_print ("... wants ordinary event, ignoring this\n"));
848               return FALSE;
849             }
850           
851           pt.x = x;
852           pt.y = y;
853           ClientToScreen (GDK_WINDOW_HWND (window), &pt);
854           g_object_unref (window);
855           window = (GdkWindow *) obj->parent;
856           obj = GDK_WINDOW_OBJECT (window);
857           g_object_ref (window);
858           ScreenToClient (GDK_WINDOW_HWND (window), &pt);
859           x = pt.x;
860           y = pt.y;
861           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
862                                               GDK_WINDOW_HWND (window), x, y));
863           goto dijkstra;
864         }
865
866       input_window = _gdk_input_window_find (window);
867
868       g_assert (input_window != NULL);
869
870       if (gdkdev->info.mode == GDK_MODE_WINDOW
871           && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
872         return FALSE;
873
874       event->any.window = window;
875       key_state = get_modifier_key_state ();
876       if (event->any.type == GDK_BUTTON_PRESS
877           || event->any.type == GDK_BUTTON_RELEASE)
878         {
879           event->button.time = _gdk_win32_get_next_tick (msg->time);
880           event->button.device = &gdkdev->info;
881           
882           event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
883
884           gdk_input_translate_coordinates (gdkdev, input_window,
885                                            gdkdev->last_axis_data,
886                                            event->button.axes,
887                                            &event->button.x, 
888                                            &event->button.y);
889
890           /* Also calculate root coordinates. Note that input_window->root_x
891              is in GDK root coordinates. */
892           event->button.x_root = event->button.x + input_window->root_x;
893           event->button.y_root = event->button.y + input_window->root_y;
894
895           event->button.state = ((gdkdev->button_state << 8)
896                                  & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
897                                     | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
898                                     | GDK_BUTTON5_MASK))
899                                 | key_state;
900           GDK_NOTE (EVENTS_OR_INPUT,
901                     g_print ("WINTAB button %s:%d %g,%g\n",
902                              (event->button.type == GDK_BUTTON_PRESS ?
903                               "press" : "release"),
904                              event->button.button,
905                              event->button.x, event->button.y));
906         }
907       else
908         {
909           event->motion.time = _gdk_win32_get_next_tick (msg->time);
910           event->motion.is_hint = FALSE;
911           event->motion.device = &gdkdev->info;
912
913           event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
914
915           gdk_input_translate_coordinates (gdkdev, input_window,
916                                            gdkdev->last_axis_data,
917                                            event->motion.axes,
918                                            &event->motion.x, 
919                                            &event->motion.y);
920
921           /* Also calculate root coordinates. Note that input_window->root_x
922              is in GDK root coordinates. */
923           event->motion.x_root = event->motion.x + input_window->root_x;
924           event->motion.y_root = event->motion.y + input_window->root_y;
925
926           event->motion.state = ((gdkdev->button_state << 8)
927                                  & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
928                                     | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
929                                     | GDK_BUTTON5_MASK))
930                                 | key_state;
931
932           GDK_NOTE (EVENTS_OR_INPUT,
933                     g_print ("WINTAB motion: %g,%g\n",
934                              event->motion.x, event->motion.y));
935
936           /* Check for missing release or press events for the normal
937            * pressure button. At least on my ArtPadII I sometimes miss a
938            * release event?
939            */
940           if ((gdkdev->pktdata & PK_NORMAL_PRESSURE
941                && (event->motion.state & GDK_BUTTON1_MASK)
942                && packet.pkNormalPressure <= MAX (0, (gint) gdkdev->npbtnmarks[0] - 2))
943               || (gdkdev->pktdata & PK_NORMAL_PRESSURE
944                   && !(event->motion.state & GDK_BUTTON1_MASK)
945                   && packet.pkNormalPressure > gdkdev->npbtnmarks[1] + 2))
946             {
947               GdkEvent *event2 = gdk_event_copy (event);
948               if (event->motion.state & GDK_BUTTON1_MASK)
949                 {
950                   event2->button.type = GDK_BUTTON_RELEASE;
951                   gdkdev->button_state &= ~1;
952                 }
953               else
954                 {
955                   event2->button.type = GDK_BUTTON_PRESS;
956                   gdkdev->button_state |= 1;
957                 }
958               event2->button.state = ((gdkdev->button_state << 8)
959                                       & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
960                                          | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
961                                          | GDK_BUTTON5_MASK))
962                                      | key_state;
963               event2->button.button = 1;
964               GDK_NOTE (EVENTS_OR_INPUT,
965                         g_print ("WINTAB synthesized button %s: %d %g,%gg\n",
966                                  (event2->button.type == GDK_BUTTON_PRESS ?
967                                   "press" : "release"),
968                                  event2->button.button,
969                                  event2->button.x,
970                                  event2->button.y));
971               _gdk_event_queue_append (display, event2);
972             }
973         }
974       return TRUE;
975
976     case WT_PROXIMITY:
977       if (LOWORD (msg->lParam) == 0)
978         {
979           event->proximity.type = GDK_PROXIMITY_OUT;
980           set_ignore_core (FALSE);
981         }
982       else
983         {
984           event->proximity.type = GDK_PROXIMITY_IN;
985           set_ignore_core (TRUE);
986         }
987       event->proximity.time = _gdk_win32_get_next_tick (msg->time);
988       event->proximity.device = &gdkdev->info;
989
990       GDK_NOTE (EVENTS_OR_INPUT,
991                 g_print ("WINTAB proximity %s\n",
992                          (event->proximity.type == GDK_PROXIMITY_IN ?
993                           "in" : "out")));
994       return TRUE;
995     }
996 #endif
997   return FALSE;
998 }
999
1000 gboolean
1001 _gdk_input_enable_window (GdkWindow        *window,
1002                           GdkDevicePrivate *gdkdev)
1003 {
1004 #ifdef HAVE_SOME_XINPUT
1005   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1006
1007   impl->extension_events_selected = TRUE;
1008 #endif
1009
1010   return TRUE;
1011 }
1012
1013 gboolean
1014 _gdk_input_disable_window (GdkWindow        *window,
1015                            GdkDevicePrivate *gdkdev)
1016 {
1017 #ifdef HAVE_SOME_XINPUT
1018   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1019
1020   impl->extension_events_selected = FALSE;
1021 #endif
1022
1023   return TRUE;
1024 }
1025
1026 gint
1027 _gdk_input_grab_pointer (GdkWindow    *window,
1028                          gint          owner_events,
1029                          GdkEventMask  event_mask,
1030                          GdkWindow    *confine_to,
1031                          guint32       time)
1032 {
1033 #ifdef HAVE_SOME_XINPUT
1034   GdkInputWindow *input_window, *new_window;
1035   gboolean need_ungrab;
1036   GdkDevicePrivate *gdkdev;
1037   GList *tmp_list;
1038
1039   tmp_list = _gdk_input_windows;
1040   new_window = NULL;
1041   need_ungrab = FALSE;
1042
1043   GDK_NOTE (INPUT, g_print ("gdk_input_win32_grab_pointer: %p %d %p\n",
1044                            GDK_WINDOW_HWND (window),
1045                            owner_events,
1046                            (confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
1047
1048   while (tmp_list)
1049     {
1050       input_window = (GdkInputWindow *)tmp_list->data;
1051
1052       if (input_window->window == window)
1053         new_window = input_window;
1054       else if (input_window->grabbed)
1055         {
1056           input_window->grabbed = FALSE;
1057           need_ungrab = TRUE;
1058         }
1059
1060       tmp_list = tmp_list->next;
1061     }
1062
1063   if (new_window)
1064     {
1065       new_window->grabbed = TRUE;
1066       x_grab_window = window;
1067       x_grab_mask = event_mask;
1068       x_grab_owner_events = owner_events;
1069
1070       /* FIXME: Do we need to handle confine_to and time? */
1071       
1072       tmp_list = _gdk_input_devices;
1073       while (tmp_list)
1074         {
1075           gdkdev = (GdkDevicePrivate *)tmp_list->data;
1076           if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
1077             {
1078 #if 0         
1079               /* XXX */
1080               gdk_input_common_find_events (window, gdkdev,
1081                                             event_mask,
1082                                             event_classes, &num_classes);
1083               
1084               result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
1085                                     GDK_WINDOW_XWINDOW (window),
1086                                     owner_events, num_classes, event_classes,
1087                                     GrabModeAsync, GrabModeAsync, time);
1088               
1089               /* FIXME: if failure occurs on something other than the first
1090                  device, things will be badly inconsistent */
1091               if (result != Success)
1092                 return result;
1093 #endif
1094             }
1095           tmp_list = tmp_list->next;
1096         }
1097     }
1098   else
1099     { 
1100       x_grab_window = NULL;
1101       tmp_list = _gdk_input_devices;
1102       while (tmp_list)
1103         {
1104           gdkdev = (GdkDevicePrivate *)tmp_list->data;
1105           if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
1106               ((gdkdev->button_state != 0) || need_ungrab))
1107             {
1108 #if 0
1109               /* XXX */
1110               XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1111 #endif
1112               gdkdev->button_state = 0;
1113             }
1114           
1115           tmp_list = tmp_list->next;
1116         }
1117     }
1118 #endif
1119
1120   return GDK_GRAB_SUCCESS;
1121 }
1122
1123 void 
1124 _gdk_input_ungrab_pointer (guint32 time)
1125 {
1126 #ifdef HAVE_SOME_XINPUT
1127   GdkInputWindow *input_window;
1128   GdkDevicePrivate *gdkdev;
1129   GList *tmp_list;
1130
1131   GDK_NOTE (INPUT, g_print ("gdk_input_win32_ungrab_pointer\n"));
1132
1133   tmp_list = _gdk_input_windows;
1134   while (tmp_list)
1135     {
1136       input_window = (GdkInputWindow *)tmp_list->data;
1137       if (input_window->grabbed)
1138         break;
1139       tmp_list = tmp_list->next;
1140     }
1141
1142   if (tmp_list)                 /* we found a grabbed window */
1143     {
1144       input_window->grabbed = FALSE;
1145
1146       tmp_list = _gdk_input_devices;
1147       while (tmp_list)
1148         {
1149           gdkdev = (GdkDevicePrivate *)tmp_list->data;
1150 #if 0
1151           /* XXX */
1152           if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
1153             XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1154 #endif
1155           tmp_list = tmp_list->next;
1156         }
1157     }
1158   x_grab_window = NULL;
1159 #endif
1160 }
1161
1162 gboolean
1163 _gdk_device_get_history (GdkDevice         *device,
1164                          GdkWindow         *window,
1165                          guint32            start,
1166                          guint32            stop,
1167                          GdkTimeCoord    ***events,
1168                          gint              *n_events)
1169 {
1170   return FALSE;
1171 }
1172
1173 void 
1174 gdk_device_get_state (GdkDevice       *device,
1175                       GdkWindow       *window,
1176                       gdouble         *axes,
1177                       GdkModifierType *mask)
1178 {
1179   g_return_if_fail (device != NULL);
1180   g_return_if_fail (GDK_IS_WINDOW (window));
1181
1182   if (GDK_IS_CORE (device))
1183     {
1184       gint x_int, y_int;
1185       
1186       gdk_window_get_pointer (window, &x_int, &y_int, mask);
1187
1188       if (axes)
1189         {
1190           axes[0] = x_int;
1191           axes[1] = y_int;
1192         }
1193     }
1194   else
1195     {
1196       GdkDevicePrivate *gdkdev;
1197       GdkInputWindow *input_window;
1198       
1199       gdkdev = (GdkDevicePrivate *)device;
1200       /* For now just use the last known button and axis state of the device.
1201        * Since graphical tablets send an insane amount of motion events each
1202        * second, the info should be fairly up to date */
1203       if (mask)
1204         {
1205           gdk_window_get_pointer (window, NULL, NULL, mask);
1206           *mask &= 0xFF; /* Mask away core pointer buttons */
1207           *mask |= ((gdkdev->button_state << 8)
1208                     & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1209                        | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1210                        | GDK_BUTTON5_MASK));
1211         }
1212       input_window = _gdk_input_window_find (window);
1213       g_return_if_fail (input_window != NULL);
1214       /* For some reason, input_window is sometimes NULL when I use The GIMP 2
1215        * (bug #141543?). Avoid crashing if debugging is disabled. */
1216       if (axes && gdkdev->last_axis_data && input_window)
1217         gdk_input_translate_coordinates (gdkdev, input_window,
1218                                          gdkdev->last_axis_data,
1219                                          axes, NULL, NULL);
1220     }
1221 }
1222
1223 #ifdef HAVE_WINTAB
1224 void
1225 _gdk_input_set_tablet_active (void)
1226 {
1227   GList *tmp_list;
1228   HCTX *hctx;
1229
1230   /* Bring the contexts to the top of the overlap order when one of the
1231    * application's windows is activated */
1232   
1233   if (!wintab_contexts)
1234     return; /* No tablet devices found, or Wintab not initialized yet */
1235   
1236   GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
1237         "Bringing Wintab contexts to the top of the overlap order\n"));
1238
1239   tmp_list = wintab_contexts;
1240   while (tmp_list)
1241     {
1242       hctx = (HCTX *) (tmp_list->data);
1243       WTOverlap (*hctx, TRUE);
1244       tmp_list = tmp_list->next;
1245     }
1246 }
1247 #endif /* HAVE_WINTAB */
1248
1249 void 
1250 _gdk_input_init (GdkDisplay *display)
1251 {
1252   _gdk_input_ignore_core = FALSE;
1253   _gdk_input_devices = NULL;
1254
1255   _gdk_init_input_core (display);
1256 #ifdef HAVE_WINTAB
1257 #ifdef WINTAB_NO_LAZY_INIT
1258   /* Normally, Wintab is only initialized when the application performs
1259    * an action that requires it, such as enabling extended input events
1260    * for a window or enumerating the devices.
1261    */
1262   _gdk_input_wintab_init_check ();
1263 #endif /* WINTAB_NO_LAZY_INIT */
1264 #endif /* HAVE_WINTAB */
1265
1266   _gdk_input_devices = g_list_append (_gdk_input_devices, display->core_pointer);
1267 }
1268