1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
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.
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.
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/>.
26 #include "gdkprivate-win32.h"
27 #include "gdkdevicemanager-win32.h"
28 #include "gdkdeviceprivate.h"
29 #include "gdkdevice-win32.h"
30 #include "gdkdevice-virtual.h"
31 #include "gdkdevice-wintab.h"
32 #include "gdkdisplayprivate.h"
34 #define WINTAB32_DLL "Wintab32.dll"
36 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION)
37 /* We want everything in absolute mode */
38 #define PACKETMODE (0)
41 #define DEBUG_WINTAB 1 /* Verbose debug messages enabled */
42 #define TWOPI (2 * G_PI)
44 static GList *wintab_contexts = NULL;
45 static GdkWindow *wintab_window = NULL;
46 extern gint _gdk_input_ignore_core;
48 typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
49 typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
50 typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
51 typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
52 typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
53 typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
54 typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
55 typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
56 typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
58 static t_WTInfoA p_WTInfoA;
59 static t_WTInfoW p_WTInfoW;
60 static t_WTEnable p_WTEnable;
61 static t_WTOpenA p_WTOpenA;
62 static t_WTGetA p_WTGetA;
63 static t_WTSetA p_WTSetA;
64 static t_WTOverlap p_WTOverlap;
65 static t_WTPacket p_WTPacket;
66 static t_WTQueueSizeSet p_WTQueueSizeSet;
69 static void gdk_device_manager_win32_finalize (GObject *object);
70 static void gdk_device_manager_win32_constructed (GObject *object);
72 static GList * gdk_device_manager_win32_list_devices (GdkDeviceManager *device_manager,
74 static GdkDevice * gdk_device_manager_win32_get_client_pointer (GdkDeviceManager *device_manager);
77 G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, GDK_TYPE_DEVICE_MANAGER)
80 gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
82 GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
83 GObjectClass *object_class = G_OBJECT_CLASS (klass);
85 object_class->finalize = gdk_device_manager_win32_finalize;
86 object_class->constructed = gdk_device_manager_win32_constructed;
87 device_manager_class->list_devices = gdk_device_manager_win32_list_devices;
88 device_manager_class->get_client_pointer = gdk_device_manager_win32_get_client_pointer;
92 create_pointer (GdkDeviceManager *device_manager,
97 return g_object_new (g_type,
100 "input-source", GDK_SOURCE_MOUSE,
101 "input-mode", GDK_MODE_SCREEN,
102 "has-cursor", type == GDK_DEVICE_TYPE_MASTER,
103 "display", _gdk_display,
104 "device-manager", device_manager,
109 create_keyboard (GdkDeviceManager *device_manager,
114 return g_object_new (g_type,
117 "input-source", GDK_SOURCE_KEYBOARD,
118 "input-mode", GDK_MODE_SCREEN,
120 "display", _gdk_display,
121 "device-manager", device_manager,
126 gdk_device_manager_win32_init (GdkDeviceManagerWin32 *device_manager_win32)
131 gdk_device_manager_win32_finalize (GObject *object)
133 GdkDeviceManagerWin32 *device_manager_win32;
135 device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (object);
137 g_object_unref (device_manager_win32->core_pointer);
138 g_object_unref (device_manager_win32->core_keyboard);
140 G_OBJECT_CLASS (gdk_device_manager_win32_parent_class)->finalize (object);
146 print_lc(LOGCONTEXT *lc)
148 g_print ("lcName = %s\n", lc->lcName);
149 g_print ("lcOptions =");
150 if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
151 if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
152 if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
153 if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
154 if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
155 if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
157 g_print ("lcStatus =");
158 if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
159 if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
160 if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
162 g_print ("lcLocks =");
163 if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
164 if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
165 if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
166 if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
168 g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
169 lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
170 g_print ("lcPktData =");
171 if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
172 if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
173 if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
174 if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
175 if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
176 if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
177 if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
178 if (lc->lcPktData & PK_X) g_print (" PK_X");
179 if (lc->lcPktData & PK_Y) g_print (" PK_Y");
180 if (lc->lcPktData & PK_Z) g_print (" PK_Z");
181 if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
182 if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
183 if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
184 if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
186 g_print ("lcPktMode =");
187 if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
188 if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
189 if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
190 if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
191 if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
192 if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
193 if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
194 if (lc->lcPktMode & PK_X) g_print (" PK_X");
195 if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
196 if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
197 if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
198 if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
199 if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
200 if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
202 g_print ("lcMoveMask =");
203 if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
204 if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
205 if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
206 if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
207 if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
208 if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
209 if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
210 if (lc->lcMoveMask & PK_X) g_print (" PK_X");
211 if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
212 if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
213 if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
214 if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
215 if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
216 if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
218 g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
219 (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
220 g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
221 lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
222 g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
223 lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
224 g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
225 lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
226 g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
227 lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
228 g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
229 lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
230 g_print ("lcSysMode = %d\n", lc->lcSysMode);
231 g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
232 lc->lcSysOrgX, lc->lcSysOrgY);
233 g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
234 lc->lcSysExtX, lc->lcSysExtY);
235 g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
236 lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
240 print_cursor (int index)
265 size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
266 name = g_malloc (size + 1);
267 (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
268 g_print ("NAME: %s\n", name);
269 (*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
270 g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
271 (*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
272 g_print ("PKTDATA: %#x:", (guint) wtpkt);
273 #define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
283 BIT (NORMAL_PRESSURE);
284 BIT (TANGENT_PRESSURE);
289 (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
290 g_print ("BUTTONS: %d\n", buttons);
291 (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
292 g_print ("BUTTONBITS: %d\n", buttonbits);
293 size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
294 g_print ("BTNNAMES:");
297 btnnames = g_malloc (size + 1);
298 (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
307 (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
308 g_print ("BUTTONMAP:");
309 for (i = 0; i < buttons; i++)
310 g_print (" %d", buttonmap[i]);
312 (*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
313 g_print ("SYSBTNMAP:");
314 for (i = 0; i < buttons; i++)
315 g_print (" %d", sysbtnmap[i]);
317 (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
318 g_print ("NPBUTTON: %d\n", npbutton);
319 (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
320 g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
321 size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
322 g_print ("NPRESPONSE:");
325 npresponse = g_malloc (size);
326 (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
327 for (i = 0; i < size / sizeof (UINT); i++)
328 g_print (" %d", npresponse[i]);
331 (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
332 g_print ("TPBUTTON: %d\n", tpbutton);
333 (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
334 g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
335 size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
336 g_print ("TPRESPONSE:");
339 tpresponse = g_malloc (size);
340 (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
341 for (i = 0; i < size / sizeof (UINT); i++)
342 g_print (" %d", tpresponse[i]);
345 (*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
346 g_print ("PHYSID: %#x\n", (guint) physid);
347 (*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
348 g_print ("CAPABILITIES: %#x:", capabilities);
349 #define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
355 if (capabilities & CRC_MULTIMODE)
357 (*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
358 g_print ("MODE: %d\n", mode);
360 if (capabilities & CRC_AGGREGATE)
362 (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
363 g_print ("MINPKTDATA: %d\n", minpktdata);
364 (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
365 g_print ("MINBUTTONS: %d\n", minbuttons);
371 _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager)
373 GdkDeviceManagerWin32 *device_manager = (GdkDeviceManagerWin32 *)_device_manager;
374 static gboolean wintab_initialized = FALSE;
375 GdkDeviceWintab *device;
379 UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
382 AXIS axis_x, axis_y, axis_npressure, axis_or[3];
383 int i, devix, cursorix, num_axes = 0;
384 wchar_t devname[100], csrname[100];
385 gchar *devname_utf8, *csrname_utf8, *device_name;
386 BOOL defcontext_done;
388 char *wintab32_dll_path;
392 if (wintab_initialized)
395 wintab_initialized = TRUE;
397 wintab_contexts = NULL;
399 if (_gdk_input_ignore_wintab)
402 n = GetSystemDirectory (&dummy, 0);
407 wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
408 k = GetSystemDirectory (wintab32_dll_path, n);
412 g_free (wintab32_dll_path);
416 if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
417 strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
418 strcat (wintab32_dll_path, WINTAB32_DLL);
420 if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
423 if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
425 if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
427 if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
429 if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
431 if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
433 if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
435 if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
437 if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
439 if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
442 if (!(*p_WTInfoA) (0, 0, NULL))
445 (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
446 GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
447 HIBYTE (specversion), LOBYTE (specversion)));
448 (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
449 (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
451 GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
452 ndevices, ncursors));
454 /* Create a dummy window to receive wintab events */
455 wa.wclass = GDK_INPUT_OUTPUT;
456 wa.event_mask = GDK_ALL_EVENTS_MASK;
461 wa.window_type = GDK_WINDOW_TOPLEVEL;
462 if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
464 g_warning ("gdk_input_wintab_init: gdk_window_new failed");
467 g_object_ref (wintab_window);
469 for (devix = 0; devix < ndevices; devix++)
473 /* We open the Wintab device (hmm, what if there are several, or
474 * can there even be several, probably not?) as a system
475 * pointing device, i.e. it controls the normal Windows
476 * cursor. This seems much more natural.
479 (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
480 devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
482 GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8)));
484 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
485 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
486 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
487 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
488 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
489 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
490 (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
492 defcontext_done = FALSE;
493 if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
495 /* Try to get device-specific default context */
496 /* Some drivers, e.g. Aiptek, don't provide this info */
497 if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
498 defcontext_done = TRUE;
501 GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
503 GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
507 if (!defcontext_done)
508 (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
510 GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
512 lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
514 lc.lcMsgBase = WT_DEFBASE;
516 lc.lcPktData = PACKETDATA;
517 lc.lcPktMode = PACKETMODE;
518 lc.lcMoveMask = PACKETDATA;
519 lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
520 lc.lcOutOrgX = axis_x.axMin;
521 lc.lcOutOrgY = axis_y.axMin;
522 lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
523 lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
524 lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
526 GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
529 hctx = g_new (HCTX, 1);
530 if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
532 g_warning ("gdk_input_wintab_init: WTOpen failed");
535 GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
538 wintab_contexts = g_list_append (wintab_contexts, hctx);
540 (*p_WTEnable) (*hctx, TRUE);
542 (*p_WTOverlap) (*hctx, TRUE);
545 GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
548 /* Increase packet queue size to reduce the risk of lost packets.
549 * According to the specs, if the function fails we must try again
550 * with a smaller queue size.
552 GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
553 for (i = 128; i >= 1; i >>= 1)
555 if ((*p_WTQueueSizeSet) (*hctx, i))
557 GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
562 GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
563 for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
566 GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
569 (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
573 /* Wacom tablets seem to report cursors corresponding to
574 * nonexistent pens or pucks. At least my ArtPad II reports
575 * six cursors: a puck, pressure stylus and eraser stylus,
576 * and then the same three again. I only have a
577 * pressure-sensitive pen. The puck instances, and the
578 * second instances of the styluses report physid zero. So
579 * at least for Wacom, skip cursors with physid zero.
581 (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
582 if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
585 (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
586 csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
587 device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
589 device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
591 "type", GDK_DEVICE_TYPE_FLOATING,
592 "input-source", GDK_SOURCE_PEN,
593 "input-mode", GDK_MODE_SCREEN,
594 "has-cursor", lc.lcOptions & CXO_SYSTEM,
595 "display", _gdk_display,
596 "device-manager", device_manager,
599 device->sends_core = lc.lcOptions & CXO_SYSTEM;
600 if (device->sends_core)
602 _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device));
603 _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
606 g_free (csrname_utf8);
608 device->hctx = *hctx;
609 device->cursor = cursorix;
610 (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
612 if (device->pktdata & PK_X)
614 _gdk_device_add_axis (GDK_DEVICE (device),
619 axis_x.axResolution / 65535);
623 if (device->pktdata & PK_Y)
625 _gdk_device_add_axis (GDK_DEVICE (device),
630 axis_y.axResolution / 65535);
635 if (device->pktdata & PK_NORMAL_PRESSURE)
637 _gdk_device_add_axis (GDK_DEVICE (device),
640 axis_npressure.axMin,
641 axis_npressure.axMax,
642 axis_npressure.axResolution / 65535);
646 /* The wintab driver for the Wacom ArtPad II reports
647 * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
648 * actually sense tilt. Catch this by noticing that the
649 * orientation axis's azimuth resolution is zero.
651 if ((device->pktdata & PK_ORIENTATION) && axis_or[0].axResolution == 0)
653 device->orientation_axes[0] = axis_or[0];
654 device->orientation_axes[1] = axis_or[1];
656 /* Wintab gives us aximuth and altitude, which
657 * we convert to x and y tilt in the -1000..1000 range
659 _gdk_device_add_axis (GDK_DEVICE (device),
666 _gdk_device_add_axis (GDK_DEVICE (device),
675 device->last_axis_data = g_new (gint, num_axes);
677 GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n",
683 for (i = 0; i < gdkdev->info.num_axes; i++)
684 GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
686 gdkdev->axes[i].min_value,
687 gdkdev->axes[i].max_value,
688 gdkdev->axes[i].resolution));
691 device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
694 g_free (device_name);
697 g_free (devname_utf8);
702 gdk_device_manager_win32_constructed (GObject *object)
704 GdkDeviceManagerWin32 *device_manager;
706 device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
707 device_manager->core_pointer =
708 create_pointer (GDK_DEVICE_MANAGER (device_manager),
709 GDK_TYPE_DEVICE_VIRTUAL,
710 "Virtual Core Pointer",
711 GDK_DEVICE_TYPE_MASTER);
712 device_manager->system_pointer =
713 create_pointer (GDK_DEVICE_MANAGER (device_manager),
714 GDK_TYPE_DEVICE_WIN32,
715 "System Aggregated Pointer",
716 GDK_DEVICE_TYPE_SLAVE);
717 _gdk_device_virtual_set_active (device_manager->core_pointer,
718 device_manager->system_pointer);
719 _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
720 _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer);
722 device_manager->core_keyboard =
723 create_keyboard (GDK_DEVICE_MANAGER (device_manager),
724 GDK_TYPE_DEVICE_VIRTUAL,
725 "Virtual Core Keyboard",
726 GDK_DEVICE_TYPE_MASTER);
727 device_manager->system_keyboard =
728 create_keyboard (GDK_DEVICE_MANAGER (device_manager),
729 GDK_TYPE_DEVICE_WIN32,
730 "System Aggregated Keyboard",
731 GDK_DEVICE_TYPE_SLAVE);
732 _gdk_device_virtual_set_active (device_manager->core_keyboard,
733 device_manager->system_keyboard);
734 _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
735 _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard);
737 _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
738 _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
742 gdk_device_manager_win32_list_devices (GdkDeviceManager *device_manager,
745 GdkDeviceManagerWin32 *device_manager_win32;
746 GList *devices = NULL, *l;
748 device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager;
750 if (type == GDK_DEVICE_TYPE_MASTER)
752 devices = g_list_prepend (devices, device_manager_win32->core_keyboard);
753 devices = g_list_prepend (devices, device_manager_win32->core_pointer);
757 if (type == GDK_DEVICE_TYPE_SLAVE)
759 devices = g_list_prepend (devices, device_manager_win32->system_keyboard);
760 devices = g_list_prepend (devices, device_manager_win32->system_pointer);
763 for (l = device_manager_win32->wintab_devices; l != NULL; l = l->next)
765 GdkDevice *device = l->data;
767 if (gdk_device_get_device_type (device) == type)
768 devices = g_list_prepend (devices, device);
772 return g_list_reverse (devices);
776 gdk_device_manager_win32_get_client_pointer (GdkDeviceManager *device_manager)
778 GdkDeviceManagerWin32 *device_manager_win32;
780 device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager;
781 return device_manager_win32->core_pointer;
785 _gdk_input_set_tablet_active (void)
790 /* Bring the contexts to the top of the overlap order when one of the
791 * application's windows is activated */
793 if (!wintab_contexts)
794 return; /* No tablet devices found, or Wintab not initialized yet */
796 GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
797 "Bringing Wintab contexts to the top of the overlap order\n"));
799 tmp_list = wintab_contexts;
803 hctx = (HCTX *) (tmp_list->data);
804 (*p_WTOverlap) (*hctx, TRUE);
805 tmp_list = tmp_list->next;
810 decode_tilt (gint *axis_data,
816 /* As I don't have a tilt-sensing tablet,
817 * I cannot test this code.
819 az = TWOPI * packet->pkOrientation.orAzimuth /
820 (axes[0].axResolution / 65536.);
821 el = TWOPI * packet->pkOrientation.orAltitude /
822 (axes[1].axResolution / 65536.);
825 axis_data[0] = cos (az) * cos (el) * 1000;
827 axis_data[1] = sin (az) * cos (el) * 1000;
831 * Get the currently active keyboard modifiers (ignoring the mouse buttons)
832 * We could use gdk_window_get_pointer but that function does a lot of other
833 * expensive things besides getting the modifiers. This code is somewhat based
834 * on build_pointer_event_state from gdkevents-win32.c
837 get_modifier_key_state (void)
842 /* High-order bit is up/down, low order bit is toggled/untoggled */
843 if (GetKeyState (VK_CONTROL) < 0)
844 state |= GDK_CONTROL_MASK;
845 if (GetKeyState (VK_SHIFT) < 0)
846 state |= GDK_SHIFT_MASK;
847 if (GetKeyState (VK_MENU) < 0)
848 state |= GDK_MOD1_MASK;
849 if (GetKeyState (VK_CAPITAL) & 0x1)
850 state |= GDK_LOCK_MASK;
855 static GdkDeviceWintab *
856 _gdk_device_manager_find_wintab_device (HCTX hctx,
859 GdkDeviceManagerWin32 *device_manager;
860 GdkDeviceWintab *device;
863 device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display));
864 tmp_list = device_manager->wintab_devices;
868 device = tmp_list->data;
869 tmp_list = tmp_list->next;
871 if (device->hctx == hctx &&
872 device->cursor == cursor)
880 _gdk_input_other_event (GdkEvent *event,
884 GdkDeviceManagerWin32 *device_manager;
886 GdkDeviceWintab *source_device = NULL;
887 GdkDeviceGrabInfo *last_grab;
888 GdkEventMask masktest;
896 guint translated_buttons, button_diff, button_mask;
897 /* Translation from tablet button state to GDK button state for
898 * buttons 1-3 - swap button 2 and 3.
900 static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
902 if (event->any.window != wintab_window)
904 g_warning ("_gdk_input_other_event: not wintab_window?");
908 device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display));
910 window = gdk_window_at_pointer (&x, &y);
914 g_object_ref (window);
915 display = gdk_window_get_display (window);
917 GDK_NOTE (EVENTS_OR_INPUT,
918 g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
919 GDK_WINDOW_HWND (window), x, y));
921 if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
923 if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
927 switch (msg->message)
930 /* Don't produce any button or motion events while a window is being
931 * moved or resized, see bug #151090.
933 if (_modal_operation_in_progress)
935 GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
939 if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
940 packet.pkCursor)) == NULL)
943 if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
946 last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (source_device));
948 if (last_grab && last_grab->window)
950 g_object_unref (window);
952 window = g_object_ref (last_grab->window);
955 if (window == _gdk_root)
957 GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
962 if (source_device->pktdata & PK_X)
963 source_device->last_axis_data[num_axes++] = packet.pkX;
964 if (source_device->pktdata & PK_Y)
965 source_device->last_axis_data[num_axes++] = packet.pkY;
966 if (source_device->pktdata & PK_NORMAL_PRESSURE)
967 source_device->last_axis_data[num_axes++] = packet.pkNormalPressure;
968 if (source_device->pktdata & PK_ORIENTATION)
970 decode_tilt (source_device->last_axis_data + num_axes,
971 source_device->orientation_axes, &packet);
975 translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
977 if (translated_buttons != source_device->button_state)
979 /* At least one button has changed state so produce a button event
980 * If more than one button has changed state (unlikely),
981 * just care about the first and act on the next the next time
984 button_diff = translated_buttons ^ source_device->button_state;
986 /* Gdk buttons are numbered 1.. */
987 event->button.button = 1;
989 for (button_mask = 1; button_mask != 0x80000000;
990 button_mask <<= 1, event->button.button++)
992 if (button_diff & button_mask)
994 /* Found a button that has changed state */
999 if (!(translated_buttons & button_mask))
1001 event->any.type = GDK_BUTTON_RELEASE;
1002 masktest = GDK_BUTTON_RELEASE_MASK;
1006 event->any.type = GDK_BUTTON_PRESS;
1007 masktest = GDK_BUTTON_PRESS_MASK;
1009 source_device->button_state ^= button_mask;
1013 event->any.type = GDK_MOTION_NOTIFY;
1014 masktest = GDK_POINTER_MOTION_MASK;
1015 if (source_device->button_state & (1 << 0))
1016 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
1017 if (source_device->button_state & (1 << 1))
1018 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
1019 if (source_device->button_state & (1 << 2))
1020 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
1023 /* Now we can check if the window wants the event, and
1024 * propagate if necessary.
1026 while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 &&
1027 (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE &&
1028 (gdk_window_get_events (window) & masktest) == 0))
1030 GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
1032 if (window->parent == GDK_WINDOW (_gdk_root) ||
1033 window->parent == NULL)
1038 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1039 g_object_unref (window);
1040 window = window->parent;
1041 g_object_ref (window);
1042 ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1045 GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
1046 GDK_WINDOW_HWND (window), x, y));
1049 event->any.window = window;
1050 key_state = get_modifier_key_state ();
1051 if (event->any.type == GDK_BUTTON_PRESS ||
1052 event->any.type == GDK_BUTTON_RELEASE)
1054 event->button.time = _gdk_win32_get_next_tick (msg->time);
1055 if (source_device->sends_core)
1056 gdk_event_set_device (event, device_manager->core_pointer);
1057 gdk_event_set_source_device (event, GDK_DEVICE (source_device));
1059 event->button.axes = g_new (gdouble, num_axes);
1060 gdk_window_get_origin (window, &root_x, &root_y);
1062 _gdk_device_wintab_translate_axes (source_device,
1068 event->button.x_root = event->button.x + root_x;
1069 event->button.y_root = event->button.y + root_y;
1071 event->button.state =
1072 key_state | ((source_device->button_state << 8)
1073 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1074 | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1075 | GDK_BUTTON5_MASK));
1077 GDK_NOTE (EVENTS_OR_INPUT,
1078 g_print ("WINTAB button %s:%d %g,%g\n",
1079 (event->button.type == GDK_BUTTON_PRESS ?
1080 "press" : "release"),
1081 event->button.button,
1082 event->button.x, event->button.y));
1086 event->motion.time = _gdk_win32_get_next_tick (msg->time);
1087 event->motion.is_hint = FALSE;
1088 gdk_event_set_device (event, device_manager->core_pointer);
1089 gdk_event_set_source_device (event, GDK_DEVICE (source_device));
1091 event->motion.axes = g_new (gdouble, num_axes);
1092 gdk_window_get_origin (window, &root_x, &root_y);
1094 _gdk_device_wintab_translate_axes (source_device,
1100 event->motion.x_root = event->motion.x + root_x;
1101 event->motion.y_root = event->motion.y + root_y;
1103 event->motion.state =
1104 key_state | ((source_device->button_state << 8)
1105 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1106 | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1107 | GDK_BUTTON5_MASK));
1109 GDK_NOTE (EVENTS_OR_INPUT,
1110 g_print ("WINTAB motion: %g,%g\n",
1111 event->motion.x, event->motion.y));
1116 if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
1117 packet.pkCursor)) == NULL)
1120 if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
1123 if (source_device->sends_core)
1125 _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device));
1126 _gdk_input_ignore_core = TRUE;
1132 if (LOWORD (msg->lParam) == 0)
1134 _gdk_input_ignore_core = FALSE;
1135 _gdk_device_virtual_set_active (device_manager->core_pointer,
1136 device_manager->system_pointer);