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-winpointer.h"
32 #include "gdkdevice-wintab.h"
33 #include "gdkdisplayprivate.h"
34 #include "gdkdevicetoolprivate.h"
35 #include "gdkseatdefaultprivate.h"
36 
37 #include <tchar.h>
38 #include <tpcshrd.h>
39 #include <hidsdi.h>
40 #include "winpointer.h"
41 
42 #define WINTAB32_DLL "Wintab32.dll"
43 
44 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y  | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_TANGENT_PRESSURE)
45 /* We want everything in absolute mode */
46 #define PACKETMODE (0)
47 #include <pktdef.h>
48 
49 #define DEBUG_WINTAB 1		/* Verbose debug messages enabled */
50 #define TWOPI (2 * G_PI)
51 
52 typedef BOOL
53 (WINAPI *registerPointerDeviceNotifications_t)(HWND window, BOOL notifyRange);
54 typedef BOOL
55 (WINAPI *getPointerDevices_t)(UINT32 *deviceCount, POINTER_DEVICE_INFO *pointerDevices);
56 typedef BOOL
57 (WINAPI *getPointerDeviceCursors_t)(HANDLE device, UINT32 *cursorCount, POINTER_DEVICE_CURSOR_INFO *deviceCursors);
58 typedef BOOL
59 (WINAPI *getPointerDeviceRects_t)(HANDLE device, RECT *pointerDeviceRect, RECT *displayRect);
60 typedef BOOL
61 (WINAPI *getPointerType_t)(UINT32 pointerId, POINTER_INPUT_TYPE *pointerType);
62 typedef BOOL
63 (WINAPI *getPointerCursorId_t)(UINT32 pointerId, UINT32 *cursorId);
64 typedef BOOL
65 (WINAPI *getPointerPenInfo_t)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
66 typedef BOOL
67 (WINAPI *getPointerTouchInfo_t)(UINT32 pointerId, POINTER_TOUCH_INFO *touchInfo);
68 typedef BOOL
69 (WINAPI *getPointerPenInfoHistory_t)(UINT32 pointerId, UINT32 *entriesCount, POINTER_PEN_INFO *penInfo);
70 typedef BOOL
71 (WINAPI *getPointerTouchInfoHistory_t)(UINT32 pointerId, UINT32 *entriesCount, POINTER_TOUCH_INFO *touchInfo);
72 typedef BOOL
73 (WINAPI *setGestureConfig_t)(HWND hwnd, DWORD dwReserved, UINT cIDs, PGESTURECONFIG pGestureConfig, UINT cbSize);
74 typedef BOOL
75 (WINAPI *setWindowFeedbackSetting_t)(HWND hwnd, FEEDBACK_TYPE feedback, DWORD dwFlags, UINT32 size, const VOID *configuration);
76 
77 static registerPointerDeviceNotifications_t registerPointerDeviceNotifications;
78 static getPointerDevices_t getPointerDevices;
79 static getPointerDeviceCursors_t getPointerDeviceCursors;
80 static getPointerDeviceRects_t getPointerDeviceRects;
81 static getPointerType_t getPointerType;
82 static getPointerCursorId_t getPointerCursorId;
83 static getPointerPenInfo_t getPointerPenInfo;
84 static getPointerTouchInfo_t getPointerTouchInfo;
85 static getPointerPenInfoHistory_t getPointerPenInfoHistory;
86 static getPointerTouchInfoHistory_t getPointerTouchInfoHistory;
87 static setGestureConfig_t setGestureConfig;
88 static setWindowFeedbackSetting_t setWindowFeedbackSetting;
89 
90 static ATOM winpointer_notif_window_class;
91 static HWND winpointer_notif_window_handle;
92 
93 static GPtrArray *winpointer_ignored_interactions;
94 
95 static GList     *wintab_contexts = NULL;
96 static GdkWindow *wintab_window = NULL;
97 extern gint       _gdk_input_ignore_core;
98 
99 typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
100 typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
101 typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
102 typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
103 typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
104 typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
105 typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
106 typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
107 typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
108 
109 static t_WTInfoA p_WTInfoA;
110 static t_WTInfoW p_WTInfoW;
111 static t_WTEnable p_WTEnable;
112 static t_WTOpenA p_WTOpenA;
113 static t_WTGetA p_WTGetA;
114 static t_WTSetA p_WTSetA;
115 static t_WTOverlap p_WTOverlap;
116 static t_WTPacket p_WTPacket;
117 static t_WTQueueSizeSet p_WTQueueSizeSet;
118 
119 static gboolean default_display_opened = FALSE;
120 
121 G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, GDK_TYPE_DEVICE_MANAGER)
122 
123 static GdkDeviceWintab *gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *, HCTX, UINT);
124 UINT _wintab_recognize_new_cursors (GdkDeviceManagerWin32 *, HCTX);
125 int _gdk_find_wintab_device_index (HCTX);
126 
127 static GdkDevice *
create_pointer(GdkDeviceManager * device_manager,GType g_type,const char * name,GdkDeviceType type)128 create_pointer (GdkDeviceManager *device_manager,
129 		GType g_type,
130 		const char *name,
131 		GdkDeviceType type)
132 {
133   return g_object_new (g_type,
134                        "name", name,
135                        "type", type,
136                        "input-source", GDK_SOURCE_MOUSE,
137                        "input-mode", GDK_MODE_SCREEN,
138                        "has-cursor", type == GDK_DEVICE_TYPE_MASTER,
139                        "display", gdk_device_manager_get_display (device_manager),
140                        "device-manager", device_manager,
141                        NULL);
142 }
143 
144 static GdkDevice *
create_keyboard(GdkDeviceManager * device_manager,GType g_type,const char * name,GdkDeviceType type)145 create_keyboard (GdkDeviceManager *device_manager,
146 		 GType g_type,
147 		 const char *name,
148 		 GdkDeviceType type)
149 {
150   return g_object_new (g_type,
151                        "name", name,
152                        "type", type,
153                        "input-source", GDK_SOURCE_KEYBOARD,
154                        "input-mode", GDK_MODE_SCREEN,
155                        "has-cursor", FALSE,
156                        "display", gdk_device_manager_get_display (device_manager),
157                        "device-manager", device_manager,
158                        NULL);
159 }
160 
161 static void
gdk_device_manager_win32_init(GdkDeviceManagerWin32 * device_manager_win32)162 gdk_device_manager_win32_init (GdkDeviceManagerWin32 *device_manager_win32)
163 {
164 }
165 
166 static void
gdk_device_manager_win32_finalize(GObject * object)167 gdk_device_manager_win32_finalize (GObject *object)
168 {
169   GdkDeviceManagerWin32 *device_manager_win32;
170 
171   device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (object);
172 
173   g_object_unref (device_manager_win32->core_pointer);
174   g_object_unref (device_manager_win32->core_keyboard);
175 
176   G_OBJECT_CLASS (gdk_device_manager_win32_parent_class)->finalize (object);
177 }
178 
179 static inline double
rect_width(RECT * rect)180 rect_width (RECT *rect)
181 {
182   return rect->right - rect->left;
183 }
184 
185 static inline double
rect_height(RECT * rect)186 rect_height (RECT *rect)
187 {
188   return rect->bottom - rect->top;
189 }
190 
191 static inline gboolean
rect_is_degenerate(RECT * rect)192 rect_is_degenerate (RECT *rect)
193 {
194   return rect_width (rect) == 0 || rect_height (rect) == 0;
195 }
196 
197 static gboolean
winpointer_device_update_scale_factors(GdkDeviceWinpointer * device)198 winpointer_device_update_scale_factors (GdkDeviceWinpointer *device)
199 {
200   RECT device_rect;
201   RECT display_rect;
202 
203   if (!getPointerDeviceRects (device->device_handle, &device_rect, &display_rect))
204     {
205       WIN32_API_FAILED ("GetPointerDeviceRects");
206       return FALSE;
207     }
208 
209   if (rect_is_degenerate (&device_rect))
210     {
211       g_warning ("Invalid coordinates from GetPointerDeviceRects");
212       return FALSE;
213     }
214 
215   device->origin_x = display_rect.left;
216   device->origin_y = display_rect.top;
217   device->scale_x = rect_width (&display_rect) / rect_width (&device_rect);
218   device->scale_y = rect_height (&display_rect) / rect_height (&device_rect);
219 
220   return TRUE;
221 }
222 
223 #define HID_STRING_BYTES_LIMIT 200
224 #define VID_PID_CHARS 4
225 
226 static void
winpointer_get_device_details(HANDLE device,char * vid,char * pid,char ** manufacturer,char ** product)227 winpointer_get_device_details (HANDLE device,
228                                char *vid,
229                                char *pid,
230                                char **manufacturer,
231                                char **product)
232 {
233   RID_DEVICE_INFO info;
234   UINT wchars_count = 0;
235   UINT size = 0;
236 
237   memset (&info, 0, sizeof (info));
238 
239   info.cbSize = sizeof (info);
240   size = sizeof (info);
241 
242   if (GetRawInputDeviceInfoW (device, RIDI_DEVICEINFO, &info, &size) > 0 &&
243       info.dwType == RIM_TYPEHID &&
244       info.hid.dwVendorId > 0 &&
245       info.hid.dwProductId > 0)
246     {
247       const char *format_string = "%0" G_STRINGIFY (VID_PID_CHARS) "x";
248 
249       g_snprintf (vid, VID_PID_CHARS + 1, format_string, (unsigned) info.hid.dwVendorId);
250       g_snprintf (pid, VID_PID_CHARS + 1, format_string, (unsigned) info.hid.dwProductId);
251     }
252 
253   if (GetRawInputDeviceInfoW (device, RIDI_DEVICENAME, NULL, &wchars_count) == 0)
254     {
255       gunichar2 *path = g_new0 (gunichar2, wchars_count);
256 
257       if (GetRawInputDeviceInfoW (device, RIDI_DEVICENAME, path, &wchars_count) > 0)
258         {
259           HANDLE device_file = CreateFileW (path,
260                                             0,
261                                             FILE_SHARE_READ |
262                                             FILE_SHARE_WRITE |
263                                             FILE_SHARE_DELETE,
264                                             NULL,
265                                             OPEN_EXISTING,
266                                             FILE_FLAG_SESSION_AWARE,
267                                             NULL);
268 
269           if (device_file != INVALID_HANDLE_VALUE)
270             {
271               gunichar2 *buffer = g_malloc0 (HID_STRING_BYTES_LIMIT);
272 
273               if (HidD_GetManufacturerString (device_file, buffer, HID_STRING_BYTES_LIMIT))
274                 if (buffer[0])
275                   *manufacturer = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
276 
277               if (HidD_GetProductString (device_file, buffer, HID_STRING_BYTES_LIMIT))
278                 if (buffer[0])
279                   *product = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
280 
281               g_free (buffer);
282               CloseHandle (device_file);
283             }
284         }
285 
286       g_free (path);
287     }
288 }
289 
290 static void
winpointer_create_device(GdkDeviceManagerWin32 * device_manager,POINTER_DEVICE_INFO * info,GdkInputSource source)291 winpointer_create_device (GdkDeviceManagerWin32 *device_manager,
292                           POINTER_DEVICE_INFO *info,
293                           GdkInputSource source)
294 {
295   GdkDisplay *display = NULL;
296   GdkSeat *seat = NULL;
297   GdkDeviceWinpointer *device = NULL;
298   unsigned num_touches = 0;
299   char vid[VID_PID_CHARS + 1];
300   char pid[VID_PID_CHARS + 1];
301   char *manufacturer = NULL;
302   char *product = NULL;
303   char *base_name = NULL;
304   char *name = NULL;
305   UINT32 num_cursors = 0;
306 
307   memset (pid, 0, VID_PID_CHARS + 1);
308   memset (vid, 0, VID_PID_CHARS + 1);
309 
310   g_object_get (device_manager, "display", &display, NULL);
311   seat = gdk_display_get_default_seat (display);
312 
313   if (!getPointerDeviceCursors (info->device, &num_cursors, NULL))
314     {
315       WIN32_API_FAILED ("GetPointerDeviceCursors");
316       return;
317     }
318 
319   if (num_cursors == 0)
320     return;
321 
322   winpointer_get_device_details (info->device, vid, pid, &manufacturer, &product);
323 
324   /* build up the name */
325   if (!manufacturer && vid[0])
326     manufacturer = g_strdup (vid);
327 
328   if (!product && pid[0])
329     product = g_strdup (pid);
330 
331   if (manufacturer && product)
332     base_name = g_strconcat (manufacturer, " ", product, NULL);
333 
334   if (!base_name && info->productString[0])
335     base_name = g_utf16_to_utf8 (info->productString, -1, NULL, NULL, NULL);
336 
337   if (!base_name)
338     base_name = g_strdup ("Unnamed");
339 
340   switch (source)
341     {
342     case GDK_SOURCE_PEN:
343       name = g_strconcat (base_name, " Pen stylus", NULL);
344     break;
345     case GDK_SOURCE_ERASER:
346       name = g_strconcat (base_name, " Eraser", NULL);
347     break;
348     case GDK_SOURCE_TOUCHSCREEN:
349       num_touches = info->maxActiveContacts;
350       name = g_strconcat (base_name, " Finger touch", NULL);
351     break;
352     default:
353       name = g_strdup (base_name);
354     break;
355     }
356 
357   device = g_object_new (GDK_TYPE_DEVICE_WINPOINTER,
358                          "display", display,
359                          "device-manager", device_manager,
360                          "seat", seat,
361                          "type", GDK_DEVICE_TYPE_SLAVE,
362                          "input-mode", GDK_MODE_SCREEN,
363                          "has-cursor", TRUE,
364                          "input-source", source,
365                          "name", name,
366                          "num-touches", num_touches,
367                          "vendor-id", vid[0] ? vid : NULL,
368                          "product-id", pid[0] ? pid : NULL,
369                          NULL);
370 
371   switch (source)
372     {
373     case GDK_SOURCE_PEN:
374     case GDK_SOURCE_ERASER:
375       _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_PRESSURE, 0.0, 1.0, 1.0 / 1024.0);
376       _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_XTILT, -1.0, 1.0, 1.0 / 90.0);
377       _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_YTILT, -1.0, 1.0, 1.0 / 90.0);
378       _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_ROTATION, 0.0, 1.0, 1.0 / 360.0);
379 
380       device->num_axes = 4;
381     break;
382     case GDK_SOURCE_TOUCHSCREEN:
383       _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_PRESSURE, 0.0, 1.0, 1.0 / 1024.0);
384 
385       device->num_axes = 1;
386     break;
387     }
388 
389   device->device_handle = info->device;
390   device->start_cursor_id = info->startingCursorId;
391   device->end_cursor_id = info->startingCursorId + num_cursors - 1;
392 
393   device->last_axis_data = g_new0 (double, device->num_axes);
394 
395   switch (source)
396     {
397     case GDK_SOURCE_PEN:
398       {
399         GdkAxisFlags axes = gdk_device_get_axes (GDK_DEVICE (device));
400         GdkDeviceTool *tool = gdk_device_tool_new (0, 0, GDK_DEVICE_TOOL_TYPE_PEN, axes);
401 
402         gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
403         gdk_device_update_tool (GDK_DEVICE (device), tool);
404       }
405     break;
406     case GDK_SOURCE_ERASER:
407       {
408         GdkAxisFlags axes = gdk_device_get_axes (GDK_DEVICE (device));
409         GdkDeviceTool *tool = gdk_device_tool_new (0, 0, GDK_DEVICE_TOOL_TYPE_ERASER, axes);
410 
411         gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
412         gdk_device_update_tool (GDK_DEVICE (device), tool);
413       }
414     break;
415     case GDK_SOURCE_TOUCHSCREEN:
416     break;
417     }
418 
419   if (!winpointer_device_update_scale_factors (device))
420     {
421       g_set_object (&device, NULL);
422       goto cleanup;
423     }
424 
425   device_manager->winpointer_devices = g_list_append (device_manager->winpointer_devices, device);
426 
427   _gdk_device_set_associated_device (GDK_DEVICE (device), device_manager->core_pointer);
428   _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
429 
430   gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
431 
432   g_signal_emit_by_name (device_manager, "device-added", device);
433 
434 cleanup:
435   g_free (name);
436   g_free (base_name);
437   g_free (product);
438   g_free (manufacturer);
439 }
440 
441 static void
winpointer_create_devices(GdkDeviceManagerWin32 * device_manager,POINTER_DEVICE_INFO * info)442 winpointer_create_devices (GdkDeviceManagerWin32 *device_manager,
443                            POINTER_DEVICE_INFO *info)
444 {
445   switch (info->pointerDeviceType)
446     {
447     case POINTER_DEVICE_TYPE_INTEGRATED_PEN:
448     case POINTER_DEVICE_TYPE_EXTERNAL_PEN:
449       winpointer_create_device (device_manager, info, GDK_SOURCE_PEN);
450       winpointer_create_device (device_manager, info, GDK_SOURCE_ERASER);
451     break;
452     case POINTER_DEVICE_TYPE_TOUCH:
453       winpointer_create_device (device_manager, info, GDK_SOURCE_TOUCHSCREEN);
454     break;
455     }
456 }
457 
458 static gboolean
winpointer_match_device_in_system_list(GdkDeviceWinpointer * device,POINTER_DEVICE_INFO * infos,UINT32 infos_count)459 winpointer_match_device_in_system_list (GdkDeviceWinpointer *device,
460                                         POINTER_DEVICE_INFO *infos,
461                                         UINT32 infos_count)
462 {
463   UINT32 i = 0;
464 
465   for (i = 0; i < infos_count; i++)
466     {
467       if (device->device_handle == infos[i].device &&
468           device->start_cursor_id == infos[i].startingCursorId)
469         return TRUE;
470     }
471 
472   return FALSE;
473 }
474 
475 static gboolean
winpointer_match_system_device_in_device_manager(GdkDeviceManagerWin32 * device_manager,POINTER_DEVICE_INFO * info)476 winpointer_match_system_device_in_device_manager (GdkDeviceManagerWin32 *device_manager,
477                                                   POINTER_DEVICE_INFO *info)
478 {
479   GList *l = NULL;
480 
481   for (l = device_manager->winpointer_devices; l; l = l->next)
482     {
483       GdkDeviceWinpointer *device = GDK_DEVICE_WINPOINTER (l->data);
484 
485       if (device->device_handle == info->device &&
486           device->start_cursor_id == info->startingCursorId)
487         return TRUE;
488     }
489 
490   return FALSE;
491 }
492 
493 static void
winpointer_enumerate_devices(GdkDeviceManagerWin32 * device_manager)494 winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager)
495 {
496   POINTER_DEVICE_INFO *infos = NULL;
497   UINT32 infos_count = 0;
498   UINT32 i = 0;
499   GList *current = NULL;
500 
501   do
502     {
503       infos = g_new0 (POINTER_DEVICE_INFO, infos_count);
504       if (!getPointerDevices (&infos_count, infos))
505         {
506           WIN32_API_FAILED ("GetPointerDevices");
507           g_free (infos);
508           return;
509         }
510     }
511   while (infos_count > 0 && !infos);
512 
513   /* remove any gdk device not present anymore or update info */
514   current = device_manager->winpointer_devices;
515   while (current != NULL)
516     {
517       GdkDeviceWinpointer *device = GDK_DEVICE_WINPOINTER (current->data);
518       GList *next = current->next;
519 
520       if (!winpointer_match_device_in_system_list (device, infos, infos_count))
521         {
522           GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (device));
523 
524           gdk_device_update_tool (GDK_DEVICE (device), NULL);
525           gdk_seat_default_remove_tool (GDK_SEAT_DEFAULT (seat), (GDK_DEVICE (device))->last_tool);
526 
527           gdk_seat_default_remove_slave (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device));
528           device_manager->winpointer_devices = g_list_delete_link (device_manager->winpointer_devices,
529                                                                    current);
530           g_signal_emit_by_name (device_manager, "device-removed", device);
531 
532           _gdk_device_set_associated_device (GDK_DEVICE (device), NULL);
533           _gdk_device_remove_slave (device_manager->core_pointer, GDK_DEVICE (device));
534 
535           g_object_unref (device);
536         }
537       else
538         winpointer_device_update_scale_factors (device);
539 
540       current = next;
541     }
542 
543   /* create new gdk devices */
544   for (i = 0; i < infos_count; i++)
545     if (!winpointer_match_system_device_in_device_manager (device_manager,
546                                                            &infos[i]))
547       winpointer_create_devices (device_manager, &infos[i]);
548 
549   g_free (infos);
550 }
551 
552 static LRESULT CALLBACK
winpointer_notif_window_proc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)553 winpointer_notif_window_proc (HWND hWnd,
554                               UINT uMsg,
555                               WPARAM wParam,
556                               LPARAM lParam)
557 {
558   switch (uMsg)
559     {
560     case WM_POINTERDEVICECHANGE:
561       {
562         LONG_PTR user_data = GetWindowLongPtrW (hWnd, GWLP_USERDATA);
563         GdkDeviceManagerWin32 *device_manager = GDK_DEVICE_MANAGER_WIN32 (user_data);
564 
565         winpointer_enumerate_devices (device_manager);
566       }
567     return 0;
568     }
569 
570   return DefWindowProcW (hWnd, uMsg, wParam, lParam);
571 }
572 
573 static gboolean
winpointer_notif_window_create()574 winpointer_notif_window_create ()
575 {
576   WNDCLASSEXW wndclass;
577 
578   memset (&wndclass, 0, sizeof (wndclass));
579   wndclass.cbSize = sizeof (wndclass);
580   wndclass.lpszClassName = L"GdkWin32WinPointerNotificationsWindowClass";
581   wndclass.lpfnWndProc = winpointer_notif_window_proc;
582   wndclass.hInstance = _gdk_dll_hinstance;
583 
584   if ((winpointer_notif_window_class = RegisterClassExW (&wndclass)) == 0)
585     {
586       WIN32_API_FAILED ("RegisterClassExW");
587       return FALSE;
588     }
589 
590   if (!(winpointer_notif_window_handle = CreateWindowExW (0,
591                                                           (LPCWSTR) winpointer_notif_window_class,
592                                                           L"GdkWin32 WinPointer Notifications",
593                                                           0,
594                                                           0, 0, 0, 0,
595                                                           HWND_MESSAGE,
596                                                           NULL,
597                                                           _gdk_dll_hinstance,
598                                                           NULL)))
599     {
600       WIN32_API_FAILED ("CreateWindowExW");
601       return FALSE;
602     }
603 
604   return TRUE;
605 }
606 
607 static gboolean
winpointer_ensure_procedures()608 winpointer_ensure_procedures ()
609 {
610   static HMODULE user32_dll = NULL;
611 
612   if (!user32_dll)
613     {
614       user32_dll = LoadLibraryW (L"user32.dll");
615       if (!user32_dll)
616         {
617           WIN32_API_FAILED ("LoadLibraryW");
618           return FALSE;
619         }
620 
621       registerPointerDeviceNotifications = (registerPointerDeviceNotifications_t)
622         GetProcAddress (user32_dll, "RegisterPointerDeviceNotifications");
623       getPointerDevices = (getPointerDevices_t)
624         GetProcAddress (user32_dll, "GetPointerDevices");
625       getPointerDeviceCursors = (getPointerDeviceCursors_t)
626         GetProcAddress (user32_dll, "GetPointerDeviceCursors");
627       getPointerDeviceRects = (getPointerDeviceRects_t)
628         GetProcAddress (user32_dll, "GetPointerDeviceRects");
629       getPointerType = (getPointerType_t)
630         GetProcAddress (user32_dll, "GetPointerType");
631       getPointerCursorId = (getPointerCursorId_t)
632         GetProcAddress (user32_dll, "GetPointerCursorId");
633       getPointerPenInfo = (getPointerPenInfo_t)
634         GetProcAddress (user32_dll, "GetPointerPenInfo");
635       getPointerTouchInfo = (getPointerTouchInfo_t)
636         GetProcAddress (user32_dll, "GetPointerTouchInfo");
637       getPointerPenInfoHistory = (getPointerPenInfoHistory_t)
638         GetProcAddress (user32_dll, "GetPointerPenInfoHistory");
639       getPointerTouchInfoHistory = (getPointerTouchInfoHistory_t)
640         GetProcAddress (user32_dll, "GetPointerTouchInfoHistory");
641       setGestureConfig = (setGestureConfig_t)
642         GetProcAddress (user32_dll, "SetGestureConfig");
643       setWindowFeedbackSetting = (setWindowFeedbackSetting_t)
644         GetProcAddress (user32_dll, "SetWindowFeedbackSetting");
645     }
646 
647   return registerPointerDeviceNotifications &&
648          getPointerDevices &&
649          getPointerDeviceCursors &&
650          getPointerDeviceRects &&
651          getPointerType &&
652          getPointerCursorId &&
653          getPointerPenInfo &&
654          getPointerTouchInfo &&
655          getPointerPenInfoHistory &&
656          getPointerTouchInfoHistory &&
657          setGestureConfig;
658 }
659 
660 static gboolean
winpointer_initialize(GdkDeviceManagerWin32 * device_manager)661 winpointer_initialize (GdkDeviceManagerWin32 *device_manager)
662 {
663   if (!winpointer_ensure_procedures ())
664     return FALSE;
665 
666   if (!winpointer_notif_window_create ())
667     return FALSE;
668 
669   /* associate device_manager with the window */
670   SetLastError (0);
671   if (SetWindowLongPtrW (winpointer_notif_window_handle,
672                          GWLP_USERDATA,
673                          (LONG_PTR) device_manager) == 0
674       && GetLastError () != 0)
675     {
676       WIN32_API_FAILED ("SetWindowLongPtrW");
677       return FALSE;
678     }
679 
680   if (!registerPointerDeviceNotifications (winpointer_notif_window_handle, FALSE))
681     {
682       WIN32_API_FAILED ("RegisterPointerDeviceNotifications");
683       return FALSE;
684     }
685 
686   winpointer_ignored_interactions = g_ptr_array_new ();
687 
688   winpointer_enumerate_devices (device_manager);
689 
690   return TRUE;
691 }
692 
693 void
gdk_winpointer_initialize_window(GdkWindow * window)694 gdk_winpointer_initialize_window (GdkWindow *window)
695 {
696   HWND hwnd = GDK_WINDOW_HWND (window);
697   ATOM key = 0;
698   HANDLE val = (HANDLE)(TABLET_DISABLE_PRESSANDHOLD |
699                         TABLET_DISABLE_PENTAPFEEDBACK |
700                         TABLET_DISABLE_PENBARRELFEEDBACK |
701                         TABLET_DISABLE_FLICKS |
702                         TABLET_DISABLE_FLICKFALLBACKKEYS);
703 
704   winpointer_ensure_procedures ();
705 
706   key = GlobalAddAtom (MICROSOFT_TABLETPENSERVICE_PROPERTY);
707   API_CALL (SetPropW, (hwnd, (LPCWSTR) key, val));
708   GlobalDeleteAtom (key);
709 
710   if (setGestureConfig != NULL)
711     {
712       GESTURECONFIG gesture_config;
713       memset (&gesture_config, 0, sizeof (gesture_config));
714 
715       gesture_config.dwID = 0;
716       gesture_config.dwWant = 0;
717       gesture_config.dwBlock = GC_ALLGESTURES;
718 
719       API_CALL (setGestureConfig, (hwnd, 0, 1, &gesture_config, sizeof (gesture_config)));
720     }
721 
722   if (setWindowFeedbackSetting != NULL)
723     {
724       FEEDBACK_TYPE feedbacks[] = {
725         FEEDBACK_TOUCH_CONTACTVISUALIZATION,
726         FEEDBACK_PEN_BARRELVISUALIZATION,
727         FEEDBACK_PEN_TAP,
728         FEEDBACK_PEN_DOUBLETAP,
729         FEEDBACK_PEN_PRESSANDHOLD,
730         FEEDBACK_PEN_RIGHTTAP,
731         FEEDBACK_TOUCH_TAP,
732         FEEDBACK_TOUCH_DOUBLETAP,
733         FEEDBACK_TOUCH_PRESSANDHOLD,
734         FEEDBACK_TOUCH_RIGHTTAP,
735         FEEDBACK_GESTURE_PRESSANDTAP
736       };
737       gsize i = 0;
738 
739       for (i = 0; i < G_N_ELEMENTS (feedbacks); i++)
740         {
741           BOOL setting = FALSE;
742 
743           API_CALL (setWindowFeedbackSetting, (hwnd, feedbacks[i], 0, sizeof (BOOL), &setting));
744         }
745     }
746 }
747 
748 void
gdk_winpointer_finalize_window(GdkWindow * window)749 gdk_winpointer_finalize_window (GdkWindow *window)
750 {
751   HWND hwnd = GDK_WINDOW_HWND (window);
752   ATOM key = 0;
753 
754   key = GlobalAddAtom (MICROSOFT_TABLETPENSERVICE_PROPERTY);
755   RemovePropW (hwnd, (LPCWSTR) key);
756   GlobalDeleteAtom (key);
757 }
758 
759 #if DEBUG_WINTAB
760 
761 static void
print_lc(LOGCONTEXT * lc)762 print_lc(LOGCONTEXT *lc)
763 {
764   g_print ("lcName = %s\n", lc->lcName);
765   g_print ("lcOptions =");
766   if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
767   if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
768   if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
769   if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
770   if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
771   if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
772   g_print ("\n");
773   g_print ("lcStatus =");
774   if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
775   if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
776   if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
777   g_print ("\n");
778   g_print ("lcLocks =");
779   if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
780   if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
781   if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
782   if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
783   g_print ("\n");
784   g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
785 	  lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
786   g_print ("lcPktData =");
787   if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
788   if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
789   if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
790   if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
791   if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
792   if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
793   if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
794   if (lc->lcPktData & PK_X) g_print (" PK_X");
795   if (lc->lcPktData & PK_Y) g_print (" PK_Y");
796   if (lc->lcPktData & PK_Z) g_print (" PK_Z");
797   if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
798   if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
799   if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
800   if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
801   g_print ("\n");
802   g_print ("lcPktMode =");
803   if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
804   if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
805   if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
806   if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
807   if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
808   if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
809   if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
810   if (lc->lcPktMode & PK_X) g_print (" PK_X");
811   if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
812   if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
813   if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
814   if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
815   if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
816   if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
817   g_print ("\n");
818   g_print ("lcMoveMask =");
819   if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
820   if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
821   if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
822   if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
823   if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
824   if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
825   if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
826   if (lc->lcMoveMask & PK_X) g_print (" PK_X");
827   if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
828   if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
829   if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
830   if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
831   if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
832   if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
833   g_print ("\n");
834   g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
835 	  (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
836   g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
837 	  lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
838   g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
839 	  lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
840   g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
841 	  lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
842   g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
843 	  lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
844   g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
845 	  lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
846   g_print ("lcSysMode = %d\n", lc->lcSysMode);
847   g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
848 	  lc->lcSysOrgX, lc->lcSysOrgY);
849   g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
850 	  lc->lcSysExtX, lc->lcSysExtY);
851   g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
852 	  lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
853 }
854 
855 static void
print_cursor(int index)856 print_cursor (int index)
857 {
858   int size;
859   int i;
860   char *name;
861   BOOL active;
862   WTPKT wtpkt;
863   BYTE buttons;
864   BYTE buttonbits;
865   char *btnnames;
866   char *p;
867   BYTE buttonmap[32];
868   BYTE sysbtnmap[32];
869   BYTE npbutton;
870   UINT npbtnmarks[2];
871   UINT *npresponse;
872   BYTE tpbutton;
873   UINT tpbtnmarks[2];
874   UINT *tpresponse;
875   DWORD physid;
876   UINT mode;
877   UINT minpktdata;
878   UINT minbuttons;
879   UINT capabilities;
880 
881   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
882   name = g_malloc (size + 1);
883   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
884   g_print ("NAME: %s\n", name);
885   (*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
886   g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
887   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
888   g_print ("PKTDATA: %#x:", (guint) wtpkt);
889 #define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
890   BIT (CONTEXT);
891   BIT (STATUS);
892   BIT (TIME);
893   BIT (CHANGED);
894   BIT (SERIAL_NUMBER);
895   BIT (BUTTONS);
896   BIT (X);
897   BIT (Y);
898   BIT (Z);
899   BIT (NORMAL_PRESSURE);
900   BIT (TANGENT_PRESSURE);
901   BIT (ORIENTATION);
902   BIT (ROTATION);
903 #undef BIT
904   g_print ("\n");
905   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
906   g_print ("BUTTONS: %d\n", buttons);
907   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
908   g_print ("BUTTONBITS: %d\n", buttonbits);
909   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
910   g_print ("BTNNAMES:");
911   if (size > 0)
912     {
913       btnnames = g_malloc (size + 1);
914       (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
915       p = btnnames;
916       while (*p)
917         {
918           g_print (" %s", p);
919           p += strlen (p) + 1;
920         }
921     }
922   g_print ("\n");
923   (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
924   g_print ("BUTTONMAP:");
925   for (i = 0; i < buttons; i++)
926     g_print (" %d", buttonmap[i]);
927   g_print ("\n");
928   (*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
929   g_print ("SYSBTNMAP:");
930   for (i = 0; i < buttons; i++)
931     g_print (" %d", sysbtnmap[i]);
932   g_print ("\n");
933   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
934   g_print ("NPBUTTON: %d\n", npbutton);
935   (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
936   g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
937   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
938   g_print ("NPRESPONSE:");
939   if (size > 0)
940     {
941       npresponse = g_malloc (size);
942       (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
943       for (i = 0; i < size / sizeof (UINT); i++)
944         g_print (" %d", npresponse[i]);
945     }
946   g_print ("\n");
947   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
948   g_print ("TPBUTTON: %d\n", tpbutton);
949   (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
950   g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
951   size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
952   g_print ("TPRESPONSE:");
953   if (size > 0)
954     {
955       tpresponse = g_malloc (size);
956       (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
957       for (i = 0; i < size / sizeof (UINT); i++)
958         g_print (" %d", tpresponse[i]);
959     }
960   g_print ("\n");
961   (*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
962   g_print ("PHYSID: %#x\n", (guint) physid);
963   (*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
964   g_print ("CAPABILITIES: %#x:", capabilities);
965 #define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
966   BIT (MULTIMODE);
967   BIT (AGGREGATE);
968   BIT (INVERT);
969 #undef BIT
970   g_print ("\n");
971   if (capabilities & CRC_MULTIMODE)
972     {
973       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
974       g_print ("MODE: %d\n", mode);
975     }
976   if (capabilities & CRC_AGGREGATE)
977     {
978       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
979       g_print ("MINPKTDATA: %d\n", minpktdata);
980       (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
981       g_print ("MINBUTTONS: %d\n", minbuttons);
982     }
983 }
984 #endif
985 
986 static void
wintab_init_check(GdkDeviceManagerWin32 * device_manager)987 wintab_init_check (GdkDeviceManagerWin32 *device_manager)
988 {
989   GdkDisplay *display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
990   GdkWindow *root = gdk_screen_get_root_window (gdk_display_get_default_screen (display));
991   static gboolean wintab_initialized = FALSE;
992   GdkWindowAttr wa;
993   WORD specversion;
994   HCTX *hctx;
995   UINT ndevices, ncursors;
996   UINT devix;
997   AXIS axis_x, axis_y;
998   int i;
999   wchar_t devname[100];
1000   gchar *devname_utf8;
1001   BOOL defcontext_done;
1002   HMODULE wintab32;
1003   char *wintab32_dll_path;
1004   char dummy;
1005   int n, k;
1006 
1007   if (wintab_initialized)
1008     return;
1009 
1010   wintab_initialized = TRUE;
1011 
1012   wintab_contexts = NULL;
1013 
1014   n = GetSystemDirectory (&dummy, 0);
1015 
1016   if (n <= 0)
1017     return;
1018 
1019   wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
1020   k = GetSystemDirectory (wintab32_dll_path, n);
1021 
1022   if (k == 0 || k > n)
1023     {
1024       g_free (wintab32_dll_path);
1025       return;
1026     }
1027 
1028   if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
1029     strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
1030   strcat (wintab32_dll_path, WINTAB32_DLL);
1031 
1032   if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
1033     return;
1034 
1035   if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
1036     return;
1037   if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
1038     return;
1039   if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
1040     return;
1041   if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
1042     return;
1043   if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
1044     return;
1045   if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
1046     return;
1047   if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
1048     return;
1049   if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
1050     return;
1051   if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
1052     return;
1053 
1054   if (!(*p_WTInfoA) (0, 0, NULL))
1055     return;
1056 
1057   (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
1058   GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
1059 			    HIBYTE (specversion), LOBYTE (specversion)));
1060   (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
1061   (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
1062 #if DEBUG_WINTAB
1063   GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
1064 			    ndevices, ncursors));
1065 #endif
1066   /* Create a dummy window to receive wintab events */
1067   wa.wclass = GDK_INPUT_OUTPUT;
1068   wa.event_mask = GDK_ALL_EVENTS_MASK;
1069   wa.width = 2;
1070   wa.height = 2;
1071   wa.x = -100;
1072   wa.y = -100;
1073   wa.window_type = GDK_WINDOW_TOPLEVEL;
1074   if ((wintab_window = gdk_window_new (root, &wa, GDK_WA_X | GDK_WA_Y)) == NULL)
1075     {
1076       g_warning ("gdk_input_wintab_init: gdk_window_new failed");
1077       return;
1078     }
1079   g_object_ref (wintab_window);
1080 
1081   for (devix = 0; devix < ndevices; devix++)
1082     {
1083       LOGCONTEXT lc;
1084 
1085       /* We open the Wintab device (hmm, what if there are several, or
1086        * can there even be several, probably not?) as a system
1087        * pointing device, i.e. it controls the normal Windows
1088        * cursor. This seems much more natural.
1089        */
1090 
1091       (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
1092       devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
1093 #ifdef DEBUG_WINTAB
1094       GDK_NOTE (INPUT, (g_print("Device %u: %s\n", devix, devname_utf8)));
1095 #endif
1096       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
1097       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
1098 
1099       defcontext_done = FALSE;
1100       if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
1101         {
1102           /* Try to get device-specific default context */
1103           /* Some drivers, e.g. Aiptek, don't provide this info */
1104           if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
1105             defcontext_done = TRUE;
1106 #if DEBUG_WINTAB
1107           if (defcontext_done)
1108             GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
1109           else
1110             GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
1111 #endif
1112         }
1113 
1114       if (!defcontext_done)
1115         (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
1116 #if DEBUG_WINTAB
1117       GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
1118 #endif
1119       lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
1120       lc.lcStatus = 0;
1121       lc.lcMsgBase = WT_DEFBASE;
1122       lc.lcPktRate = 0;
1123       lc.lcPktData = PACKETDATA;
1124       lc.lcPktMode = PACKETMODE;
1125       lc.lcMoveMask = PACKETDATA;
1126       lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
1127       lc.lcOutOrgX = axis_x.axMin;
1128       lc.lcOutOrgY = axis_y.axMin;
1129       lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
1130       lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
1131       lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
1132 #if DEBUG_WINTAB
1133       GDK_NOTE (INPUT, (g_print("context for device %u:\n", devix),
1134 			print_lc(&lc)));
1135 #endif
1136       hctx = g_new (HCTX, 1);
1137       if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
1138         {
1139           g_warning ("gdk_input_wintab_init: WTOpen failed");
1140           return;
1141         }
1142       GDK_NOTE (INPUT, g_print ("opened Wintab device %u %p\n",
1143                                 devix, *hctx));
1144 
1145       wintab_contexts = g_list_append (wintab_contexts, hctx);
1146 
1147       /* Set the CXO_SYSTEM flag */
1148       if (!(lc.lcOptions & CXO_SYSTEM))
1149         {
1150           lc.lcOptions |= CXO_SYSTEM;
1151           if (!p_WTSetA (*hctx, &lc))
1152             g_warning ("Could not set the CXO_SYSTEM option in the WINTAB context");
1153         }
1154 
1155       (*p_WTOverlap) (*hctx, TRUE);
1156 
1157 #if DEBUG_WINTAB
1158       GDK_NOTE (INPUT, (g_print("context for device %u after WTOpen:\n", devix),
1159 			print_lc(&lc)));
1160 #endif
1161       /* Increase packet queue size to reduce the risk of lost packets.
1162        * According to the specs, if the function fails we must try again
1163        * with a smaller queue size.
1164        */
1165       GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
1166       for (i = 128; i >= 1; i >>= 1)
1167         {
1168           if ((*p_WTQueueSizeSet) (*hctx, i))
1169             {
1170               GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
1171               break;
1172             }
1173         }
1174       if (!i)
1175         GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
1176 
1177       /* Get the cursors that Wintab is currently aware of */
1178       _wintab_recognize_new_cursors(device_manager, *hctx);
1179     }
1180 }
1181 
1182 UINT
_wintab_recognize_new_cursors(GdkDeviceManagerWin32 * device_manager,HCTX hctx)1183 _wintab_recognize_new_cursors (GdkDeviceManagerWin32 *device_manager,
1184                                HCTX                  hctx)
1185 {
1186   GdkDisplay *display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
1187   int devix;
1188   wchar_t devname[100], csrname[100];
1189   gchar *devname_utf8, *csrname_utf8, *device_name;
1190   UINT ncsrtypes, firstcsr, cursorix;
1191   BOOL active;
1192   DWORD physid;
1193   AXIS axis_x, axis_y, axis_npressure, axis_or[3], axis_tpressure;
1194   GdkDeviceWintab *device;
1195   LOGCONTEXT lc;
1196   int num_axes;
1197   UINT num_new_cursors = 0;
1198 
1199   devix = _gdk_find_wintab_device_index(hctx);
1200   if (devix == -1)
1201     return num_new_cursors;
1202 
1203   (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
1204   devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
1205 #ifdef DEBUG_WINTAB
1206   GDK_NOTE (INPUT, (g_print("Finding cursors for device %u: %s\n", devix, devname_utf8)));
1207 #endif
1208 
1209   (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
1210   (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
1211   for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
1212     {
1213 #ifdef DEBUG_WINTAB
1214       GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (cursorix)));
1215 #endif
1216       /* Skip cursors that are already known to us */
1217       if (gdk_device_manager_find_wintab_device(device_manager, hctx, cursorix) != NULL)
1218         continue;
1219 
1220       active = FALSE;
1221       (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
1222       if (!active)
1223         continue;
1224 
1225       /* Wacom tablets iterate through all possible cursors,
1226        * even if the cursor's presence has not been recognized.
1227        * Unrecognized cursors have a physid of zero and are ignored.
1228        * Recognized cursors have a non-zero physid and we create a
1229        * Wintab device object for each of them.
1230        */
1231       (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
1232       if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
1233         continue;
1234 
1235       if (!(*p_WTGetA) (hctx, &lc))
1236         {
1237           g_warning ("wintab_recognize_new_cursors: Failed to retrieve device LOGCONTEXT");
1238           continue;
1239         }
1240 
1241       /* Create a Wintab device for this cursor */
1242       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
1243       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
1244       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
1245       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
1246       (*p_WTInfoA) (WTI_DEVICES + devix, DVC_TPRESSURE, &axis_tpressure);
1247       (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
1248       csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
1249       device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
1250       g_free (csrname_utf8);
1251 
1252       device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
1253                               "name", device_name,
1254                               "type", GDK_DEVICE_TYPE_FLOATING,
1255                               "input-source", GDK_SOURCE_PEN,
1256                               "input-mode", GDK_MODE_SCREEN,
1257                               "has-cursor", lc.lcOptions & CXO_SYSTEM,
1258                               "display", display,
1259                               "device-manager", device_manager,
1260                               NULL);
1261 
1262       device->sends_core = lc.lcOptions & CXO_SYSTEM;
1263       if (device->sends_core)
1264         {
1265           _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device));
1266           _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
1267         }
1268 
1269       device->hctx = hctx;
1270       device->cursor = cursorix;
1271       (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
1272       num_axes = 0;
1273 
1274       if (device->pktdata & PK_X)
1275         {
1276           _gdk_device_add_axis (GDK_DEVICE (device),
1277                                 GDK_NONE,
1278                                 GDK_AXIS_X,
1279                                 axis_x.axMin,
1280                                 axis_x.axMax,
1281                                 axis_x.axResolution / 65535);
1282           num_axes++;
1283         }
1284 
1285       if (device->pktdata & PK_Y)
1286         {
1287           _gdk_device_add_axis (GDK_DEVICE (device),
1288                                 GDK_NONE,
1289                                 GDK_AXIS_Y,
1290                                 axis_y.axMin,
1291                                 axis_y.axMax,
1292                                 axis_y.axResolution / 65535);
1293           num_axes++;
1294         }
1295 
1296       if (device->pktdata & PK_NORMAL_PRESSURE)
1297         {
1298           _gdk_device_add_axis (GDK_DEVICE (device),
1299                                 GDK_NONE,
1300                                 GDK_AXIS_PRESSURE,
1301                                 axis_npressure.axMin,
1302                                 axis_npressure.axMax,
1303                                 axis_npressure.axResolution / 65535);
1304           num_axes++;
1305         }
1306 
1307       if (device->pktdata & PK_ORIENTATION)
1308         {
1309           if (device->pktdata & PK_TANGENT_PRESSURE) /* If we have a wheel, disable the twist axis */
1310             axis_or[2].axResolution = 0;
1311 
1312           device->orientation_axes[0] = axis_or[0];
1313           device->orientation_axes[1] = axis_or[1];
1314           device->orientation_axes[2] = axis_or[2];
1315 
1316           /* Wintab gives us azimuth and altitude, which
1317            * we convert to x and y tilt in the -1000..1000 range
1318            */
1319           _gdk_device_add_axis (GDK_DEVICE (device),
1320                                 GDK_NONE,
1321                                 GDK_AXIS_XTILT,
1322                                 -1000,
1323                                 1000,
1324                                 1000);
1325 
1326           _gdk_device_add_axis (GDK_DEVICE (device),
1327                                 GDK_NONE,
1328                                 GDK_AXIS_YTILT,
1329                                 -1000,
1330                                 1000,
1331                                 1000);
1332           num_axes += 2;
1333 
1334           if (axis_or[2].axResolution != 0) /* If twist is present */
1335             {
1336               /* Wacom's Wintab driver returns the rotation
1337                * of an Art Pen as the orientation twist value.
1338                * We're using GDK_AXIS_WHEEL as it's actually
1339                * called Wheel/Rotation to the user.
1340                * axMin and axMax are back to front on purpose. If you put them
1341                * the "correct" way round, rotation will be flipped!
1342                */
1343                _gdk_device_add_axis (GDK_DEVICE (device),
1344                                      GDK_NONE,
1345                                      GDK_AXIS_WHEEL,
1346                                      axis_or[2].axMax,
1347                                      axis_or[2].axMin,
1348                                      axis_or[2].axResolution / 65535);
1349               num_axes++;
1350             }
1351         }
1352 
1353       if (device->pktdata & PK_TANGENT_PRESSURE)
1354         {
1355           /* This is the finger wheel on a Wacom Airbrush
1356            */
1357           _gdk_device_add_axis (GDK_DEVICE (device),
1358                                 GDK_NONE,
1359                                 GDK_AXIS_WHEEL,
1360                                 axis_tpressure.axMin,
1361                                 axis_tpressure.axMax,
1362                                 axis_tpressure.axResolution / 65535);
1363           num_axes++;
1364         }
1365 
1366       device->last_axis_data = g_new (gint, num_axes);
1367 
1368       GDK_NOTE (INPUT, g_print ("device: (%u) %s axes: %d\n",
1369                                 cursorix,
1370                                 device_name,
1371                                 num_axes));
1372 
1373 #if 0
1374       for (i = 0; i < gdkdev->info.num_axes; i++)
1375         GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
1376                                   i,
1377                                   gdkdev->axes[i].min_value,
1378                                   gdkdev->axes[i].max_value,
1379                                   gdkdev->axes[i].resolution));
1380 #endif
1381 
1382       device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
1383                                                       device);
1384       num_new_cursors++;
1385       g_free (device_name);
1386     }
1387   g_free (devname_utf8);
1388   return num_new_cursors;
1389 }
1390 
1391 /* Only initialize Wintab after the default display is set for
1392  * the first time. WTOpenA() executes code beyond our control,
1393  * and it can cause messages to be sent to the application even
1394  * before a window is opened. GDK has to be in a fit state to
1395  * handle them when they come.
1396  *
1397  * https://bugzilla.gnome.org/show_bug.cgi?id=774379
1398  */
1399 static void
wintab_default_display_notify_cb(GdkDisplayManager * display_manager)1400 wintab_default_display_notify_cb (GdkDisplayManager *display_manager)
1401 {
1402   GdkDeviceManagerWin32 *device_manager = NULL;
1403   GdkDisplay *display = gdk_display_get_default();
1404 
1405   if (default_display_opened)
1406     return;
1407 
1408   g_assert (display != NULL);
1409 
1410 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1411   device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
1412 G_GNUC_END_IGNORE_DEPRECATIONS;
1413   g_assert (display_manager != NULL);
1414 
1415   default_display_opened = TRUE;
1416   GDK_NOTE (INPUT, g_print ("wintab init: doing delayed initialization\n"));
1417   wintab_init_check (device_manager);
1418 }
1419 
1420 static void
gdk_device_manager_win32_constructed(GObject * object)1421 gdk_device_manager_win32_constructed (GObject *object)
1422 {
1423   GdkDeviceManagerWin32 *device_manager;
1424   GdkSeat *seat;
1425   GdkDisplayManager *display_manager = NULL;
1426   GdkDisplay *default_display = NULL;
1427   const char *tablet_input_api_user_preference = NULL;
1428   gboolean have_tablet_input_api_preference = FALSE;
1429 
1430   device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
1431   device_manager->core_pointer =
1432     create_pointer (GDK_DEVICE_MANAGER (device_manager),
1433 		    GDK_TYPE_DEVICE_VIRTUAL,
1434 		    "Virtual Core Pointer",
1435 		    GDK_DEVICE_TYPE_MASTER);
1436   device_manager->system_pointer =
1437     create_pointer (GDK_DEVICE_MANAGER (device_manager),
1438 		    GDK_TYPE_DEVICE_WIN32,
1439 		    "System Aggregated Pointer",
1440 		    GDK_DEVICE_TYPE_SLAVE);
1441   _gdk_device_virtual_set_active (device_manager->core_pointer,
1442 				  device_manager->system_pointer);
1443   _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
1444   _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer);
1445 
1446   device_manager->core_keyboard =
1447     create_keyboard (GDK_DEVICE_MANAGER (device_manager),
1448 		     GDK_TYPE_DEVICE_VIRTUAL,
1449 		     "Virtual Core Keyboard",
1450 		     GDK_DEVICE_TYPE_MASTER);
1451   device_manager->system_keyboard =
1452     create_keyboard (GDK_DEVICE_MANAGER (device_manager),
1453 		    GDK_TYPE_DEVICE_WIN32,
1454 		     "System Aggregated Keyboard",
1455 		     GDK_DEVICE_TYPE_SLAVE);
1456   _gdk_device_virtual_set_active (device_manager->core_keyboard,
1457 				  device_manager->system_keyboard);
1458   _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
1459   _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard);
1460 
1461   _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
1462   _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
1463 
1464   seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer,
1465                                                device_manager->core_keyboard);
1466   gdk_display_add_seat (gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object)), seat);
1467   gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->system_pointer);
1468   gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
1469   g_object_unref (seat);
1470 
1471   tablet_input_api_user_preference = g_getenv ("GDK_WIN32_TABLET_INPUT_API");
1472   if (g_strcmp0 (tablet_input_api_user_preference, "none") == 0)
1473     {
1474       have_tablet_input_api_preference = TRUE;
1475       _gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_NONE;
1476     }
1477   else if (g_strcmp0 (tablet_input_api_user_preference, "wintab") == 0)
1478     {
1479       have_tablet_input_api_preference = TRUE;
1480       _gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
1481     }
1482   else if (g_strcmp0 (tablet_input_api_user_preference, "winpointer") == 0)
1483     {
1484       have_tablet_input_api_preference = TRUE;
1485       _gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
1486     }
1487   else
1488     {
1489       have_tablet_input_api_preference = FALSE;
1490       _gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
1491     }
1492 
1493   if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
1494     {
1495       if (!winpointer_initialize (device_manager) &&
1496           !have_tablet_input_api_preference)
1497         _gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
1498     }
1499 
1500   if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
1501     {
1502       /* Only call Wintab init stuff after the default display
1503        * is globally known and accessible through the display manager
1504        * singleton. Approach lifted from gtkmodules.c.
1505        */
1506       display_manager = gdk_display_manager_get();
1507       g_assert (display_manager != NULL);
1508       default_display = gdk_display_manager_get_default_display (display_manager);
1509       g_assert (default_display == NULL);
1510 
1511       g_signal_connect (display_manager, "notify::default-display",
1512                         G_CALLBACK (wintab_default_display_notify_cb),
1513                         NULL);
1514     }
1515 }
1516 
1517 static GList *
gdk_device_manager_win32_list_devices(GdkDeviceManager * device_manager,GdkDeviceType type)1518 gdk_device_manager_win32_list_devices (GdkDeviceManager *device_manager,
1519                                        GdkDeviceType     type)
1520 {
1521   GdkDeviceManagerWin32 *device_manager_win32;
1522   GList *devices = NULL, *l;
1523 
1524   device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager;
1525 
1526   if (type == GDK_DEVICE_TYPE_MASTER)
1527     {
1528       devices = g_list_prepend (devices, device_manager_win32->core_keyboard);
1529       devices = g_list_prepend (devices, device_manager_win32->core_pointer);
1530     }
1531   else
1532     {
1533       if (type == GDK_DEVICE_TYPE_SLAVE)
1534 	{
1535 	  devices = g_list_prepend (devices, device_manager_win32->system_keyboard);
1536 	  devices = g_list_prepend (devices, device_manager_win32->system_pointer);
1537 	}
1538 
1539       for (l = device_manager_win32->winpointer_devices; l != NULL; l = l->next)
1540         {
1541           GdkDevice *device = l->data;
1542 
1543           if (gdk_device_get_device_type (device) == type)
1544             devices = g_list_prepend (devices, device);
1545         }
1546 
1547       for (l = device_manager_win32->wintab_devices; l != NULL; l = l->next)
1548 	{
1549 	  GdkDevice *device = l->data;
1550 
1551 	  if (gdk_device_get_device_type (device) == type)
1552 	    devices = g_list_prepend (devices, device);
1553 	}
1554     }
1555 
1556   return g_list_reverse (devices);
1557 }
1558 
1559 static GdkDevice *
gdk_device_manager_win32_get_client_pointer(GdkDeviceManager * device_manager)1560 gdk_device_manager_win32_get_client_pointer (GdkDeviceManager *device_manager)
1561 {
1562   GdkDeviceManagerWin32 *device_manager_win32;
1563 
1564   device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager;
1565   return device_manager_win32->core_pointer;
1566 }
1567 
1568 static void
gdk_device_manager_win32_class_init(GdkDeviceManagerWin32Class * klass)1569 gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
1570 {
1571   GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
1572   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1573 
1574   object_class->finalize = gdk_device_manager_win32_finalize;
1575   object_class->constructed = gdk_device_manager_win32_constructed;
1576   device_manager_class->list_devices = gdk_device_manager_win32_list_devices;
1577   device_manager_class->get_client_pointer = gdk_device_manager_win32_get_client_pointer;
1578 }
1579 
1580 static inline void
winpointer_ignore_interaction(UINT32 pointer_id)1581 winpointer_ignore_interaction (UINT32 pointer_id)
1582 {
1583   g_ptr_array_add (winpointer_ignored_interactions, GUINT_TO_POINTER (pointer_id));
1584 }
1585 
1586 static inline void
winpointer_remove_ignored_interaction(UINT32 pointer_id)1587 winpointer_remove_ignored_interaction (UINT32 pointer_id)
1588 {
1589   g_ptr_array_remove_fast (winpointer_ignored_interactions, GUINT_TO_POINTER (pointer_id));
1590 }
1591 
1592 static inline gboolean
winpointer_should_ignore_interaction(UINT32 pointer_id)1593 winpointer_should_ignore_interaction (UINT32 pointer_id)
1594 {
1595   return g_ptr_array_find (winpointer_ignored_interactions, GUINT_TO_POINTER (pointer_id), NULL);
1596 }
1597 
1598 static inline guint32
winpointer_get_time(MSG * msg,POINTER_INFO * info)1599 winpointer_get_time (MSG *msg, POINTER_INFO *info)
1600 {
1601   return info->dwTime != 0 ? info->dwTime : msg->time;
1602 }
1603 
1604 static inline gboolean
winpointer_is_eraser(POINTER_PEN_INFO * pen_info)1605 winpointer_is_eraser (POINTER_PEN_INFO *pen_info)
1606 {
1607   return (pen_info->penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER)) != 0;
1608 }
1609 
1610 static inline gboolean
winpointer_should_filter_message(MSG * msg,POINTER_INPUT_TYPE type)1611 winpointer_should_filter_message (MSG *msg,
1612                                   POINTER_INPUT_TYPE type)
1613 {
1614   switch (type)
1615     {
1616     case PT_TOUCH:
1617       return msg->message == WM_POINTERENTER ||
1618              msg->message == WM_POINTERLEAVE;
1619     break;
1620     }
1621 
1622   return FALSE;
1623 }
1624 
1625 static GdkDeviceWinpointer*
winpointer_find_device_with_source(GdkDeviceManagerWin32 * device_manager,HANDLE device_handle,UINT32 cursor_id,GdkInputSource input_source)1626 winpointer_find_device_with_source (GdkDeviceManagerWin32 *device_manager,
1627                                     HANDLE device_handle,
1628                                     UINT32 cursor_id,
1629                                     GdkInputSource input_source)
1630 {
1631   GList *l;
1632 
1633   for (l = device_manager->winpointer_devices; l; l = l->next)
1634     {
1635       GdkDeviceWinpointer *device = (GdkDeviceWinpointer*) l->data;
1636 
1637       if (device->device_handle == device_handle &&
1638           device->start_cursor_id <= cursor_id &&
1639           device->end_cursor_id >= cursor_id &&
1640           gdk_device_get_source (GDK_DEVICE (device)) == input_source)
1641         return device;
1642     }
1643 
1644   return NULL;
1645 }
1646 
1647 static GdkEvent*
winpointer_allocate_event(MSG * msg,POINTER_INFO * info)1648 winpointer_allocate_event (MSG *msg,
1649                            POINTER_INFO *info)
1650 {
1651   switch (info->pointerType)
1652     {
1653     case PT_PEN:
1654       switch (msg->message)
1655         {
1656         case WM_POINTERENTER:
1657           g_return_val_if_fail (IS_POINTER_NEW_WPARAM (msg->wParam), NULL);
1658           return gdk_event_new (GDK_PROXIMITY_IN);
1659         break;
1660         case WM_POINTERLEAVE:
1661           g_return_val_if_fail (!IS_POINTER_INRANGE_WPARAM (msg->wParam), NULL);
1662           return gdk_event_new (GDK_PROXIMITY_OUT);
1663         break;
1664         case WM_POINTERDOWN:
1665           return gdk_event_new (GDK_BUTTON_PRESS);
1666         break;
1667         case WM_POINTERUP:
1668           return gdk_event_new (GDK_BUTTON_RELEASE);
1669         break;
1670         case WM_POINTERUPDATE:
1671           return gdk_event_new (GDK_MOTION_NOTIFY);
1672         break;
1673         }
1674     break;
1675     case PT_TOUCH:
1676       if (IS_POINTER_CANCELED_WPARAM (msg->wParam) ||
1677           !HAS_POINTER_CONFIDENCE_WPARAM (msg->wParam))
1678         {
1679           winpointer_ignore_interaction (GET_POINTERID_WPARAM (msg->wParam));
1680 
1681           if (((info->pointerFlags & POINTER_FLAG_INCONTACT) &&
1682                (info->pointerFlags & POINTER_FLAG_UPDATE))
1683               || (info->pointerFlags & POINTER_FLAG_UP))
1684             return gdk_event_new (GDK_TOUCH_CANCEL);
1685           else
1686             return NULL;
1687         }
1688 
1689       g_return_val_if_fail (msg->message != WM_POINTERENTER &&
1690                             msg->message != WM_POINTERLEAVE, NULL);
1691 
1692       switch (msg->message)
1693         {
1694           case WM_POINTERDOWN:
1695             return gdk_event_new (GDK_TOUCH_BEGIN);
1696           break;
1697           case WM_POINTERUP:
1698             return gdk_event_new (GDK_TOUCH_END);
1699           break;
1700           case WM_POINTERUPDATE:
1701             if (IS_POINTER_INCONTACT_WPARAM (msg->wParam))
1702               return gdk_event_new (GDK_TOUCH_UPDATE);
1703             else if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
1704               return gdk_event_new (GDK_MOTION_NOTIFY);
1705             else
1706               return NULL;
1707           break;
1708         }
1709     break;
1710     }
1711 
1712   g_warn_if_reached ();
1713   return NULL;
1714 }
1715 
1716 static void
winpointer_make_event(GdkDisplay * display,GdkDeviceManagerWin32 * device_manager,GdkDeviceWinpointer * device,GdkWindow * window,MSG * msg,POINTER_INFO * info)1717 winpointer_make_event (GdkDisplay *display,
1718                        GdkDeviceManagerWin32 *device_manager,
1719                        GdkDeviceWinpointer *device,
1720                        GdkWindow *window,
1721                        MSG *msg,
1722                        POINTER_INFO *info)
1723 {
1724   guint32 time = 0;
1725   double x_root = 0.0;
1726   double y_root = 0.0;
1727   double x = 0.0;
1728   double y = 0.0;
1729   unsigned int state = 0;
1730   double *axes = NULL;
1731   unsigned int button = 0;
1732   GdkEventSequence *sequence = NULL;
1733   gboolean emulating_pointer = FALSE;
1734   POINT client_area_coordinates;
1735   GdkWindowImplWin32 *impl = NULL;
1736   GdkEvent *evt = NULL;
1737 
1738   evt = winpointer_allocate_event (msg, info);
1739   if (!evt)
1740     return;
1741 
1742   time = winpointer_get_time (msg, info);
1743 
1744   x_root = device->origin_x + info->ptHimetricLocation.x * device->scale_x;
1745   y_root = device->origin_y + info->ptHimetricLocation.y * device->scale_y;
1746 
1747   client_area_coordinates.x = 0;
1748   client_area_coordinates.y = 0;
1749   ClientToScreen (GDK_WINDOW_HWND (window), &client_area_coordinates);
1750   x = x_root - client_area_coordinates.x;
1751   y = y_root - client_area_coordinates.y;
1752 
1753   /* bring potential win32 negative screen coordinates to
1754      the non-negative screen coordinates that GDK expects. */
1755   x_root += _gdk_offset_x;
1756   y_root += _gdk_offset_y;
1757 
1758   /* handle DPI scaling */
1759   impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1760   x_root /= impl->window_scale;
1761   y_root /= impl->window_scale;
1762   x /= impl->window_scale;
1763   y /= impl->window_scale;
1764 
1765   state = 0;
1766   if (info->dwKeyStates & POINTER_MOD_CTRL)
1767     state |= GDK_CONTROL_MASK;
1768   if (info->dwKeyStates & POINTER_MOD_SHIFT)
1769     state |= GDK_SHIFT_MASK;
1770   if (GetKeyState (VK_MENU) < 0)
1771     state |= GDK_MOD1_MASK;
1772   if (GetKeyState (VK_CAPITAL) & 0x1)
1773     state |= GDK_LOCK_MASK;
1774 
1775   device->last_button_mask = 0;
1776   if (((info->pointerFlags & POINTER_FLAG_FIRSTBUTTON) &&
1777        (info->ButtonChangeType != POINTER_CHANGE_FIRSTBUTTON_DOWN))
1778       || info->ButtonChangeType == POINTER_CHANGE_FIRSTBUTTON_UP)
1779     device->last_button_mask |= GDK_BUTTON1_MASK;
1780   if (((info->pointerFlags & POINTER_FLAG_SECONDBUTTON) &&
1781        (info->ButtonChangeType != POINTER_CHANGE_SECONDBUTTON_DOWN))
1782       || info->ButtonChangeType == POINTER_CHANGE_SECONDBUTTON_UP)
1783     device->last_button_mask |= GDK_BUTTON3_MASK;
1784   state |= device->last_button_mask;
1785 
1786   switch (info->pointerType)
1787     {
1788     case PT_PEN:
1789       {
1790         POINTER_PEN_INFO *pen_info = (POINTER_PEN_INFO*) info;
1791 
1792         axes = g_new (double, device->num_axes);
1793         axes[0] = (pen_info->penMask & PEN_MASK_PRESSURE) ? pen_info->pressure / 1024.0 :
1794                   (pen_info->pointerInfo.pointerFlags & POINTER_FLAG_INCONTACT) ? 1.0 : 0.0;
1795         axes[1] = (pen_info->penMask & PEN_MASK_TILT_X) ? pen_info->tiltX / 90.0 : 0.0;
1796         axes[2] = (pen_info->penMask & PEN_MASK_TILT_Y) ? pen_info->tiltY / 90.0 : 0.0;
1797         axes[3] = (pen_info->penMask & PEN_MASK_ROTATION) ? pen_info->rotation / 360.0 : 0.0;
1798       }
1799     break;
1800     case PT_TOUCH:
1801       {
1802         POINTER_TOUCH_INFO *touch_info = (POINTER_TOUCH_INFO*) info;
1803 
1804         axes = g_new (double, device->num_axes);
1805         axes[0] = (touch_info->touchMask & TOUCH_MASK_PRESSURE) ? touch_info->pressure / 1024.0 :
1806                   (touch_info->pointerInfo.pointerFlags & POINTER_FLAG_INCONTACT) ? 1.0 : 0.0;
1807       }
1808     break;
1809     }
1810 
1811   if (axes)
1812     {
1813       memcpy (device->last_axis_data, axes, sizeof (double) * device->num_axes);
1814     }
1815 
1816   sequence = (GdkEventSequence*) GUINT_TO_POINTER (info->pointerId);
1817   emulating_pointer = (info->pointerFlags & POINTER_FLAG_PRIMARY) != 0;
1818   button = (info->pointerFlags & POINTER_FLAG_FIRSTBUTTON) ||
1819            (info->ButtonChangeType == POINTER_CHANGE_FIRSTBUTTON_UP) ? 1 : 3;
1820 
1821   switch (evt->any.type)
1822     {
1823     case GDK_PROXIMITY_IN:
1824     case GDK_PROXIMITY_OUT:
1825       evt->proximity.time = time;
1826     break;
1827     case GDK_BUTTON_PRESS:
1828     case GDK_BUTTON_RELEASE:
1829       evt->button.time = time;
1830       evt->button.x_root = x_root;
1831       evt->button.y_root = y_root;
1832       evt->button.x = x;
1833       evt->button.y = y;
1834       evt->button.state = state;
1835       evt->button.axes = axes;
1836       evt->button.button = button;
1837     break;
1838     case GDK_MOTION_NOTIFY:
1839       evt->motion.time = time;
1840       evt->motion.x_root = x_root;
1841       evt->motion.y_root = y_root;
1842       evt->motion.x = x;
1843       evt->motion.y = y;
1844       evt->motion.state = state;
1845       evt->motion.axes = axes;
1846     break;
1847     case GDK_TOUCH_BEGIN:
1848     case GDK_TOUCH_UPDATE:
1849     case GDK_TOUCH_CANCEL:
1850     case GDK_TOUCH_END:
1851       evt->touch.time = time;
1852       evt->touch.x_root = x_root;
1853       evt->touch.y_root = y_root;
1854       evt->touch.x = x;
1855       evt->touch.y = y;
1856       evt->touch.state = state;
1857       evt->touch.axes = axes;
1858       evt->touch.sequence = sequence;
1859       evt->touch.emulating_pointer = emulating_pointer;
1860       gdk_event_set_pointer_emulated (evt, emulating_pointer);
1861     break;
1862     }
1863 
1864   evt->any.send_event = FALSE;
1865   evt->any.window = window;
1866   gdk_event_set_device (evt, device_manager->core_pointer);
1867   gdk_event_set_source_device (evt, GDK_DEVICE (device));
1868   gdk_event_set_device_tool (evt, ((GdkDevice*)device)->last_tool);
1869   gdk_event_set_seat (evt, gdk_device_get_seat (device_manager->core_pointer));
1870   gdk_event_set_screen (evt, gdk_display_get_default_screen (display));
1871 
1872   _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (device));
1873 
1874   _gdk_win32_append_event (evt);
1875 }
1876 
1877 void
gdk_winpointer_input_events(GdkDisplay * display,GdkWindow * window,crossing_cb_t crossing_cb,MSG * msg)1878 gdk_winpointer_input_events (GdkDisplay *display,
1879                              GdkWindow *window,
1880                              crossing_cb_t crossing_cb,
1881                              MSG *msg)
1882 {
1883   GdkDeviceManagerWin32 *device_manager = NULL;
1884   UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
1885   POINTER_INPUT_TYPE type = PT_POINTER;
1886   UINT32 cursor_id = 0;
1887 
1888   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1889   device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
1890   G_GNUC_END_IGNORE_DEPRECATIONS;
1891 
1892   if (!getPointerType (pointer_id, &type))
1893     {
1894       WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
1895       return;
1896     }
1897 
1898   if (!getPointerCursorId (pointer_id, &cursor_id))
1899     {
1900       WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
1901       return;
1902     }
1903 
1904   if (winpointer_should_filter_message (msg, type))
1905     {
1906       return;
1907     }
1908 
1909   if (winpointer_should_ignore_interaction (pointer_id))
1910     {
1911       return;
1912     }
1913 
1914   switch (type)
1915     {
1916     case PT_PEN:
1917       {
1918         POINTER_PEN_INFO *infos = NULL;
1919         UINT32 history_count = 0;
1920         GdkDeviceWinpointer *device = NULL;
1921         UINT32 h = 0;
1922 
1923         do
1924           {
1925             infos = g_new0 (POINTER_PEN_INFO, history_count);
1926             if (!getPointerPenInfoHistory (pointer_id, &history_count, infos))
1927               {
1928                 WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfoHistory");
1929                 g_free (infos);
1930                 return;
1931               }
1932           }
1933         while (!infos && history_count > 0);
1934 
1935         if (history_count == 0)
1936           return;
1937 
1938         device = winpointer_find_device_with_source (device_manager,
1939                                                      infos->pointerInfo.sourceDevice,
1940                                                      cursor_id,
1941                                                      winpointer_is_eraser (infos) ?
1942                                                      GDK_SOURCE_ERASER : GDK_SOURCE_PEN);
1943         if (!device)
1944           {
1945             g_free (infos);
1946             return;
1947           }
1948 
1949         h = history_count - 1;
1950 
1951         if (crossing_cb)
1952           {
1953             POINT screen_pt = infos[h].pointerInfo.ptPixelLocation;
1954             guint32 event_time = winpointer_get_time (msg, &infos[h].pointerInfo);
1955 
1956             crossing_cb(display, GDK_DEVICE (device), window, &screen_pt, event_time);
1957           }
1958 
1959         do
1960           winpointer_make_event (display,
1961                                  device_manager,
1962                                  device,
1963                                  window,
1964                                  msg,
1965                                  (POINTER_INFO*) &infos[h]);
1966         while (h-- > 0);
1967 
1968         g_free (infos);
1969       }
1970     break;
1971     case PT_TOUCH:
1972       {
1973         POINTER_TOUCH_INFO *infos = NULL;
1974         UINT32 history_count = 0;
1975         GdkDeviceWinpointer *device = NULL;
1976         UINT32 h = 0;
1977 
1978         do
1979           {
1980             infos = g_new0 (POINTER_TOUCH_INFO, history_count);
1981             if (!getPointerTouchInfoHistory (pointer_id, &history_count, infos))
1982               {
1983                 WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfoHistory");
1984                 g_free (infos);
1985                 return;
1986               }
1987           }
1988         while (!infos && history_count > 0);
1989 
1990         if (history_count == 0)
1991           return;
1992 
1993         device = winpointer_find_device_with_source (device_manager,
1994                                                      infos->pointerInfo.sourceDevice,
1995                                                      cursor_id,
1996                                                      GDK_SOURCE_TOUCHSCREEN);
1997         if (!device)
1998           {
1999             g_free (infos);
2000             return;
2001           }
2002 
2003         h = history_count - 1;
2004 
2005         if (crossing_cb)
2006           {
2007             POINT screen_pt = infos[h].pointerInfo.ptPixelLocation;
2008             guint32 event_time = winpointer_get_time (msg, &infos[h].pointerInfo);
2009 
2010             crossing_cb(display, GDK_DEVICE (device), window, &screen_pt, event_time);
2011           }
2012 
2013         do
2014           winpointer_make_event (display,
2015                                  device_manager,
2016                                  device,
2017                                  window,
2018                                  msg,
2019                                  (POINTER_INFO*) &infos[h]);
2020         while (h-- > 0);
2021 
2022         g_free (infos);
2023       }
2024     break;
2025     }
2026 }
2027 
2028 gboolean
gdk_winpointer_get_message_info(GdkDisplay * display,MSG * msg,GdkDevice ** device,guint32 * time_)2029 gdk_winpointer_get_message_info (GdkDisplay *display,
2030                                  MSG *msg,
2031                                  GdkDevice **device,
2032                                  guint32 *time_)
2033 {
2034   GdkDeviceManagerWin32 *device_manager = NULL;
2035   UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
2036   POINTER_INPUT_TYPE type = PT_POINTER;
2037   UINT32 cursor_id = 0;
2038 
2039   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2040   device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
2041   G_GNUC_END_IGNORE_DEPRECATIONS;
2042 
2043   if (!getPointerType (pointer_id, &type))
2044     {
2045       WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
2046       return FALSE;
2047     }
2048 
2049   if (!getPointerCursorId (pointer_id, &cursor_id))
2050     {
2051       WIN32_API_FAILED_LOG_ONCE ("GetPointerCursorId");
2052       return FALSE;
2053     }
2054 
2055   switch (type)
2056     {
2057     case PT_PEN:
2058       {
2059         POINTER_PEN_INFO pen_info;
2060 
2061         if (!getPointerPenInfo (pointer_id, &pen_info))
2062           {
2063             WIN32_API_FAILED_LOG_ONCE ("GetPointerPenInfo");
2064             return FALSE;
2065           }
2066 
2067         *device = GDK_DEVICE (winpointer_find_device_with_source (device_manager,
2068                                                                   pen_info.pointerInfo.sourceDevice,
2069                                                                   cursor_id,
2070                                                                   winpointer_is_eraser (&pen_info) ?
2071                                                                   GDK_SOURCE_ERASER : GDK_SOURCE_PEN));
2072 
2073         *time_ = winpointer_get_time (msg, &pen_info.pointerInfo);
2074       }
2075     break;
2076     case PT_TOUCH:
2077       {
2078         POINTER_TOUCH_INFO touch_info;
2079 
2080         if (!getPointerTouchInfo (pointer_id, &touch_info))
2081             {
2082               WIN32_API_FAILED_LOG_ONCE ("GetPointerTouchInfo");
2083               return FALSE;
2084             }
2085 
2086         *device = GDK_DEVICE (winpointer_find_device_with_source (device_manager,
2087                                                                   touch_info.pointerInfo.sourceDevice,
2088                                                                   cursor_id,
2089                                                                   GDK_SOURCE_TOUCHSCREEN));
2090 
2091         *time_ = winpointer_get_time (msg, &touch_info.pointerInfo);
2092       }
2093     break;
2094     default:
2095       g_warn_if_reached ();
2096       return FALSE;
2097     break;
2098     }
2099 
2100   return *device ? TRUE : FALSE;
2101 }
2102 
2103 gboolean
gdk_winpointer_should_forward_message(MSG * msg)2104 gdk_winpointer_should_forward_message (MSG *msg)
2105 {
2106   UINT32 pointer_id = GET_POINTERID_WPARAM (msg->wParam);
2107   POINTER_INPUT_TYPE type = PT_POINTER;
2108 
2109   if (!getPointerType (pointer_id, &type))
2110     {
2111       WIN32_API_FAILED_LOG_ONCE ("GetPointerType");
2112       return TRUE;
2113     }
2114 
2115   return !(type == PT_PEN || type == PT_TOUCH);
2116 }
2117 
2118 void
gdk_winpointer_interaction_ended(MSG * msg)2119 gdk_winpointer_interaction_ended (MSG *msg)
2120 {
2121   winpointer_remove_ignored_interaction (GET_POINTERID_WPARAM (msg->wParam));
2122 }
2123 
2124 void
_gdk_wintab_set_tablet_active(void)2125 _gdk_wintab_set_tablet_active (void)
2126 {
2127   GList *tmp_list;
2128   HCTX *hctx;
2129 
2130   /* Bring the contexts to the top of the overlap order when one of the
2131    * application's windows is activated */
2132 
2133   if (!wintab_contexts)
2134     return; /* No tablet devices found, or Wintab not initialized yet */
2135 
2136   GDK_NOTE (INPUT, g_print ("_gdk_wintab_set_tablet_active: "
2137                             "Bringing Wintab contexts to the top of the overlap order\n"));
2138 
2139   tmp_list = wintab_contexts;
2140 
2141   while (tmp_list)
2142     {
2143       hctx = (HCTX *) (tmp_list->data);
2144       (*p_WTOverlap) (*hctx, TRUE);
2145       tmp_list = tmp_list->next;
2146     }
2147 }
2148 
2149 static void
decode_tilt(gint * axis_data,AXIS * axes,PACKET * packet)2150 decode_tilt (gint   *axis_data,
2151              AXIS   *axes,
2152              PACKET *packet)
2153 {
2154   double az, el;
2155 
2156   g_return_if_fail (axis_data != NULL);
2157 
2158   /* The wintab driver for the Wacom ArtPad II reports
2159    * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
2160    * actually sense tilt. Catch this by noticing that the
2161    * orientation axis's azimuth resolution is zero.
2162    *
2163    * The same is true of the Huion H610PRO, but in this case
2164    * it's the altitude resolution that's zero. GdkEvents with
2165    * sensible tilts will need both, so only add the GDK tilt axes
2166    * if both wintab axes are going to be well-behaved in use.
2167    */
2168   if (axes == NULL)
2169     return;
2170 
2171   if ((axes[0].axResolution == 0) ||
2172       (axes[1].axResolution == 0))
2173     {
2174       axis_data[0] = 0;
2175       axis_data[1] = 0;
2176     }
2177   else
2178     {
2179       /*
2180        * Tested with a Wacom Intuos 5 touch M (PTH-650) + Wacom drivers 6.3.18-5.
2181        * Wintab's reference angle leads gdk's by 90 degrees.
2182        */
2183       az = TWOPI * packet->pkOrientation.orAzimuth /
2184         (axes[0].axResolution / 65536.);
2185       az -= G_PI / 2;
2186       el = TWOPI * packet->pkOrientation.orAltitude /
2187         (axes[1].axResolution / 65536.);
2188 
2189       /* X tilt */
2190       axis_data[0] = cos (az) * cos (el) * 1000;
2191       /* Y tilt */
2192       axis_data[1] = sin (az) * cos (el) * 1000;
2193     }
2194 
2195   /* Twist (Rotation) if present */
2196   if (axes[2].axResolution != 0)
2197     axis_data[2] = packet->pkOrientation.orTwist;
2198 }
2199 
2200 /*
2201  * Get the currently active keyboard modifiers (ignoring the mouse buttons)
2202  * We could use gdk_window_get_pointer but that function does a lot of other
2203  * expensive things besides getting the modifiers. This code is somewhat based
2204  * on build_pointer_event_state from gdkevents-win32.c
2205  */
2206 static guint
get_modifier_key_state(void)2207 get_modifier_key_state (void)
2208 {
2209   guint state;
2210 
2211   state = 0;
2212   /* High-order bit is up/down, low order bit is toggled/untoggled */
2213   if (GetKeyState (VK_CONTROL) < 0)
2214     state |= GDK_CONTROL_MASK;
2215   if (GetKeyState (VK_SHIFT) < 0)
2216     state |= GDK_SHIFT_MASK;
2217   if (GetKeyState (VK_MENU) < 0)
2218     state |= GDK_MOD1_MASK;
2219   if (GetKeyState (VK_CAPITAL) & 0x1)
2220     state |= GDK_LOCK_MASK;
2221 
2222   return state;
2223 }
2224 
2225 int
_gdk_find_wintab_device_index(HCTX hctx)2226 _gdk_find_wintab_device_index (HCTX hctx)
2227 {
2228   GList *tmp_list;
2229   int devix;
2230 
2231   /* Find the index of the Wintab driver's input device (probably zero) */
2232   if (!wintab_contexts)
2233     return -1; /* No tablet devices found or Wintab not initialized yet */
2234 
2235   tmp_list = wintab_contexts;
2236   devix = 0;
2237   while (tmp_list)
2238     {
2239       if ((*(HCTX *) (tmp_list->data)) == hctx)
2240         return devix;
2241       else
2242         {
2243           devix++;
2244           tmp_list = tmp_list->next;
2245         }
2246     }
2247   return -1;
2248 }
2249 
2250 static GdkDeviceWintab *
gdk_device_manager_find_wintab_device(GdkDeviceManagerWin32 * device_manager,HCTX hctx,UINT cursor)2251 gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *device_manager,
2252                                        HCTX                   hctx,
2253                                        UINT                   cursor)
2254 {
2255   GdkDeviceWintab *device;
2256   GList *tmp_list;
2257 
2258   for (tmp_list = device_manager->wintab_devices; tmp_list != NULL; tmp_list = tmp_list->next)
2259     {
2260       device = tmp_list->data;
2261 
2262       if (device->hctx == hctx &&
2263           device->cursor == cursor)
2264         return device;
2265     }
2266 
2267   return NULL;
2268 }
2269 
2270 gboolean
gdk_wintab_input_events(GdkDisplay * display,GdkEvent * event,MSG * msg,GdkWindow * window)2271 gdk_wintab_input_events (GdkDisplay *display,
2272                          GdkEvent   *event,
2273                          MSG        *msg,
2274                          GdkWindow  *window)
2275 {
2276   GdkDeviceManagerWin32 *device_manager;
2277   GdkDeviceWintab *source_device = NULL;
2278   GdkDeviceGrabInfo *last_grab;
2279   GdkEventMask masktest;
2280   guint key_state;
2281   POINT pt;
2282   GdkWindowImplWin32 *impl;
2283 
2284   PACKET packet;
2285   gint root_x, root_y;
2286   gint num_axes;
2287   gint x, y;
2288   guint translated_buttons, button_diff, button_mask;
2289   /* Translation from tablet button state to GDK button state for
2290    * buttons 1-3 - swap button 2 and 3.
2291    */
2292   static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
2293 
2294   if (event->any.window != wintab_window)
2295     {
2296       g_warning ("gdk_wintab_input_events: not wintab_window?");
2297       return FALSE;
2298     }
2299 
2300 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2301   device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
2302 G_GNUC_END_IGNORE_DEPRECATIONS;
2303   window = gdk_device_get_window_at_position (device_manager->core_pointer, &x, &y);
2304   if (window == NULL)
2305     window = gdk_get_default_root_window ();
2306 
2307   g_object_ref (window);
2308 
2309   GDK_NOTE (EVENTS_OR_INPUT,
2310 	    g_print ("gdk_wintab_input_events: window=%p %+d%+d\n",
2311                GDK_WINDOW_HWND (window), x, y));
2312 
2313   if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
2314     {
2315       if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
2316         return FALSE;
2317     }
2318 
2319   switch (msg->message)
2320     {
2321     case WT_PACKET:
2322       source_device = gdk_device_manager_find_wintab_device (device_manager,
2323 							     (HCTX) msg->lParam,
2324 							     packet.pkCursor);
2325 
2326       /* Check this first, as we get WT_PROXIMITY for disabled devices too */
2327       if (device_manager->dev_entered_proximity > 0)
2328 	{
2329 	  /* This is the same code as in WT_CSRCHANGE. Some drivers send
2330 	   * WT_CSRCHANGE after each WT_PROXIMITY with LOWORD(lParam) != 0,
2331 	   * this code is for those that don't.
2332 	   */
2333 	  device_manager->dev_entered_proximity -= 1;
2334 
2335 	  if (source_device != NULL &&
2336 	      source_device->sends_core &&
2337 	      gdk_device_get_mode (GDK_DEVICE (source_device)) != GDK_MODE_DISABLED)
2338 	    {
2339 	      _gdk_device_virtual_set_active (device_manager->core_pointer,
2340 					      GDK_DEVICE (source_device));
2341 	      _gdk_input_ignore_core += 1;
2342 	    }
2343 	}
2344       else if (source_device != NULL &&
2345 	       source_device->sends_core &&
2346 	       gdk_device_get_mode (GDK_DEVICE (source_device)) != GDK_MODE_DISABLED &&
2347                _gdk_input_ignore_core == 0)
2348         {
2349           /* A fallback for cases when two devices (disabled and enabled)
2350            * were in proximity simultaneously.
2351            * In this case the removal of a disabled device would also
2352            * make the system pointer active, as we don't know which
2353            * device was removed and assume it was the enabled one.
2354            * If we are still getting packets for the enabled device,
2355            * it means that the device that was removed was the disabled
2356            * device, so we must make the enabled device active again and
2357            * start ignoring the core pointer events. In practice this means that
2358            * removing a disabled device while an enabled device is still
2359            * in proximity might briefly make the core pointer active/visible.
2360            */
2361 	  _gdk_device_virtual_set_active (device_manager->core_pointer,
2362 					  GDK_DEVICE (source_device));
2363 	  _gdk_input_ignore_core += 1;
2364         }
2365 
2366       if (source_device == NULL ||
2367 	  gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
2368 	return FALSE;
2369 
2370       /* Don't produce any button or motion events while a window is being
2371        * moved or resized, see bug #151090.
2372        */
2373       if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
2374         {
2375           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
2376           return FALSE;
2377         }
2378 
2379       last_grab = _gdk_display_get_last_device_grab (display, GDK_DEVICE (source_device));
2380 
2381       if (last_grab && last_grab->window)
2382         {
2383           g_object_unref (window);
2384 
2385           window = g_object_ref (last_grab->window);
2386         }
2387 
2388       if (window == gdk_get_default_root_window ())
2389         {
2390           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
2391           return FALSE;
2392         }
2393 
2394       num_axes = 0;
2395       if (source_device->pktdata & PK_X)
2396         source_device->last_axis_data[num_axes++] = packet.pkX;
2397       if (source_device->pktdata & PK_Y)
2398         source_device->last_axis_data[num_axes++] = packet.pkY;
2399       if (source_device->pktdata & PK_NORMAL_PRESSURE)
2400         source_device->last_axis_data[num_axes++] = packet.pkNormalPressure;
2401       if (source_device->pktdata & PK_ORIENTATION)
2402         {
2403           decode_tilt (source_device->last_axis_data + num_axes,
2404                        source_device->orientation_axes, &packet);
2405           /* we could have 3 axes if twist is present */
2406           if (source_device->orientation_axes[2].axResolution == 0)
2407             {
2408               num_axes += 2;
2409             }
2410           else
2411             {
2412               num_axes += 3;
2413             }
2414         }
2415       if (source_device->pktdata & PK_TANGENT_PRESSURE)
2416         source_device->last_axis_data[num_axes++] = packet.pkTangentPressure;
2417 
2418       translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
2419 
2420       if (translated_buttons != source_device->button_state)
2421         {
2422           /* At least one button has changed state so produce a button event
2423            * If more than one button has changed state (unlikely),
2424            * just care about the first and act on the next the next time
2425            * we get a packet
2426            */
2427           button_diff = translated_buttons ^ source_device->button_state;
2428 
2429           /* Gdk buttons are numbered 1.. */
2430           event->button.button = 1;
2431 
2432           for (button_mask = 1; button_mask != 0x80000000;
2433                button_mask <<= 1, event->button.button++)
2434             {
2435               if (button_diff & button_mask)
2436                 {
2437                   /* Found a button that has changed state */
2438                   break;
2439                 }
2440             }
2441 
2442           if (!(translated_buttons & button_mask))
2443             {
2444               event->any.type = GDK_BUTTON_RELEASE;
2445               masktest = GDK_BUTTON_RELEASE_MASK;
2446             }
2447           else
2448             {
2449               event->any.type = GDK_BUTTON_PRESS;
2450               masktest = GDK_BUTTON_PRESS_MASK;
2451             }
2452           source_device->button_state ^= button_mask;
2453         }
2454       else
2455         {
2456           event->any.type = GDK_MOTION_NOTIFY;
2457           masktest = GDK_POINTER_MOTION_MASK;
2458           if (source_device->button_state & (1 << 0))
2459             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
2460           if (source_device->button_state & (1 << 1))
2461             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
2462           if (source_device->button_state & (1 << 2))
2463             masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
2464         }
2465 
2466       /* Now we can check if the window wants the event, and
2467        * propagate if necessary.
2468        */
2469       while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 &&
2470 	     (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE &&
2471 	      (gdk_window_get_events (window) & masktest) == 0))
2472         {
2473           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
2474 
2475           if (window->parent == gdk_get_default_root_window () || window->parent == NULL)
2476             return FALSE;
2477 
2478           impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2479           pt.x = x * impl->window_scale;
2480           pt.y = y * impl->window_scale;
2481           ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2482           g_object_unref (window);
2483           window = window->parent;
2484           impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2485           g_object_ref (window);
2486           ScreenToClient (GDK_WINDOW_HWND (window), &pt);
2487           x = pt.x / impl->window_scale;
2488           y = pt.y / impl->window_scale;
2489           GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
2490                                               GDK_WINDOW_HWND (window), x, y));
2491         }
2492 
2493       event->any.window = window;
2494       key_state = get_modifier_key_state ();
2495       if (event->any.type == GDK_BUTTON_PRESS ||
2496           event->any.type == GDK_BUTTON_RELEASE)
2497         {
2498           event->button.time = _gdk_win32_get_next_tick (msg->time);
2499 	  if (source_device->sends_core)
2500 	    gdk_event_set_device (event, device_manager->core_pointer);
2501           else
2502             gdk_event_set_device (event, GDK_DEVICE (source_device));
2503           gdk_event_set_source_device (event, GDK_DEVICE (source_device));
2504           gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
2505 
2506           event->button.axes = g_new (gdouble, num_axes);
2507 	  gdk_window_get_origin (window, &root_x, &root_y);
2508 
2509           _gdk_device_wintab_translate_axes (source_device,
2510                                              window,
2511                                              event->button.axes,
2512                                              &event->button.x,
2513                                              &event->button.y);
2514 
2515           event->button.x_root = event->button.x + root_x;
2516           event->button.y_root = event->button.y + root_y;
2517 
2518           event->button.state =
2519             key_state | ((source_device->button_state << 8)
2520                          & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
2521                             | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
2522                             | GDK_BUTTON5_MASK));
2523 
2524           GDK_NOTE (EVENTS_OR_INPUT,
2525                     g_print ("WINTAB button %s:%d %g,%g\n",
2526                              (event->button.type == GDK_BUTTON_PRESS ?
2527                               "press" : "release"),
2528                              event->button.button,
2529                              event->button.x, event->button.y));
2530         }
2531       else
2532         {
2533           event->motion.time = _gdk_win32_get_next_tick (msg->time);
2534           event->motion.is_hint = FALSE;
2535           if (source_device->sends_core)
2536             gdk_event_set_device (event, device_manager->core_pointer);
2537           else
2538             gdk_event_set_device (event, GDK_DEVICE (source_device));
2539           gdk_event_set_source_device (event, GDK_DEVICE (source_device));
2540           gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
2541 
2542           event->motion.axes = g_new (gdouble, num_axes);
2543 	  gdk_window_get_origin (window, &root_x, &root_y);
2544 
2545           _gdk_device_wintab_translate_axes (source_device,
2546                                              window,
2547                                              event->motion.axes,
2548                                              &event->motion.x,
2549                                              &event->motion.y);
2550 
2551           event->motion.x_root = event->motion.x + root_x;
2552           event->motion.y_root = event->motion.y + root_y;
2553 
2554           event->motion.state =
2555             key_state | ((source_device->button_state << 8)
2556                          & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
2557                             | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
2558                             | GDK_BUTTON5_MASK));
2559 
2560           GDK_NOTE (EVENTS_OR_INPUT,
2561                     g_print ("WINTAB motion: %g,%g\n",
2562                              event->motion.x, event->motion.y));
2563         }
2564       return TRUE;
2565 
2566     case WT_CSRCHANGE:
2567       if (device_manager->dev_entered_proximity > 0)
2568         device_manager->dev_entered_proximity -= 1;
2569 
2570       if ((source_device =
2571         gdk_device_manager_find_wintab_device (device_manager,
2572 								                                (HCTX) msg->lParam,
2573 								                                packet.pkCursor)) == NULL)
2574         {
2575           /* Check for new cursors and try again */
2576           if (_wintab_recognize_new_cursors(device_manager,
2577                                             (HCTX) msg->lParam) == 0)
2578               return FALSE;
2579           if ((source_device =
2580             gdk_device_manager_find_wintab_device (device_manager,
2581                                                     (HCTX) msg->lParam,
2582                                                     packet.pkCursor)) == NULL)
2583             return FALSE;
2584         }
2585 
2586       if (source_device->sends_core &&
2587 	        gdk_device_get_mode (GDK_DEVICE (source_device)) != GDK_MODE_DISABLED)
2588 	      {
2589 	        _gdk_device_virtual_set_active (device_manager->core_pointer,
2590 					                                GDK_DEVICE (source_device));
2591 	        _gdk_input_ignore_core += 1;
2592 	      }
2593       return FALSE;
2594 
2595     case WT_PROXIMITY:
2596       if (LOWORD (msg->lParam) == 0)
2597         {
2598           if (_gdk_input_ignore_core > 0)
2599             {
2600 	      _gdk_input_ignore_core -= 1;
2601 
2602 	      if (_gdk_input_ignore_core == 0)
2603 		_gdk_device_virtual_set_active (device_manager->core_pointer,
2604 						device_manager->system_pointer);
2605 	    }
2606 	}
2607       else
2608 	{
2609 	  device_manager->dev_entered_proximity += 1;
2610 	}
2611 
2612       return FALSE;
2613     }
2614 
2615   return FALSE;
2616 }
2617