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