00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 #include <math.h>
00033
00034 #include "gdk.h"
00035 #include "gdkinput.h"
00036 #include "gdkprivate.h"
00037 #include "gdkwin32.h"
00038
00039 #ifdef HAVE_WINTAB
00040 #include "d:\development\wtkit\include\wintab.h"
00041 #define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION)
00042 #define PACKETMODE (PK_BUTTONS)
00043 #include "d:\development\wtkit\include\pktdef.h"
00044 #endif
00045
00046 #include "gdkinputprivate.h"
00047
00048 struct _GdkDevicePrivate {
00049 GdkDeviceInfo info;
00050
00051
00052 GdkAxisInfo *axes;
00053
00054
00055 gint axis_for_use[GDK_AXIS_LAST];
00056
00057
00058
00059
00060 gint needs_update;
00061
00062
00063 gint button_state;
00064
00065 gint *last_axis_data;
00066 gint last_buttons;
00067 #ifdef HAVE_WINTAB
00068
00069 HCTX hctx;
00070
00071 UINT cursor;
00072
00073 WTPKT pktdata;
00074
00075 UINT npbtnmarks[2];
00076
00077 AXIS orientation_axes[2];
00078 #endif
00079 };
00080
00081 #ifndef G_PI
00082 #define G_PI 3.14159265358979323846
00083 #endif
00084
00085
00086
00087
00088
00089 #define USE_SYSCONTEXT 1
00090
00091
00092
00093 #ifdef HAVE_WINTAB
00094 #define DEBUG_WINTAB 1
00095 #endif
00096
00097 #define TWOPI (2.*G_PI)
00098
00099
00100
00101 static gint gdk_input_enable_window(GdkWindow * window,
00102 GdkDevicePrivate * gdkdev);
00103 static gint gdk_input_disable_window(GdkWindow * window,
00104 GdkDevicePrivate * gdkdev);
00105 static void gdk_input_none_get_pointer(GdkWindow * window,
00106 guint32 deviceid,
00107 gdouble * x,
00108 gdouble * y,
00109 gdouble * pressure,
00110 gdouble * xtilt,
00111 gdouble * ytilt,
00112 GdkModifierType * mask);
00113
00114 static GdkDevicePrivate *gdk_input_find_device(guint32 deviceid);
00115
00116 #ifdef HAVE_WINTAB
00117
00118 static gint gdk_input_win32_set_mode(guint32 deviceid, GdkInputMode mode);
00119 static void gdk_input_win32_get_pointer(GdkWindow * window,
00120 guint32 deviceid,
00121 gdouble * x,
00122 gdouble * y,
00123 gdouble * pressure,
00124 gdouble * xtilt,
00125 gdouble * ytilt,
00126 GdkModifierType * mask);
00127 static gint gdk_input_win32_grab_pointer(GdkWindow * window,
00128 gint owner_events,
00129 GdkEventMask event_mask,
00130 GdkWindow * confine_to,
00131 guint32 time);
00132 static void gdk_input_win32_ungrab_pointer(guint32 time);
00133 static void gdk_input_win32_configure_event(GdkEventConfigure * event,
00134 GdkWindow * window);
00135 static void gdk_input_win32_enter_event(GdkEventCrossing * xevent,
00136 GdkWindow * window);
00137 static gint gdk_input_win32_other_event(GdkEvent * event, MSG * xevent);
00138 static gint gdk_input_win32_enable_window(GdkWindow * window,
00139 GdkDevicePrivate * gdkdev);
00140 static gint gdk_input_win32_disable_window(GdkWindow * window,
00141 GdkDevicePrivate * gdkdev);
00142
00143 static GdkInputWindow *gdk_input_window_find(GdkWindow * window);
00144 #if !USE_SYSCONTEXT
00145 static GdkInputWindow *gdk_input_window_find_within(GdkWindow * window);
00146 #endif
00147 static GdkDevicePrivate *gdk_input_find_dev_from_ctx(HCTX hctx, UINT id);
00148 #endif
00149
00150
00151
00152 static GList *gdk_input_devices;
00153 static GList *gdk_input_windows;
00154 static GList *wintab_contexts;
00155
00156 static gint gdk_input_root_width;
00157 static gint gdk_input_root_height;
00158
00159 static GdkWindow *wintab_window;
00160
00161 static guint32 last_moved_cursor_id;
00162
00163 static GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
00164
00165 static GdkDeviceInfo gdk_input_core_info = {
00166 GDK_CORE_POINTER,
00167 "Core Pointer",
00168 GDK_SOURCE_MOUSE,
00169 GDK_MODE_SCREEN,
00170 TRUE,
00171 2,
00172 gdk_input_core_axes
00173 };
00174
00175
00176
00177 GdkInputVTable gdk_input_vtable;
00178 gint gdk_input_ignore_core;
00179 gint gdk_input_ignore_wintab = FALSE;
00180
00181 #if DEBUG_WINTAB
00182
00183 static void print_lc(LOGCONTEXT * lc)
00184 {
00185 g_print("lcName = %s\n", lc->lcName);
00186 g_print("lcOptions =");
00187 if (lc->lcOptions & CXO_SYSTEM)
00188 g_print(" CXO_SYSTEM");
00189 if (lc->lcOptions & CXO_PEN)
00190 g_print(" CXO_PEN");
00191 if (lc->lcOptions & CXO_MESSAGES)
00192 g_print(" CXO_MESSAGES");
00193 if (lc->lcOptions & CXO_MARGIN)
00194 g_print(" CXO_MARGIN");
00195 if (lc->lcOptions & CXO_MGNINSIDE)
00196 g_print(" CXO_MGNINSIDE");
00197 if (lc->lcOptions & CXO_CSRMESSAGES)
00198 g_print(" CXO_CSRMESSAGES");
00199 if (lc->lcOptions & CXO_CSRMESSAGES)
00200 g_print(" CXO_CSRMESSAGES");
00201 g_print("\n");
00202 g_print("lcStatus =");
00203 if (lc->lcStatus & CXS_DISABLED)
00204 g_print(" CXS_DISABLED");
00205 if (lc->lcStatus & CXS_OBSCURED)
00206 g_print(" CXS_OBSCURED");
00207 if (lc->lcStatus & CXS_ONTOP)
00208 g_print(" CXS_ONTOP");
00209 g_print("\n");
00210 g_print("lcLocks =");
00211 if (lc->lcLocks & CXL_INSIZE)
00212 g_print(" CXL_INSIZE");
00213 if (lc->lcLocks & CXL_INASPECT)
00214 g_print(" CXL_INASPECT");
00215 if (lc->lcLocks & CXL_SENSITIVITY)
00216 g_print(" CXL_SENSITIVITY");
00217 if (lc->lcLocks & CXL_MARGIN)
00218 g_print(" CXL_MARGIN");
00219 g_print("\n");
00220 g_print("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
00221 lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
00222 g_print("lcPktData =");
00223 if (lc->lcPktData & PK_CONTEXT)
00224 g_print(" PK_CONTEXT");
00225 if (lc->lcPktData & PK_STATUS)
00226 g_print(" PK_STATUS");
00227 if (lc->lcPktData & PK_TIME)
00228 g_print(" PK_TIME");
00229 if (lc->lcPktData & PK_CHANGED)
00230 g_print(" PK_CHANGED");
00231 if (lc->lcPktData & PK_SERIAL_NUMBER)
00232 g_print(" PK_SERIAL_NUMBER");
00233 if (lc->lcPktData & PK_CURSOR)
00234 g_print(" PK_CURSOR");
00235 if (lc->lcPktData & PK_BUTTONS)
00236 g_print(" PK_BUTTONS");
00237 if (lc->lcPktData & PK_X)
00238 g_print(" PK_X");
00239 if (lc->lcPktData & PK_Y)
00240 g_print(" PK_Y");
00241 if (lc->lcPktData & PK_Z)
00242 g_print(" PK_Z");
00243 if (lc->lcPktData & PK_NORMAL_PRESSURE)
00244 g_print(" PK_NORMAL_PRESSURE");
00245 if (lc->lcPktData & PK_TANGENT_PRESSURE)
00246 g_print(" PK_TANGENT_PRESSURE");
00247 if (lc->lcPktData & PK_ORIENTATION)
00248 g_print(" PK_ORIENTATION");
00249 if (lc->lcPktData & PK_ROTATION)
00250 g_print(" PK_ROTATION");
00251 g_print("\n");
00252 g_print("lcPktMode =");
00253 if (lc->lcPktMode & PK_CONTEXT)
00254 g_print(" PK_CONTEXT");
00255 if (lc->lcPktMode & PK_STATUS)
00256 g_print(" PK_STATUS");
00257 if (lc->lcPktMode & PK_TIME)
00258 g_print(" PK_TIME");
00259 if (lc->lcPktMode & PK_CHANGED)
00260 g_print(" PK_CHANGED");
00261 if (lc->lcPktMode & PK_SERIAL_NUMBER)
00262 g_print(" PK_SERIAL_NUMBER");
00263 if (lc->lcPktMode & PK_CURSOR)
00264 g_print(" PK_CURSOR");
00265 if (lc->lcPktMode & PK_BUTTONS)
00266 g_print(" PK_BUTTONS");
00267 if (lc->lcPktMode & PK_X)
00268 g_print(" PK_X");
00269 if (lc->lcPktMode & PK_Y)
00270 g_print(" PK_Y");
00271 if (lc->lcPktMode & PK_Z)
00272 g_print(" PK_Z");
00273 if (lc->lcPktMode & PK_NORMAL_PRESSURE)
00274 g_print(" PK_NORMAL_PRESSURE");
00275 if (lc->lcPktMode & PK_TANGENT_PRESSURE)
00276 g_print(" PK_TANGENT_PRESSURE");
00277 if (lc->lcPktMode & PK_ORIENTATION)
00278 g_print(" PK_ORIENTATION");
00279 if (lc->lcPktMode & PK_ROTATION)
00280 g_print(" PK_ROTATION");
00281 g_print("\n");
00282 g_print("lcMoveMask =");
00283 if (lc->lcMoveMask & PK_CONTEXT)
00284 g_print(" PK_CONTEXT");
00285 if (lc->lcMoveMask & PK_STATUS)
00286 g_print(" PK_STATUS");
00287 if (lc->lcMoveMask & PK_TIME)
00288 g_print(" PK_TIME");
00289 if (lc->lcMoveMask & PK_CHANGED)
00290 g_print(" PK_CHANGED");
00291 if (lc->lcMoveMask & PK_SERIAL_NUMBER)
00292 g_print(" PK_SERIAL_NUMBER");
00293 if (lc->lcMoveMask & PK_CURSOR)
00294 g_print(" PK_CURSOR");
00295 if (lc->lcMoveMask & PK_BUTTONS)
00296 g_print(" PK_BUTTONS");
00297 if (lc->lcMoveMask & PK_X)
00298 g_print(" PK_X");
00299 if (lc->lcMoveMask & PK_Y)
00300 g_print(" PK_Y");
00301 if (lc->lcMoveMask & PK_Z)
00302 g_print(" PK_Z");
00303 if (lc->lcMoveMask & PK_NORMAL_PRESSURE)
00304 g_print(" PK_NORMAL_PRESSURE");
00305 if (lc->lcMoveMask & PK_TANGENT_PRESSURE)
00306 g_print(" PK_TANGENT_PRESSURE");
00307 if (lc->lcMoveMask & PK_ORIENTATION)
00308 g_print(" PK_ORIENTATION");
00309 if (lc->lcMoveMask & PK_ROTATION)
00310 g_print(" PK_ROTATION");
00311 g_print("\n");
00312 g_print("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
00313 lc->lcBtnDnMask, lc->lcBtnUpMask);
00314 g_print("lcInOrgX = %d, lcInOrgY = %d, lcInOrgZ = %d\n",
00315 lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
00316 g_print("lcInExtX = %d, lcInExtY = %d, lcInExtZ = %d\n",
00317 lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
00318 g_print("lcOutOrgX = %d, lcOutOrgY = %d, lcOutOrgZ = %d\n",
00319 lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
00320 g_print("lcOutExtX = %d, lcOutExtY = %d, lcOutExtZ = %d\n",
00321 lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
00322 g_print("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
00323 lc->lcSensX / 65536., lc->lcSensY / 65536.,
00324 lc->lcSensZ / 65536.);
00325 g_print("lcSysMode = %d\n", lc->lcSysMode);
00326 g_print("lcSysOrgX = %d, lcSysOrgY = %d\n",
00327 lc->lcSysOrgX, lc->lcSysOrgY);
00328 g_print("lcSysExtX = %d, lcSysExtY = %d\n",
00329 lc->lcSysExtX, lc->lcSysExtY);
00330 g_print("lcSysSensX = %g, lcSysSensY = %g\n",
00331 lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
00332 }
00333
00334 #endif
00335
00336 void gdk_input_init(void)
00337 {
00338 guint32 deviceid_counter = 0;
00339 #ifdef HAVE_WINTAB
00340 GdkDevicePrivate *gdkdev;
00341 GdkWindowAttr wa;
00342 WORD specversion;
00343 LOGCONTEXT defcontext;
00344 HCTX *hctx;
00345 UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
00346 BOOL active;
00347 AXIS axis_x, axis_y, axis_npressure, axis_or[3];
00348 int i, j, k;
00349 int devix, cursorix;
00350 char devname[100], csrname[100];
00351
00352 gdk_input_devices = NULL;
00353 wintab_contexts = NULL;
00354
00355 if (!gdk_input_ignore_wintab && WTInfo(0, 0, NULL)) {
00356 WTInfo(WTI_INTERFACE, IFC_SPECVERSION, &specversion);
00357 GDK_NOTE(MISC, g_print("Wintab interface version %d.%d\n",
00358 HIBYTE(specversion), LOBYTE(specversion)));
00359 #if USE_SYSCONTEXT
00360 WTInfo(WTI_DEFSYSCTX, 0, &defcontext);
00361 #if DEBUG_WINTAB
00362 GDK_NOTE(MISC, (g_print("DEFSYSCTX:\n"), print_lc(&defcontext)));
00363 #endif
00364 #else
00365 WTInfo(WTI_DEFCONTEXT, 0, &defcontext);
00366 #if DEBUG_WINTAB
00367 GDK_NOTE(MISC, (g_print("DEFCONTEXT:\n"), print_lc(&defcontext)));
00368 #endif
00369 #endif
00370 WTInfo(WTI_INTERFACE, IFC_NDEVICES, &ndevices);
00371 WTInfo(WTI_INTERFACE, IFC_NCURSORS, &ncursors);
00372 #if DEBUG_WINTAB
00373 GDK_NOTE(MISC, g_print("NDEVICES: %d, NCURSORS: %d\n",
00374 ndevices, ncursors));
00375 #endif
00376
00377 wa.wclass = GDK_INPUT_OUTPUT;
00378 wa.event_mask = GDK_ALL_EVENTS_MASK;
00379 wa.width = 2;
00380 wa.height = 2;
00381 wa.x = -100;
00382 wa.y = -100;
00383 wa.window_type = GDK_WINDOW_TOPLEVEL;
00384 if ((wintab_window =
00385 gdk_window_new(NULL, &wa, GDK_WA_X | GDK_WA_Y)) == NULL) {
00386 g_warning("gdk_input_init: gdk_window_new failed");
00387 return;
00388 }
00389 gdk_window_ref(wintab_window);
00390
00391 for (devix = 0; devix < ndevices; devix++) {
00392 LOGCONTEXT lc;
00393
00394 WTInfo(WTI_DEVICES + devix, DVC_NAME, devname);
00395
00396 WTInfo(WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
00397 WTInfo(WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
00398 WTInfo(WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
00399 WTInfo(WTI_DEVICES + devix, DVC_X, &axis_x);
00400 WTInfo(WTI_DEVICES + devix, DVC_Y, &axis_y);
00401 WTInfo(WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
00402 WTInfo(WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
00403
00404 if (HIBYTE(specversion) > 1 || LOBYTE(specversion) >= 1) {
00405 WTInfo(WTI_DDCTXS + devix, CTX_NAME, lc.lcName);
00406 WTInfo(WTI_DDCTXS + devix, CTX_OPTIONS, &lc.lcOptions);
00407 lc.lcOptions |= CXO_MESSAGES;
00408 #if USE_SYSCONTEXT
00409 lc.lcOptions |= CXO_SYSTEM;
00410 #endif
00411 lc.lcStatus = 0;
00412 WTInfo(WTI_DDCTXS + devix, CTX_LOCKS, &lc.lcLocks);
00413 lc.lcMsgBase = WT_DEFBASE;
00414 lc.lcDevice = devix;
00415 lc.lcPktRate = 50;
00416 lc.lcPktData = PACKETDATA;
00417 lc.lcPktMode = PK_BUTTONS;
00418 lc.lcMoveMask = PACKETDATA;
00419 lc.lcBtnDnMask = lc.lcBtnUpMask = ~0;
00420 WTInfo(WTI_DDCTXS + devix, CTX_INORGX, &lc.lcInOrgX);
00421 WTInfo(WTI_DDCTXS + devix, CTX_INORGY, &lc.lcInOrgY);
00422 WTInfo(WTI_DDCTXS + devix, CTX_INORGZ, &lc.lcInOrgZ);
00423 WTInfo(WTI_DDCTXS + devix, CTX_INEXTX, &lc.lcInExtX);
00424 WTInfo(WTI_DDCTXS + devix, CTX_INEXTY, &lc.lcInExtY);
00425 WTInfo(WTI_DDCTXS + devix, CTX_INEXTZ, &lc.lcInExtZ);
00426 lc.lcOutOrgX = axis_x.axMin;
00427 lc.lcOutOrgY = axis_y.axMin;
00428 lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
00429 lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
00430 lc.lcOutExtY = -lc.lcOutExtY;
00431 WTInfo(WTI_DDCTXS + devix, CTX_SENSX, &lc.lcSensX);
00432 WTInfo(WTI_DDCTXS + devix, CTX_SENSY, &lc.lcSensY);
00433 WTInfo(WTI_DDCTXS + devix, CTX_SENSZ, &lc.lcSensZ);
00434 WTInfo(WTI_DDCTXS + devix, CTX_SYSMODE, &lc.lcSysMode);
00435 lc.lcSysOrgX = lc.lcSysOrgY = 0;
00436 WTInfo(WTI_DDCTXS + devix, CTX_SYSEXTX, &lc.lcSysExtX);
00437 WTInfo(WTI_DDCTXS + devix, CTX_SYSEXTY, &lc.lcSysExtY);
00438 WTInfo(WTI_DDCTXS + devix, CTX_SYSSENSX, &lc.lcSysSensX);
00439 WTInfo(WTI_DDCTXS + devix, CTX_SYSSENSY, &lc.lcSysSensY);
00440 } else {
00441 lc = defcontext;
00442 lc.lcOptions |= CXO_MESSAGES;
00443 lc.lcMsgBase = WT_DEFBASE;
00444 lc.lcPktRate = 50;
00445 lc.lcPktData = PACKETDATA;
00446 lc.lcPktMode = PACKETMODE;
00447 lc.lcMoveMask = PACKETDATA;
00448 lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
00449 #if 0
00450 lc.lcOutExtY = -lc.lcOutExtY;
00451 #else
00452 lc.lcOutOrgX = axis_x.axMin;
00453 lc.lcOutOrgY = axis_y.axMin;
00454 lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
00455 lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
00456 lc.lcOutExtY = -lc.lcOutExtY;
00457 #endif
00458 }
00459 #if DEBUG_WINTAB
00460 GDK_NOTE(MISC, (g_print("context for device %d:\n", devix),
00461 print_lc(&lc)));
00462 #endif
00463 hctx = g_new(HCTX, 1);
00464 if ((*hctx =
00465 WTOpen(GDK_DRAWABLE_XID(wintab_window), &lc,
00466 TRUE)) == NULL) {
00467 g_warning("gdk_input_init: WTOpen failed");
00468 return;
00469 }
00470 GDK_NOTE(MISC, g_print("opened Wintab device %d %#x\n",
00471 devix, *hctx));
00472
00473 wintab_contexts = g_list_append(wintab_contexts, hctx);
00474 #if 0
00475 WTEnable(*hctx, TRUE);
00476 #endif
00477 WTOverlap(*hctx, TRUE);
00478
00479 #if DEBUG_WINTAB
00480 GDK_NOTE(MISC,
00481 (g_print("context for device %d after WTOpen:\n", devix),
00482 print_lc(&lc)));
00483 #endif
00484 for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes;
00485 cursorix++) {
00486 active = FALSE;
00487 WTInfo(WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
00488 if (!active)
00489 continue;
00490 gdkdev = g_new(GdkDevicePrivate, 1);
00491 WTInfo(WTI_CURSORS + cursorix, CSR_NAME, csrname);
00492 gdkdev->info.name = g_strconcat(devname, " ", csrname, NULL);
00493 gdkdev->info.deviceid = deviceid_counter++;
00494 gdkdev->info.source = GDK_SOURCE_PEN;
00495 gdkdev->info.mode = GDK_MODE_SCREEN;
00496 #if USE_SYSCONTEXT
00497 gdkdev->info.has_cursor = TRUE;
00498 #else
00499 gdkdev->info.has_cursor = FALSE;
00500 #endif
00501 gdkdev->hctx = *hctx;
00502 gdkdev->cursor = cursorix;
00503 WTInfo(WTI_CURSORS + cursorix, CSR_PKTDATA, &gdkdev->pktdata);
00504 gdkdev->info.num_axes = 0;
00505 if (gdkdev->pktdata & PK_X)
00506 gdkdev->info.num_axes++;
00507 if (gdkdev->pktdata & PK_Y)
00508 gdkdev->info.num_axes++;
00509 if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
00510 gdkdev->info.num_axes++;
00511
00512
00513
00514
00515
00516 if ((gdkdev->pktdata & PK_ORIENTATION)
00517 && axis_or[0].axResolution == 0)
00518 gdkdev->pktdata &= ~PK_ORIENTATION;
00519
00520 if (gdkdev->pktdata & PK_ORIENTATION)
00521 gdkdev->info.num_axes += 2;
00522 WTInfo(WTI_CURSORS + cursorix, CSR_NPBTNMARKS,
00523 &gdkdev->npbtnmarks);
00524 gdkdev->axes = g_new(GdkAxisInfo, gdkdev->info.num_axes);
00525 gdkdev->info.axes = g_new(GdkAxisUse, gdkdev->info.num_axes);
00526 gdkdev->last_axis_data = g_new(gint, gdkdev->info.num_axes);
00527
00528 for (k = 0; k < GDK_AXIS_LAST; k++)
00529 gdkdev->axis_for_use[k] = -1;
00530
00531 k = 0;
00532 if (gdkdev->pktdata & PK_X) {
00533 gdkdev->axes[k].xresolution =
00534 gdkdev->axes[k].resolution =
00535 axis_x.axResolution / 65535.;
00536 gdkdev->axes[k].xmin_value = gdkdev->axes[k].min_value =
00537 axis_x.axMin;
00538 gdkdev->axes[k].xmax_value = gdkdev->axes[k].max_value =
00539 axis_x.axMax;
00540 gdkdev->info.axes[k] = GDK_AXIS_X;
00541 gdkdev->axis_for_use[GDK_AXIS_X] = k;
00542 k++;
00543 }
00544 if (gdkdev->pktdata & PK_Y) {
00545 gdkdev->axes[k].xresolution =
00546 gdkdev->axes[k].resolution =
00547 axis_y.axResolution / 65535.;
00548 gdkdev->axes[k].xmin_value = gdkdev->axes[k].min_value =
00549 axis_y.axMin;
00550 gdkdev->axes[k].xmax_value = gdkdev->axes[k].max_value =
00551 axis_y.axMax;
00552 gdkdev->info.axes[k] = GDK_AXIS_Y;
00553 gdkdev->axis_for_use[GDK_AXIS_Y] = k;
00554 k++;
00555 }
00556 if (gdkdev->pktdata & PK_NORMAL_PRESSURE) {
00557 gdkdev->axes[k].xresolution =
00558 gdkdev->axes[k].resolution =
00559 axis_npressure.axResolution / 65535.;
00560 gdkdev->axes[k].xmin_value = gdkdev->axes[k].min_value =
00561 axis_npressure.axMin;
00562 gdkdev->axes[k].xmax_value = gdkdev->axes[k].max_value =
00563 axis_npressure.axMax;
00564 gdkdev->info.axes[k] = GDK_AXIS_PRESSURE;
00565 gdkdev->axis_for_use[GDK_AXIS_PRESSURE] = k;
00566 k++;
00567 }
00568 if (gdkdev->pktdata & PK_ORIENTATION) {
00569 GdkAxisUse axis;
00570
00571 gdkdev->orientation_axes[0] = axis_or[0];
00572 gdkdev->orientation_axes[1] = axis_or[1];
00573 for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++) {
00574
00575
00576
00577 gdkdev->axes[k].xresolution =
00578 gdkdev->axes[k].resolution = 1000;
00579 gdkdev->axes[k].xmin_value =
00580 gdkdev->axes[k].min_value = -1000;
00581 gdkdev->axes[k].xmax_value =
00582 gdkdev->axes[k].max_value = 1000;
00583 gdkdev->info.axes[k] = axis;
00584 gdkdev->axis_for_use[axis] = k;
00585 k++;
00586 }
00587 }
00588 gdkdev->info.num_keys = 0;
00589 gdkdev->info.keys = NULL;
00590 GDK_NOTE(EVENTS,
00591 (g_print("device: %d (%d) %s axes: %d\n",
00592 gdkdev->info.deviceid, cursorix,
00593 gdkdev->info.name,
00594 gdkdev->info.num_axes),
00595 g_print("axes: X:%d, Y:%d, PRESSURE:%d, "
00596 "XTILT:%d, YTILT:%d\n",
00597 gdkdev->axis_for_use[GDK_AXIS_X],
00598 gdkdev->axis_for_use[GDK_AXIS_Y],
00599 gdkdev->axis_for_use[GDK_AXIS_PRESSURE],
00600 gdkdev->axis_for_use[GDK_AXIS_XTILT],
00601 gdkdev->axis_for_use[GDK_AXIS_YTILT])));
00602 for (i = 0; i < gdkdev->info.num_axes; i++)
00603 GDK_NOTE(EVENTS,
00604 g_print("...axis %d: %d--%d@%d (%d--%d@%d)\n",
00605 i,
00606 gdkdev->axes[i].xmin_value,
00607 gdkdev->axes[i].xmax_value,
00608 gdkdev->axes[i].xresolution,
00609 gdkdev->axes[i].min_value,
00610 gdkdev->axes[i].max_value,
00611 gdkdev->axes[i].resolution));
00612 gdk_input_devices = g_list_append(gdk_input_devices, gdkdev);
00613 }
00614 }
00615 }
00616 #endif
00617
00618 if (deviceid_counter > 0) {
00619 #ifdef HAVE_WINTAB
00620 gdk_input_vtable.set_mode = gdk_input_win32_set_mode;
00621 gdk_input_vtable.set_axes = NULL;
00622 gdk_input_vtable.set_key = NULL;
00623 gdk_input_vtable.motion_events = NULL;
00624 gdk_input_vtable.get_pointer = gdk_input_win32_get_pointer;
00625 gdk_input_vtable.grab_pointer = gdk_input_win32_grab_pointer;
00626 gdk_input_vtable.ungrab_pointer = gdk_input_win32_ungrab_pointer;
00627 gdk_input_vtable.configure_event = gdk_input_win32_configure_event;
00628 gdk_input_vtable.enter_event = gdk_input_win32_enter_event;
00629 gdk_input_vtable.other_event = gdk_input_win32_other_event;
00630 gdk_input_vtable.enable_window = gdk_input_win32_enable_window;
00631 gdk_input_vtable.disable_window = gdk_input_win32_disable_window;
00632
00633 gdk_input_root_width = gdk_screen_width();
00634 gdk_input_root_height = gdk_screen_height();
00635 gdk_input_ignore_core = FALSE;
00636 #else
00637 g_assert_not_reached();
00638 #endif
00639 } else {
00640 gdk_input_vtable.set_mode = NULL;
00641 gdk_input_vtable.set_axes = NULL;
00642 gdk_input_vtable.set_key = NULL;
00643 gdk_input_vtable.motion_events = NULL;
00644 gdk_input_vtable.get_pointer = gdk_input_none_get_pointer;
00645 gdk_input_vtable.grab_pointer = NULL;
00646 gdk_input_vtable.ungrab_pointer = NULL;
00647 gdk_input_vtable.configure_event = NULL;
00648 gdk_input_vtable.enter_event = NULL;
00649 gdk_input_vtable.other_event = NULL;
00650 gdk_input_vtable.enable_window = NULL;
00651 gdk_input_vtable.disable_window = NULL;
00652 gdk_input_ignore_core = FALSE;
00653 }
00654
00655 gdk_input_devices =
00656 g_list_append(gdk_input_devices, &gdk_input_core_info);
00657 }
00658
00659 gint gdk_input_set_mode(guint32 deviceid, GdkInputMode mode)
00660 {
00661 if (deviceid == GDK_CORE_POINTER)
00662 return FALSE;
00663
00664 if (gdk_input_vtable.set_mode)
00665 return gdk_input_vtable.set_mode(deviceid, mode);
00666 else
00667 return FALSE;
00668 }
00669
00670 void gdk_input_set_axes(guint32 deviceid, GdkAxisUse * axes)
00671 {
00672 int i;
00673 GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
00674 g_return_if_fail(gdkdev != NULL);
00675
00676 if (deviceid == GDK_CORE_POINTER)
00677 return;
00678
00679 for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++) {
00680 gdkdev->axis_for_use[i] = -1;
00681 }
00682
00683 for (i = 0; i < gdkdev->info.num_axes; i++) {
00684 gdkdev->info.axes[i] = axes[i];
00685 gdkdev->axis_for_use[axes[i]] = i;
00686 }
00687 }
00688
00689 static void
00690 gdk_input_none_get_pointer(GdkWindow * window,
00691 guint32 deviceid,
00692 gdouble * x,
00693 gdouble * y,
00694 gdouble * pressure,
00695 gdouble * xtilt,
00696 gdouble * ytilt, GdkModifierType * mask)
00697 {
00698 gint x_int, y_int;
00699
00700 gdk_window_get_pointer(window, &x_int, &y_int, mask);
00701
00702 if (x)
00703 *x = x_int;
00704 if (y)
00705 *y = y_int;
00706 if (pressure)
00707 *pressure = 0.5;
00708 if (xtilt)
00709 *xtilt = 0;
00710 if (ytilt)
00711 *ytilt = 0;
00712 }
00713
00714 #ifdef HAVE_WINTAB
00715
00716 static void
00717 gdk_input_translate_coordinates(GdkDevicePrivate * gdkdev,
00718 GdkInputWindow * input_window,
00719 gint * axis_data,
00720 gdouble * x,
00721 gdouble * y,
00722 gdouble * pressure,
00723 gdouble * xtilt, gdouble * ytilt)
00724 {
00725 GdkDrawablePrivate *window_private;
00726 gint x_axis, y_axis, pressure_axis, xtilt_axis, ytilt_axis;
00727 gdouble device_width, device_height;
00728 gdouble x_offset, y_offset, x_scale, y_scale;
00729
00730 window_private = (GdkDrawablePrivate *) input_window->window;
00731
00732 x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
00733 y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
00734 pressure_axis = gdkdev->axis_for_use[GDK_AXIS_PRESSURE];
00735 xtilt_axis = gdkdev->axis_for_use[GDK_AXIS_XTILT];
00736 ytilt_axis = gdkdev->axis_for_use[GDK_AXIS_YTILT];
00737
00738 device_width = gdkdev->axes[x_axis].max_value -
00739 gdkdev->axes[x_axis].min_value;
00740 device_height = gdkdev->axes[y_axis].max_value -
00741 gdkdev->axes[y_axis].min_value;
00742
00743 if (gdkdev->info.mode == GDK_MODE_SCREEN) {
00744 x_scale = gdk_input_root_width / device_width;
00745 y_scale = gdk_input_root_height / device_height;
00746
00747 x_offset = -input_window->root_x;
00748 y_offset = -input_window->root_y;
00749 } else {
00750
00751 double device_aspect =
00752 (device_height * gdkdev->axes[y_axis].resolution) /
00753 (device_width * gdkdev->axes[x_axis].resolution);
00754
00755 if (device_aspect * window_private->width >= window_private->height) {
00756
00757 x_scale = window_private->width / device_width;
00758 y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
00759 / gdkdev->axes[y_axis].resolution;
00760
00761 x_offset = 0;
00762 y_offset = -(device_height * y_scale -
00763 window_private->height) / 2;
00764 } else {
00765
00766 y_scale = window_private->height / device_height;
00767 x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
00768 / gdkdev->axes[x_axis].resolution;
00769
00770 y_offset = 0;
00771 x_offset = -(device_width * x_scale - window_private->width) / 2;
00772 }
00773 }
00774
00775 if (x)
00776 *x = x_offset + x_scale * axis_data[x_axis];
00777 if (y)
00778 *y = y_offset + y_scale * axis_data[y_axis];
00779
00780 if (pressure) {
00781 if (pressure_axis != -1)
00782 *pressure = ((double) axis_data[pressure_axis]
00783 - gdkdev->axes[pressure_axis].min_value)
00784 / (gdkdev->axes[pressure_axis].max_value
00785 - gdkdev->axes[pressure_axis].min_value);
00786 else
00787 *pressure = 0.5;
00788 }
00789
00790 if (xtilt) {
00791 if (xtilt_axis != -1) {
00792 *xtilt = 2. * (double) (axis_data[xtilt_axis] -
00793 (gdkdev->axes[xtilt_axis].min_value +
00794 gdkdev->axes[xtilt_axis].max_value) /
00795 2) / (gdkdev->axes[xtilt_axis].max_value -
00796 gdkdev->axes[xtilt_axis].min_value);
00797 } else
00798 *xtilt = 0;
00799 }
00800
00801 if (ytilt) {
00802 if (ytilt_axis != -1) {
00803 *ytilt = 2. * (double) (axis_data[ytilt_axis] -
00804 (gdkdev->axes[ytilt_axis].min_value +
00805 gdkdev->axes[ytilt_axis].max_value) /
00806 2) / (gdkdev->axes[ytilt_axis].max_value -
00807 gdkdev->axes[ytilt_axis].min_value);
00808 } else
00809 *ytilt = 0;
00810 }
00811 }
00812
00813 static void
00814 gdk_input_win32_get_pointer(GdkWindow * window,
00815 guint32 deviceid,
00816 gdouble * x,
00817 gdouble * y,
00818 gdouble * pressure,
00819 gdouble * xtilt,
00820 gdouble * ytilt, GdkModifierType * mask)
00821 {
00822 GdkDevicePrivate *gdkdev;
00823 GdkInputWindow *input_window;
00824 gint x_int, y_int;
00825 gint i;
00826
00827 if (deviceid == GDK_CORE_POINTER) {
00828 gdk_window_get_pointer(window, &x_int, &y_int, mask);
00829 if (x)
00830 *x = x_int;
00831 if (y)
00832 *y = y_int;
00833 if (pressure)
00834 *pressure = 0.5;
00835 if (xtilt)
00836 *xtilt = 0;
00837 if (ytilt)
00838 *ytilt = 0;
00839 } else {
00840 if (mask)
00841 gdk_window_get_pointer(window, NULL, NULL, mask);
00842
00843 gdkdev = gdk_input_find_device(deviceid);
00844 g_return_if_fail(gdkdev != NULL);
00845
00846 input_window = gdk_input_window_find(window);
00847 g_return_if_fail(input_window != NULL);
00848
00849 gdk_input_translate_coordinates(gdkdev, input_window,
00850 gdkdev->last_axis_data,
00851 x, y, pressure, xtilt, ytilt);
00852 if (mask) {
00853 *mask &= 0xFF;
00854 *mask |= ((gdkdev->last_buttons & 0x1F) << 8);
00855 }
00856 }
00857 }
00858
00859 static void
00860 gdk_input_get_root_relative_geometry(HWND w, int *x_ret, int *y_ret)
00861 {
00862 RECT rect;
00863
00864 GetWindowRect(w, &rect);
00865
00866 if (x_ret)
00867 *x_ret = rect.left;
00868 if (y_ret)
00869 *y_ret = rect.top;
00870 }
00871
00872 static gint gdk_input_win32_set_mode(guint32 deviceid, GdkInputMode mode)
00873 {
00874 GList *tmp_list;
00875 GdkDevicePrivate *gdkdev;
00876 GdkInputMode old_mode;
00877 GdkInputWindow *input_window;
00878
00879 if (deviceid == GDK_CORE_POINTER)
00880 return FALSE;
00881
00882 gdkdev = gdk_input_find_device(deviceid);
00883 g_return_val_if_fail(gdkdev != NULL, FALSE);
00884 old_mode = gdkdev->info.mode;
00885
00886 if (old_mode == mode)
00887 return TRUE;
00888
00889 gdkdev->info.mode = mode;
00890
00891 if (mode == GDK_MODE_WINDOW) {
00892 gdkdev->info.has_cursor = FALSE;
00893 for (tmp_list = gdk_input_windows; tmp_list;
00894 tmp_list = tmp_list->next) {
00895 input_window = (GdkInputWindow *) tmp_list->data;
00896 if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
00897 gdk_input_win32_enable_window(input_window->window, gdkdev);
00898 else if (old_mode != GDK_MODE_DISABLED)
00899 gdk_input_win32_disable_window(input_window->window, gdkdev);
00900 }
00901 } else if (mode == GDK_MODE_SCREEN) {
00902 gdkdev->info.has_cursor = TRUE;
00903 for (tmp_list = gdk_input_windows; tmp_list;
00904 tmp_list = tmp_list->next)
00905 gdk_input_win32_enable_window(((GdkInputWindow *) tmp_list->
00906 data)->window, gdkdev);
00907 } else {
00908
00909 for (tmp_list = gdk_input_windows; tmp_list;
00910 tmp_list = tmp_list->next) {
00911 input_window = (GdkInputWindow *) tmp_list->data;
00912 if (old_mode != GDK_MODE_WINDOW ||
00913 input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
00914 gdk_input_win32_disable_window(input_window->window, gdkdev);
00915 }
00916 }
00917
00918 return TRUE;
00919 }
00920
00921 static void
00922 gdk_input_win32_configure_event(GdkEventConfigure * event,
00923 GdkWindow * window)
00924 {
00925 GdkInputWindow *input_window;
00926 gint root_x, root_y;
00927
00928 input_window = gdk_input_window_find(window);
00929 g_return_if_fail(window != NULL);
00930
00931 gdk_input_get_root_relative_geometry
00932 (GDK_DRAWABLE_XID(window), &root_x, &root_y);
00933
00934 input_window->root_x = root_x;
00935 input_window->root_y = root_y;
00936 }
00937
00938 static void
00939 gdk_input_win32_enter_event(GdkEventCrossing * event, GdkWindow * window)
00940 {
00941 GdkInputWindow *input_window;
00942 gint root_x, root_y;
00943
00944 input_window = gdk_input_window_find(window);
00945 g_return_if_fail(window != NULL);
00946
00947 gdk_input_get_root_relative_geometry
00948 (GDK_DRAWABLE_XID(window), &root_x, &root_y);
00949
00950 input_window->root_x = root_x;
00951 input_window->root_y = root_y;
00952 }
00953
00954 static void decode_tilt(gint * axis_data, AXIS * axes, PACKET * packet)
00955 {
00956
00957
00958
00959
00960 double az, el;
00961
00962 az = TWOPI * packet->pkOrientation.orAzimuth /
00963 (axes[0].axResolution / 65536.);
00964 el = TWOPI * packet->pkOrientation.orAltitude /
00965 (axes[1].axResolution / 65536.);
00966
00967
00968 axis_data[0] = cos(az) * cos(el) * 1000;
00969
00970 axis_data[1] = sin(az) * cos(el) * 1000;
00971 }
00972
00973 static GdkDevicePrivate *gdk_input_find_dev_from_ctx(HCTX hctx,
00974 UINT cursor)
00975 {
00976 GList *tmp_list = gdk_input_devices;
00977 GdkDevicePrivate *gdkdev;
00978
00979 while (tmp_list) {
00980 gdkdev = (GdkDevicePrivate *) (tmp_list->data);
00981 if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
00982 return gdkdev;
00983 tmp_list = tmp_list->next;
00984 }
00985 return NULL;
00986 }
00987
00988 static gint gdk_input_win32_other_event(GdkEvent * event, MSG * xevent)
00989 {
00990 GdkWindow *current_window;
00991 GdkInputWindow *input_window;
00992 GdkWindow *window;
00993 GdkDevicePrivate *gdkdev;
00994 GdkEventMask masktest;
00995 POINT pt;
00996 PACKET packet;
00997 gint return_val;
00998 gint k;
00999 gint x, y;
01000
01001 if (event->any.window != wintab_window) {
01002 g_warning("gdk_input_win32_other_event: not wintab_window?");
01003 return FALSE;
01004 }
01005 #if USE_SYSCONTEXT
01006 window = gdk_window_at_pointer(&x, &y);
01007 if (window == NULL)
01008 window = gdk_parent_root;
01009
01010 gdk_window_ref(window);
01011
01012 GDK_NOTE(EVENTS,
01013 g_print("gdk_input_win32_other_event: window=%#x (%d,%d)\n",
01014 GDK_DRAWABLE_XID(window), x, y));
01015
01016 #else
01017
01018 current_window = gdk_window_lookup(GetActiveWindow());
01019 if (current_window == NULL)
01020 return FALSE;
01021
01022 input_window = gdk_input_window_find_within(current_window);
01023 if (input_window == NULL)
01024 return FALSE;
01025 #endif
01026
01027 if (xevent->message == WT_PACKET) {
01028 if (!WTPacket((HCTX) xevent->lParam, xevent->wParam, &packet))
01029 return FALSE;
01030 }
01031
01032 switch (xevent->message) {
01033 case WT_PACKET:
01034 if (window == gdk_parent_root) {
01035 GDK_NOTE(EVENTS, g_print("...is root\n"));
01036 return FALSE;
01037 }
01038
01039 if ((gdkdev = gdk_input_find_dev_from_ctx((HCTX) xevent->lParam,
01040 packet.pkCursor)) == NULL)
01041 return FALSE;
01042
01043 if (gdkdev->info.mode == GDK_MODE_DISABLED)
01044 return FALSE;
01045
01046 k = 0;
01047 if (gdkdev->pktdata & PK_X)
01048 gdkdev->last_axis_data[k++] = packet.pkX;
01049 if (gdkdev->pktdata & PK_Y)
01050 gdkdev->last_axis_data[k++] = packet.pkY;
01051 if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
01052 gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
01053 if (gdkdev->pktdata & PK_ORIENTATION) {
01054 decode_tilt(gdkdev->last_axis_data + k,
01055 gdkdev->orientation_axes, &packet);
01056 k += 2;
01057 }
01058
01059 g_assert(k == gdkdev->info.num_axes);
01060
01061 if (HIWORD(packet.pkButtons) != TBN_NONE) {
01062
01063 event->button.button = 1 + LOWORD(packet.pkButtons);
01064
01065 if (HIWORD(packet.pkButtons) == TBN_UP) {
01066 event->any.type = GDK_BUTTON_RELEASE;
01067 masktest = GDK_BUTTON_RELEASE_MASK;
01068 gdkdev->button_state &= ~(1 << LOWORD(packet.pkButtons));
01069 } else {
01070 event->any.type = GDK_BUTTON_PRESS;
01071 masktest = GDK_BUTTON_PRESS_MASK;
01072 gdkdev->button_state |= 1 << LOWORD(packet.pkButtons);
01073 }
01074 } else {
01075 event->any.type = GDK_MOTION_NOTIFY;
01076 masktest = GDK_POINTER_MOTION_MASK;
01077 if (gdkdev->button_state & (1 << 0))
01078 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
01079 if (gdkdev->button_state & (1 << 1))
01080 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
01081 if (gdkdev->button_state & (1 << 2))
01082 masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
01083 }
01084
01085
01086
01087
01088 dijkstra:
01089 if (!GDK_WINDOW_WIN32DATA(window)->extension_events_selected
01090 || !(((GdkWindowPrivate *) window)->extension_events & masktest))
01091 {
01092 GDK_NOTE(EVENTS, g_print("...not selected\n"));
01093
01094 if (((GdkWindowPrivate *) window)->parent == gdk_parent_root)
01095 return FALSE;
01096
01097 pt.x = x;
01098 pt.y = y;
01099 ClientToScreen(GDK_DRAWABLE_XID(window), &pt);
01100 gdk_window_unref(window);
01101 window = ((GdkWindowPrivate *) window)->parent;
01102 gdk_window_ref(window);
01103 ScreenToClient(GDK_DRAWABLE_XID(window), &pt);
01104 x = pt.x;
01105 y = pt.y;
01106 GDK_NOTE(EVENTS, g_print("...propagating to %#x, (%d,%d)\n",
01107 GDK_DRAWABLE_XID(window), x, y));
01108 goto dijkstra;
01109 }
01110
01111 input_window = gdk_input_window_find(window);
01112
01113 g_assert(input_window != NULL);
01114
01115 if (gdkdev->info.mode == GDK_MODE_WINDOW
01116 && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
01117 return FALSE;
01118
01119 event->any.window = window;
01120
01121 if (event->any.type == GDK_BUTTON_PRESS
01122 || event->any.type == GDK_BUTTON_RELEASE) {
01123 event->button.time = xevent->time;
01124 event->button.source = gdkdev->info.source;
01125 last_moved_cursor_id =
01126 event->button.deviceid = gdkdev->info.deviceid;
01127
01128 #if 0
01129 #if USE_SYSCONTEXT
01130
01131 if (event->button.button <= 3)
01132 return FALSE;
01133 #endif
01134 #endif
01135 gdk_input_translate_coordinates(gdkdev, input_window,
01136 gdkdev->last_axis_data,
01137 &event->button.x,
01138 &event->button.y,
01139 &event->button.pressure,
01140 &event->button.xtilt,
01141 &event->button.ytilt);
01142
01143 event->button.state = ((gdkdev->button_state << 8)
01144 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
01145 | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
01146 | GDK_BUTTON5_MASK));
01147 GDK_NOTE(EVENTS,
01148 g_print("WINTAB button %s: %d %d %g,%g %g %g,%g\n",
01149 (event->button.type ==
01150 GDK_BUTTON_PRESS ? "press" : "release"),
01151 event->button.deviceid, event->button.button,
01152 event->button.x, event->button.y,
01153 event->button.pressure, event->button.xtilt,
01154 event->button.ytilt));
01155 } else {
01156 event->motion.time = xevent->time;
01157 last_moved_cursor_id =
01158 event->motion.deviceid = gdkdev->info.deviceid;
01159 event->motion.is_hint = FALSE;
01160 event->motion.source = gdkdev->info.source;
01161
01162 gdk_input_translate_coordinates(gdkdev, input_window,
01163 gdkdev->last_axis_data,
01164 &event->motion.x,
01165 &event->motion.y,
01166 &event->motion.pressure,
01167 &event->motion.xtilt,
01168 &event->motion.ytilt);
01169
01170 event->motion.state = ((gdkdev->button_state << 8)
01171 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
01172 | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
01173 | GDK_BUTTON5_MASK));
01174
01175 GDK_NOTE(EVENTS, g_print("WINTAB motion: %d %g,%g %g %g,%g\n",
01176 event->motion.deviceid,
01177 event->motion.x, event->motion.y,
01178 event->motion.pressure,
01179 event->motion.xtilt,
01180 event->motion.ytilt));
01181
01182
01183
01184
01185
01186 if ((gdkdev->pktdata & PK_NORMAL_PRESSURE
01187 && (event->motion.state & GDK_BUTTON1_MASK)
01188 && packet.pkNormalPressure <= MAX(0,
01189 gdkdev->npbtnmarks[0] - 2))
01190 || (gdkdev->pktdata & PK_NORMAL_PRESSURE
01191 && !(event->motion.state & GDK_BUTTON1_MASK)
01192 && packet.pkNormalPressure > gdkdev->npbtnmarks[1] + 2)) {
01193 GdkEvent *event2 = gdk_event_copy(event);
01194 if (event->motion.state & GDK_BUTTON1_MASK) {
01195 event2->button.type = GDK_BUTTON_RELEASE;
01196 gdkdev->button_state &= ~1;
01197 } else {
01198 event2->button.type = GDK_BUTTON_PRESS;
01199 gdkdev->button_state |= 1;
01200 }
01201 event2->button.state = ((gdkdev->button_state << 8)
01202 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
01203 | GDK_BUTTON3_MASK |
01204 GDK_BUTTON4_MASK |
01205 GDK_BUTTON5_MASK));
01206 event2->button.button = 1;
01207 GDK_NOTE(EVENTS,
01208 g_print
01209 ("WINTAB synthesized button %s: %d %d %g,%g %g\n",
01210 (event2->button.type ==
01211 GDK_BUTTON_PRESS ? "press" : "release"),
01212 event2->button.deviceid, event2->button.button,
01213 event2->button.x, event2->button.y,
01214 event2->button.pressure));
01215 gdk_event_queue_append(event2);
01216 }
01217 }
01218 return TRUE;
01219
01220 case WT_PROXIMITY:
01221 if (LOWORD(xevent->lParam) == 0) {
01222 event->proximity.type = GDK_PROXIMITY_OUT;
01223 gdk_input_ignore_core = FALSE;
01224 } else {
01225 event->proximity.type = GDK_PROXIMITY_IN;
01226 gdk_input_ignore_core = TRUE;
01227 }
01228 event->proximity.time = xevent->time;
01229 event->proximity.source = GDK_SOURCE_PEN;
01230 event->proximity.deviceid = last_moved_cursor_id;
01231
01232 GDK_NOTE(EVENTS, g_print("WINTAB proximity %s: %d\n",
01233 (event->proximity.type == GDK_PROXIMITY_IN ?
01234 "in" : "out"), event->proximity.deviceid));
01235 return TRUE;
01236 }
01237 return FALSE;
01238 }
01239
01240 static gint
01241 gdk_input_win32_enable_window(GdkWindow * window,
01242 GdkDevicePrivate * gdkdev)
01243 {
01244 GDK_WINDOW_WIN32DATA(window)->extension_events_selected = TRUE;
01245 return TRUE;
01246 }
01247
01248 static gint
01249 gdk_input_win32_disable_window(GdkWindow * window,
01250 GdkDevicePrivate * gdkdev)
01251 {
01252 GDK_WINDOW_WIN32DATA(window)->extension_events_selected = FALSE;
01253 return TRUE;
01254 }
01255
01256 static gint
01257 gdk_input_win32_grab_pointer(GdkWindow * window,
01258 gint owner_events,
01259 GdkEventMask event_mask,
01260 GdkWindow * confine_to, guint32 time)
01261 {
01262 GdkInputWindow *input_window, *new_window;
01263 gboolean need_ungrab;
01264 GdkDevicePrivate *gdkdev;
01265 GList *tmp_list;
01266 gint result;
01267
01268 tmp_list = gdk_input_windows;
01269 new_window = NULL;
01270 need_ungrab = FALSE;
01271
01272 GDK_NOTE(MISC, g_print("gdk_input_win32_grab_pointer: %#x %d %#x\n",
01273 GDK_DRAWABLE_XID(window),
01274 owner_events,
01275 (confine_to ? GDK_DRAWABLE_XID(confine_to) :
01276 0)));
01277
01278 while (tmp_list) {
01279 input_window = (GdkInputWindow *) tmp_list->data;
01280
01281 if (input_window->window == window)
01282 new_window = input_window;
01283 else if (input_window->grabbed) {
01284 input_window->grabbed = FALSE;
01285 need_ungrab = TRUE;
01286 }
01287
01288 tmp_list = tmp_list->next;
01289 }
01290
01291 if (new_window) {
01292 new_window->grabbed = TRUE;
01293
01294 tmp_list = gdk_input_devices;
01295 while (tmp_list) {
01296 gdkdev = (GdkDevicePrivate *) tmp_list->data;
01297 if (gdkdev->info.deviceid != GDK_CORE_POINTER) {
01298 #if 0
01299
01300 gdk_input_find_events(window, gdkdev,
01301 event_mask, event_classes, &num_classes);
01302 result = XGrabDevice(GDK_DISPLAY(), gdkdev->xdevice,
01303 GDK_WINDOW_XWINDOW(window),
01304 owner_events, num_classes, event_classes,
01305 GrabModeAsync, GrabModeAsync, time);
01306
01307
01308
01309 if (result != Success)
01310 return result;
01311 #endif
01312 }
01313 tmp_list = tmp_list->next;
01314 }
01315 } else {
01316 tmp_list = gdk_input_devices;
01317 while (tmp_list) {
01318 gdkdev = (GdkDevicePrivate *) tmp_list->data;
01319 if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
01320 ((gdkdev->button_state != 0) || need_ungrab)) {
01321 #if 0
01322
01323 XUngrabDevice(gdk_display, gdkdev->xdevice, time);
01324 #endif
01325 gdkdev->button_state = 0;
01326 }
01327
01328 tmp_list = tmp_list->next;
01329 }
01330 }
01331
01332 return Success;
01333
01334 }
01335
01336 static void gdk_input_win32_ungrab_pointer(guint32 time)
01337 {
01338 GdkInputWindow *input_window;
01339 GdkDevicePrivate *gdkdev;
01340 GList *tmp_list;
01341
01342 GDK_NOTE(MISC, g_print("gdk_input_win32_ungrab_pointer\n"));
01343
01344 tmp_list = gdk_input_windows;
01345 while (tmp_list) {
01346 input_window = (GdkInputWindow *) tmp_list->data;
01347 if (input_window->grabbed)
01348 break;
01349 tmp_list = tmp_list->next;
01350 }
01351
01352 if (tmp_list) {
01353 input_window->grabbed = FALSE;
01354
01355 tmp_list = gdk_input_devices;
01356 while (tmp_list) {
01357 gdkdev = (GdkDevicePrivate *) tmp_list->data;
01358 #if 0
01359
01360 if (gdkdev->info.deviceid != GDK_CORE_POINTER && gdkdev->xdevice)
01361 XUngrabDevice(gdk_display, gdkdev->xdevice, time);
01362 #endif
01363 tmp_list = tmp_list->next;
01364 }
01365 }
01366 }
01367
01368 #endif
01369
01370 GList *gdk_input_list_devices(void)
01371 {
01372 return gdk_input_devices;
01373 }
01374
01375 void gdk_input_set_source(guint32 deviceid, GdkInputSource source)
01376 {
01377 GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
01378 g_return_if_fail(gdkdev != NULL);
01379
01380 gdkdev->info.source = source;
01381 }
01382
01383 void gdk_input_set_key(guint32 deviceid,
01384 guint index,
01385 guint keyval, GdkModifierType modifiers)
01386 {
01387 if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key)
01388 gdk_input_vtable.set_key(deviceid, index, keyval, modifiers);
01389 }
01390
01391 GdkTimeCoord *gdk_input_motion_events(GdkWindow * window,
01392 guint32 deviceid,
01393 guint32 start,
01394 guint32 stop, gint * nevents_return)
01395 {
01396 g_return_val_if_fail(window != NULL, NULL);
01397 if (GDK_DRAWABLE_DESTROYED(window))
01398 return NULL;
01399
01400 *nevents_return = 0;
01401 return NULL;
01402 }
01403
01404 static gint
01405 gdk_input_enable_window(GdkWindow * window, GdkDevicePrivate * gdkdev)
01406 {
01407 if (gdk_input_vtable.enable_window)
01408 return gdk_input_vtable.enable_window(window, gdkdev);
01409 else
01410 return TRUE;
01411 }
01412
01413 static gint
01414 gdk_input_disable_window(GdkWindow * window, GdkDevicePrivate * gdkdev)
01415 {
01416 if (gdk_input_vtable.disable_window)
01417 return gdk_input_vtable.disable_window(window, gdkdev);
01418 else
01419 return TRUE;
01420 }
01421
01422
01423 static GdkInputWindow *gdk_input_window_find(GdkWindow * window)
01424 {
01425 GList *tmp_list;
01426
01427 for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
01428 if (((GdkInputWindow *) (tmp_list->data))->window == window)
01429 return (GdkInputWindow *) (tmp_list->data);
01430
01431 return NULL;
01432 }
01433
01434 #if !USE_SYSCONTEXT
01435
01436 static GdkInputWindow *gdk_input_window_find_within(GdkWindow * window)
01437 {
01438 GList *list;
01439 GdkWindow *tmpw;
01440 GdkInputWindow *candidate = NULL;
01441
01442 for (list = gdk_input_windows; list != NULL; list = list->next) {
01443 tmpw = ((GdkInputWindow *) (tmp_list->data))->window;
01444 if (tmpw == window
01445 || IsChild(GDK_DRAWABLE_XID(window), GDK_DRAWABLE_XID(tmpw))) {
01446 if (candidate)
01447 return NULL;
01448 candidate = (GdkInputWindow *) (list->data);
01449 }
01450 }
01451
01452 return candidate;
01453 }
01454
01455 #endif
01456
01457
01458
01459
01460
01461
01462
01463 void
01464 gdk_input_set_extension_events(GdkWindow * window,
01465 gint mask, GdkExtensionMode mode)
01466 {
01467 GdkWindowPrivate *window_private;
01468 GList *tmp_list;
01469 GdkInputWindow *iw;
01470
01471 g_return_if_fail(window != NULL);
01472 if (GDK_DRAWABLE_DESTROYED(window))
01473 return;
01474 window_private = (GdkWindowPrivate *) window;
01475
01476 if (mode == GDK_EXTENSION_EVENTS_NONE)
01477 mask = 0;
01478
01479 if (mask != 0) {
01480 iw = g_new(GdkInputWindow, 1);
01481
01482 iw->window = window;
01483 iw->mode = mode;
01484
01485 iw->grabbed = FALSE;
01486
01487 gdk_input_windows = g_list_append(gdk_input_windows, iw);
01488 window_private->extension_events = mask;
01489
01490
01491 gdk_window_set_events(window,
01492 gdk_window_get_events(window) |
01493 GDK_ENTER_NOTIFY_MASK);
01494 } else {
01495 iw = gdk_input_window_find(window);
01496 if (iw) {
01497 gdk_input_windows = g_list_remove(gdk_input_windows, iw);
01498 g_free(iw);
01499 }
01500
01501 window_private->extension_events = 0;
01502 }
01503
01504 for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) {
01505 GdkDevicePrivate *gdkdev = (GdkDevicePrivate *) (tmp_list->data);
01506
01507 if (gdkdev->info.deviceid != GDK_CORE_POINTER) {
01508 if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
01509 && (gdkdev->info.has_cursor
01510 || mode == GDK_EXTENSION_EVENTS_ALL))
01511 gdk_input_enable_window(window, gdkdev);
01512 else
01513 gdk_input_disable_window(window, gdkdev);
01514 }
01515 }
01516 }
01517
01518 void gdk_input_window_destroy(GdkWindow * window)
01519 {
01520 GdkInputWindow *input_window;
01521
01522 input_window = gdk_input_window_find(window);
01523 g_return_if_fail(input_window != NULL);
01524
01525 gdk_input_windows = g_list_remove(gdk_input_windows, input_window);
01526 g_free(input_window);
01527 }
01528
01529 void gdk_input_exit(void)
01530 {
01531 #ifdef HAVE_WINTAB
01532 GList *tmp_list;
01533 GdkDevicePrivate *gdkdev;
01534
01535 for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) {
01536 gdkdev = (GdkDevicePrivate *) (tmp_list->data);
01537 if (gdkdev->info.deviceid != GDK_CORE_POINTER) {
01538 gdk_input_win32_set_mode(gdkdev->info.deviceid,
01539 GDK_MODE_DISABLED);
01540 g_free(gdkdev->info.name);
01541 g_free(gdkdev->last_axis_data);
01542 g_free(gdkdev->info.axes);
01543 g_free(gdkdev->info.keys);
01544 g_free(gdkdev->axes);
01545 g_free(gdkdev);
01546 }
01547 }
01548
01549 g_list_free(gdk_input_devices);
01550
01551 for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next) {
01552 g_free(tmp_list->data);
01553 }
01554 g_list_free(gdk_input_windows);
01555 gdk_input_windows = NULL;
01556
01557 gdk_window_unref(wintab_window);
01558 wintab_window = NULL;
01559
01560 #if 1
01561 for (tmp_list = wintab_contexts; tmp_list; tmp_list = tmp_list->next) {
01562 HCTX *hctx = (HCTX *) tmp_list->data;
01563 BOOL result;
01564
01565 #ifdef _MSC_VER
01566
01567
01568
01569
01570
01571
01572 __try {
01573 #if 0
01574 WTEnable(*hctx, FALSE);
01575 #endif
01576 result = WTClose(*hctx);
01577 }
01578 __except(
01579 EXCEPTION_EXECUTE_HANDLER
01580 ) {
01581 result = FALSE;
01582 }
01583 if (!result)
01584 g_warning("gdk_input_exit: Closing Wintab context %#x failed",
01585 *hctx);
01586 #endif
01587 g_free(hctx);
01588 }
01589 #endif
01590 g_list_free(wintab_contexts);
01591 wintab_contexts = NULL;
01592 #endif
01593 }
01594
01595 static GdkDevicePrivate *gdk_input_find_device(guint32 id)
01596 {
01597 GList *tmp_list = gdk_input_devices;
01598 GdkDevicePrivate *gdkdev;
01599
01600 while (tmp_list) {
01601 gdkdev = (GdkDevicePrivate *) (tmp_list->data);
01602 if (gdkdev->info.deviceid == id)
01603 return gdkdev;
01604 tmp_list = tmp_list->next;
01605 }
01606 return NULL;
01607 }
01608
01609 void
01610 gdk_input_window_get_pointer(GdkWindow * window,
01611 guint32 deviceid,
01612 gdouble * x,
01613 gdouble * y,
01614 gdouble * pressure,
01615 gdouble * xtilt,
01616 gdouble * ytilt, GdkModifierType * mask)
01617 {
01618 if (gdk_input_vtable.get_pointer)
01619 gdk_input_vtable.get_pointer(window, deviceid, x, y, pressure,
01620 xtilt, ytilt, mask);
01621 }