1
/* GDK - The GIMP Drawing Kit
2
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3
* Copyright (C) 1998-2002 Tor Lillqvist
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.
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.
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.
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/.
36
#include "gdkinternals.h"
37
#include "gdkprivate-win32.h"
38
#include "gdkinput-win32.h"
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)
47
#define DEBUG_WINTAB 1 /* Verbose debug messages enabled */
49
#define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */
53
#if defined(HAVE_WINTAB) || defined(HAVE_WHATEVER_OTHER)
54
#define HAVE_SOME_XINPUT
57
#define TWOPI (2.*G_PI)
59
/* Forward declarations */
63
static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
65
static GList *wintab_contexts = NULL;
67
static GdkWindow *wintab_window = NULL;
69
#endif /* HAVE_WINTAB */
71
#ifdef HAVE_SOME_XINPUT
73
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
74
* the extended inputs grab
76
static GdkEventMask x_grab_mask;
77
static gboolean x_grab_owner_events;
79
#endif /* HAVE_SOME_XINPUT */
83
static GdkDevicePrivate *
84
gdk_input_find_dev_from_ctx (HCTX hctx,
87
GList *tmp_list = _gdk_input_devices;
88
GdkDevicePrivate *gdkdev;
92
gdkdev = (GdkDevicePrivate *) (tmp_list->data);
93
if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
95
tmp_list = tmp_list->next;
103
print_lc(LOGCONTEXT *lc)
105
g_print ("lcName = %s\n", lc->lcName);
106
g_print ("lcOptions =");
107
if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
108
if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
109
if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
110
if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
111
if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
112
if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
114
g_print ("lcStatus =");
115
if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
116
if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
117
if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
119
g_print ("lcLocks =");
120
if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
121
if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
122
if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
123
if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
125
g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
126
lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
127
g_print ("lcPktData =");
128
if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
129
if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
130
if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
131
if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
132
if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
133
if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
134
if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
135
if (lc->lcPktData & PK_X) g_print (" PK_X");
136
if (lc->lcPktData & PK_Y) g_print (" PK_Y");
137
if (lc->lcPktData & PK_Z) g_print (" PK_Z");
138
if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
139
if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
140
if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
141
if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
143
g_print ("lcPktMode =");
144
if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
145
if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
146
if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
147
if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
148
if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
149
if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
150
if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
151
if (lc->lcPktMode & PK_X) g_print (" PK_X");
152
if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
153
if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
154
if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
155
if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
156
if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
157
if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
159
g_print ("lcMoveMask =");
160
if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
161
if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
162
if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
163
if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
164
if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
165
if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
166
if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
167
if (lc->lcMoveMask & PK_X) g_print (" PK_X");
168
if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
169
if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
170
if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
171
if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
172
if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
173
if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
175
g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
176
(guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
177
g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
178
lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
179
g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
180
lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
181
g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
182
lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
183
g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
184
lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
185
g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
186
lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
187
g_print ("lcSysMode = %d\n", lc->lcSysMode);
188
g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
189
lc->lcSysOrgX, lc->lcSysOrgY);
190
g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
191
lc->lcSysExtX, lc->lcSysExtY);
192
g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
193
lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
197
print_cursor (int index)
222
size = WTInfo (WTI_CURSORS + index, CSR_NAME, NULL);
223
name = g_malloc (size + 1);
224
WTInfo (WTI_CURSORS + index, CSR_NAME, name);
225
g_print ("NAME: %s\n", name);
226
WTInfo (WTI_CURSORS + index, CSR_ACTIVE, &active);
227
g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
228
WTInfo (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
229
g_print ("PKTDATA: %#x:", (guint) wtpkt);
230
#define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
240
BIT (NORMAL_PRESSURE);
241
BIT (TANGENT_PRESSURE);
246
WTInfo (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
247
g_print ("BUTTONS: %d\n", buttons);
248
WTInfo (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
249
g_print ("BUTTONBITS: %d\n", buttonbits);
250
size = WTInfo (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
251
g_print ("BTNNAMES:");
254
btnnames = g_malloc (size + 1);
255
WTInfo (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
264
WTInfo (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
265
g_print ("BUTTONMAP:");
266
for (i = 0; i < buttons; i++)
267
g_print (" %d", buttonmap[i]);
269
WTInfo (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
270
g_print ("SYSBTNMAP:");
271
for (i = 0; i < buttons; i++)
272
g_print (" %d", sysbtnmap[i]);
274
WTInfo (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
275
g_print ("NPBUTTON: %d\n", npbutton);
276
WTInfo (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
277
g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
278
size = WTInfo (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
279
g_print ("NPRESPONSE:");
282
npresponse = g_malloc (size);
283
WTInfo (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
284
for (i = 0; i < size / sizeof (UINT); i++)
285
g_print (" %d", npresponse[i]);
288
WTInfo (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
289
g_print ("TPBUTTON: %d\n", tpbutton);
290
WTInfo (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
291
g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
292
size = WTInfo (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
293
g_print ("TPRESPONSE:");
296
tpresponse = g_malloc (size);
297
WTInfo (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
298
for (i = 0; i < size / sizeof (UINT); i++)
299
g_print (" %d", tpresponse[i]);
302
WTInfo (WTI_CURSORS + index, CSR_PHYSID, &physid);
303
g_print ("PHYSID: %#x\n", (guint) physid);
304
WTInfo (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
305
g_print ("CAPABILITIES: %#x:", capabilities);
306
#define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
312
if (capabilities & CRC_MULTIMODE)
314
WTInfo (WTI_CURSORS + index, CSR_MODE, &mode);
315
g_print ("MODE: %d\n", mode);
317
if (capabilities & CRC_AGGREGATE)
319
WTInfo (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
320
g_print ("MINPKTDATA: %d\n", minpktdata);
321
WTInfo (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
322
g_print ("MINBUTTONS: %d\n", minbuttons);
328
_gdk_input_wintab_init_check (void)
330
static gboolean wintab_initialized = FALSE;
331
GdkDevicePrivate *gdkdev;
335
UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
338
AXIS axis_x, axis_y, axis_npressure, axis_or[3];
341
char devname[100], csrname[100];
342
BOOL defcontext_done;
344
if (wintab_initialized)
347
wintab_initialized = TRUE;
349
wintab_contexts = NULL;
351
if (!_gdk_input_ignore_wintab &&
354
WTInfo (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
355
GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
356
HIBYTE (specversion), LOBYTE (specversion)));
357
WTInfo (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
358
WTInfo (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
360
GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
361
ndevices, ncursors));
363
/* Create a dummy window to receive wintab events */
364
wa.wclass = GDK_INPUT_OUTPUT;
365
wa.event_mask = GDK_ALL_EVENTS_MASK;
370
wa.window_type = GDK_WINDOW_TOPLEVEL;
371
if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
373
g_warning ("gdk_input_wintab_init: gdk_window_new failed");
376
g_object_ref (wintab_window);
378
for (devix = 0; devix < ndevices; devix++)
382
/* We open the Wintab device (hmm, what if there are several?) as a
383
* system pointing device, i.e. it controls the normal Windows
384
* cursor. This seems much more natural.
387
WTInfo (WTI_DEVICES + devix, DVC_NAME, devname);
389
WTInfo (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
390
WTInfo (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
391
WTInfo (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
392
WTInfo (WTI_DEVICES + devix, DVC_X, &axis_x);
393
WTInfo (WTI_DEVICES + devix, DVC_Y, &axis_y);
394
WTInfo (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
395
WTInfo (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
397
defcontext_done = FALSE;
398
if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
400
/* Try to get device-specific default context */
401
/* Some drivers, e.g. Aiptek, don't provide this info */
402
if (WTInfo (WTI_DSCTXS + devix, 0, &lc) > 0)
403
defcontext_done = TRUE;
406
GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
408
GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
412
if (!defcontext_done)
413
WTInfo (WTI_DEFSYSCTX, 0, &lc);
415
GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
417
lc.lcOptions |= CXO_MESSAGES;
419
lc.lcMsgBase = WT_DEFBASE;
421
lc.lcPktData = PACKETDATA;
422
lc.lcPktMode = PACKETMODE;
423
lc.lcMoveMask = PACKETDATA;
424
lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
425
lc.lcOutOrgX = axis_x.axMin;
426
lc.lcOutOrgY = axis_y.axMin;
427
lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
428
lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
429
lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
431
GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
434
hctx = g_new (HCTX, 1);
435
if ((*hctx = WTOpen (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
437
g_warning ("gdk_input_wintab_init: WTOpen failed");
440
GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
443
wintab_contexts = g_list_append (wintab_contexts, hctx);
445
WTEnable (*hctx, TRUE);
447
WTOverlap (*hctx, TRUE);
450
GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
453
/* Increase packet queue size to reduce the risk of lost packets */
454
/* According to the specs, if the function fails we must try again */
455
/* with a smaller queue size */
456
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
457
for (i = 32; i >= 1; i >>= 1)
459
if (WTQueueSizeSet(*hctx, i))
461
GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
466
GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
467
for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
470
GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
473
WTInfo (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
477
/* Wacom tablets seem to report cursors corresponding to
478
* nonexistent pens or pucks. At least my ArtPad II
479
* reports six cursors: a puck, pressure stylus and
480
* eraser stylus, and then the same three again. I only
481
* have a pressure-sensitive pen. The puck instances,
482
* and the second instances of the styluses report
483
* physid zero. So at least for Wacom, skip cursors with
486
WTInfo (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
487
if (strcmp (devname, "WACOM Tablet") == 0 && physid == 0)
490
gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
492
WTInfo (WTI_CURSORS + cursorix, CSR_NAME, csrname);
493
gdkdev->info.name = g_strconcat (devname, " ", csrname, NULL);
494
gdkdev->info.source = GDK_SOURCE_PEN;
495
gdkdev->info.mode = GDK_MODE_SCREEN;
496
gdkdev->info.has_cursor = TRUE;
497
gdkdev->hctx = *hctx;
498
gdkdev->cursor = cursorix;
499
WTInfo (WTI_CURSORS + cursorix, CSR_PKTDATA, &gdkdev->pktdata);
500
gdkdev->info.num_axes = 0;
501
if (gdkdev->pktdata & PK_X)
502
gdkdev->info.num_axes++;
503
if (gdkdev->pktdata & PK_Y)
504
gdkdev->info.num_axes++;
505
if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
506
gdkdev->info.num_axes++;
507
/* The wintab driver for the Wacom ArtPad II reports
508
* PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
509
* actually sense tilt. Catch this by noticing that the
510
* orientation axis's azimuth resolution is zero.
512
if ((gdkdev->pktdata & PK_ORIENTATION)
513
&& axis_or[0].axResolution == 0)
514
gdkdev->pktdata &= ~PK_ORIENTATION;
516
if (gdkdev->pktdata & PK_ORIENTATION)
517
gdkdev->info.num_axes += 2; /* x and y tilt */
518
WTInfo (WTI_CURSORS + cursorix, CSR_NPBTNMARKS, &gdkdev->npbtnmarks);
519
gdkdev->info.axes = g_new (GdkDeviceAxis, gdkdev->info.num_axes);
520
gdkdev->axes = g_new (GdkAxisInfo, gdkdev->info.num_axes);
521
gdkdev->last_axis_data = g_new (gint, gdkdev->info.num_axes);
524
if (gdkdev->pktdata & PK_X)
526
gdkdev->axes[k].xresolution =
527
gdkdev->axes[k].resolution = axis_x.axResolution / 65535.;
528
gdkdev->axes[k].xmin_value =
529
gdkdev->axes[k].min_value = axis_x.axMin;
530
gdkdev->axes[k].xmax_value =
531
gdkdev->axes[k].max_value = axis_x.axMax;
532
gdkdev->info.axes[k].use = GDK_AXIS_X;
533
gdkdev->info.axes[k].min = axis_x.axMin;
534
gdkdev->info.axes[k].max = axis_x.axMax;
537
if (gdkdev->pktdata & PK_Y)
539
gdkdev->axes[k].xresolution =
540
gdkdev->axes[k].resolution = axis_y.axResolution / 65535.;
541
gdkdev->axes[k].xmin_value =
542
gdkdev->axes[k].min_value = axis_y.axMin;
543
gdkdev->axes[k].xmax_value =
544
gdkdev->axes[k].max_value = axis_y.axMax;
545
gdkdev->info.axes[k].use = GDK_AXIS_Y;
546
gdkdev->info.axes[k].min = axis_y.axMin;
547
gdkdev->info.axes[k].max = axis_y.axMax;
550
if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
552
gdkdev->axes[k].xresolution =
553
gdkdev->axes[k].resolution = axis_npressure.axResolution / 65535.;
554
gdkdev->axes[k].xmin_value =
555
gdkdev->axes[k].min_value = axis_npressure.axMin;
556
gdkdev->axes[k].xmax_value =
557
gdkdev->axes[k].max_value = axis_npressure.axMax;
558
gdkdev->info.axes[k].use = GDK_AXIS_PRESSURE;
559
/* GIMP seems to expect values in the range 0-1 */
560
gdkdev->info.axes[k].min = 0.0; /*axis_npressure.axMin;*/
561
gdkdev->info.axes[k].max = 1.0; /*axis_npressure.axMax;*/
564
if (gdkdev->pktdata & PK_ORIENTATION)
568
gdkdev->orientation_axes[0] = axis_or[0];
569
gdkdev->orientation_axes[1] = axis_or[1];
570
for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++)
572
/* Wintab gives us aximuth and altitude, which
573
* we convert to x and y tilt in the -1000..1000 range
575
gdkdev->axes[k].xresolution =
576
gdkdev->axes[k].resolution = 1000;
577
gdkdev->axes[k].xmin_value =
578
gdkdev->axes[k].min_value = -1000;
579
gdkdev->axes[k].xmax_value =
580
gdkdev->axes[k].max_value = 1000;
581
gdkdev->info.axes[k].use = axis;
582
gdkdev->info.axes[k].min = -1000;
583
gdkdev->info.axes[k].max = 1000;
587
gdkdev->info.num_keys = 0;
588
gdkdev->info.keys = NULL;
590
g_print ("device: (%d) %s axes: %d\n",
593
gdkdev->info.num_axes));
594
for (i = 0; i < gdkdev->info.num_axes; i++)
596
g_print ("... axis %d: %d--%d@%d (%d--%d@%d)\n",
598
gdkdev->axes[i].xmin_value,
599
gdkdev->axes[i].xmax_value,
600
gdkdev->axes[i].xresolution,
601
gdkdev->axes[i].min_value,
602
gdkdev->axes[i].max_value,
603
gdkdev->axes[i].resolution));
604
_gdk_input_devices = g_list_append (_gdk_input_devices,
612
decode_tilt (gint *axis_data,
616
/* As I don't have a tilt-sensing tablet,
617
* I cannot test this code.
622
az = TWOPI * packet->pkOrientation.orAzimuth /
623
(axes[0].axResolution / 65536.);
624
el = TWOPI * packet->pkOrientation.orAltitude /
625
(axes[1].axResolution / 65536.);
628
axis_data[0] = cos (az) * cos (el) * 1000;
630
axis_data[1] = sin (az) * cos (el) * 1000;
633
#endif /* HAVE_WINTAB */
636
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
637
GdkInputWindow *input_window,
643
GdkWindowImplWin32 *impl, *root_impl;
649
double device_width, device_height;
650
double x_offset, y_offset, x_scale, y_scale;
652
impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (input_window->window)->impl);
654
for (i=0; i<gdkdev->info.num_axes; i++)
656
switch (gdkdev->info.axes[i].use)
669
device_width = gdkdev->axes[x_axis].max_value -
670
gdkdev->axes[x_axis].min_value;
671
device_height = gdkdev->axes[y_axis].max_value -
672
gdkdev->axes[y_axis].min_value;
674
if (gdkdev->info.mode == GDK_MODE_SCREEN)
676
root_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl);
677
x_scale = root_impl->width / device_width;
678
y_scale = root_impl->height / device_height;
680
x_offset = - input_window->root_x;
681
y_offset = - input_window->root_y;
683
else /* GDK_MODE_WINDOW */
685
double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
686
(device_width*gdkdev->axes[x_axis].resolution);
688
if (device_aspect * impl->width >= impl->height)
690
/* device taller than window */
691
x_scale = impl->width / device_width;
692
y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
693
/ gdkdev->axes[y_axis].resolution;
696
y_offset = -(device_height * y_scale -
701
/* window taller than device */
702
y_scale = impl->height / device_height;
703
x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
704
/ gdkdev->axes[x_axis].resolution;
707
x_offset = - (device_width * x_scale - impl->width)/2;
711
for (i=0; i<gdkdev->info.num_axes; i++)
713
switch (gdkdev->info.axes[i].use)
716
axis_out[i] = x_offset + x_scale*axis_data[x_axis];
718
*x_out = axis_out[i];
721
axis_out[i] = y_offset + y_scale*axis_data[y_axis];
723
*y_out = axis_out[i];
727
(gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
728
gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
729
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
736
gdk_input_get_root_relative_geometry (HWND w,
742
GetWindowRect (w, &rect);
745
*x_ret = rect.left + _gdk_offset_x;
747
*y_ret = rect.top + _gdk_offset_y;
751
_gdk_input_configure_event (GdkWindow *window)
753
GdkInputWindow *input_window;
756
input_window = _gdk_input_window_find (window);
757
g_return_if_fail (window != NULL);
759
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
762
input_window->root_x = root_x;
763
input_window->root_y = root_y;
767
_gdk_input_enter_event (GdkWindow *window)
769
GdkInputWindow *input_window;
772
input_window = _gdk_input_window_find (window);
773
g_return_if_fail (window != NULL);
775
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &root_x, &root_y);
777
input_window->root_x = root_x;
778
input_window->root_y = root_y;
782
* Get the currently active keyboard modifiers (ignoring the mouse buttons)
783
* We could use gdk_window_get_pointer but that function does a lot of other
784
* expensive things besides getting the modifiers. This code is somewhat based
785
* on build_pointer_event_state from gdkevents-win32.c
788
get_modifier_key_state (void)
793
/* High-order bit is up/down, low order bit is toggled/untoggled */
794
if (GetKeyState (VK_CONTROL) < 0)
795
state |= GDK_CONTROL_MASK;
796
if (GetKeyState (VK_SHIFT) < 0)
797
state |= GDK_SHIFT_MASK;
798
if (GetKeyState (VK_MENU) < 0)
799
state |= GDK_MOD1_MASK;
800
if (GetKeyState (VK_CAPITAL) & 0x1)
801
state |= GDK_LOCK_MASK;
808
static guint ignore_core_timer = 0;
811
ignore_core_timefunc (gpointer data)
813
/* The delay has passed */
814
_gdk_input_ignore_core = FALSE;
815
ignore_core_timer = 0;
817
return FALSE; /* remove timeout */
821
* Set or unset the _gdk_input_ignore_core variable that tells GDK
822
* to ignore events for the core pointer when the tablet is in proximity
823
* The unsetting is delayed slightly so that if a tablet event arrives
824
* just after proximity out, it does not cause a core pointer event
825
* which e.g. causes GIMP to switch tools.
828
set_ignore_core (gboolean ignore)
832
_gdk_input_ignore_core = TRUE;
833
/* Remove any pending clear */
834
if (ignore_core_timer)
836
g_source_remove (ignore_core_timer);
837
ignore_core_timer = 0;
841
if (!ignore_core_timer)
842
ignore_core_timer = g_timeout_add (PROXIMITY_OUT_DELAY,
843
ignore_core_timefunc, NULL);
845
#endif /* HAVE_WINTAB */
848
_gdk_input_other_event (GdkEvent *event,
854
GdkWindowObject *obj, *grab_obj;
855
GdkInputWindow *input_window;
856
GdkDevicePrivate *gdkdev = NULL;
857
GdkEventMask masktest;
864
guint translated_buttons, button_diff, button_mask;
865
/* Translation from tablet button state to GDK button state for
866
* buttons 1-3 - swap button 2 and 3.
868
static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
870
if (event->any.window != wintab_window)
872
g_warning ("_gdk_input_other_event: not wintab_window?");
876
window = gdk_window_at_pointer (&x, &y);
880
g_object_ref (window);
881
display = gdk_drawable_get_display (window);
883
GDK_NOTE (EVENTS_OR_INPUT,
884
g_print ("gdk_input_win32_other_event: window=%p %+d%+d\n",
885
GDK_WINDOW_HWND (window), x, y));
887
if (msg->message == WT_PACKET)
889
if (!WTPacket ((HCTX) msg->lParam, msg->wParam, &packet))
893
obj = GDK_WINDOW_OBJECT (window);
895
switch (msg->message)
898
/* Don't produce any button or motion events while a window is being
899
* moved or resized, see bug #151090. */
900
if (_sizemove_in_progress)
902
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
905
if (window == _gdk_root && x_grab_window == NULL)
907
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
911
if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
912
packet.pkCursor)) == NULL)
915
if (gdkdev->info.mode == GDK_MODE_DISABLED)
919
if (gdkdev->pktdata & PK_X)
920
gdkdev->last_axis_data[k++] = packet.pkX;
921
if (gdkdev->pktdata & PK_Y)
922
gdkdev->last_axis_data[k++] = packet.pkY;
923
if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
924
gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
925
if (gdkdev->pktdata & PK_ORIENTATION)
927
decode_tilt (gdkdev->last_axis_data + k,
928
gdkdev->orientation_axes, &packet);
932
g_assert (k == gdkdev->info.num_axes);
934
translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
936
if (translated_buttons != gdkdev->button_state)
938
/* At least one button has changed state so produce a button event
939
* If more than one button has changed state (unlikely),
940
* just care about the first and act on the next the next time
943
button_diff = translated_buttons ^ gdkdev->button_state;
945
/* Gdk buttons are numbered 1.. */
946
event->button.button = 1;
948
for (button_mask = 1; button_mask != 0x80000000;
949
button_mask <<= 1, event->button.button++)
951
if (button_diff & button_mask)
953
/* Found a button that has changed state */
958
if (!(translated_buttons & button_mask))
960
event->any.type = GDK_BUTTON_RELEASE;
961
masktest = GDK_BUTTON_RELEASE_MASK;
965
event->any.type = GDK_BUTTON_PRESS;
966
masktest = GDK_BUTTON_PRESS_MASK;
968
gdkdev->button_state ^= button_mask;
972
event->any.type = GDK_MOTION_NOTIFY;
973
masktest = GDK_POINTER_MOTION_MASK;
974
if (gdkdev->button_state & (1 << 0))
975
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
976
if (gdkdev->button_state & (1 << 1))
977
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
978
if (gdkdev->button_state & (1 << 2))
979
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
982
/* See if input is grabbed */
983
/* FIXME: x_grab_owner_events should probably be handled somehow */
984
if (x_grab_window != NULL)
986
grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
987
if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
988
|| !(grab_obj->extension_events & masktest)
989
|| !(x_grab_mask && masktest))
991
GDK_NOTE (EVENTS_OR_INPUT,
992
g_print ("... grabber doesn't want it\n"));
995
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
997
g_object_ref(x_grab_window);
998
g_object_unref(window);
999
window = x_grab_window;
1002
/* Now we can check if the window wants the event, and
1003
* propagate if necessary.
1006
if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
1007
|| !(obj->extension_events & masktest))
1009
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
1011
if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
1014
/* It is not good to propagate the extended events up to the parent
1015
* if this window wants normal (not extended) motion/button events */
1016
if (obj->event_mask & masktest)
1018
GDK_NOTE (EVENTS_OR_INPUT,
1019
g_print ("... wants ordinary event, ignoring this\n"));
1025
ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1026
g_object_unref (window);
1027
window = (GdkWindow *) obj->parent;
1028
obj = GDK_WINDOW_OBJECT (window);
1029
g_object_ref (window);
1030
ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1033
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
1034
GDK_WINDOW_HWND (window), x, y));
1038
input_window = _gdk_input_window_find (window);
1040
g_assert (input_window != NULL);
1042
if (gdkdev->info.mode == GDK_MODE_WINDOW
1043
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
1046
event->any.window = window;
1047
key_state = get_modifier_key_state ();
1048
if (event->any.type == GDK_BUTTON_PRESS
1049
|| event->any.type == GDK_BUTTON_RELEASE)
1051
event->button.time = _gdk_win32_get_next_tick (msg->time);
1052
event->button.device = &gdkdev->info;
1054
event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
1056
gdk_input_translate_coordinates (gdkdev, input_window,
1057
gdkdev->last_axis_data,
1062
/* Also calculate root coordinates. Note that input_window->root_x
1063
is in GDK root coordinates. */
1064
event->button.x_root = event->button.x + input_window->root_x;
1065
event->button.y_root = event->button.y + input_window->root_y;
1067
event->button.state = ((gdkdev->button_state << 8)
1068
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1069
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1070
| GDK_BUTTON5_MASK))
1072
GDK_NOTE (EVENTS_OR_INPUT,
1073
g_print ("WINTAB button %s:%d %g,%g\n",
1074
(event->button.type == GDK_BUTTON_PRESS ?
1075
"press" : "release"),
1076
event->button.button,
1077
event->button.x, event->button.y));
1081
event->motion.time = _gdk_win32_get_next_tick (msg->time);
1082
event->motion.is_hint = FALSE;
1083
event->motion.device = &gdkdev->info;
1085
event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
1087
gdk_input_translate_coordinates (gdkdev, input_window,
1088
gdkdev->last_axis_data,
1093
/* Also calculate root coordinates. Note that input_window->root_x
1094
is in GDK root coordinates. */
1095
event->motion.x_root = event->motion.x + input_window->root_x;
1096
event->motion.y_root = event->motion.y + input_window->root_y;
1098
event->motion.state = ((gdkdev->button_state << 8)
1099
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1100
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1101
| GDK_BUTTON5_MASK))
1104
GDK_NOTE (EVENTS_OR_INPUT,
1105
g_print ("WINTAB motion: %g,%g\n",
1106
event->motion.x, event->motion.y));
1111
if (LOWORD (msg->lParam) == 0)
1113
event->proximity.type = GDK_PROXIMITY_OUT;
1114
set_ignore_core (FALSE);
1118
event->proximity.type = GDK_PROXIMITY_IN;
1119
set_ignore_core (TRUE);
1121
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1122
event->proximity.device = &gdkdev->info;
1124
GDK_NOTE (EVENTS_OR_INPUT,
1125
g_print ("WINTAB proximity %s\n",
1126
(event->proximity.type == GDK_PROXIMITY_IN ?
1135
_gdk_input_enable_window (GdkWindow *window,
1136
GdkDevicePrivate *gdkdev)
1138
#ifdef HAVE_SOME_XINPUT
1139
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1141
impl->extension_events_selected = TRUE;
1148
_gdk_input_disable_window (GdkWindow *window,
1149
GdkDevicePrivate *gdkdev)
1151
#ifdef HAVE_SOME_XINPUT
1152
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1154
impl->extension_events_selected = FALSE;
1161
_gdk_input_grab_pointer (GdkWindow *window,
1163
GdkEventMask event_mask,
1164
GdkWindow *confine_to,
1167
#ifdef HAVE_SOME_XINPUT
1168
GdkInputWindow *input_window, *new_window;
1169
gboolean need_ungrab;
1170
GdkDevicePrivate *gdkdev;
1173
tmp_list = _gdk_input_windows;
1175
need_ungrab = FALSE;
1177
GDK_NOTE (INPUT, g_print ("gdk_input_win32_grab_pointer: %p %d %p\n",
1178
GDK_WINDOW_HWND (window),
1180
(confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
1184
input_window = (GdkInputWindow *)tmp_list->data;
1186
if (input_window->window == window)
1187
new_window = input_window;
1188
else if (input_window->grabbed)
1190
input_window->grabbed = FALSE;
1194
tmp_list = tmp_list->next;
1199
new_window->grabbed = TRUE;
1200
x_grab_window = window;
1201
x_grab_mask = event_mask;
1202
x_grab_owner_events = owner_events;
1204
/* FIXME: Do we need to handle confine_to and time? */
1206
tmp_list = _gdk_input_devices;
1209
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1210
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
1214
gdk_input_common_find_events (window, gdkdev,
1216
event_classes, &num_classes);
1218
result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
1219
GDK_WINDOW_XWINDOW (window),
1220
owner_events, num_classes, event_classes,
1221
GrabModeAsync, GrabModeAsync, time);
1223
/* FIXME: if failure occurs on something other than the first
1224
device, things will be badly inconsistent */
1225
if (result != Success)
1229
tmp_list = tmp_list->next;
1234
x_grab_window = NULL;
1236
tmp_list = _gdk_input_devices;
1239
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1240
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
1241
((gdkdev->button_state != 0) || need_ungrab))
1245
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1247
gdkdev->button_state = 0;
1250
tmp_list = tmp_list->next;
1256
return GDK_GRAB_SUCCESS;
1260
_gdk_input_ungrab_pointer (guint32 time)
1262
#ifdef HAVE_SOME_XINPUT
1263
GdkInputWindow *input_window;
1264
GdkDevicePrivate *gdkdev;
1267
GDK_NOTE (INPUT, g_print ("gdk_input_win32_ungrab_pointer\n"));
1269
tmp_list = _gdk_input_windows;
1272
input_window = (GdkInputWindow *)tmp_list->data;
1273
if (input_window->grabbed)
1275
tmp_list = tmp_list->next;
1278
if (tmp_list) /* we found a grabbed window */
1280
input_window->grabbed = FALSE;
1282
tmp_list = _gdk_input_devices;
1285
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1288
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
1289
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1291
tmp_list = tmp_list->next;
1294
x_grab_window = NULL;
1299
_gdk_device_get_history (GdkDevice *device,
1303
GdkTimeCoord ***events,
1310
gdk_device_get_state (GdkDevice *device,
1313
GdkModifierType *mask)
1315
g_return_if_fail (device != NULL);
1316
g_return_if_fail (GDK_IS_WINDOW (window));
1318
if (GDK_IS_CORE (device))
1322
gdk_window_get_pointer (window, &x_int, &y_int, mask);
1332
GdkDevicePrivate *gdkdev;
1333
GdkInputWindow *input_window;
1335
gdkdev = (GdkDevicePrivate *)device;
1336
/* For now just use the last known button and axis state of the device.
1337
* Since graphical tablets send an insane amount of motion events each
1338
* second, the info should be fairly up to date */
1341
gdk_window_get_pointer (window, NULL, NULL, mask);
1342
*mask &= 0xFF; /* Mask away core pointer buttons */
1343
*mask |= ((gdkdev->button_state << 8)
1344
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
1345
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1346
| GDK_BUTTON5_MASK));
1348
input_window = _gdk_input_window_find (window);
1349
g_return_if_fail (input_window != NULL);
1350
/* For some reason, input_window is sometimes NULL when I use The GIMP 2
1351
* (bug #141543?). Avoid crashing if debugging is disabled. */
1352
if (axes && gdkdev->last_axis_data && input_window)
1353
gdk_input_translate_coordinates (gdkdev, input_window,
1354
gdkdev->last_axis_data,
1361
_gdk_input_set_tablet_active (void)
1366
/* Bring the contexts to the top of the overlap order when one of the
1367
* application's windows is activated */
1369
if (!wintab_contexts)
1370
return; /* No tablet devices found, or Wintab not initialized yet */
1372
GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
1373
"Bringing Wintab contexts to the top of the overlap order\n"));
1375
tmp_list = wintab_contexts;
1378
hctx = (HCTX *) (tmp_list->data);
1379
WTOverlap (*hctx, TRUE);
1380
tmp_list = tmp_list->next;
1383
#endif /* HAVE_WINTAB */
1386
_gdk_input_init (GdkDisplay *display)
1388
_gdk_input_ignore_core = FALSE;
1389
_gdk_input_devices = NULL;
1391
_gdk_init_input_core (display);
1393
#ifdef WINTAB_NO_LAZY_INIT
1394
/* Normally, Wintab is only initialized when the application performs
1395
* an action that requires it, such as enabling extended input events
1396
* for a window or enumerating the devices.
1398
_gdk_input_wintab_init_check ();
1399
#endif /* WINTAB_NO_LAZY_INIT */
1400
#endif /* HAVE_WINTAB */
1402
_gdk_input_devices = g_list_append (_gdk_input_devices, display->core_pointer);