~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to gdk/win32/gdkinput-win32.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
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
#ifdef HAVE_WINTAB
 
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
#endif
 
52
 
 
53
#if defined(HAVE_WINTAB) || defined(HAVE_WHATEVER_OTHER)
 
54
#define HAVE_SOME_XINPUT
 
55
#endif
 
56
 
 
57
#define TWOPI (2.*G_PI)
 
58
 
 
59
/* Forward declarations */
 
60
 
 
61
#ifdef HAVE_WINTAB
 
62
 
 
63
static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
 
64
                                                      UINT id);
 
65
static GList     *wintab_contexts = NULL;
 
66
 
 
67
static GdkWindow *wintab_window = NULL;
 
68
 
 
69
#endif /* HAVE_WINTAB */
 
70
 
 
71
#ifdef HAVE_SOME_XINPUT
 
72
 
 
73
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
 
74
                                         * the extended inputs grab
 
75
                                         */
 
76
static GdkEventMask x_grab_mask;
 
77
static gboolean x_grab_owner_events;
 
78
 
 
79
#endif /* HAVE_SOME_XINPUT */
 
80
 
 
81
#ifdef HAVE_WINTAB
 
82
 
 
83
static GdkDevicePrivate *
 
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
#if DEBUG_WINTAB
 
101
 
 
102
static void
 
103
print_lc(LOGCONTEXT *lc)
 
104
{
 
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");
 
113
  g_print ("\n");
 
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");
 
118
  g_print ("\n");
 
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");
 
124
  g_print ("\n");
 
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");
 
142
  g_print ("\n");
 
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");
 
158
  g_print ("\n");
 
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");
 
174
  g_print ("\n");
 
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.);
 
194
}
 
195
 
 
196
static void
 
197
print_cursor (int index)
 
198
{
 
199
  int size;
 
200
  int i;
 
201
  char *name;
 
202
  BOOL active;
 
203
  WTPKT wtpkt;
 
204
  BYTE buttons;
 
205
  BYTE buttonbits;
 
206
  char *btnnames;
 
207
  char *p;
 
208
  BYTE buttonmap[32];
 
209
  BYTE sysbtnmap[32];
 
210
  BYTE npbutton;
 
211
  UINT npbtnmarks[2];
 
212
  UINT *npresponse;
 
213
  BYTE tpbutton;
 
214
  UINT tpbtnmarks[2];
 
215
  UINT *tpresponse;
 
216
  DWORD physid;
 
217
  UINT mode;
 
218
  UINT minpktdata;
 
219
  UINT minbuttons;
 
220
  UINT capabilities;
 
221
 
 
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)
 
231
  BIT (CONTEXT);
 
232
  BIT (STATUS);
 
233
  BIT (TIME);
 
234
  BIT (CHANGED);
 
235
  BIT (SERIAL_NUMBER);
 
236
  BIT (BUTTONS);
 
237
  BIT (X);
 
238
  BIT (Y);
 
239
  BIT (Z);
 
240
  BIT (NORMAL_PRESSURE);
 
241
  BIT (TANGENT_PRESSURE);
 
242
  BIT (ORIENTATION);
 
243
  BIT (ROTATION);
 
244
#undef BIT
 
245
  g_print ("\n");
 
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:");
 
252
  if (size > 0)
 
253
    {
 
254
      btnnames = g_malloc (size + 1);
 
255
      WTInfo (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
 
256
      p = btnnames;
 
257
      while (*p)
 
258
        {
 
259
          g_print (" %s", p);
 
260
          p += strlen (p) + 1;
 
261
        }
 
262
    }
 
263
  g_print ("\n");
 
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]);
 
268
  g_print ("\n");
 
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]);
 
273
  g_print ("\n");
 
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:");
 
280
  if (size > 0)
 
281
    {
 
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]);
 
286
    }
 
287
  g_print ("\n");
 
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:");
 
294
  if (size > 0)
 
295
    {
 
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]);
 
300
    }
 
301
  g_print ("\n");
 
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)
 
307
  BIT (MULTIMODE);
 
308
  BIT (AGGREGATE);
 
309
  BIT (INVERT);
 
310
#undef BIT
 
311
  g_print ("\n");
 
312
  if (capabilities & CRC_MULTIMODE)
 
313
    {
 
314
      WTInfo (WTI_CURSORS + index, CSR_MODE, &mode);
 
315
      g_print ("MODE: %d\n", mode);
 
316
    }
 
