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