1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 
24 #include <gdk/gdk.h>
25 #include "gdkwin32.h"
26 #include "gdkprivate-win32.h"
27 #include "gdkdevicemanager-win32.h"
28 #include "gdkdeviceprivate.h"
29 #include "gdkdevice-win32.h"
30 #include "gdkdevice-virtual.h"
31 #include "gdkdevice-wintab.h"
32 #include "gdkinput-winpointer.h"
33 #include "gdkdisplayprivate.h"
34 #include "gdkdisplay-win32.h"
35 #include "gdkseatdefaultprivate.h"
36 
37 #define WINTAB32_DLL "Wintab32.dll"
38 
39 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y  | PK_NORMAL_PRESSURE | PK_ORIENTATION)
40 /* We want everything in absolute mode */
41 #define PACKETMODE (0)
42 #include <pktdef.h>
43 
44 #define DEBUG_WINTAB 1		/* Verbose debug messages enabled */
45 #define TWOPI (2 * G_PI)
46 
47 static GList     *wintab_contexts = NULL;
48 static GdkSurface *wintab_window = NULL;
49 extern int        _gdk_input_ignore_core;
50 
51 typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
52 typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
53 typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
54 typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
55 typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
56 typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
57 typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
58 typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
59 typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
60 
61 static t_WTInfoA p_WTInfoA;
62 static t_WTInfoW p_WTInfoW;
63 static t_WTEnable p_WTEnable;
64 static t_WTOpenA p_WTOpenA;
65 static t_WTGetA p_WTGetA;
66 static t_WTSetA p_WTSetA;
67 static t_WTOverlap p_WTOverlap;
68 static t_WTPacket p_WTPacket;
69 static t_WTQueueSizeSet p_WTQueueSizeSet;
70 
71 static gboolean default_display_opened = FALSE;
72 
G_DEFINE_TYPE(GdkDeviceManagerWin32,gdk_device_manager_win32,G_TYPE_OBJECT)73 G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, G_TYPE_OBJECT)
74 
75 static GdkDevice *
76 create_pointer (GdkDeviceManagerWin32 *device_manager,
77 		GType g_type,
78 		const char *name,
79                 gboolean has_cursor)
80 {
81   return g_object_new (g_type,
82                        "name", name,
83                        "source", GDK_SOURCE_MOUSE,
84                        "has-cursor", has_cursor,
85                        "display", _gdk_display,
86                        NULL);
87 }
88 
89 static GdkDevice *
create_keyboard(GdkDeviceManagerWin32 * device_manager,GType g_type,const char * name)90 create_keyboard (GdkDeviceManagerWin32 *device_manager,
91 		 GType g_type,
92 		 const char *name)
93 {
94   return g_object_new (g_type,
95                        "name", name,
96                        "source", GDK_SOURCE_KEYBOARD,
97                        "has-cursor", FALSE,
98                        "display", _gdk_display,
99                        NULL);
100 }
101 
102 static void
gdk_device_manager_win32_init(GdkDeviceManagerWin32 * device_manager_win32)103 gdk_device_manager_win32_init (GdkDeviceManagerWin32 *device_manager_win32)
104 {
105 }
106 
107 static void
gdk_device_manager_win32_finalize(GObject * object)108 gdk_device_manager_win32_finalize (GObject *object)
109 {
110   GdkDeviceManagerWin32 *device_manager_win32;
111 
112   device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (object);
113 
114   g_object_unref (device_manager_win32->core_pointer);
115   g_object_unref (device_manager_win32->core_keyboard);
116 
117   G_OBJECT_CLASS (gdk_device_manager_win32_parent_class)->finalize (object);
118 }
119 
120 #if DEBUG_WINTAB
121 
122 static void
print_lc(LOGCONTEXT * lc)123 print_lc(LOGCONTEXT *lc)
124 {
125   g_print ("lcName = %s\n", lc->lcName);
126   g_print ("lcOptions =");
127   if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
128   if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
129   if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
130   if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
131   if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
132   if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
133   g_print ("\n");
134   g_print ("lcStatus =");
135   if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
136   if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
137   if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
138   g_print ("\n");
139   g_print ("lcLocks =");
140   if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
141   if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
142   if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
143   if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
144   g_print ("\n");
145   g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
146 	  lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
147   g_print ("lcPktData =");
148   if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
149   if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
150   if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
151   if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
152   if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
153   if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
154   if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
155   if (lc->lcPktData & PK_X) g_print (" PK_X");
156   if (lc->lcPktData & PK_Y) g_print (" PK_Y");
157   if (lc->lcPktData & PK_Z) g_print (" PK_Z");
158   if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
159   if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
160   if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
161   if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
162   g_print ("\n");
163   g_print ("lcPktMode =");
164   if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
165   if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
166   if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
167   if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
168   if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
169   if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
170   if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
171   if (lc->lcPktMode & PK_X) g_print (" PK_X");
172   if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
173   if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
174   if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
175   if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
176   if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
177   if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
178   g_print ("\n");
179   g_print ("lcMoveMask =");
180   if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
181   if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
182   if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
183   if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
184   if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
185   if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
186   if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
187   if (lc->lcMoveMask & PK_X) g_print (" PK_X");
188   if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
189   if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
190   if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
191   if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
192   if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
193   if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
194   g_print ("\n");
195   g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
196 	  (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
197   g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
198 	  lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
199   g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
200 	  lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
201   g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
202 	  lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
203   g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
204 	  lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
205   g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
206 	  lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
207   g_print ("lcSysMode = %d\n", lc->lcSysMode);
208   g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
209 	  lc->lcSysOrgX, lc->lcSysOrgY);
210   g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
211 	  lc->lcSysExtX, lc->lcSysExtY);
212   g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
213 	  lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
214 }
215 
216 static void
print_cursor(int index)217 print_cursor (int index)
218 {
219   int size;
220   int i;
221   char *name;
222   BOOL active;
223   WTPKT wtpkt;
224   BYTE buttons;
225   BYTE buttonbits;
226   char *btnnames;
227   char *p;
228   BYTE buttonmap[32];
229   BYTE sysbtnmap[32];
230   BYTE npbutton;
231   UINT npbtnmarks[2];
232   UINT *npresponse;
233   BYTE tpbutton;
234   UINT tpbtnmarks[2];
235   UINT *tpresponse;
236   DWORD physid;
237   UINT mode;
238   UINT minpktdata;
239   UINT minbuttons;
240   UINT capabilities;
241 
242   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
243   name = g_malloc (size + 1);
244   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
245   g_print ("NAME: %s\n", name);
246   (*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
247   g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
248   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
249   g_print ("PKTDATA: %#x:", (guint) wtpkt);
250 #define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
251   BIT (CONTEXT);
252   BIT (STATUS);
253   BIT (TIME);
254   BIT (CHANGED);
255   BIT (SERIAL_NUMBER);
256   BIT (BUTTONS);
257   BIT (X);
258   BIT (Y);
259   BIT (Z);
260   BIT (NORMAL_PRESSURE);
261   BIT (TANGENT_PRESSURE);
262   BIT (ORIENTATION);
263   BIT (ROTATION);
264 #undef BIT
265   g_print ("\n");
266   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
267   g_print ("BUTTONS: %d\n", buttons);
268   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
269   g_print ("BUTTONBITS: %d\n", buttonbits);
270   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
271   g_print ("BTNNAMES:");
272   if (size > 0)
273     {
274       btnnames = g_malloc (size + 1);
275       (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
276       p = btnnames;
277       while (*p)
278         {
279           g_print (" %s", p);
280           p += strlen (p) + 1;
281         }
282     }
283   g_print ("\n");
284   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
285   g_print ("BUTTONMAP:");
286   for (i = 0; i < buttons; i++)
287     g_print (" %d", buttonmap[i]);
288   g_print ("\n");
289   (*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
290   g_print ("SYSBTNMAP:");
291   for (i = 0; i < buttons; i++)
292     g_print (" %d", sysbtnmap[i]);
293   g_print ("\n");
294   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
295   g_print ("NPBUTTON: %d\n", npbutton);
296   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
297   g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
298   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
299   g_print ("NPRESPONSE:");
300   if (size > 0)
301     {
302       npresponse = g_malloc (size);
303       (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
304       for (i = 0; i < size / sizeof (UINT); i++)
305         g_print (" %d", npresponse[i]);
306     }
307   g_print ("\n");
308   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
309   g_print ("TPBUTTON: %d\n", tpbutton);
310   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
311   g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
312   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
313   g_print ("TPRESPONSE:");
314   if (size > 0)
315     {
316       tpresponse = g_malloc (size);
317       (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
318       for (i = 0; i < size / sizeof (UINT); i++)
319         g_print (" %d", tpresponse[i]);
320     }
321   g_print ("\n");
322   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
323   g_print ("PHYSID: %#x\n", (guint) physid);
324   (*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
325   g_print ("CAPABILITIES: %#x:", capabilities);
326 #define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
327   BIT (MULTIMODE);
328   BIT (AGGREGATE);
329   BIT (INVERT);
330 #undef BIT
331   g_print ("\n");
332   if (capabilities & CRC_MULTIMODE)
333     {
334       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
335       g_print ("MODE: %d\n", mode);
336     }
337   if (capabilities & CRC_AGGREGATE)
338     {
339       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
340       g_print ("MINPKTDATA: %d\n", minpktdata);
341       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
342       g_print ("MINBUTTONS: %d\n", minbuttons);
343     }
344 }
345 #endif
346 
347 static void
wintab_init_check(GdkDeviceManagerWin32 * device_manager)348 wintab_init_check (GdkDeviceManagerWin32 *device_manager)
349 {
350   GdkDisplay *display = device_manager->display;
351   static gboolean wintab_initialized = FALSE;
352   GdkDeviceWintab *device;
353   WORD specversion;
354   HCTX *hctx;
355   UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
356   BOOL active;
357   DWORD physid;
358   AXIS axis_x, axis_y, axis_npressure, axis_or[3];
359   UINT devix, cursorix;
360   int i, num_axes = 0;
361   wchar_t devname[100], csrname[100];
362   char *devname_utf8, *csrname_utf8, *device_name;
363   BOOL defcontext_done;
364   HMODULE wintab32;
365   char *wintab32_dll_path;
366   char dummy;
367   int n, k;
368 
369   if (wintab_initialized)
370     return;
371 
372   wintab_initialized = TRUE;
373 
374   wintab_contexts = NULL;
375 
376   n = GetSystemDirectory (&dummy, 0);
377 
378   if (n <= 0)
379     return;
380 
381   wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
382   k = GetSystemDirectory (wintab32_dll_path, n);
383 
384   if (k == 0 || k > n)
385     {
386       g_free (wintab32_dll_path);
387       return;
388     }
389 
390   if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
391     strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
392   strcat (wintab32_dll_path, WINTAB32_DLL);
393 
394   if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
395     return;
396 
397   if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
398     return;
399   if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
400     return;
401   if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
402     return;
403   if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
404     return;
405   if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
406     return;
407   if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
408     return;
409   if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
410     return;
411   if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
412     return;
413   if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
414     return;
415 
416   if (!(*p_WTInfoA) (0, 0, NULL))
417     return;
418 
419   (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
420   GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
421 			    HIBYTE (specversion), LOBYTE (specversion)));
422   (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
423   (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
424 #if DEBUG_WINTAB
425   GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
426 			    ndevices, ncursors));
427 #endif
428   /* Create a dummy window to receive wintab events */
429   wintab_window =
430       _gdk_win32_display_create_surface (display,
431                                          GDK_SURFACE_TEMP,
432                                          NULL,
433                                          -100, -100, 2, 2);
434 
435   g_object_ref (wintab_window);
436 
437   for (devix = 0; devix < ndevices; devix++)
438     {
439       LOGCONTEXT lc;
440 
441       /* We open the Wintab device (hmm, what if there are several, or
442        * can there even be several, probably not?) as a system
443        * pointing device, i.e. it controls the normal Windows
444        * cursor. This seems much more natural.
445        */
446 
447       (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
448       devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
449 #ifdef DEBUG_WINTAB
450       GDK_NOTE (INPUT, (g_print("Device %u: %s\n", devix, devname_utf8)));
451 #endif
452       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
453       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
454       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
455       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
456       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
457       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
458       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
459 
460       defcontext_done = FALSE;
461       if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
462         {
463           /* Try to get device-specific default context */
464           /* Some drivers, e.g. Aiptek, don't provide this info */
465           if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
466             defcontext_done = TRUE;
467 #if DEBUG_WINTAB
468           if (defcontext_done)
469             GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
470           else
471             GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
472 #endif
473         }
474 
475       if (!defcontext_done)
476         (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
477 #if DEBUG_WINTAB
478       GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
479 #endif
480       lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
481       lc.lcStatus = 0;
482       lc.lcMsgBase = WT_DEFBASE;
483       lc.lcPktRate = 0;
484       lc.lcPktData = PACKETDATA;
485       lc.lcPktMode = PACKETMODE;
486       lc.lcMoveMask = PACKETDATA;
487       lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
488       lc.lcOutOrgX = axis_x.axMin;
489       lc.lcOutOrgY = axis_y.axMin;
490       lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
491       lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
492       lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
493 #if DEBUG_WINTAB
494       GDK_NOTE (INPUT, (g_print("context for device %u:\n", devix),
495 			print_lc(&lc)));
496 #endif
497       hctx = g_new (HCTX, 1);
498       if ((*hctx = (*p_WTOpenA) (GDK_SURFACE_HWND (wintab_window), &lc, TRUE)) == NULL)
499         {
500           g_warning ("gdk_input_wintab_init: WTOpen failed");
501           return;
502         }
503       GDK_NOTE (INPUT, g_print ("opened Wintab device %u %p\n",
504                                 devix, *hctx));
505 
506       wintab_contexts = g_list_append (wintab_contexts, hctx);
507 #if 0
508       (*p_WTEnable) (*hctx, TRUE);
509 #endif
510       (*p_WTOverlap) (*hctx, TRUE);
511 
512 #if DEBUG_WINTAB
513       GDK_NOTE (INPUT, (g_print("context for device %u after WTOpen:\n", devix),
514 			print_lc(&lc)));
515 #endif
516       /* Increase packet queue size to reduce the risk of lost packets.
517        * According to the specs, if the function fails we must try again
518        * with a smaller queue size.
519        */
520       GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
521       for (i = 128; i >= 1; i >>= 1)
522         {
523           if ((*p_WTQueueSizeSet) (*hctx, i))
524             {
525               GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
526               break;
527             }
528         }
529       if (!i)
530         GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
531       for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
532         {
533 #ifdef DEBUG_WINTAB
534           GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (cursorix)));
535 #endif
536           active = FALSE;
537           (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
538           if (!active)
539             continue;
540 
541           /* Wacom tablets seem to report cursors corresponding to
542            * nonexistent pens or pucks. At least my ArtPad II reports
543            * six cursors: a puck, pressure stylus and eraser stylus,
544            * and then the same three again. I only have a
545            * pressure-sensitive pen. The puck instances, and the
546            * second instances of the styluses report physid zero. So
547            * at least for Wacom, skip cursors with physid zero.
548            */
549           (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
550           if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
551             continue;
552 
553           (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
554           csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
555           device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
556 
557           device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
558                                  "name", device_name,
559                                  "source", GDK_SOURCE_PEN,
560                                  "has-cursor", lc.lcOptions & CXO_SYSTEM,
561                                  "display", display,
562                                  NULL);
563 
564 	  device->sends_core = lc.lcOptions & CXO_SYSTEM;
565 	  if (device->sends_core)
566 	    {
567 	      _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device));
568 	      _gdk_device_add_physical_device (device_manager->core_pointer, GDK_DEVICE (device));
569 	    }
570 
571           g_free (csrname_utf8);
572 
573           device->hctx = *hctx;
574           device->cursor = cursorix;
575           (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
576 
577           if (device->pktdata & PK_X)
578             {
579               _gdk_device_add_axis (GDK_DEVICE (device),
580                                     GDK_AXIS_X,
581                                     axis_x.axMin,
582                                     axis_x.axMax,
583                                     axis_x.axResolution / 65535);
584               num_axes++;
585             }
586 
587           if (device->pktdata & PK_Y)
588             {
589               _gdk_device_add_axis (GDK_DEVICE (device),
590                                     GDK_AXIS_Y,
591                                     axis_y.axMin,
592                                     axis_y.axMax,
593                                     axis_y.axResolution / 65535);
594               num_axes++;
595             }
596 
597 
598           if (device->pktdata & PK_NORMAL_PRESSURE)
599             {
600               _gdk_device_add_axis (GDK_DEVICE (device),
601                                     GDK_AXIS_PRESSURE,
602                                     axis_npressure.axMin,
603                                     axis_npressure.axMax,
604                                     axis_npressure.axResolution / 65535);
605               num_axes++;
606             }
607 
608           if (device->pktdata & PK_ORIENTATION)
609             {
610               device->orientation_axes[0] = axis_or[0];
611               device->orientation_axes[1] = axis_or[1];
612 
613               /* Wintab gives us azimuth and altitude, which
614                * we convert to x and y tilt in the -1000..1000 range
615                */
616               _gdk_device_add_axis (GDK_DEVICE (device),
617                                     GDK_AXIS_XTILT,
618                                     -1000,
619                                     1000,
620                                     1000);
621 
622               _gdk_device_add_axis (GDK_DEVICE (device),
623                                     GDK_AXIS_YTILT,
624                                     -1000,
625                                     1000,
626                                     1000);
627               num_axes += 2;
628             }
629 
630           device->last_axis_data = g_new (int, num_axes);
631 
632           GDK_NOTE (INPUT, g_print ("device: (%u) %s axes: %d\n",
633                                     cursorix,
634                                     device_name,
635                                     num_axes));
636 
637 #if 0
638           for (i = 0; i < gdkdev->info.num_axes; i++)
639             GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
640                                       i,
641                                       gdkdev->axes[i].min_value,
642                                       gdkdev->axes[i].max_value,
643                                       gdkdev->axes[i].resolution));
644 #endif
645 
646           device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
647                                                           device);
648 
649           g_free (device_name);
650         }
651 
652       g_free (devname_utf8);
653     }
654 }
655 
656 /* Only initialize Wintab after the default display is set for
657  * the first time. WTOpenA() executes code beyond our control,
658  * and it can cause messages to be sent to the application even
659  * before a window is opened. GDK has to be in a fit state to
660  * handle them when they come.
661  *
662  * https://bugzilla.gnome.org/show_bug.cgi?id=774379
663  */
664 static void
wintab_default_display_notify_cb(GdkDisplayManager * display_manager)665 wintab_default_display_notify_cb (GdkDisplayManager *display_manager)
666 {
667   GdkDeviceManagerWin32 *device_manager = NULL;
668   GdkDisplay *display = gdk_display_get_default();
669 
670   if (default_display_opened)
671     return;
672 
673   g_assert (display != NULL);
674 
675   device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
676   g_assert (display_manager != NULL);
677 
678   default_display_opened = TRUE;
679   GDK_NOTE (INPUT, g_print ("wintab init: doing delayed initialization\n"));
680   wintab_init_check (device_manager);
681 }
682 
683 static void
gdk_device_manager_win32_constructed(GObject * object)684 gdk_device_manager_win32_constructed (GObject *object)
685 {
686   GdkWin32Display *display_win32;
687   GdkDeviceManagerWin32 *device_manager;
688   GdkSeat *seat;
689   const char *api_preference = NULL;
690   gboolean have_api_preference = TRUE;
691 
692   display_win32 = GDK_WIN32_DISPLAY (_gdk_display);
693 
694   device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
695   device_manager->core_pointer =
696     create_pointer (device_manager,
697 		    GDK_TYPE_DEVICE_VIRTUAL,
698 		    "Virtual Core Pointer",
699                     TRUE);
700   device_manager->system_pointer =
701     create_pointer (device_manager,
702 		    GDK_TYPE_DEVICE_WIN32,
703 		    "System Aggregated Pointer",
704                     FALSE);
705   _gdk_device_virtual_set_active (device_manager->core_pointer,
706 				  device_manager->system_pointer);
707   _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
708   _gdk_device_add_physical_device (device_manager->core_pointer, device_manager->system_pointer);
709 
710   device_manager->core_keyboard =
711     create_keyboard (device_manager,
712 		     GDK_TYPE_DEVICE_VIRTUAL,
713 		     "Virtual Core Keyboard");
714   device_manager->system_keyboard =
715     create_keyboard (device_manager,
716 		    GDK_TYPE_DEVICE_WIN32,
717 		     "System Aggregated Keyboard");
718   _gdk_device_virtual_set_active (device_manager->core_keyboard,
719 				  device_manager->system_keyboard);
720   _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
721   _gdk_device_add_physical_device (device_manager->core_keyboard, device_manager->system_keyboard);
722 
723   _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
724   _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
725 
726   seat = gdk_seat_default_new_for_logical_pair (device_manager->core_pointer,
727                                                 device_manager->core_keyboard);
728   gdk_display_add_seat (_gdk_display, seat);
729   gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), device_manager->system_pointer);
730   gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
731   g_object_unref (seat);
732 
733   _gdk_device_manager = device_manager;
734 
735   api_preference = g_getenv ("GDK_WIN32_TABLET_INPUT_API");
736   if (g_strcmp0 (api_preference, "none") == 0)
737     {
738       display_win32->tablet_input_api = GDK_WIN32_TABLET_INPUT_API_NONE;
739     }
740   else if (g_strcmp0 (api_preference, "wintab") == 0)
741     {
742       display_win32->tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
743     }
744   else if (g_strcmp0 (api_preference, "winpointer") == 0)
745     {
746       display_win32->tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
747     }
748   else
749     {
750       /* No user preference, default to WinPointer. If unsuccessful,
751        * try to initialize other API's in sequence until one succeeds.
752        */
753       display_win32->tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
754       have_api_preference = FALSE;
755     }
756 
757   if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
758     {
759       gboolean init_successful = gdk_winpointer_initialize ();
760 
761       if (!init_successful && !have_api_preference)
762         {
763           /* Try Wintab */
764           display_win32->tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
765         }
766     }
767 
768   if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
769     {
770       GdkDisplayManager *display_manager = NULL;
771       GdkDisplay *default_display = NULL;
772 
773       /* Only call Wintab init stuff after the default display
774        * is globally known and accessible through the display manager
775        * singleton. Approach lifted from gtkmodules.c.
776        */
777       display_manager = gdk_display_manager_get ();
778       g_assert (display_manager != NULL);
779       default_display = gdk_display_manager_get_default_display (display_manager);
780       g_assert (default_display == NULL);
781 
782       g_signal_connect (display_manager, "notify::default-display",
783                         G_CALLBACK (wintab_default_display_notify_cb),
784                         NULL);
785     }
786 }
787 
788 static void
gdk_device_manager_win32_class_init(GdkDeviceManagerWin32Class * klass)789 gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
790 {
791   GObjectClass *object_class = G_OBJECT_CLASS (klass);
792 
793   object_class->finalize = gdk_device_manager_win32_finalize;
794   object_class->constructed = gdk_device_manager_win32_constructed;
795 }
796 
797 void
_gdk_wintab_set_tablet_active(void)798 _gdk_wintab_set_tablet_active (void)
799 {
800   GList *tmp_list;
801   HCTX *hctx;
802 
803   /* Bring the contexts to the top of the overlap order when one of the
804    * application's windows is activated */
805 
806   if (!wintab_contexts)
807     return; /* No tablet devices found, or Wintab not initialized yet */
808 
809   GDK_NOTE (INPUT, g_print ("_gdk_wintab_set_tablet_active: "
810                             "Bringing Wintab contexts to the top of the overlap order\n"));
811 
812   tmp_list = wintab_contexts;
813 
814   while (tmp_list)
815     {
816       hctx = (HCTX *) (tmp_list->data);
817       (*p_WTOverlap) (*hctx, TRUE);
818       tmp_list = tmp_list->next;
819     }
820 }
821 
822 static void
decode_tilt(int * axis_data,AXIS * axes,PACKET * packet)823 decode_tilt (int    *axis_data,
824              AXIS   *axes,
825              PACKET *packet)
826 {
827   double az, el;
828 
829   g_return_if_fail (axis_data != NULL);
830 
831   /* The wintab driver for the Wacom ArtPad II reports
832    * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
833    * actually sense tilt. Catch this by noticing that the
834    * orientation axis's azimuth resolution is zero.
835    *
836    * The same is true of the Huion H610PRO, but in this case
837    * it's the altitude resolution that's zero. GdkEvents with
838    * sensible tilts will need both, so only add the GDK tilt axes
839    * if both wintab axes are going to be well-behaved in use.
840    */
841   if ((axes == NULL) ||
842       (axes[0].axResolution == 0) ||
843       (axes[1].axResolution == 0))
844     {
845       axis_data[0] = 0;
846       axis_data[1] = 0;
847       return;
848     }
849 
850   /*
851    * Tested with a Wacom Intuos 5 touch M (PTH-650) + Wacom drivers 6.3.18-5.
852    * Wintab's reference angle leads gdk's by 90 degrees.
853    */
854   az = TWOPI * packet->pkOrientation.orAzimuth /
855     (axes[0].axResolution / 65536.);
856   az -= G_PI / 2;
857   el = TWOPI * packet->pkOrientation.orAltitude /
858     (axes[1].axResolution / 65536.);
859 
860   /* X tilt */
861   axis_data[0] = cos (az) * cos (el) * 1000;
862   /* Y tilt */
863   axis_data[1] = sin (az) * cos (el) * 1000;
864 }
865 
866 /*
867  * Get the currently active keyboard modifiers (ignoring the mouse buttons)
868  * We could use gdk_surface_get_pointer but that function does a lot of other
869  * expensive things besides getting the modifiers. This code is somewhat based
870  * on build_pointer_event_state from gdkevents-win32.c
871  */
872 static guint
get_modifier_key_state(void)873 get_modifier_key_state (void)
874 {
875   guint state;
876 
877   state = 0;
878   /* High-order bit is up/down, low order bit is toggled/untoggled */
879   if (GetKeyState (VK_CONTROL) < 0)
880     state |= GDK_CONTROL_MASK;
881   if (GetKeyState (VK_SHIFT) < 0)
882     state |= GDK_SHIFT_MASK;
883   if (GetKeyState (VK_MENU) < 0)
884     state |= GDK_ALT_MASK;
885   if (GetKeyState (VK_CAPITAL) & 0x1)
886     state |= GDK_LOCK_MASK;
887 
888   return state;
889 }
890 
891 static GdkDeviceWintab *
gdk_device_manager_find_wintab_device(GdkDeviceManagerWin32 * device_manager,HCTX hctx,UINT cursor)892 gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *device_manager,
893                                        HCTX                   hctx,
894                                        UINT                   cursor)
895 {
896   GdkDeviceWintab *device;
897   GList *tmp_list;
898 
899   for (tmp_list = device_manager->wintab_devices; tmp_list != NULL; tmp_list = tmp_list->next)
900     {
901       device = tmp_list->data;
902 
903       if (device->hctx == hctx &&
904           device->cursor == cursor)
905         return device;
906     }
907 
908   return NULL;
909 }
910 
911 GdkEvent *
gdk_wintab_make_event(GdkDisplay * display,MSG * msg,GdkSurface * window)912 gdk_wintab_make_event (GdkDisplay *display,
913                        MSG        *msg,
914                        GdkSurface  *window)
915 {
916   GdkDeviceManagerWin32 *device_manager;
917   GdkDeviceWintab *source_device = NULL;
918   GdkDeviceGrabInfo *last_grab;
919   guint key_state;
920   GdkEvent *event;
921 
922   PACKET packet;
923   int num_axes;
924   double x, y;
925   guint translated_buttons, button_diff, button_mask;
926 
927   GdkEventType event_type;
928   int event_button = 0;
929   GdkModifierType event_state;
930   double event_x, event_y;
931   double *axes;
932 
933   /* Translation from tablet button state to GDK button state for
934    * buttons 1-3 - swap button 2 and 3.
935    */
936   static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
937 
938   if (window != wintab_window)
939     {
940       g_warning ("gdk_wintab_make_event: not wintab_window?");
941       return NULL;
942     }
943 
944   device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
945   window = gdk_device_get_surface_at_position (device_manager->core_pointer, &x, &y);
946 
947   if (window)
948     g_object_ref (window);
949 
950   GDK_NOTE (EVENTS_OR_INPUT,
951 	    g_print ("gdk_wintab_make_event: window=%p %+g%+g\n",
952                window ? GDK_SURFACE_HWND (window) : NULL, x, y));
953 
954   if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
955     {
956       if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
957         return NULL;
958     }
959 
960   switch (msg->message)
961     {
962     case WT_PACKET:
963       source_device = gdk_device_manager_find_wintab_device (device_manager,
964 							     (HCTX) msg->lParam,
965 							     packet.pkCursor);
966 
967       /* Check this first, as we get WT_PROXIMITY for disabled devices too */
968       if (device_manager->dev_entered_proximity > 0)
969 	{
970 	  /* This is the same code as in WT_CSRCHANGE. Some drivers send
971 	   * WT_CSRCHANGE after each WT_PROXIMITY with LOWORD(lParam) != 0,
972 	   * this code is for those that don't.
973 	   */
974 	  device_manager->dev_entered_proximity -= 1;
975 
976 	  if (source_device != NULL &&
977 	      source_device->sends_core)
978 	    {
979 	      _gdk_device_virtual_set_active (device_manager->core_pointer,
980 					      GDK_DEVICE (source_device));
981 	      _gdk_input_ignore_core += 1;
982 	    }
983 	}
984       else if (source_device != NULL &&
985 	       source_device->sends_core &&
986                _gdk_input_ignore_core == 0)
987         {
988           /* A fallback for cases when two devices (disabled and enabled)
989            * were in proximity simultaneously.
990            * In this case the removal of a disabled device would also
991            * make the system pointer active, as we don't know which
992            * device was removed and assume it was the enabled one.
993            * If we are still getting packets for the enabled device,
994            * it means that the device that was removed was the disabled
995            * device, so we must make the enabled device active again and
996            * start ignoring the core pointer events. In practice this means that
997            * removing a disabled device while an enabled device is still
998            * in proximity might briefly make the core pointer active/visible.
999            */
1000 	  _gdk_device_virtual_set_active (device_manager->core_pointer,
1001 					  GDK_DEVICE (source_device));
1002 	  _gdk_input_ignore_core += 1;
1003         }
1004 
1005       if (source_device == NULL)
1006 	return NULL;
1007 
1008       /* Don't produce any button or motion events while a window is being
1009        * moved or resized, see bug #151090.
1010        */
1011       if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
1012         {
1013           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
1014           return NULL;
1015         }
1016 
1017       last_grab = _gdk_display_get_last_device_grab (display, GDK_DEVICE (source_device));
1018 
1019       if (last_grab && last_grab->surface)
1020         {
1021           g_object_unref (window);
1022 
1023           window = g_object_ref (last_grab->surface);
1024         }
1025 
1026       if (window == NULL)
1027         {
1028           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
1029           return NULL;
1030         }
1031 
1032       num_axes = 0;
1033       if (source_device->pktdata & PK_X)
1034         source_device->last_axis_data[num_axes++] = packet.pkX;
1035       if (source_device->pktdata & PK_Y)
1036         source_device->last_axis_data[num_axes++] = packet.pkY;
1037       if (source_device->pktdata & PK_NORMAL_PRESSURE)
1038         source_device->last_axis_data[num_axes++] = packet.pkNormalPressure;
1039       if (source_device->pktdata & PK_ORIENTATION)
1040         {
1041           decode_tilt (source_device->last_axis_data + num_axes,
1042                        source_device->orientation_axes, &packet);
1043           num_axes += 2;
1044         }
1045 
1046       translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
1047 
1048       if (translated_buttons != source_device->button_state)
1049         {
1050           /* At least one button has changed state so produce a button event
1051            * If more than one button has changed state (unlikely),
1052            * just care about the first and act on the next the next time
1053            * we get a packet
1054            */
1055           button_diff = translated_buttons ^ source_device->button_state;
1056 
1057           /* Gdk buttons are numbered 1.. */
1058           event_button = 1;
1059 
1060           for (button_mask = 1; button_mask != 0x80000000;
1061                button_mask <<= 1, event_button++)
1062             {
1063               if (button_diff & button_mask)
1064                 {
1065                   /* Found a button that has changed state */
1066                   break;
1067                 }
1068             }
1069 
1070           if (!(translated_buttons & button_mask))
1071             {
1072               event_type = GDK_BUTTON_RELEASE;
1073             }
1074           else
1075             {
1076               event_type = GDK_BUTTON_PRESS;
1077             }
1078           source_device->button_state ^= button_mask;
1079         }
1080       else
1081         {
1082           event_type = GDK_MOTION_NOTIFY;
1083         }
1084 
1085       key_state = get_modifier_key_state ();
1086       if (event_type == GDK_BUTTON_PRESS ||
1087           event_type == GDK_BUTTON_RELEASE)
1088         {
1089           axes = g_new (double, GDK_AXIS_LAST);
1090 
1091           _gdk_device_wintab_translate_axes (source_device,
1092                                              window,
1093                                              axes,
1094                                              &event_x,
1095                                              &event_y);
1096 
1097           event_state =
1098             key_state | ((source_device->button_state << 8)
1099                          & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1100                             | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1101                             | GDK_BUTTON5_MASK));
1102 
1103           event = gdk_button_event_new (event_type,
1104                                         window,
1105                                         device_manager->core_pointer,
1106                                         NULL,
1107                                         _gdk_win32_get_next_tick (msg->time),
1108                                         event_state,
1109                                         event_button,
1110                                         event_x,
1111                                         event_y,
1112                                         axes);
1113 
1114           GDK_NOTE (EVENTS_OR_INPUT,
1115                     g_print ("WINTAB button %s:%d %g,%g\n",
1116                              (event->event_type == GDK_BUTTON_PRESS ?
1117                               "press" : "release"),
1118                              ((GdkButtonEvent *) event)->button,
1119                              ((GdkButtonEvent *) event)->x,
1120                              ((GdkButtonEvent *) event)->y));
1121         }
1122       else
1123         {
1124           axes = g_new (double, GDK_AXIS_LAST);
1125           _gdk_device_wintab_translate_axes (source_device,
1126                                              window,
1127                                              axes,
1128                                              &event_x,
1129                                              &event_y);
1130 
1131           event_state =
1132             key_state | ((source_device->button_state << 8)
1133                          & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1134                             | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1135                             | GDK_BUTTON5_MASK));
1136 
1137           event = gdk_motion_event_new (window,
1138                                         device_manager->core_pointer,
1139                                         NULL,
1140                                         _gdk_win32_get_next_tick (msg->time),
1141                                         event_state,
1142                                         event_x,
1143                                         event_y,
1144                                         axes);
1145           GDK_NOTE (EVENTS_OR_INPUT,
1146                     g_print ("WINTAB motion: %g,%g\n",
1147                              ((GdkMotionEvent *) event)->x,
1148                              ((GdkMotionEvent *) event)->y));
1149         }
1150       return event;
1151 
1152     case WT_CSRCHANGE:
1153       if (device_manager->dev_entered_proximity > 0)
1154 	device_manager->dev_entered_proximity -= 1;
1155 
1156       if ((source_device = gdk_device_manager_find_wintab_device (device_manager,
1157 								  (HCTX) msg->lParam,
1158 								  packet.pkCursor)) == NULL)
1159 	return NULL;
1160 
1161       if (source_device->sends_core)
1162 	{
1163 	  _gdk_device_virtual_set_active (device_manager->core_pointer,
1164 					  GDK_DEVICE (source_device));
1165 	  _gdk_input_ignore_core += 1;
1166 	}
1167 
1168       return NULL;
1169 
1170     case WT_PROXIMITY:
1171       if (LOWORD (msg->lParam) == 0)
1172         {
1173           if (_gdk_input_ignore_core > 0)
1174             {
1175 	      _gdk_input_ignore_core -= 1;
1176 
1177 	      if (_gdk_input_ignore_core == 0)
1178 		_gdk_device_virtual_set_active (device_manager->core_pointer,
1179 						device_manager->system_pointer);
1180 	    }
1181 	}
1182       else
1183 	{
1184 	  device_manager->dev_entered_proximity += 1;
1185 	}
1186 
1187       return NULL;
1188     }
1189 
1190   return NULL;
1191 }
1192