317
  if (capabilities & CRC_AGGREGATE)
 
318
    {
 
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);
 
323
    }
 
324
}
 
325
#endif
 
326
 
 
327
void
 
328
_gdk_input_wintab_init_check (void)
 
329
{
 
330
  static gboolean wintab_initialized = FALSE;
 
331
  GdkDevicePrivate *gdkdev;
 
332
  GdkWindowAttr wa;
 
333
  WORD specversion;
 
334
  HCTX *hctx;
 
335
  UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
 
336
  BOOL active;
 
337
  DWORD physid;
 
338
  AXIS axis_x, axis_y, axis_npressure, axis_or[3];
 
339
  int i, k;
 
340
  int devix, cursorix;
 
341
  char devname[100], csrname[100];
 
342
  BOOL defcontext_done;
 
343
 
 
344
  if (wintab_initialized)
 
345
    return;
 
346
  
 
347
  wintab_initialized = TRUE;
 
348
  
 
349
  wintab_contexts = NULL;
 
350
 
 
351
  if (!_gdk_input_ignore_wintab &&
 
352
      WTInfo (0, 0, NULL))
 
353
    {
 
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);
 
359
#if DEBUG_WINTAB
 
360
      GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
 
361
                               ndevices, ncursors));
 
362
#endif
 
363
      /* Create a dummy window to receive wintab events */
 
364
      wa.wclass = GDK_INPUT_OUTPUT;
 
365
      wa.event_mask = GDK_ALL_EVENTS_MASK;
 
366
      wa.width = 2;
 
367
      wa.height = 2;
 
368
      wa.x = -100;
 
369
      wa.y = -100;
 
370
      wa.window_type = GDK_WINDOW_TOPLEVEL;
 
371
      if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
 
372
        {
 
373
          g_warning ("gdk_input_wintab_init: gdk_window_new failed");
 
374
          return;
 
375
        }
 
376
      g_object_ref (wintab_window);
 
377
      
 
378
      for (devix = 0; devix < ndevices; devix++)
 
379
        {
 
380
          LOGCONTEXT lc;
 
381
          
 
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.
 
385
           */
 
386
 
 
387
          WTInfo (WTI_DEVICES + devix, DVC_NAME, devname);
 
388
      
 
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);
 
396
 
 
397
          defcontext_done = FALSE;
 
398
          if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
 
399
            {
 
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;
 
404
#if DEBUG_WINTAB
 
405
              if (defcontext_done)
 
406
                GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
 
407
              else
 
408
                GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
 
409
#endif
 
410
            }
 
411
 
 
412
          if (!defcontext_done)
 
413
            WTInfo (WTI_DEFSYSCTX, 0, &lc);
 
414
#if DEBUG_WINTAB
 
415
          GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
 
416
#endif
 
417
          lc.lcOptions |= CXO_MESSAGES;
 
418
          lc.lcStatus = 0;
 
419
          lc.lcMsgBase = WT_DEFBASE;
 
420
          lc.lcPktRate = 50;
 
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 */
 
430
#if DEBUG_WINTAB
 
431
          GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
 
432
                           print_lc(&lc)));
 
433
#endif
 
434
          hctx = g_new (HCTX, 1);
 
435
          if ((*hctx = WTOpen (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
 
436
            {
 
437
              g_warning ("gdk_input_wintab_init: WTOpen failed");
 
438
              return;
 
439
            }
 
440
          GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
 
441
                                   devix, *hctx));
 
442
 
 
443
          wintab_contexts = g_list_append (wintab_contexts, hctx);
 
444
#if 0
 
445
          WTEnable (*hctx, TRUE);
 
446
#endif
 
447
          WTOverlap (*hctx, TRUE);
 
448
 
 
449
#if DEBUG_WINTAB
 
450
          GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
 
451
                           print_lc(&lc)));
 
452
#endif
 
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)
 
458
            {
 
459
              if (WTQueueSizeSet(*hctx, i))
 
460
                {
 
461
                  GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
 
462
                  break;
 
463
                }
 
464
            }
 
465
          if (!i)
 
466
            GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
 
467
          for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
 
