1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-2007 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 #define WINTAB32_DLL "Wintab32.dll"
41 
42 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y  | PK_NORMAL_PRESSURE | PK_ORIENTATION)
43 /* We want everything in absolute mode */
44 #define PACKETMODE (0)
45 #include <pktdef.h>
46 
47 #define DEBUG_WINTAB 1		/* Verbose debug messages enabled */
48 
49 #define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */
50 
51 #define TWOPI (2.*G_PI)
52 
53 /* Forward declarations */
54 
55 static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
56 						      UINT id);
57 static GList     *wintab_contexts = NULL;
58 
59 static GdkWindow *wintab_window = NULL;
60 
61 static GdkDevicePrivate *_gdk_device_in_proximity;
62 
63 typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
64 typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
65 typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
66 typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
67 typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
68 typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
69 typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
70 typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
71 typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
72 
73 static t_WTInfoA p_WTInfoA;
74 static t_WTInfoW p_WTInfoW;
75 static t_WTEnable p_WTEnable;
76 static t_WTOpenA p_WTOpenA;
77 static t_WTGetA p_WTGetA;
78 static t_WTSetA p_WTSetA;
79 static t_WTOverlap p_WTOverlap;
80 static t_WTPacket p_WTPacket;
81 static t_WTQueueSizeSet p_WTQueueSizeSet;
82 
83 static GdkDevicePrivate *
gdk_input_find_dev_from_ctx(HCTX hctx,UINT cursor)84 gdk_input_find_dev_from_ctx (HCTX hctx,
85 			     UINT cursor)
86 {
87   GList *tmp_list = _gdk_input_devices;
88   GdkDevicePrivate *gdkdev;
89 
90   while (tmp_list)
91     {
92       gdkdev = (GdkDevicePrivate *) (tmp_list->data);
93       if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
94 	return gdkdev;
95       tmp_list = tmp_list->next;
96     }
97   return NULL;
98 }
99 
100 
101 #if DEBUG_WINTAB
102 
103 #ifdef G_ENABLE_DEBUG
104 static void
print_lc(LOGCONTEXT * lc)105 print_lc(LOGCONTEXT *lc)
106 {
107   g_print ("lcName = %s\n", lc->lcName);
108   g_print ("lcOptions =");
109   if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
110   if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
111   if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
112   if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
113   if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
114   if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
115   g_print ("\n");
116   g_print ("lcStatus =");
117   if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
118   if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
119   if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
120   g_print ("\n");
121   g_print ("lcLocks =");
122   if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
123   if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
124   if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
125   if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
126   g_print ("\n");
127   g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
128 	  lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
129   g_print ("lcPktData =");
130   if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
131   if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
132   if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
133   if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
134   if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
135   if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
136   if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
137   if (lc->lcPktData & PK_X) g_print (" PK_X");
138   if (lc->lcPktData & PK_Y) g_print (" PK_Y");
139   if (lc->lcPktData & PK_Z) g_print (" PK_Z");
140   if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
141   if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
142   if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
143   if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
144   g_print ("\n");
145   g_print ("lcPktMode =");
146   if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
147   if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
148   if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
149   if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
150   if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
151   if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
152   if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
153   if (lc->lcPktMode & PK_X) g_print (" PK_X");
154   if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
155   if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
156   if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
157   if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
158   if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
159   if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
160   g_print ("\n");
161   g_print ("lcMoveMask =");
162   if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
163   if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
164   if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
165   if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
166   if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
167   if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
168   if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
169   if (lc->lcMoveMask & PK_X) g_print (" PK_X");
170   if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
171   if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
172   if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
173   if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
174   if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
175   if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
176   g_print ("\n");
177   g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
178 	  (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
179   g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
180 	  lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
181   g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
182 	  lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
183   g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
184 	  lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
185   g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
186 	  lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
187   g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
188 	  lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
189   g_print ("lcSysMode = %d\n", lc->lcSysMode);
190   g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
191 	  lc->lcSysOrgX, lc->lcSysOrgY);
192   g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
193 	  lc->lcSysExtX, lc->lcSysExtY);
194   g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
195 	  lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
196 }
197 
198 static void
print_cursor(int index)199 print_cursor (int index)
200 {
201   int size;
202   int i;
203   char *name;
204   BOOL active;
205   WTPKT wtpkt;
206   BYTE buttons;
207   BYTE buttonbits;
208   char *btnnames;
209   char *p;
210   BYTE buttonmap[32];
211   BYTE sysbtnmap[32];
212   BYTE npbutton;
213   UINT npbtnmarks[2];
214   UINT *npresponse;
215   BYTE tpbutton;
216   UINT tpbtnmarks[2];
217   UINT *tpresponse;
218   DWORD physid;
219   UINT mode;
220   UINT minpktdata;
221   UINT minbuttons;
222   UINT capabilities;
223 
224   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
225   name = g_malloc (size + 1);
226   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
227   g_print ("NAME: %s\n", name);
228   (*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
229   g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
230   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
231   g_print ("PKTDATA: %#x:", (guint) wtpkt);
232 #define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
233   BIT (CONTEXT);
234   BIT (STATUS);
235   BIT (TIME);
236   BIT (CHANGED);
237   BIT (SERIAL_NUMBER);
238   BIT (BUTTONS);
239   BIT (X);
240   BIT (Y);
241   BIT (Z);
242   BIT (NORMAL_PRESSURE);
243   BIT (TANGENT_PRESSURE);
244   BIT (ORIENTATION);
245   BIT (ROTATION);
246 #undef BIT
247   g_print ("\n");
248   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
249   g_print ("BUTTONS: %d\n", buttons);
250   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
251   g_print ("BUTTONBITS: %d\n", buttonbits);
252   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
253   g_print ("BTNNAMES:");
254   if (size > 0)
255     {
256       btnnames = g_malloc (size + 1);
257       (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
258       p = btnnames;
259       while (*p)
260 	{
261 	  g_print (" %s", p);
262 	  p += strlen (p) + 1;
263 	}
264     }
265   g_print ("\n");
266   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
267   g_print ("BUTTONMAP:");
268   for (i = 0; i < buttons; i++)
269     g_print (" %d", buttonmap[i]);
270   g_print ("\n");
271   (*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
272   g_print ("SYSBTNMAP:");
273   for (i = 0; i < buttons; i++)
274     g_print (" %d", sysbtnmap[i]);
275   g_print ("\n");
276   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
277   g_print ("NPBUTTON: %d\n", npbutton);
278   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
279   g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
280   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
281   g_print ("NPRESPONSE:");
282   if (size > 0)
283     {
284       npresponse = g_malloc (size);
285       (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
286       for (i = 0; i < size / sizeof (UINT); i++)
287 	g_print (" %d", npresponse[i]);
288     }
289   g_print ("\n");
290   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
291   g_print ("TPBUTTON: %d\n", tpbutton);
292   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
293   g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
294   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
295   g_print ("TPRESPONSE:");
296   if (size > 0)
297     {
298       tpresponse = g_malloc (size);
299       (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
300       for (i = 0; i < size / sizeof (UINT); i++)
301 	g_print (" %d", tpresponse[i]);
302     }
303   g_print ("\n");
304   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
305   g_print ("PHYSID: %#x\n", (guint) physid);
306   (*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
307   g_print ("CAPABILITIES: %#x:", capabilities);
308 #define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
309   BIT (MULTIMODE);
310   BIT (AGGREGATE);
311   BIT (INVERT);
312 #undef BIT
313   g_print ("\n");
314   if (capabilities & CRC_MULTIMODE)
315     {
316       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
317       g_print ("MODE: %d\n", mode);
318     }
319   if (capabilities & CRC_AGGREGATE)
320     {
321       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
322       g_print ("MINPKTDATA: %d\n", minpktdata);
323       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
324       g_print ("MINBUTTONS: %d\n", minbuttons);
325     }
326 }
327 #endif
328 #endif
329 
330 void
_gdk_input_wintab_init_check(void)331 _gdk_input_wintab_init_check (void)
332 {
333   static gboolean wintab_initialized = FALSE;
334   GdkDevicePrivate *gdkdev;
335   GdkWindowAttr wa;
336   WORD specversion;
337   HCTX *hctx;
338   UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
339   BOOL active;
340   DWORD physid;
341   AXIS axis_x, axis_y, axis_npressure, axis_or[3];
342   int i, k, n;
343   int devix, cursorix;
344   wchar_t devname[100], csrname[100];
345   gchar *devname_utf8, *csrname_utf8;
346   BOOL defcontext_done;
347   HMODULE wintab32;
348   char *wintab32_dll_path;
349   char dummy;
350 
351   if (wintab_initialized)
352     return;
353 
354   wintab_initialized = TRUE;
355 
356   wintab_contexts = NULL;
357 
358   if (_gdk_input_ignore_wintab)
359     return;
360 
361   n = GetSystemDirectory (&dummy, 0);
362 
363   if (n <= 0)
364     return;
365 
366   wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
367   k = GetSystemDirectory (wintab32_dll_path, n);
368 
369   if (k == 0 || k > n)
370     {
371       g_free (wintab32_dll_path);
372       return;
373     }
374 
375   if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
376     strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
377   strcat (wintab32_dll_path, WINTAB32_DLL);
378 
379   if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
380     return;
381 
382   if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
383     return;
384   if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
385     return;
386   if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
387     return;
388   if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
389     return;
390   if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
391     return;
392   if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
393     return;
394   if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
395     return;
396   if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
397     return;
398   if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
399     return;
400 
401   if (!(*p_WTInfoA) (0, 0, NULL))
402     return;
403 
404   (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
405   GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
406 			    HIBYTE (specversion), LOBYTE (specversion)));
407   (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
408   (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
409 #if DEBUG_WINTAB
410   GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
411 			    ndevices, ncursors));
412 #endif
413   /* Create a dummy window to receive wintab events */
414   wa.wclass = GDK_INPUT_OUTPUT;
415   wa.event_mask = GDK_ALL_EVENTS_MASK;
416   wa.width = 2;
417   wa.height = 2;
418   wa.x = -100;
419   wa.y = -100;
420   wa.window_type = GDK_WINDOW_TOPLEVEL;
421   if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
422     {
423       g_warning ("gdk_input_wintab_init: gdk_window_new failed");
424       return;
425     }
426   g_object_ref (wintab_window);
427 
428   for (devix = 0; devix < ndevices; devix++)
429     {
430       LOGCONTEXT lc;
431 
432       /* We open the Wintab device (hmm, what if there are several, or
433        * can there even be several, probably not?) as a system
434        * pointing device, i.e. it controls the normal Windows
435        * cursor. This seems much more natural.
436        */
437 
438       (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
439       devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
440 #ifdef DEBUG_WINTAB
441       GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8)));
442 #endif
443       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
444       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
445       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
446       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
447       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
448       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
449       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
450 
451       defcontext_done = FALSE;
452       if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
453 	{
454 	  /* Try to get device-specific default context */
455 	  /* Some drivers, e.g. Aiptek, don't provide this info */
456 	  if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
457 	    defcontext_done = TRUE;
458 #if DEBUG_WINTAB
459 	  if (defcontext_done)
460 	    GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
461 	  else
462 	    GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
463 #endif
464 	}
465 
466       if (!defcontext_done)
467 	(*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
468 #if DEBUG_WINTAB
469       GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
470 #endif
471       lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
472       lc.lcStatus = 0;
473       lc.lcMsgBase = WT_DEFBASE;
474       lc.lcPktRate = 0;
475       lc.lcPktData = PACKETDATA;
476       lc.lcPktMode = PACKETMODE;
477       lc.lcMoveMask = PACKETDATA;
478       lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
479       lc.lcOutOrgX = axis_x.axMin;
480       lc.lcOutOrgY = axis_y.axMin;
481       lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
482       lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
483       lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
484 #if DEBUG_WINTAB
485       GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
486 			print_lc(&lc)));
487 #endif
488       hctx = g_new (HCTX, 1);
489       if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
490 	{
491 	  g_warning ("gdk_input_wintab_init: WTOpen failed");
492 	  return;
493 	}
494       GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
495 				devix, *hctx));
496 
497       wintab_contexts = g_list_append (wintab_contexts, hctx);
498 
499       (*p_WTOverlap) (*hctx, TRUE);
500 
501 #if DEBUG_WINTAB
502       GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
503 			print_lc(&lc)));
504 #endif
505       /* Increase packet queue size to reduce the risk of lost packets.
506        * According to the specs, if the function fails we must try again
507        * with a smaller queue size.
508        */
509       GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
510       for (i = 128; i >= 1; i >>= 1)
511 	{
512 	  if ((*p_WTQueueSizeSet) (*hctx, i))
513 	    {
514 	      GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
515 	      break;
516 	    }
517 	}
518       if (!i)
519 	GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
520       for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
521 	{
522 #ifdef DEBUG_WINTAB
523 	  GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
524 #endif
525 	  active = FALSE;
526 	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
527 	  if (!active)
528 	    continue;
529 
530 	  /* Wacom tablets seem to report cursors corresponding to
531 	   * nonexistent pens or pucks. At least my ArtPad II reports
532 	   * six cursors: a puck, pressure stylus and eraser stylus,
533 	   * and then the same three again. I only have a
534 	   * pressure-sensitive pen. The puck instances, and the
535 	   * second instances of the styluses report physid zero. So
536 	   * at least for Wacom, skip cursors with physid zero.
537 	   */
538 	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
539 	  if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
540 	    continue;
541 
542 	  gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
543 	  (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
544 	  csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
545 	  gdkdev->info.name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
546 	  g_free (csrname_utf8);
547 	  gdkdev->info.source = GDK_SOURCE_PEN;
548 	  gdkdev->info.mode = GDK_MODE_SCREEN;
549 	  gdkdev->info.has_cursor = TRUE;
550 	  gdkdev->hctx = *hctx;
551 	  gdkdev->cursor = cursorix;
552 	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &gdkdev->pktdata);
553 	  gdkdev->info.num_axes = 0;
554 	  if (gdkdev->pktdata & PK_X)
555 	    gdkdev->info.num_axes++;
556 	  if (gdkdev->pktdata & PK_Y)
557 	    gdkdev->info.num_axes++;
558 	  if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
559 	    gdkdev->info.num_axes++;
560 	  /* The wintab driver for the Wacom ArtPad II reports
561 	   * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
562 	   * actually sense tilt. Catch this by noticing that the
563 	   * orientation axis's azimuth resolution is zero.
564 	   */
565 	  if ((gdkdev->pktdata & PK_ORIENTATION)
566 	      && axis_or[0].axResolution == 0)
567 	    gdkdev->pktdata &= ~PK_ORIENTATION;
568 
569 	  if (gdkdev->pktdata & PK_ORIENTATION)
570 	    gdkdev->info.num_axes += 2; /* x and y tilt */
571 
572 	  gdkdev->info.axes = g_new (GdkDeviceAxis, gdkdev->info.num_axes);
573 	  gdkdev->axes = g_new (GdkAxisInfo, gdkdev->info.num_axes);
574 	  gdkdev->last_axis_data = g_new (gint, gdkdev->info.num_axes);
575 
576 	  k = 0;
577 	  if (gdkdev->pktdata & PK_X)
578 	    {
579 	      gdkdev->axes[k].resolution = axis_x.axResolution / 65535.;
580 	      gdkdev->axes[k].min_value = axis_x.axMin;
581 	      gdkdev->axes[k].max_value = axis_x.axMax;
582 	      gdkdev->info.axes[k].use = GDK_AXIS_X;
583 	      gdkdev->info.axes[k].min = axis_x.axMin;
584 	      gdkdev->info.axes[k].max = axis_x.axMax;
585 	      k++;
586 	    }
587 	  if (gdkdev->pktdata & PK_Y)
588 	    {
589 	      gdkdev->axes[k].resolution = axis_y.axResolution / 65535.;
590 	      gdkdev->axes[k].min_value = axis_y.axMin;
591 	      gdkdev->axes[k].max_value = axis_y.axMax;
592 	      gdkdev->info.axes[k].use = GDK_AXIS_Y;
593 	      gdkdev->info.axes[k].min = axis_y.axMin;
594 	      gdkdev->info.axes[k].max = axis_y.axMax;
595 	      k++;
596 	    }
597 	  if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
598 	    {
599 	      gdkdev->axes[k].resolution = axis_npressure.axResolution / 65535.;
600 	      gdkdev->axes[k].min_value = axis_npressure.axMin;
601 	      gdkdev->axes[k].max_value = axis_npressure.axMax;
602 	      gdkdev->info.axes[k].use = GDK_AXIS_PRESSURE;
603 	      /* GIMP seems to expect values in the range 0-1 */
604 	      gdkdev->info.axes[k].min = 0.0; /*axis_npressure.axMin;*/
605 	      gdkdev->info.axes[k].max = 1.0; /*axis_npressure.axMax;*/
606 	      k++;
607 	    }
608 	  if (gdkdev->pktdata & PK_ORIENTATION)
609 	    {
610 	      GdkAxisUse axis;
611 
612 	      gdkdev->orientation_axes[0] = axis_or[0];
613 	      gdkdev->orientation_axes[1] = axis_or[1];
614 	      for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++)
615 		{
616 		  /* Wintab gives us aximuth and altitude, which
617 		   * we convert to x and y tilt in the -1000..1000 range
618 		   */
619 		  gdkdev->axes[k].resolution = 1000;
620 		  gdkdev->axes[k].min_value = -1000;
621 		  gdkdev->axes[k].max_value = 1000;
622 		  gdkdev->info.axes[k].use = axis;
623 		  gdkdev->info.axes[k].min = -1.0;
624 		  gdkdev->info.axes[k].max = 1.0;
625 		  k++;
626 		}
627 	    }
628 	  gdkdev->info.num_keys = 0;
629 	  gdkdev->info.keys = NULL;
630 	  GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n",
631 				    cursorix,
632 				    gdkdev->info.name,
633 				    gdkdev->info.num_axes));
634 	  for (i = 0; i < gdkdev->info.num_axes; i++)
635 	    GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
636 				      i,
637 				      gdkdev->axes[i].min_value,
638 				      gdkdev->axes[i].max_value,
639 				      gdkdev->axes[i].resolution));
640 	  _gdk_input_devices = g_list_append (_gdk_input_devices,
641 					      gdkdev);
642 	}
643       g_free (devname_utf8);
644     }
645 }
646 
647 static void
decode_tilt(gint * axis_data,AXIS * axes,PACKET * packet)648 decode_tilt (gint   *axis_data,
649 	     AXIS   *axes,
650 	     PACKET *packet)
651 {
652   /* As I don't have a tilt-sensing tablet,
653    * I cannot test this code.
654    */
655 
656   double az, el;
657 
658   az = TWOPI * packet->pkOrientation.orAzimuth /
659     (axes[0].axResolution / 65536.);
660   el = TWOPI * packet->pkOrientation.orAltitude /
661     (axes[1].axResolution / 65536.);
662 
663   /* X tilt */
664   axis_data[0] = cos (az) * cos (el) * 1000;
665   /* Y tilt */
666   axis_data[1] = sin (az) * cos (el) * 1000;
667 }
668 
669 static void
gdk_input_translate_coordinates(GdkDevicePrivate * gdkdev,GdkWindow * window,gint * axis_data,gdouble * axis_out,gdouble * x_out,gdouble * y_out)670 gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
671 				 GdkWindow        *window,
672 				 gint             *axis_data,
673 				 gdouble          *axis_out,
674 				 gdouble          *x_out,
675 				 gdouble          *y_out)
676 {
677   GdkWindowObject *priv, *impl_window;
678   GdkWindowImplWin32 *root_impl;
679 
680   int i;
681   int x_axis = 0;
682   int y_axis = 0;
683 
684   double device_width, device_height, x_min, y_min;
685   double x_offset, y_offset, x_scale, y_scale;
686 
687   priv = (GdkWindowObject *) window;
688   impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
689 
690   for (i=0; i<gdkdev->info.num_axes; i++)
691     {
692       switch (gdkdev->info.axes[i].use)
693 	{
694 	case GDK_AXIS_X:
695 	  x_axis = i;
696 	  break;
697 	case GDK_AXIS_Y:
698 	  y_axis = i;
699 	  break;
700 	default:
701 	  break;
702 	}
703     }
704 
705   device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
706   x_min = gdkdev->axes[x_axis].min_value;
707   device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
708   y_min = gdkdev->axes[y_axis].min_value;
709 
710   if (gdkdev->info.mode == GDK_MODE_SCREEN)
711     {
712       root_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl);
713       x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width;
714       y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height;
715 
716       x_offset = - impl_window->input_window->root_x - priv->abs_x;
717       y_offset = - impl_window->input_window->root_y - priv->abs_y;
718     }
719   else				/* GDK_MODE_WINDOW */
720     {
721       double x_resolution = gdkdev->axes[x_axis].resolution;
722       double y_resolution = gdkdev->axes[y_axis].resolution;
723       double device_aspect = (device_height*y_resolution) / (device_width * x_resolution);
724 
725       if (device_aspect * priv->width >= priv->height)
726 	{
727 	  /* device taller than window */
728 	  x_scale = priv->width / device_width;
729 	  y_scale = (x_scale * x_resolution) / y_resolution;
730 
731 	  x_offset = 0;
732 	  y_offset = -(device_height * y_scale - priv->height) / 2;
733 	}
734       else
735 	{
736 	  /* window taller than device */
737 	  y_scale = priv->height / device_height;
738 	  x_scale = (y_scale * y_resolution)  / x_resolution;
739 
740 	  y_offset = 0;
741 	  x_offset = - (device_width * x_scale - priv->width) / 2;
742 	}
743     }
744 
745   for (i = 0; i < gdkdev->info.num_axes; i++)
746     {
747       switch (gdkdev->info.axes[i].use)
748 	{
749 	case GDK_AXIS_X:
750 	  axis_out[i] = x_offset + x_scale * axis_data[x_axis];
751 	  if (x_out)
752 	    *x_out = axis_out[i];
753 	  break;
754 	case GDK_AXIS_Y:
755 	  axis_out[i] = y_offset + y_scale * axis_data[y_axis];
756 	  if (y_out)
757 	    *y_out = axis_out[i];
758 	  break;
759 	default:
760 	  axis_out[i] =
761 	    (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
762 	     gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
763 	    (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
764 	  break;
765 	}
766     }
767 }
768 
769 static void
gdk_input_get_root_relative_geometry(HWND w,int * x_ret,int * y_ret)770 gdk_input_get_root_relative_geometry (HWND w,
771 				      int  *x_ret,
772 				      int  *y_ret)
773 {
774   POINT pt;
775 
776   pt.x = 0;
777   pt.y = 0;
778   ClientToScreen (w, &pt);
779 
780   if (x_ret)
781     *x_ret = pt.x + _gdk_offset_x;
782   if (y_ret)
783     *y_ret = pt.y + _gdk_offset_y;
784 }
785 
786 void
_gdk_input_configure_event(GdkWindow * window)787 _gdk_input_configure_event (GdkWindow         *window)
788 {
789   GdkInputWindow *input_window;
790   GdkWindowObject *impl_window;
791   int root_x, root_y;
792 
793   g_return_if_fail (window != NULL);
794 
795   impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
796   input_window = impl_window->input_window;
797 
798   gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
799 					&root_x, &root_y);
800 
801   input_window->root_x = root_x;
802   input_window->root_y = root_y;
803 }
804 
805 /*
806  * Get the currently active keyboard modifiers (ignoring the mouse buttons)
807  * We could use gdk_window_get_pointer but that function does a lot of other
808  * expensive things besides getting the modifiers. This code is somewhat based
809  * on build_pointer_event_state from gdkevents-win32.c
810  */
811 static guint
get_modifier_key_state(void)812 get_modifier_key_state (void)
813 {
814   guint state;
815 
816   state = 0;
817   /* High-order bit is up/down, low order bit is toggled/untoggled */
818   if (GetKeyState (VK_CONTROL) < 0)
819     state |= GDK_CONTROL_MASK;
820   if (GetKeyState (VK_SHIFT) < 0)
821     state |= GDK_SHIFT_MASK;
822   if (GetKeyState (VK_MENU) < 0)
823     state |= GDK_MOD1_MASK;
824   if (GetKeyState (VK_CAPITAL) & 0x1)
825     state |= GDK_LOCK_MASK;
826 
827   return state;
828 }
829 
830 #if 0
831 static guint ignore_core_timer = 0;
832 
833 static gboolean
834 ignore_core_timefunc (gpointer data)
835 {
836   /* The delay has passed */
837   _gdk_input_ignore_core = FALSE;
838   ignore_core_timer = 0;
839 
840   return FALSE; /* remove timeout */
841 }
842 
843 /*
844  * Set or unset the _gdk_input_ignore_core variable that tells GDK
845  * to ignore events for the core pointer when the tablet is in proximity
846  * The unsetting is delayed slightly so that if a tablet event arrives
847  * just after proximity out, it does not cause a core pointer event
848  * which e.g. causes GIMP to switch tools.
849  */
850 static void
851 set_ignore_core (gboolean ignore)
852 {
853   if (ignore)
854     {
855       _gdk_input_ignore_core = TRUE;
856       /* Remove any pending clear */
857       if (ignore_core_timer)
858         {
859 	  g_source_remove (ignore_core_timer);
860 	  ignore_core_timer = 0;
861 	}
862     }
863   else
864     if (!ignore_core_timer)
865       ignore_core_timer = gdk_threads_add_timeout (PROXIMITY_OUT_DELAY,
866 					 ignore_core_timefunc, NULL);
867 }
868 
869 #endif
870 
871 void
_gdk_input_update_for_device_mode(GdkDevicePrivate * gdkdev)872 _gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev)
873 {
874   LOGCONTEXT lc;
875 
876   if (gdkdev != _gdk_device_in_proximity)
877     return;
878 
879   if (p_WTGetA (gdkdev->hctx, &lc))
880     {
881       if (gdkdev->info.mode == GDK_MODE_SCREEN &&
882 	  (lc.lcOptions & CXO_SYSTEM) == 0)
883 	{
884 	  lc.lcOptions |= CXO_SYSTEM;
885 	  p_WTSetA (gdkdev->hctx, &lc);
886 	}
887       else if (gdkdev->info.mode == GDK_MODE_WINDOW &&
888 	       (lc.lcOptions & CXO_SYSTEM) != 0)
889 	{
890 	  lc.lcOptions &= ~CXO_SYSTEM;
891 	  p_WTSetA (gdkdev->hctx, &lc);
892 	}
893     }
894 }
895 
896 static GdkWindow *
find_window_for_input_event(MSG * msg,int * x,int * y)897 find_window_for_input_event (MSG* msg, int *x, int *y)
898 {
899   POINT pt;
900   GdkWindow *window;
901   HWND hwnd;
902   RECT rect;
903 
904   pt = msg->pt;
905 
906   window = NULL;
907   hwnd = WindowFromPoint (pt);
908   if (hwnd != NULL)
909     {
910       POINT client_pt = pt;
911 
912       ScreenToClient (hwnd, &client_pt);
913       GetClientRect (hwnd, &rect);
914       if (PtInRect (&rect, client_pt))
915 	window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
916     }
917 
918   /* need to also adjust the coordinates to the new window */
919   if (window)
920     ScreenToClient (GDK_WINDOW_HWND (window), &pt);
921 
922   *x = pt.x;
923   *y = pt.y;
924 
925   if (window)
926     return window;
927 
928   return _gdk_root;
929 }
930 
931 gboolean
_gdk_input_other_event(GdkEvent * event,MSG * msg,GdkWindow * window)932 _gdk_input_other_event (GdkEvent  *event,
933 			MSG       *msg,
934 			GdkWindow *window)
935 {
936   GdkWindowObject *obj, *impl_window;
937   GdkWindow *native_window;
938   GdkInputWindow *input_window;
939   GdkDevicePrivate *gdkdev = NULL;
940   guint key_state;
941 
942   PACKET packet;
943   gint k;
944   gint x, y;
945   guint translated_buttons, button_diff, button_mask;
946   /* Translation from tablet button state to GDK button state for
947    * buttons 1-3 - swap button 2 and 3.
948    */
949   static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
950 
951   if (window != wintab_window)
952     {
953       g_warning ("_gdk_input_other_event: not wintab_window?");
954       return FALSE;
955     }
956 
957   native_window = find_window_for_input_event (msg, &x, &y);
958 
959   GDK_NOTE (EVENTS_OR_INPUT,
960 	    g_print ("_gdk_input_other_event: native_window=%p %+d%+d\n",
961 		     GDK_WINDOW_HWND (native_window), x, y));
962 
963   if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
964     {
965       if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
966 	return FALSE;
967     }
968 
969   switch (msg->message)
970     {
971     case WT_PACKET:
972       /* Don't produce any button or motion events while a window is being
973        * moved or resized, see bug #151090.
974        */
975       if (_modal_operation_in_progress)
976 	{
977 	  GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
978 	  return FALSE;
979 	}
980 
981       if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
982 						 packet.pkCursor)) == NULL)
983 	return FALSE;
984 
985       if (gdkdev->info.mode == GDK_MODE_DISABLED)
986 	return FALSE;
987 
988       k = 0;
989       if (gdkdev->pktdata & PK_X)
990 	gdkdev->last_axis_data[k++] = packet.pkX;
991       if (gdkdev->pktdata & PK_Y)
992 	gdkdev->last_axis_data[k++] = packet.pkY;
993       if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
994 	gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
995       if (gdkdev->pktdata & PK_ORIENTATION)
996 	{
997 	  decode_tilt (gdkdev->last_axis_data + k,
998 		       gdkdev->orientation_axes, &packet);
999 	  k += 2;
1000 	}
1001 
1002       g_assert (k == gdkdev->info.num_axes);
1003 
1004       translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
1005 
1006       if (translated_buttons != gdkdev->button_state)
1007 	{
1008 	  /* At least one button has changed state so produce a button event
1009 	   * If more than one button has changed state (unlikely),
1010 	   * just care about the first and act on the next the next time
1011 	   * we get a packet
1012 	   */
1013 	  button_diff = translated_buttons ^ gdkdev->button_state;
1014 
1015 	  /* Gdk buttons are numbered 1.. */
1016 	  event->button.button = 1;
1017 
1018 	  for (button_mask = 1; button_mask != 0x80000000;
1019 	       button_mask <<= 1, event->button.button++)
1020 	    {
1021 	      if (button_diff & button_mask)
1022 	        {
1023 		  /* Found a button that has changed state */
1024 		  break;
1025 		}
1026 	    }
1027 
1028 	  if (!(translated_buttons & button_mask))
1029 	    event->any.type = GDK_BUTTON_RELEASE;
1030 	  else
1031 	    event->any.type = GDK_BUTTON_PRESS;
1032 	  gdkdev->button_state ^= button_mask;
1033 	}
1034       else
1035 	{
1036 	  event->any.type = GDK_MOTION_NOTIFY;
1037 	}
1038 
1039       if (native_window == _gdk_root)
1040 	return FALSE;
1041 
1042       window = _gdk_window_get_input_window_for_event (native_window,
1043 						       event->any.type,
1044 						       gdkdev->button_state << 8,
1045 						       x, y, 0);
1046 
1047       obj = GDK_WINDOW_OBJECT (window);
1048 
1049       if (window == NULL ||
1050 	  obj->extension_events == 0)
1051 	return FALSE;
1052 
1053       impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
1054       input_window = impl_window->input_window;
1055 
1056       g_assert (input_window != NULL);
1057 
1058       if (gdkdev->info.mode == GDK_MODE_WINDOW &&
1059 	  (obj->extension_events & GDK_ALL_DEVICES_MASK) == 0)
1060 	return FALSE;
1061 
1062       event->any.window = window;
1063       key_state = get_modifier_key_state ();
1064       if (event->any.type == GDK_BUTTON_PRESS ||
1065 	  event->any.type == GDK_BUTTON_RELEASE)
1066 	{
1067 	  event->button.time = _gdk_win32_get_next_tick (msg->time);
1068 	  event->button.device = &gdkdev->info;
1069 
1070 	  event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
1071 
1072 	  gdk_input_translate_coordinates (gdkdev, window,
1073 					   gdkdev->last_axis_data,
1074 					   event->button.axes,
1075 					   &event->button.x,
1076 					   &event->button.y);
1077 
1078 	  /* Also calculate root coordinates. Note that input_window->root_x
1079 	     is in GDK root coordinates. */
1080 	  event->button.x_root = event->button.x + input_window->root_x;
1081 	  event->button.y_root = event->button.y + input_window->root_y;
1082 
1083 	  event->button.state = ((gdkdev->button_state << 8)
1084 				 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1085 				    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1086 				    | GDK_BUTTON5_MASK))
1087 				| key_state;
1088 	  GDK_NOTE (EVENTS_OR_INPUT,
1089 		    g_print ("WINTAB button %s:%d %g,%g\n",
1090 			     (event->button.type == GDK_BUTTON_PRESS ?
1091 			      "press" : "release"),
1092 			     event->button.button,
1093 			     event->button.x, event->button.y));
1094 	}
1095       else
1096 	{
1097 	  event->motion.time = _gdk_win32_get_next_tick (msg->time);
1098 	  event->motion.is_hint = FALSE;
1099 	  event->motion.device = &gdkdev->info;
1100 
1101 	  event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
1102 
1103 	  gdk_input_translate_coordinates (gdkdev, window,
1104 					   gdkdev->last_axis_data,
1105 					   event->motion.axes,
1106 					   &event->motion.x,
1107 					   &event->motion.y);
1108 
1109 	  /* Also calculate root coordinates. Note that input_window->root_x
1110 	     is in GDK root coordinates. */
1111 	  event->motion.x_root = event->motion.x + input_window->root_x;
1112 	  event->motion.y_root = event->motion.y + input_window->root_y;
1113 
1114 	  event->motion.state = ((gdkdev->button_state << 8)
1115 				 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1116 				    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1117 				    | GDK_BUTTON5_MASK))
1118 				| key_state;
1119 
1120 	  GDK_NOTE (EVENTS_OR_INPUT,
1121 		    g_print ("WINTAB motion: %g,%g\n",
1122 			     event->motion.x, event->motion.y));
1123 	}
1124       return TRUE;
1125 
1126     case WT_CSRCHANGE:
1127       if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
1128 						 packet.pkCursor)) == NULL)
1129 	return FALSE;
1130 
1131       _gdk_device_in_proximity = gdkdev;
1132 
1133       _gdk_input_update_for_device_mode (gdkdev);
1134 
1135       window = NULL;
1136       if (native_window != _gdk_root)
1137 	window = _gdk_window_get_input_window_for_event (native_window,
1138 							 GDK_PROXIMITY_IN,
1139 							 0,
1140 							 x, y, 0);
1141       if (window)
1142 	{
1143 	  event->proximity.type = GDK_PROXIMITY_IN;
1144 	  event->proximity.window = window;
1145 	  event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1146 	  event->proximity.device = &_gdk_device_in_proximity->info;
1147 	}
1148 
1149       GDK_NOTE (EVENTS_OR_INPUT,
1150 		g_print ("WINTAB proximity in\n"));
1151 
1152       return TRUE;
1153 
1154     case WT_PROXIMITY:
1155       /* TODO: Set ignore_core if in input_window */
1156       if (LOWORD (msg->lParam) == 0)
1157 	{
1158 	  _gdk_input_in_proximity = FALSE;
1159 
1160 	  window = NULL;
1161 	  if (native_window != _gdk_root)
1162 	    window = _gdk_window_get_input_window_for_event (native_window,
1163 							     GDK_PROXIMITY_IN,
1164 							     0,
1165 							     x, y, 0);
1166 	  if (window)
1167 	    {
1168 	      event->proximity.type = GDK_PROXIMITY_OUT;
1169 	      event->proximity.window = window;
1170 	      event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1171 	      event->proximity.device = &_gdk_device_in_proximity->info;
1172 	    }
1173 
1174 	  GDK_NOTE (EVENTS_OR_INPUT,
1175 		    g_print ("WINTAB proximity out\n"));
1176 
1177 	  return TRUE;
1178 	}
1179       else
1180 	_gdk_input_in_proximity = TRUE;
1181 
1182       _gdk_input_check_proximity ();
1183 
1184       break;
1185     }
1186   return FALSE;
1187 }
1188 
1189 void
_gdk_input_select_events(GdkWindow * impl_window)1190 _gdk_input_select_events (GdkWindow *impl_window)
1191 {
1192   guint event_mask;
1193   GdkWindowObject *w;
1194   GdkInputWindow *iw;
1195   GList *l, *dev_list;
1196 
1197 
1198   iw = ((GdkWindowObject *)impl_window)->input_window;
1199 
1200   event_mask = 0;
1201   for (dev_list = _gdk_input_devices; dev_list; dev_list = dev_list->next)
1202     {
1203       GdkDevicePrivate *gdkdev = dev_list->data;
1204 
1205       if (!GDK_IS_CORE (gdkdev) &&
1206 	  gdkdev->info.mode != GDK_MODE_DISABLED &&
1207 	  iw != NULL)
1208 	{
1209 	  for (l = iw->windows; l != NULL; l = l->next)
1210 	    {
1211 	      w = l->data;
1212 	      if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
1213 		event_mask |= w->extension_events;
1214 	    }
1215 	}
1216     }
1217 
1218   event_mask &= ~GDK_ALL_DEVICES_MASK;
1219   if (event_mask)
1220     event_mask |=
1221       GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
1222 
1223   GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *)impl_window)->impl)->extension_events_mask = event_mask;
1224 }
1225 
1226 gint
_gdk_input_grab_pointer(GdkWindow * window,gint owner_events,GdkEventMask event_mask,GdkWindow * confine_to,guint32 time)1227 _gdk_input_grab_pointer (GdkWindow    *window,
1228 			 gint          owner_events,
1229 			 GdkEventMask  event_mask,
1230 			 GdkWindow    *confine_to,
1231 			 guint32       time)
1232 {
1233   GDK_NOTE (INPUT, g_print ("_gdk_input_grab_pointer: %p %d %p\n",
1234 			   GDK_WINDOW_HWND (window),
1235 			   owner_events,
1236 			   (confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
1237 
1238   return GDK_GRAB_SUCCESS;
1239 }
1240 
1241 void
_gdk_input_ungrab_pointer(guint32 time)1242 _gdk_input_ungrab_pointer (guint32 time)
1243 {
1244 
1245   GDK_NOTE (INPUT, g_print ("_gdk_input_ungrab_pointer\n"));
1246 
1247 }
1248 
1249 gboolean
_gdk_device_get_history(GdkDevice * device,GdkWindow * window,guint32 start,guint32 stop,GdkTimeCoord *** events,gint * n_events)1250 _gdk_device_get_history (GdkDevice         *device,
1251 			 GdkWindow         *window,
1252 			 guint32            start,
1253 			 guint32            stop,
1254 			 GdkTimeCoord    ***events,
1255 			 gint              *n_events)
1256 {
1257   return FALSE;
1258 }
1259 
1260 void
gdk_device_get_state(GdkDevice * device,GdkWindow * window,gdouble * axes,GdkModifierType * mask)1261 gdk_device_get_state (GdkDevice       *device,
1262 		      GdkWindow       *window,
1263 		      gdouble         *axes,
1264 		      GdkModifierType *mask)
1265 {
1266   g_return_if_fail (device != NULL);
1267   g_return_if_fail (GDK_IS_WINDOW (window));
1268 
1269   if (GDK_IS_CORE (device))
1270     {
1271       gint x_int, y_int;
1272 
1273       gdk_window_get_pointer (window, &x_int, &y_int, mask);
1274 
1275       if (axes)
1276 	{
1277 	  axes[0] = x_int;
1278 	  axes[1] = y_int;
1279 	}
1280     }
1281   else
1282     {
1283       GdkDevicePrivate *gdkdev;
1284 
1285       gdkdev = (GdkDevicePrivate *)device;
1286       /* For now just use the last known button and axis state of the device.
1287        * Since graphical tablets send an insane amount of motion events each
1288        * second, the info should be fairly up to date */
1289       if (mask)
1290 	{
1291 	  gdk_window_get_pointer (window, NULL, NULL, mask);
1292 	  *mask &= 0xFF; /* Mask away core pointer buttons */
1293 	  *mask |= ((gdkdev->button_state << 8)
1294 		    & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1295 		       | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1296 		       | GDK_BUTTON5_MASK));
1297 	}
1298       /* For some reason, input_window is sometimes NULL when I use The GIMP 2
1299        * (bug #141543?). Avoid crashing if debugging is disabled. */
1300       if (axes && gdkdev->last_axis_data)
1301 	gdk_input_translate_coordinates (gdkdev, window,
1302 					 gdkdev->last_axis_data,
1303 					 axes, NULL, NULL);
1304     }
1305 }
1306 
1307 void
_gdk_input_set_tablet_active(void)1308 _gdk_input_set_tablet_active (void)
1309 {
1310   GList *tmp_list;
1311   HCTX *hctx;
1312 
1313   /* Bring the contexts to the top of the overlap order when one of the
1314    * application's windows is activated */
1315 
1316   if (!wintab_contexts)
1317     return; /* No tablet devices found, or Wintab not initialized yet */
1318 
1319   GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
1320 	"Bringing Wintab contexts to the top of the overlap order\n"));
1321 
1322   tmp_list = wintab_contexts;
1323   while (tmp_list)
1324     {
1325       hctx = (HCTX *) (tmp_list->data);
1326       (*p_WTOverlap) (*hctx, TRUE);
1327       tmp_list = tmp_list->next;
1328     }
1329 }
1330 
1331 void
_gdk_input_init(GdkDisplay * display)1332 _gdk_input_init (GdkDisplay *display)
1333 {
1334   _gdk_input_devices = NULL;
1335 
1336   _gdk_init_input_core (display);
1337 #ifdef WINTAB_NO_LAZY_INIT
1338   /* Normally, Wintab is only initialized when the application performs
1339    * an action that requires it, such as enabling extended input events
1340    * for a window or enumerating the devices.
1341    */
1342   _gdk_input_wintab_init_check ();
1343 #endif /* WINTAB_NO_LAZY_INIT */
1344 
1345   _gdk_input_devices = g_list_append (_gdk_input_devices, display->core_pointer);
1346 }
1347 
1348