468
            {
 
469
#ifdef DEBUG_WINTAB
 
470
              GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
 
471
#endif
 
472
              active = FALSE;
 
473
              WTInfo (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
 
474
              if (!active)
 
475
                continue;
 
476
 
 
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
 
484
               * physid zero.
 
485
               */
 
486
              WTInfo (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
 
487
              if (strcmp (devname, "WACOM Tablet") == 0 && physid == 0)
 
488
                continue;
 
489
 
 
490
              gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
 
491
 
 
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.
 
511
               */
 
512
              if ((gdkdev->pktdata & PK_ORIENTATION)
 
513
                  && axis_or[0].axResolution == 0)
 
514
                gdkdev->pktdata &= ~PK_ORIENTATION;
 
515
 
 
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);
 
522
              
 
523
              k = 0;
 
524
              if (gdkdev->pktdata & PK_X)
 
525
                {
 
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;
 
535
                  k++;
 
536
                }
 
537
              if (gdkdev->pktdata & PK_Y)
 
538
                {
 
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;
 
548
                  k++;
 
549
                }
 
550
              if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
 
551
                {
 
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;*/
 
562
                  k++;
 
563
                }
 
564
              if (gdkdev->pktdata & PK_ORIENTATION)
 
565
                {
 
566
                  GdkAxisUse axis;
 
567
 
 
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++)
 
571
                    {
 
572
                      /* Wintab gives us aximuth and altitude, which
 
573
                       * we convert to x and y tilt in the -1000..1000 range
 
574
                       */
 
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;
 
584
                      k++;
 
585
                    }
 
586
                }
 
587
              gdkdev->info.num_keys = 0;
 
588
              gdkdev->info.keys = NULL;
 
589
              GDK_NOTE (INPUT,
 
590
                        g_print ("device: (%d) %s axes: %d\n",
 
591
                                 cursorix,
 
592
                                 gdkdev->info.name,
 
593
                                 gdkdev->info.num_axes));
 
594
              for (i = 0; i < gdkdev->info.num_axes; i++)
 
595
                GDK_NOTE (INPUT,
 
596
                          g_print ("... axis %d: %d--%d@%d (%d--%d@%d)\n",
 
597
                                   i,
 
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,
 
605
                                                 gdkdev);
 
606
            }
 
607
        }
 
608
    }
 
609
}
 
610
 
 
611
static void
 
612
decode_tilt (gint   *axis_data,
 
613
             AXIS   *axes,
 
614
             PACKET *packet)
 
615
{
 
616
  /* As I don't have a tilt-sensing tablet,
 
617
   * I cannot test this code.
 
618
   */
 
619
  
 
620
  double az, el;
 
621
 
 
622
  az = TWOPI * packet->pkOrientation.orAzimuth /
 
623
    (axes[0].axResolution / 65536.);
 
624
  el = TWOPI * packet->pkOrientation.orAltitude /
 
625
    (axes[1].axResolution / 65536.);
 
626
  
 
627
  /* X tilt */
 
628
  axis_data[0] = cos (az) * cos (el) * 1000;
 
629
  /* Y tilt */
 
630
  axis_data[1] = sin (az) * cos (el) * 1000;
 
631
}
 
632
 
 
633
#endif /* HAVE_WINTAB */
 
634
 
 
635
static void
 
636
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
 
637
                                 GdkInputWindow   *input_window,
 
638
                                 gint             *axis_data,
 
639
                                 gdouble          *axis_out,
 
640
                                 gdouble          *x_out,
 
641
                                 gdouble          *y_out)
 
642
{
 
643
  GdkWindowImplWin32 *impl, *root_impl;
 
644
 
 
645
  int i;
 
646
  int x_axis = 0;
 
647
  int y_axis = 0;
 
648
 
 
649
  double device_width, device_height;
 
650
  double x_offset, y_offset, x_scale, y_scale;
 
651
 
 
652
  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (input_window->window)->impl);
 
653
 
 
654
  for (i=0; i<gdkdev->info.num_axes; i++)
 
655
    {
 
656
      switch (gdkdev->info.axes[i].use)
 
657
        {
 
658
        case GDK_AXIS_X:
 
659
          x_axis = i;
 
660
          break;
 
661
        case GDK_AXIS_Y:
 
662
          y_axis = i;
 
663
          break;
 
664
        default:
 
665
          break;
 
666
        }
 
667
    }
 
668
  
 
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;
 
673
 
 
674
  if (gdkdev->info.mode == GDK_MODE_SCREEN) 
 
675
    {
 
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;
 
679
 
 
680
      x_offset = - input_window->root_x;
 
681
      y_offset = - input_window->root_y;
 
682
    }
 
683
  else                          /* GDK_MODE_WINDOW */
 
684
    {
 
685
      double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
 
686
        (device_width*gdkdev->axes[x_axis].resolution);
 
687
 
 
688
      if (device_aspect * impl->width >= impl->height)
 
689
        {
 
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;
 
694
 
 
695
          x_offset = 0;
 
696
          y_offset = -(device_height * y_scale - 
 
697
                               impl->height)/2;
 
698
        }
 
699
      else
 
700
        {
 
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;
 
705
 
 
706
          y_offset = 0;
 
707
          x_offset = - (device_width * x_scale - impl->width)/2;
 
708
        }
 
709
    }
 
710
 
 
711
  for (i=0; i<gdkdev->info.num_axes; i++)
 
712
    {
 
713
      switch (gdkdev->info.axes[i].use)
 
714
        {
 
715
        case GDK_AXIS_X:
 
716
          axis_out[i] = x_offset + x_scale*axis_data[x_axis];
 
717
          if (x_out)
 
718
            *x_out = axis_out[i];
 
719
          break;
 
720
        case GDK_AXIS_Y:
 
721
          axis_out[i] = y_offset + y_scale*axis_data[y_axis];
 
722
          if (y_out)
 
723
            *y_out = axis_out[i];
 
724
          break;
 
725
        default:
 
726
          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);
 
730
          break;
 
731
        }
 
732
    }
 
733
}
 
734
 
 
735
static void
 
736
gdk_input_get_root_relative_geometry (HWND w,
 
737
                                      int  *x_ret,
 
738
                                      int  *y_ret)
 
739
{
 
740
  RECT rect;
 
741
 
 
742
  GetWindowRect (w, &rect);
 
743
 
 
744
  if (x_ret)
 
745
    *x_ret = rect.left + _gdk_offset_x;
 
746
  if (y_ret)
 
747
    *y_ret = rect.top + _gdk_offset_y;
 
748
}
 
749
 
 
750
void
 
751
_gdk_input_configure_event (GdkWindow         *window)
 
752
{
 
753
  GdkInputWindow *input_window;
 
754
  int root_x, root_y;
 
755
 
 
756
  input_window = _gdk_input_window_find (window);
 
757
  g_return_if_fail (window != NULL);
 
758
 
 
759
  gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
 
760
                                        &root_x, &root_y);
 
761
 
 
762
  input_window->root_x = root_x;
 
763
  input_window->root_y = root_y;
 
764
}
 
765
 
 
766
void 
 
767
_gdk_input_enter_event (GdkWindow        *window)
 
768
{
 
769
  GdkInputWindow *input_window;
 
770
  int root_x, root_y;
 
771
 
 
772
  input_window = _gdk_input_window_find (window);
 
773
  g_return_if_fail (window != NULL);
 
774
 
 
775
  gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &root_x, &root_y);
 
776
 
 
777
  input_window->root_x = root_x;
 
778
  input_window->root_y = root_y;
 
779
}
 
780
 
 
781
/*
 
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
 
786
 */
 
787
static guint
 
788
get_modifier_key_state (void)
 
789
{
 
790
  guint state;
 
791
  
 
792
  state = 0;
 
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;
 
802
 
 
803
  return state;
 
804
}
 
805
 
 
806
#ifdef HAVE_WINTAB
 
807
 
 
808
static guint ignore_core_timer = 0;
 
809
 
 
810
static gboolean
 
811
ignore_core_timefunc (gpointer data)
 
812
{
 
813
  /* The delay has passed */
 
814
  _gdk_input_ignore_core = FALSE;
 
815
  ignore_core_timer = 0;
 
816
 
 
817
  return FALSE; /* remove timeout */
 
818
}
 
819
 
 
820
/*
 
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.
 
826
 */
 
827
static void
 
828
set_ignore_core (gboolean ignore)
 
829
{
 
830
  if (ignore)
 
831
    {
 
832
      _gdk_input_ignore_core = TRUE;
 
833
      /* Remove any pending clear */
 
834
      if (ignore_core_timer)
 
835
        {
 
836
          g_source_remove (ignore_core_timer);
 
837
          ignore_core_timer = 0;
 
838
        }
 
839
    }
 
840
  else
 
841
    if (!ignore_core_timer)
 
842
      ignore_core_timer = g_timeout_add (PROXIMITY_OUT_DELAY,
 
843
                                         ignore_core_timefunc, NULL);
 
844
}
 
845
#endif /* HAVE_WINTAB */
 
846
 
 
847
gboolean 
 
848
_gdk_input_other_event (GdkEvent  *event,
 
849
                        MSG       *msg,
 
850
                        GdkWindow *window)
 
851
{
 
852
#ifdef HAVE_WINTAB
 
853
  GdkDisplay *display;
 
854
  GdkWindowObject *obj, *grab_obj;
 
855
  GdkInputWindow *input_window;
 
856
  GdkDevicePrivate *gdkdev = NULL;
 
857
  GdkEventMask masktest;
 
858
  guint key_state;
 
859
  POINT pt;
 
860
 
 
861
  PACKET packet;
 
862
  gint k;
 
863
  gint x, y;
 
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.
 
867
   */
 
868
  static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
 
869
 
 
870
  if (event->any.window != wintab_window)
 
871
    {
 
872
      g_warning ("_gdk_input_other_event: not wintab_window?");
 
873
      return FALSE;
 
874
    }
 
875
 
 
876
  window = gdk_window_at_pointer (&x, &y);
 
877
  if (window == NULL)
 
878
    window = _gdk_root;
 
879
 
 
880
  g_object_ref (window);
 
881
  display = gdk_drawable_get_display (window);
 
882
 
 
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));
 
886
  
 
887
  if (msg->message == WT_PACKET)
 
888
    {
 
889
      if (!WTPacket ((HCTX) msg->lParam, msg->wParam, &packet))
 
890
        return FALSE;
 
891
    }
 
892
 
 
893
  obj = GDK_WINDOW_OBJECT (window);
 
894
 
 
895
  switch (msg->message)
 
896
    {
 
897
    case WT_PACKET:
 
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)
 
901
        {
 
902
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
 
903
          return FALSE;
 
904
        }
 
905
      if (window == _gdk_root && x_grab_window == NULL)
 
906
        {
 
907
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
 
908
          return FALSE;
 
909
        }
 
910
 
 
911
      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
 
912
                                                 packet.pkCursor)) == NULL)
 
913
        return FALSE;
 
914
 
 
915
      if (gdkdev->info.mode == GDK_MODE_DISABLED)
 
916
        return FALSE;
 
917
      
 
918
      k = 0;
 
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)
 
926
        {
 
927
          decode_tilt (gdkdev->last_axis_data + k,
 
928
                       gdkdev->orientation_axes, &packet);
 
929
          k += 2;
 
930
        }
 
931
 
 
932
      g_assert (k == gdkdev->info.num_axes);
 
933
 
 
934
      translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
 
935
 
 
936
      if (translated_buttons != gdkdev->button_state)
 
937
        {
 
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
 
941
           * we get a packet
 
942
           */
 
943
          button_diff = translated_buttons ^ gdkdev->button_state;
 
944
          
 
945
          /* Gdk buttons are numbered 1.. */
 
946
          event->button.button = 1;
 
947
 
 
948
          for (button_mask = 1; button_mask != 0x80000000;
 
949
               button_mask <<= 1, event->button.button++)
 
950
            {
 
951
              if (button_diff & button_mask)
 
952
                {
 
953
                  /* Found a button that has changed state */
 
954
                  break;
 
955
                }
 
956
            }
 
957
 
 
958
          if (!(translated_buttons & button_mask))
 
959
            {
 
960
              event->any.type = GDK_BUTTON_RELEASE;
 
961
              masktest = GDK_BUTTON_RELEASE_MASK;
 
962
            }
 
963
          else
 
964
            {
 
965
              event->any.type = GDK_BUTTON_PRESS;
 
966
              masktest = GDK_BUTTON_PRESS_MASK;
 
967
            }
 
968
          gdkdev->button_state ^= button_mask;
 
969
        }
 
970
      else
 
971
        {
 
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;
 
980
        }
 
981
 
 
982
      /* See if input is grabbed */
 
983
      /* FIXME: x_grab_owner_events should probably be handled somehow */
 
984
      if (x_grab_window != NULL)
 
985
        {
 
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))
 
990
            {
 
991
              GDK_NOTE (EVENTS_OR_INPUT, 
 
992
                        g_print ("... grabber doesn't want it\n"));
 
993
              return FALSE;
 
994
            }
 
995
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
 
996
 
 
997
          g_object_ref(x_grab_window);
 
998
          g_object_unref(window);
 
999
          window = x_grab_window;
 
1000
          obj = grab_obj;
 
1001
        }
 
1002
      /* Now we can check if the window wants the event, and
 
1003
       * propagate if necessary.
 
1004
       */
 
1005
    dijkstra:
 
1006
      if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
 
1007
          || !(obj->extension_events & masktest))
 
1008
        {
 
1009
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
 
1010
 
 
1011
          if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
 
1012
            return FALSE;
 
1013
 
 
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)
 
1017
            {
 
1018
              GDK_NOTE (EVENTS_OR_INPUT, 
 
1019
                        g_print ("... wants ordinary event, ignoring this\n"));
 
1020
              return FALSE;
 
1021
            }
 
1022
          
 
1023
          pt.x = x;
 
1024
          pt.y = y;
 
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);
 
1031
          x = pt.x;
 
1032
          y = pt.y;
 
1033
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
 
1034
                                              GDK_WINDOW_HWND (window), x, y));
 
1035
          goto dijkstra;
 
1036
        }
 
1037
 
 
1038
      input_window = _gdk_input_window_find (window);
 
1039
 
 
1040
      g_assert (input_window != NULL);
 
1041
 
 
1042
      if (gdkdev->info.mode == GDK_MODE_WINDOW
 
1043
          && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
 
1044
        return FALSE;
 
1045
 
 
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)
 
1050
        {
 
1051
          event->button.time = _gdk_win32_get_next_tick (msg->time);
 
1052
          event->button.device = &gdkdev->info;
 
1053
          
 
1054
          event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
 
1055
 
 
1056
          gdk_input_translate_coordinates (gdkdev, input_window,
 
1057
                                           gdkdev->last_axis_data,
 
1058
                                           event->button.axes,
 
1059
                                           &event->button.x, 
 
1060
                                           &event->button.y);
 
1061
 
 
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;
 
1066
 
 
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))
 
1071
                                | key_state;
 
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));
 
1078
        }
 
1079
      else
 
1080
        {
 
1081
          event->motion.time = _gdk_win32_get_next_tick (msg->time);
 
1082
          event->motion.is_hint = FALSE;
 
1083
          event->motion.device = &gdkdev->info;
 
1084
 
 
1085
          event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
 
1086
 
 
1087
          gdk_input_translate_coordinates (gdkdev, input_window,
 
1088
                                           gdkdev->last_axis_data,
 
1089
                                           event->motion.axes,
 
1090
                                           &event->motion.x, 
 
1091
                                           &event->motion.y);
 
1092
 
 
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;
 
1097
 
 
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))
 
1102
                                | key_state;
 
1103
 
 
1104
          GDK_NOTE (EVENTS_OR_INPUT,
 
1105
                    g_print ("WINTAB motion: %g,%g\n",
 
1106
                             event->motion.x, event->motion.y));
 
1107
        }
 
1108
      return TRUE;
 
1109
 
 
1110
    case WT_PROXIMITY:
 
1111
      if (LOWORD (msg->lParam) == 0)
 
1112
        {
 
1113
          event->proximity.type = GDK_PROXIMITY_OUT;
 
1114
          set_ignore_core (FALSE);
 
1115
        }
 
1116
      else
 
1117
        {
 
1118
          event->proximity.type = GDK_PROXIMITY_IN;
 
1119
          set_ignore_core (TRUE);
 
1120
        }
 
1121
      event->proximity.time = _gdk_win32_get_next_tick (msg->time);
 
1122
      event->proximity.device = &gdkdev->info;
 
1123
 
 
1124
      GDK_NOTE (EVENTS_OR_INPUT,
 
1125
                g_print ("WINTAB proximity %s\n",
 
1126
                         (event->proximity.type == GDK_PROXIMITY_IN ?
 
1127
                          "in" : "out")));
 
1128
      return TRUE;
 
1129
    }
 
1130
#endif
 
1131
  return FALSE;
 
1132
}
 
1133
 
 
1134
gboolean
 
1135
_gdk_input_enable_window (GdkWindow        *window,
 
1136
                          GdkDevicePrivate *gdkdev)
 
1137
{
 
1138
#ifdef HAVE_SOME_XINPUT
 
1139
  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
1140
 
 
1141
  impl->extension_events_selected = TRUE;
 
1142
#endif
 
1143
 
 
1144
  return TRUE;
 
1145
}
 
1146
 
 
1147
gboolean
 
1148
_gdk_input_disable_window (GdkWindow        *window,
 
1149
                           GdkDevicePrivate *gdkdev)
 
1150
{
 
1151
#ifdef HAVE_SOME_XINPUT
 
1152
  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
1153
 
 
1154
  impl->extension_events_selected = FALSE;
 
1155
#endif
 
1156
 
 
1157
  return TRUE;
 
1158
}
 
1159
 
 
1160
gint
 
1161
_gdk_input_grab_pointer (GdkWindow    *window,
 
1162
                         gint          owner_events,
 
1163
                         GdkEventMask  event_mask,
 
1164
                         GdkWindow    *confine_to,
 
1165
                         guint32       time)
 
1166
{
 
1167
#ifdef HAVE_SOME_XINPUT
 
1168
  GdkInputWindow *input_window, *new_window;
 
1169
  gboolean need_ungrab;
 
1170
  GdkDevicePrivate *gdkdev;
 
1171
  GList *tmp_list;
 
1172
 
 
1173
  tmp_list = _gdk_input_windows;
 
1174
  new_window = NULL;
 
1175
  need_ungrab = FALSE;
 
1176
 
 
1177
  GDK_NOTE (INPUT, g_print ("gdk_input_win32_grab_pointer: %p %d %p\n",
 
1178
                           GDK_WINDOW_HWND (window),
 
1179
                           owner_events,
 
1180
                           (confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
 
1181
 
 
1182
  while (tmp_list)
 
1183
    {
 
1184
      input_window = (GdkInputWindow *)tmp_list->data;
 
1185
 
 
1186
      if (input_window->window == window)
 
1187
        new_window = input_window;
 
1188
      else if (input_window->grabbed)
 
1189
        {
 
1190
          input_window->grabbed = FALSE;
 
1191
          need_ungrab = TRUE;
 
1192
        }
 
1193
 
 
1194
      tmp_list = tmp_list->next;
 
1195
    }
 
1196
 
 
1197
  if (new_window)
 
1198
    {
 
1199
      new_window->grabbed = TRUE;
 
1200
      x_grab_window = window;
 
1201
      x_grab_mask = event_mask;
 
1202
      x_grab_owner_events = owner_events;
 
1203
 
 
1204
      /* FIXME: Do we need to handle confine_to and time? */
 
1205
      
 
1206
      tmp_list = _gdk_input_devices;
 
1207
      while (tmp_list)
 
1208
        {
 
1209
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
 
1210
          if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
 
1211
            {
 
1212
#if 0         
 
1213
              /* XXX */
 
1214
              gdk_input_common_find_events (window, gdkdev,
 
1215
                                            event_mask,
 
1216
                                            event_classes, &num_classes);
 
1217
              
 
1218
              result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
 
1219
                                    GDK_WINDOW_XWINDOW (window),
 
1220
                                    owner_events, num_classes, event_classes,
 
1221
                                    GrabModeAsync, GrabModeAsync, time);
 
1222
              
 
1223
              /* FIXME: if failure occurs on something other than the first
 
1224
                 device, things will be badly inconsistent */
 
1225
              if (result != Success)
 
1226
                return result;
 
1227
#endif
 
1228
            }
 
1229
          tmp_list = tmp_list->next;
 
1230
        }
 
1231
    }
 
1232
  else
 
1233
    { 
 
1234
      x_grab_window = NULL;
 
1235
#if 0
 
1236
      tmp_list = _gdk_input_devices;
 
1237
      while (tmp_list)
 
1238
        {
 
1239
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
 
1240
          if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
 
1241
              ((gdkdev->button_state != 0) || need_ungrab))
 
1242
            {
 
1243
#if 0
 
1244
              /* XXX */
 
1245
              XUngrabDevice (gdk_display, gdkdev->xdevice, time);
 
1246
#endif
 
1247
              gdkdev->button_state = 0;
 
1248
            }
 
1249
          
 
1250
          tmp_list = tmp_list->next;
 
1251
        }
 
1252
#endif
 
1253
    }
 
1254
#endif
 
1255
 
 
1256
  return GDK_GRAB_SUCCESS;
 
1257
}
 
1258
 
 
1259
void 
 
1260
_gdk_input_ungrab_pointer (guint32 time)
 
1261
{
 
1262
#ifdef HAVE_SOME_XINPUT
 
1263
  GdkInputWindow *input_window;
 
1264
  GdkDevicePrivate *gdkdev;
 
1265
  GList *tmp_list;
 
1266
 
 
1267
  GDK_NOTE (INPUT, g_print ("gdk_input_win32_ungrab_pointer\n"));
 
1268
 
 
1269
  tmp_list = _gdk_input_windows;
 
1270
  while (tmp_list)
 
1271
    {
 
1272
      input_window = (GdkInputWindow *)tmp_list->data;
 
1273
      if (input_window->grabbed)
 
1274
        break;
 
1275
      tmp_list = tmp_list->next;
 
1276
    }
 
1277
 
 
1278
  if (tmp_list)                 /* we found a grabbed window */
 
1279
    {
 
1280
      input_window->grabbed = FALSE;
 
1281
 
 
1282
      tmp_list = _gdk_input_devices;
 
1283
      while (tmp_list)
 
1284
        {
 
1285
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
 
1286
#if 0
 
1287
          /* XXX */
 
1288
          if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
 
1289
            XUngrabDevice (gdk_display, gdkdev->xdevice, time);
 
1290
#endif
 
1291
          tmp_list = tmp_list->next;
 
1292
        }
 
1293
    }
 
1294
  x_grab_window = NULL;
 
1295
#endif
 
1296
}
 
1297
 
 
1298
gboolean
 
1299
_gdk_device_get_history (GdkDevice         *device,
 
1300
                         GdkWindow         *window,
 
1301
                         guint32            start,
 
1302
                         guint32            stop,
 
1303
                         GdkTimeCoord    ***events,
 
1304
                         gint              *n_events)
 
1305
{
 
1306
  return FALSE;
 
1307
}
 
1308
 
 
1309
void 
 
1310
gdk_device_get_state (GdkDevice       *device,
 
1311
                      GdkWindow       *window,
 
1312
                      gdouble         *axes,
 
1313
                      GdkModifierType *mask)
 
1314
{
 
1315
  g_return_if_fail (device != NULL);
 
1316
  g_return_if_fail (GDK_IS_WINDOW (window));
 
1317
 
 
1318
  if (GDK_IS_CORE (device))
 
1319
    {
 
1320
      gint x_int, y_int;
 
1321
      
 
1322
      gdk_window_get_pointer (window, &x_int, &y_int, mask);
 
1323
 
 
1324
      if (axes)
 
1325
        {
 
1326
          axes[0] = x_int;
 
1327
          axes[1] = y_int;
 
1328
        }
 
1329
    }
 
1330
  else
 
1331
    {
 
1332
      GdkDevicePrivate *gdkdev;
 
1333
      GdkInputWindow *input_window;
 
1334
      
 
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 */
 
1339
      if (mask)
 
1340
        {
 
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));
 
1347
        }
 
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,
 
1355
                                         axes, NULL, NULL);
 
1356
    }
 
1357
}
 
1358
 
 
1359
#ifdef HAVE_WINTAB
 
1360
void
 
1361
_gdk_input_set_tablet_active (void)
 
1362
{
 
1363
  GList *tmp_list;
 
1364
  HCTX *hctx;
 
1365
 
 
1366
  /* Bring the contexts to the top of the overlap order when one of the
 
1367
   * application's windows is activated */
 
1368
  
 
1369
  if (!wintab_contexts)
 
1370
    return; /* No tablet devices found, or Wintab not initialized yet */
 
1371
  
 
1372
  GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
 
1373
        "Bringing Wintab contexts to the top of the overlap order\n"));
 
1374
 
 
1375
  tmp_list = wintab_contexts;
 
1376
  while (tmp_list)
 
1377
    {
 
1378
      hctx = (HCTX *) (tmp_list->data);
 
1379
      WTOverlap (*hctx, TRUE);
 
1380
      tmp_list = tmp_list->next;
 
1381
    }
 
1382
}
 
1383
#endif /* HAVE_WINTAB */
 
1384
 
 
1385
void 
 
1386
_gdk_input_init (GdkDisplay *display)
 
1387
{
 
1388
  _gdk_input_ignore_core = FALSE;
 
1389
  _gdk_input_devices = NULL;
 
1390
 
 
1391
  _gdk_init_input_core (display);
 
1392
#ifdef HAVE_WINTAB
 
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.
 
1397
   */
 
1398
  _gdk_input_wintab_init_check ();
 
1399
#endif /* WINTAB_NO_LAZY_INIT */
 
1400
#endif /* HAVE_WINTAB */
 
1401
 
 
1402
  _gdk_input_devices = g_list_append (_gdk_input_devices, display->core_pointer);
 
1403
}
 
1404