Blame gdk/win32/gdkinput-win32.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 * Copyright (C) 1998-2007 Tor Lillqvist
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include <stdlib.h>
Packit Service fb6fa5
#include <stdio.h>
Packit Service fb6fa5
#include <math.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdk.h"
Packit Service fb6fa5
#include "gdkinput.h"
Packit Service fb6fa5
#include "gdkinternals.h"
Packit Service fb6fa5
#include "gdkprivate-win32.h"
Packit Service fb6fa5
#include "gdkinput-win32.h"
Packit Service fb6fa5
Packit Service fb6fa5
#define WINTAB32_DLL "Wintab32.dll"
Packit Service fb6fa5
Packit Service fb6fa5
#define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y  | PK_NORMAL_PRESSURE | PK_ORIENTATION)
Packit Service fb6fa5
/* We want everything in absolute mode */
Packit Service fb6fa5
#define PACKETMODE (0)
Packit Service fb6fa5
#include <pktdef.h>
Packit Service fb6fa5
Packit Service fb6fa5
#define DEBUG_WINTAB 1		/* Verbose debug messages enabled */
Packit Service fb6fa5
Packit Service fb6fa5
#define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */
Packit Service fb6fa5
Packit Service fb6fa5
#define TWOPI (2.*G_PI)
Packit Service fb6fa5
Packit Service fb6fa5
/* Forward declarations */
Packit Service fb6fa5
Packit Service fb6fa5
static GdkDevicePrivate *gdk_input_find_dev_from_ctx (HCTX hctx,
Packit Service fb6fa5
						      UINT id);
Packit Service fb6fa5
static GList     *wintab_contexts = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static GdkWindow *wintab_window = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static GdkDevicePrivate *_gdk_device_in_proximity;
Packit Service fb6fa5
Packit Service fb6fa5
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
Packit Service fb6fa5
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
Packit Service fb6fa5
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
Packit Service fb6fa5
typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
Packit Service fb6fa5
typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
Packit Service fb6fa5
typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
Packit Service fb6fa5
typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
Packit Service fb6fa5
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
Packit Service fb6fa5
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
Packit Service fb6fa5
Packit Service fb6fa5
static t_WTInfoA p_WTInfoA;
Packit Service fb6fa5
static t_WTInfoW p_WTInfoW;
Packit Service fb6fa5
static t_WTEnable p_WTEnable;
Packit Service fb6fa5
static t_WTOpenA p_WTOpenA;
Packit Service fb6fa5
static t_WTGetA p_WTGetA;
Packit Service fb6fa5
static t_WTSetA p_WTSetA;
Packit Service fb6fa5
static t_WTOverlap p_WTOverlap;
Packit Service fb6fa5
static t_WTPacket p_WTPacket;
Packit Service fb6fa5
static t_WTQueueSizeSet p_WTQueueSizeSet;
Packit Service fb6fa5
Packit Service fb6fa5
static GdkDevicePrivate *
Packit Service fb6fa5
gdk_input_find_dev_from_ctx (HCTX hctx,
Packit Service fb6fa5
			     UINT cursor)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list = _gdk_input_devices;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gdkdev = (GdkDevicePrivate *) (tmp_list->data);
Packit Service fb6fa5
      if (gdkdev->hctx == hctx && gdkdev->cursor == cursor)
Packit Service fb6fa5
	return gdkdev;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return NULL;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef G_ENABLE_DEBUG
Packit Service fb6fa5
static void
Packit Service fb6fa5
print_lc(LOGCONTEXT *lc)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_print ("lcName = %s\n", lc->lcName);
Packit Service fb6fa5
  g_print ("lcOptions =");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_SYSTEM) g_print (" CXO_SYSTEM");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_PEN) g_print (" CXO_PEN");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_MESSAGES) g_print (" CXO_MESSAGES");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_MARGIN) g_print (" CXO_MARGIN");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_MGNINSIDE) g_print (" CXO_MGNINSIDE");
Packit Service fb6fa5
  if (lc->lcOptions & CXO_CSRMESSAGES) g_print (" CXO_CSRMESSAGES");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcStatus =");
Packit Service fb6fa5
  if (lc->lcStatus & CXS_DISABLED) g_print (" CXS_DISABLED");
Packit Service fb6fa5
  if (lc->lcStatus & CXS_OBSCURED) g_print (" CXS_OBSCURED");
Packit Service fb6fa5
  if (lc->lcStatus & CXS_ONTOP) g_print (" CXS_ONTOP");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcLocks =");
Packit Service fb6fa5
  if (lc->lcLocks & CXL_INSIZE) g_print (" CXL_INSIZE");
Packit Service fb6fa5
  if (lc->lcLocks & CXL_INASPECT) g_print (" CXL_INASPECT");
Packit Service fb6fa5
  if (lc->lcLocks & CXL_SENSITIVITY) g_print (" CXL_SENSITIVITY");
Packit Service fb6fa5
  if (lc->lcLocks & CXL_MARGIN) g_print (" CXL_MARGIN");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcMsgBase = %#x, lcDevice = %#x, lcPktRate = %d\n",
Packit Service fb6fa5
	  lc->lcMsgBase, lc->lcDevice, lc->lcPktRate);
Packit Service fb6fa5
  g_print ("lcPktData =");
Packit Service fb6fa5
  if (lc->lcPktData & PK_CONTEXT) g_print (" PK_CONTEXT");
Packit Service fb6fa5
  if (lc->lcPktData & PK_STATUS) g_print (" PK_STATUS");
Packit Service fb6fa5
  if (lc->lcPktData & PK_TIME) g_print (" PK_TIME");
Packit Service fb6fa5
  if (lc->lcPktData & PK_CHANGED) g_print (" PK_CHANGED");
Packit Service fb6fa5
  if (lc->lcPktData & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
Packit Service fb6fa5
  if (lc->lcPktData & PK_CURSOR) g_print (" PK_CURSOR");
Packit Service fb6fa5
  if (lc->lcPktData & PK_BUTTONS) g_print (" PK_BUTTONS");
Packit Service fb6fa5
  if (lc->lcPktData & PK_X) g_print (" PK_X");
Packit Service fb6fa5
  if (lc->lcPktData & PK_Y) g_print (" PK_Y");
Packit Service fb6fa5
  if (lc->lcPktData & PK_Z) g_print (" PK_Z");
Packit Service fb6fa5
  if (lc->lcPktData & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
Packit Service fb6fa5
  if (lc->lcPktData & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
Packit Service fb6fa5
  if (lc->lcPktData & PK_ORIENTATION) g_print (" PK_ORIENTATION");
Packit Service fb6fa5
  if (lc->lcPktData & PK_ROTATION) g_print (" PK_ROTATION");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcPktMode =");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_CONTEXT) g_print (" PK_CONTEXT");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_STATUS) g_print (" PK_STATUS");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_TIME) g_print (" PK_TIME");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_CHANGED) g_print (" PK_CHANGED");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_CURSOR) g_print (" PK_CURSOR");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_BUTTONS) g_print (" PK_BUTTONS");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_X) g_print (" PK_X");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_Y) g_print (" PK_Y");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_Z) g_print (" PK_Z");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_ORIENTATION) g_print (" PK_ORIENTATION");
Packit Service fb6fa5
  if (lc->lcPktMode & PK_ROTATION) g_print (" PK_ROTATION");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcMoveMask =");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_CONTEXT) g_print (" PK_CONTEXT");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_STATUS) g_print (" PK_STATUS");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_TIME) g_print (" PK_TIME");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_CHANGED) g_print (" PK_CHANGED");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_SERIAL_NUMBER) g_print (" PK_SERIAL_NUMBER");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_CURSOR) g_print (" PK_CURSOR");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_BUTTONS) g_print (" PK_BUTTONS");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_X) g_print (" PK_X");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_Y) g_print (" PK_Y");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_Z) g_print (" PK_Z");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_NORMAL_PRESSURE) g_print (" PK_NORMAL_PRESSURE");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_TANGENT_PRESSURE) g_print (" PK_TANGENT_PRESSURE");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_ORIENTATION) g_print (" PK_ORIENTATION");
Packit Service fb6fa5
  if (lc->lcMoveMask & PK_ROTATION) g_print (" PK_ROTATION");
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  g_print ("lcBtnDnMask = %#x, lcBtnUpMask = %#x\n",
Packit Service fb6fa5
	  (guint) lc->lcBtnDnMask, (guint) lc->lcBtnUpMask);
Packit Service fb6fa5
  g_print ("lcInOrgX = %ld, lcInOrgY = %ld, lcInOrgZ = %ld\n",
Packit Service fb6fa5
	  lc->lcInOrgX, lc->lcInOrgY, lc->lcInOrgZ);
Packit Service fb6fa5
  g_print ("lcInExtX = %ld, lcInExtY = %ld, lcInExtZ = %ld\n",
Packit Service fb6fa5
	  lc->lcInExtX, lc->lcInExtY, lc->lcInExtZ);
Packit Service fb6fa5
  g_print ("lcOutOrgX = %ld, lcOutOrgY = %ld, lcOutOrgZ = %ld\n",
Packit Service fb6fa5
	  lc->lcOutOrgX, lc->lcOutOrgY, lc->lcOutOrgZ);
Packit Service fb6fa5
  g_print ("lcOutExtX = %ld, lcOutExtY = %ld, lcOutExtZ = %ld\n",
Packit Service fb6fa5
	  lc->lcOutExtX, lc->lcOutExtY, lc->lcOutExtZ);
Packit Service fb6fa5
  g_print ("lcSensX = %g, lcSensY = %g, lcSensZ = %g\n",
Packit Service fb6fa5
	  lc->lcSensX / 65536., lc->lcSensY / 65536., lc->lcSensZ / 65536.);
Packit Service fb6fa5
  g_print ("lcSysMode = %d\n", lc->lcSysMode);
Packit Service fb6fa5
  g_print ("lcSysOrgX = %d, lcSysOrgY = %d\n",
Packit Service fb6fa5
	  lc->lcSysOrgX, lc->lcSysOrgY);
Packit Service fb6fa5
  g_print ("lcSysExtX = %d, lcSysExtY = %d\n",
Packit Service fb6fa5
	  lc->lcSysExtX, lc->lcSysExtY);
Packit Service fb6fa5
  g_print ("lcSysSensX = %g, lcSysSensY = %g\n",
Packit Service fb6fa5
	  lc->lcSysSensX / 65536., lc->lcSysSensY / 65536.);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
print_cursor (int index)
Packit Service fb6fa5
{
Packit Service fb6fa5
  int size;
Packit Service fb6fa5
  int i;
Packit Service fb6fa5
  char *name;
Packit Service fb6fa5
  BOOL active;
Packit Service fb6fa5
  WTPKT wtpkt;
Packit Service fb6fa5
  BYTE buttons;
Packit Service fb6fa5
  BYTE buttonbits;
Packit Service fb6fa5
  char *btnnames;
Packit Service fb6fa5
  char *p;
Packit Service fb6fa5
  BYTE buttonmap[32];
Packit Service fb6fa5
  BYTE sysbtnmap[32];
Packit Service fb6fa5
  BYTE npbutton;
Packit Service fb6fa5
  UINT npbtnmarks[2];
Packit Service fb6fa5
  UINT *npresponse;
Packit Service fb6fa5
  BYTE tpbutton;
Packit Service fb6fa5
  UINT tpbtnmarks[2];
Packit Service fb6fa5
  UINT *tpresponse;
Packit Service fb6fa5
  DWORD physid;
Packit Service fb6fa5
  UINT mode;
Packit Service fb6fa5
  UINT minpktdata;
Packit Service fb6fa5
  UINT minbuttons;
Packit Service fb6fa5
  UINT capabilities;
Packit Service fb6fa5
Packit Service fb6fa5
  size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, NULL);
Packit Service fb6fa5
  name = g_malloc (size + 1);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_NAME, name);
Packit Service fb6fa5
  g_print ("NAME: %s\n", name);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_ACTIVE, &active);
Packit Service fb6fa5
  g_print ("ACTIVE: %s\n", active ? "YES" : "NO");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_PKTDATA, &wtpkt);
Packit Service fb6fa5
  g_print ("PKTDATA: %#x:", (guint) wtpkt);
Packit Service fb6fa5
#define BIT(x) if (wtpkt & PK_##x) g_print (" " #x)
Packit Service fb6fa5
  BIT (CONTEXT);
Packit Service fb6fa5
  BIT (STATUS);
Packit Service fb6fa5
  BIT (TIME);
Packit Service fb6fa5
  BIT (CHANGED);
Packit Service fb6fa5
  BIT (SERIAL_NUMBER);
Packit Service fb6fa5
  BIT (BUTTONS);
Packit Service fb6fa5
  BIT (X);
Packit Service fb6fa5
  BIT (Y);
Packit Service fb6fa5
  BIT (Z);
Packit Service fb6fa5
  BIT (NORMAL_PRESSURE);
Packit Service fb6fa5
  BIT (TANGENT_PRESSURE);
Packit Service fb6fa5
  BIT (ORIENTATION);
Packit Service fb6fa5
  BIT (ROTATION);
Packit Service fb6fa5
#undef BIT
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONS, &buttons);
Packit Service fb6fa5
  g_print ("BUTTONS: %d\n", buttons);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONBITS, &buttonbits);
Packit Service fb6fa5
  g_print ("BUTTONBITS: %d\n", buttonbits);
Packit Service fb6fa5
  size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, NULL);
Packit Service fb6fa5
  g_print ("BTNNAMES:");
Packit Service fb6fa5
  if (size > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      btnnames = g_malloc (size + 1);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_BTNNAMES, btnnames);
Packit Service fb6fa5
      p = btnnames;
Packit Service fb6fa5
      while (*p)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_print (" %s", p);
Packit Service fb6fa5
	  p += strlen (p) + 1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_BUTTONMAP, buttonmap);
Packit Service fb6fa5
  g_print ("BUTTONMAP:");
Packit Service fb6fa5
  for (i = 0; i < buttons; i++)
Packit Service fb6fa5
    g_print (" %d", buttonmap[i]);
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_SYSBTNMAP, sysbtnmap);
Packit Service fb6fa5
  g_print ("SYSBTNMAP:");
Packit Service fb6fa5
  for (i = 0; i < buttons; i++)
Packit Service fb6fa5
    g_print (" %d", sysbtnmap[i]);
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBUTTON, &npbutton);
Packit Service fb6fa5
  g_print ("NPBUTTON: %d\n", npbutton);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPBTNMARKS, npbtnmarks);
Packit Service fb6fa5
  g_print ("NPBTNMARKS: %d %d\n", npbtnmarks[0], npbtnmarks[1]);
Packit Service fb6fa5
  size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, NULL);
Packit Service fb6fa5
  g_print ("NPRESPONSE:");
Packit Service fb6fa5
  if (size > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      npresponse = g_malloc (size);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_NPRESPONSE, npresponse);
Packit Service fb6fa5
      for (i = 0; i < size / sizeof (UINT); i++)
Packit Service fb6fa5
	g_print (" %d", npresponse[i]);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBUTTON, &tpbutton);
Packit Service fb6fa5
  g_print ("TPBUTTON: %d\n", tpbutton);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPBTNMARKS, tpbtnmarks);
Packit Service fb6fa5
  g_print ("TPBTNMARKS: %d %d\n", tpbtnmarks[0], tpbtnmarks[1]);
Packit Service fb6fa5
  size = (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, NULL);
Packit Service fb6fa5
  g_print ("TPRESPONSE:");
Packit Service fb6fa5
  if (size > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tpresponse = g_malloc (size);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_TPRESPONSE, tpresponse);
Packit Service fb6fa5
      for (i = 0; i < size / sizeof (UINT); i++)
Packit Service fb6fa5
	g_print (" %d", tpresponse[i]);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_PHYSID, &physid);
Packit Service fb6fa5
  g_print ("PHYSID: %#x\n", (guint) physid);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_CURSORS + index, CSR_CAPABILITIES, &capabilities);
Packit Service fb6fa5
  g_print ("CAPABILITIES: %#x:", capabilities);
Packit Service fb6fa5
#define BIT(x) if (capabilities & CRC_##x) g_print (" " #x)
Packit Service fb6fa5
  BIT (MULTIMODE);
Packit Service fb6fa5
  BIT (AGGREGATE);
Packit Service fb6fa5
  BIT (INVERT);
Packit Service fb6fa5
#undef BIT
Packit Service fb6fa5
  g_print ("\n");
Packit Service fb6fa5
  if (capabilities & CRC_MULTIMODE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_MODE, &mode);
Packit Service fb6fa5
      g_print ("MODE: %d\n", mode);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  if (capabilities & CRC_AGGREGATE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINPKTDATA, &minpktdata);
Packit Service fb6fa5
      g_print ("MINPKTDATA: %d\n", minpktdata);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_CURSORS + index, CSR_MINBUTTONS, &minbuttons);
Packit Service fb6fa5
      g_print ("MINBUTTONS: %d\n", minbuttons);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
#endif
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_wintab_init_check (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static gboolean wintab_initialized = FALSE;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
  GdkWindowAttr wa;
Packit Service fb6fa5
  WORD specversion;
Packit Service fb6fa5
  HCTX *hctx;
Packit Service fb6fa5
  UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
Packit Service fb6fa5
  BOOL active;
Packit Service fb6fa5
  DWORD physid;
Packit Service fb6fa5
  AXIS axis_x, axis_y, axis_npressure, axis_or[3];
Packit Service fb6fa5
  int i, k, n;
Packit Service fb6fa5
  int devix, cursorix;
Packit Service fb6fa5
  wchar_t devname[100], csrname[100];
Packit Service fb6fa5
  gchar *devname_utf8, *csrname_utf8;
Packit Service fb6fa5
  BOOL defcontext_done;
Packit Service fb6fa5
  HMODULE wintab32;
Packit Service fb6fa5
  char *wintab32_dll_path;
Packit Service fb6fa5
  char dummy;
Packit Service fb6fa5
Packit Service fb6fa5
  if (wintab_initialized)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  
Packit Service fb6fa5
  wintab_initialized = TRUE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  wintab_contexts = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (_gdk_input_ignore_wintab)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  n = GetSystemDirectory (&dummy, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  if (n <= 0)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
Packit Service fb6fa5
  k = GetSystemDirectory (wintab32_dll_path, n);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (k == 0 || k > n)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_free (wintab32_dll_path);
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
Packit Service fb6fa5
    strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
Packit Service fb6fa5
  strcat (wintab32_dll_path, WINTAB32_DLL);
Packit Service fb6fa5
Packit Service fb6fa5
  if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
    
Packit Service fb6fa5
  if (!(*p_WTInfoA) (0, 0, NULL))
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
Packit Service fb6fa5
  GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
Packit Service fb6fa5
			    HIBYTE (specversion), LOBYTE (specversion)));
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
Packit Service fb6fa5
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
  GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
Packit Service fb6fa5
			    ndevices, ncursors));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
  /* Create a dummy window to receive wintab events */
Packit Service fb6fa5
  wa.wclass = GDK_INPUT_OUTPUT;
Packit Service fb6fa5
  wa.event_mask = GDK_ALL_EVENTS_MASK;
Packit Service fb6fa5
  wa.width = 2;
Packit Service fb6fa5
  wa.height = 2;
Packit Service fb6fa5
  wa.x = -100;
Packit Service fb6fa5
  wa.y = -100;
Packit Service fb6fa5
  wa.window_type = GDK_WINDOW_TOPLEVEL;
Packit Service fb6fa5
  if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning ("gdk_input_wintab_init: gdk_window_new failed");
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_object_ref (wintab_window);
Packit Service fb6fa5
      
Packit Service fb6fa5
  for (devix = 0; devix < ndevices; devix++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      LOGCONTEXT lc;
Packit Service fb6fa5
      
Packit Service fb6fa5
      /* We open the Wintab device (hmm, what if there are several, or
Packit Service fb6fa5
       * can there even be several, probably not?) as a system
Packit Service fb6fa5
       * pointing device, i.e. it controls the normal Windows
Packit Service fb6fa5
       * cursor. This seems much more natural.
Packit Service fb6fa5
       */
Packit Service fb6fa5
Packit Service fb6fa5
      (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
Packit Service fb6fa5
      devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
Packit Service fb6fa5
#ifdef DEBUG_WINTAB
Packit Service fb6fa5
      GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8)));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
Packit Service fb6fa5
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);
Packit Service fb6fa5
Packit Service fb6fa5
      defcontext_done = FALSE;
Packit Service fb6fa5
      if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* Try to get device-specific default context */
Packit Service fb6fa5
	  /* Some drivers, e.g. Aiptek, don't provide this info */
Packit Service fb6fa5
	  if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
Packit Service fb6fa5
	    defcontext_done = TRUE;
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
	  if (defcontext_done)
Packit Service fb6fa5
	    GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      if (!defcontext_done)
Packit Service fb6fa5
	(*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
      GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
Packit Service fb6fa5
      lc.lcStatus = 0;
Packit Service fb6fa5
      lc.lcMsgBase = WT_DEFBASE;
Packit Service fb6fa5
      lc.lcPktRate = 0;
Packit Service fb6fa5
      lc.lcPktData = PACKETDATA;
Packit Service fb6fa5
      lc.lcPktMode = PACKETMODE;
Packit Service fb6fa5
      lc.lcMoveMask = PACKETDATA;
Packit Service fb6fa5
      lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
Packit Service fb6fa5
      lc.lcOutOrgX = axis_x.axMin;
Packit Service fb6fa5
      lc.lcOutOrgY = axis_y.axMin;
Packit Service fb6fa5
      lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
Packit Service fb6fa5
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
Packit Service fb6fa5
      lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
      GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
Packit Service fb6fa5
			print_lc(&lc)));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      hctx = g_new (HCTX, 1);
Packit Service fb6fa5
      if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_warning ("gdk_input_wintab_init: WTOpen failed");
Packit Service fb6fa5
	  return;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
Packit Service fb6fa5
				devix, *hctx));
Packit Service fb6fa5
      
Packit Service fb6fa5
      wintab_contexts = g_list_append (wintab_contexts, hctx);
Packit Service fb6fa5
Packit Service fb6fa5
      (*p_WTOverlap) (*hctx, TRUE);
Packit Service fb6fa5
Packit Service fb6fa5
#if DEBUG_WINTAB
Packit Service fb6fa5
      GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
Packit Service fb6fa5
			print_lc(&lc)));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      /* Increase packet queue size to reduce the risk of lost packets.
Packit Service fb6fa5
       * According to the specs, if the function fails we must try again
Packit Service fb6fa5
       * with a smaller queue size.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
Packit Service fb6fa5
      for (i = 128; i >= 1; i >>= 1)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if ((*p_WTQueueSizeSet) (*hctx, i))
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
Packit Service fb6fa5
	      break;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      if (!i)
Packit Service fb6fa5
	GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
Packit Service fb6fa5
      for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
#ifdef DEBUG_WINTAB
Packit Service fb6fa5
	  GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	  active = FALSE;
Packit Service fb6fa5
	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
Packit Service fb6fa5
	  if (!active)
Packit Service fb6fa5
	    continue;
Packit Service fb6fa5
Packit Service fb6fa5
	  /* Wacom tablets seem to report cursors corresponding to
Packit Service fb6fa5
	   * nonexistent pens or pucks. At least my ArtPad II reports
Packit Service fb6fa5
	   * six cursors: a puck, pressure stylus and eraser stylus,
Packit Service fb6fa5
	   * and then the same three again. I only have a
Packit Service fb6fa5
	   * pressure-sensitive pen. The puck instances, and the
Packit Service fb6fa5
	   * second instances of the styluses report physid zero. So
Packit Service fb6fa5
	   * at least for Wacom, skip cursors with physid zero.
Packit Service fb6fa5
	   */
Packit Service fb6fa5
	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
Packit Service fb6fa5
	  if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
Packit Service fb6fa5
	    continue;
Packit Service fb6fa5
Packit Service fb6fa5
	  gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
Packit Service fb6fa5
	  (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
Packit Service fb6fa5
	  csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
Packit Service fb6fa5
	  gdkdev->info.name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);
Packit Service fb6fa5
	  g_free (csrname_utf8);
Packit Service fb6fa5
	  gdkdev->info.source = GDK_SOURCE_PEN;
Packit Service fb6fa5
	  gdkdev->info.mode = GDK_MODE_SCREEN;
Packit Service fb6fa5
	  gdkdev->info.has_cursor = TRUE;
Packit Service fb6fa5
	  gdkdev->hctx = *hctx;
Packit Service fb6fa5
	  gdkdev->cursor = cursorix;
Packit Service fb6fa5
	  (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &gdkdev->pktdata);
Packit Service fb6fa5
	  gdkdev->info.num_axes = 0;
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_X)
Packit Service fb6fa5
	    gdkdev->info.num_axes++;
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_Y)
Packit Service fb6fa5
	    gdkdev->info.num_axes++;
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
Packit Service fb6fa5
	    gdkdev->info.num_axes++;
Packit Service fb6fa5
	  /* The wintab driver for the Wacom ArtPad II reports
Packit Service fb6fa5
	   * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
Packit Service fb6fa5
	   * actually sense tilt. Catch this by noticing that the
Packit Service fb6fa5
	   * orientation axis's azimuth resolution is zero.
Packit Service fb6fa5
	   */
Packit Service fb6fa5
	  if ((gdkdev->pktdata & PK_ORIENTATION)
Packit Service fb6fa5
	      && axis_or[0].axResolution == 0)
Packit Service fb6fa5
	    gdkdev->pktdata &= ~PK_ORIENTATION;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_ORIENTATION)
Packit Service fb6fa5
	    gdkdev->info.num_axes += 2; /* x and y tilt */
Packit Service fb6fa5
Packit Service fb6fa5
	  gdkdev->info.axes = g_new (GdkDeviceAxis, gdkdev->info.num_axes);
Packit Service fb6fa5
	  gdkdev->axes = g_new (GdkAxisInfo, gdkdev->info.num_axes);
Packit Service fb6fa5
	  gdkdev->last_axis_data = g_new (gint, gdkdev->info.num_axes);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  k = 0;
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_X)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      gdkdev->axes[k].resolution = axis_x.axResolution / 65535.;
Packit Service fb6fa5
	      gdkdev->axes[k].min_value = axis_x.axMin;
Packit Service fb6fa5
	      gdkdev->axes[k].max_value = axis_x.axMax;
Packit Service fb6fa5
	      gdkdev->info.axes[k].use = GDK_AXIS_X;
Packit Service fb6fa5
	      gdkdev->info.axes[k].min = axis_x.axMin;
Packit Service fb6fa5
	      gdkdev->info.axes[k].max = axis_x.axMax;
Packit Service fb6fa5
	      k++;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_Y)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      gdkdev->axes[k].resolution = axis_y.axResolution / 65535.;
Packit Service fb6fa5
	      gdkdev->axes[k].min_value = axis_y.axMin;
Packit Service fb6fa5
	      gdkdev->axes[k].max_value = axis_y.axMax;
Packit Service fb6fa5
	      gdkdev->info.axes[k].use = GDK_AXIS_Y;
Packit Service fb6fa5
	      gdkdev->info.axes[k].min = axis_y.axMin;
Packit Service fb6fa5
	      gdkdev->info.axes[k].max = axis_y.axMax;
Packit Service fb6fa5
	      k++;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      gdkdev->axes[k].resolution = axis_npressure.axResolution / 65535.;
Packit Service fb6fa5
	      gdkdev->axes[k].min_value = axis_npressure.axMin;
Packit Service fb6fa5
	      gdkdev->axes[k].max_value = axis_npressure.axMax;
Packit Service fb6fa5
	      gdkdev->info.axes[k].use = GDK_AXIS_PRESSURE;
Packit Service fb6fa5
	      /* GIMP seems to expect values in the range 0-1 */
Packit Service fb6fa5
	      gdkdev->info.axes[k].min = 0.0; /*axis_npressure.axMin;*/
Packit Service fb6fa5
	      gdkdev->info.axes[k].max = 1.0; /*axis_npressure.axMax;*/
Packit Service fb6fa5
	      k++;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  if (gdkdev->pktdata & PK_ORIENTATION)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      GdkAxisUse axis;
Packit Service fb6fa5
	      
Packit Service fb6fa5
	      gdkdev->orientation_axes[0] = axis_or[0];
Packit Service fb6fa5
	      gdkdev->orientation_axes[1] = axis_or[1];
Packit Service fb6fa5
	      for (axis = GDK_AXIS_XTILT; axis <= GDK_AXIS_YTILT; axis++)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  /* Wintab gives us aximuth and altitude, which
Packit Service fb6fa5
		   * we convert to x and y tilt in the -1000..1000 range
Packit Service fb6fa5
		   */
Packit Service fb6fa5
		  gdkdev->axes[k].resolution = 1000;
Packit Service fb6fa5
		  gdkdev->axes[k].min_value = -1000;
Packit Service fb6fa5
		  gdkdev->axes[k].max_value = 1000;
Packit Service fb6fa5
		  gdkdev->info.axes[k].use = axis;
Packit Service fb6fa5
		  gdkdev->info.axes[k].min = -1.0;
Packit Service fb6fa5
		  gdkdev->info.axes[k].max = 1.0;
Packit Service fb6fa5
		  k++;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  gdkdev->info.num_keys = 0;
Packit Service fb6fa5
	  gdkdev->info.keys = NULL;
Packit Service fb6fa5
	  GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n",
Packit Service fb6fa5
				    cursorix,
Packit Service fb6fa5
				    gdkdev->info.name,
Packit Service fb6fa5
				    gdkdev->info.num_axes));
Packit Service fb6fa5
	  for (i = 0; i < gdkdev->info.num_axes; i++)
Packit Service fb6fa5
	    GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
Packit Service fb6fa5
				      i,
Packit Service fb6fa5
				      gdkdev->axes[i].min_value, 
Packit Service fb6fa5
				      gdkdev->axes[i].max_value, 
Packit Service fb6fa5
				      gdkdev->axes[i].resolution));
Packit Service fb6fa5
	  _gdk_input_devices = g_list_append (_gdk_input_devices,
Packit Service fb6fa5
					      gdkdev);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      g_free (devname_utf8);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
decode_tilt (gint   *axis_data,
Packit Service fb6fa5
	     AXIS   *axes,
Packit Service fb6fa5
	     PACKET *packet)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* As I don't have a tilt-sensing tablet,
Packit Service fb6fa5
   * I cannot test this code.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  
Packit Service fb6fa5
  double az, el;
Packit Service fb6fa5
Packit Service fb6fa5
  az = TWOPI * packet->pkOrientation.orAzimuth /
Packit Service fb6fa5
    (axes[0].axResolution / 65536.);
Packit Service fb6fa5
  el = TWOPI * packet->pkOrientation.orAltitude /
Packit Service fb6fa5
    (axes[1].axResolution / 65536.);
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* X tilt */
Packit Service fb6fa5
  axis_data[0] = cos (az) * cos (el) * 1000;
Packit Service fb6fa5
  /* Y tilt */
Packit Service fb6fa5
  axis_data[1] = sin (az) * cos (el) * 1000;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
Packit Service fb6fa5
				 GdkWindow        *window,
Packit Service fb6fa5
				 gint             *axis_data,
Packit Service fb6fa5
				 gdouble          *axis_out,
Packit Service fb6fa5
				 gdouble          *x_out,
Packit Service fb6fa5
				 gdouble          *y_out)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindowObject *priv, *impl_window;
Packit Service fb6fa5
  GdkWindowImplWin32 *root_impl;
Packit Service fb6fa5
Packit Service fb6fa5
  int i;
Packit Service fb6fa5
  int x_axis = 0;
Packit Service fb6fa5
  int y_axis = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  double device_width, device_height, x_min, y_min;
Packit Service fb6fa5
  double x_offset, y_offset, x_scale, y_scale;
Packit Service fb6fa5
Packit Service fb6fa5
  priv = (GdkWindowObject *) window;
Packit Service fb6fa5
  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i=0; i<gdkdev->info.num_axes; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      switch (gdkdev->info.axes[i].use)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	case GDK_AXIS_X:
Packit Service fb6fa5
	  x_axis = i;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	case GDK_AXIS_Y:
Packit Service fb6fa5
	  y_axis = i;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	default:
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
Packit Service fb6fa5
  x_min = gdkdev->axes[x_axis].min_value;
Packit Service fb6fa5
  device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
Packit Service fb6fa5
  y_min = gdkdev->axes[y_axis].min_value;
Packit Service fb6fa5
Packit Service fb6fa5
  if (gdkdev->info.mode == GDK_MODE_SCREEN) 
Packit Service fb6fa5
    {
Packit Service fb6fa5
      root_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl);
Packit Service fb6fa5
      x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width;
Packit Service fb6fa5
      y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height;
Packit Service fb6fa5
Packit Service fb6fa5
      x_offset = - impl_window->input_window->root_x - priv->abs_x;
Packit Service fb6fa5
      y_offset = - impl_window->input_window->root_y - priv->abs_y;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else				/* GDK_MODE_WINDOW */
Packit Service fb6fa5
    {
Packit Service fb6fa5
      double x_resolution = gdkdev->axes[x_axis].resolution;
Packit Service fb6fa5
      double y_resolution = gdkdev->axes[y_axis].resolution;
Packit Service fb6fa5
      double device_aspect = (device_height*y_resolution) / (device_width * x_resolution);
Packit Service fb6fa5
Packit Service fb6fa5
      if (device_aspect * priv->width >= priv->height)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* device taller than window */
Packit Service fb6fa5
	  x_scale = priv->width / device_width;
Packit Service fb6fa5
	  y_scale = (x_scale * x_resolution) / y_resolution;
Packit Service fb6fa5
Packit Service fb6fa5
	  x_offset = 0;
Packit Service fb6fa5
	  y_offset = -(device_height * y_scale - priv->height) / 2;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* window taller than device */
Packit Service fb6fa5
	  y_scale = priv->height / device_height;
Packit Service fb6fa5
	  x_scale = (y_scale * y_resolution)  / x_resolution;
Packit Service fb6fa5
Packit Service fb6fa5
	  y_offset = 0;
Packit Service fb6fa5
	  x_offset = - (device_width * x_scale - priv->width) / 2;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < gdkdev->info.num_axes; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      switch (gdkdev->info.axes[i].use)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	case GDK_AXIS_X:
Packit Service fb6fa5
	  axis_out[i] = x_offset + x_scale * axis_data[x_axis];
Packit Service fb6fa5
	  if (x_out)
Packit Service fb6fa5
	    *x_out = axis_out[i];
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	case GDK_AXIS_Y:
Packit Service fb6fa5
	  axis_out[i] = y_offset + y_scale * axis_data[y_axis];
Packit Service fb6fa5
	  if (y_out)
Packit Service fb6fa5
	    *y_out = axis_out[i];
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	default:
Packit Service fb6fa5
	  axis_out[i] =
Packit Service fb6fa5
	    (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
Packit Service fb6fa5
	     gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
Packit Service fb6fa5
	    (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_input_get_root_relative_geometry (HWND w,
Packit Service fb6fa5
				      int  *x_ret,
Packit Service fb6fa5
				      int  *y_ret)
Packit Service fb6fa5
{
Packit Service fb6fa5
  POINT pt;
Packit Service fb6fa5
Packit Service fb6fa5
  pt.x = 0;
Packit Service fb6fa5
  pt.y = 0;
Packit Service fb6fa5
  ClientToScreen (w, &pt;;
Packit Service fb6fa5
Packit Service fb6fa5
  if (x_ret)
Packit Service fb6fa5
    *x_ret = pt.x + _gdk_offset_x;
Packit Service fb6fa5
  if (y_ret)
Packit Service fb6fa5
    *y_ret = pt.y + _gdk_offset_y;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_configure_event (GdkWindow         *window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  GdkWindowObject *impl_window;
Packit Service fb6fa5
  int root_x, root_y;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (window != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
Packit Service fb6fa5
  input_window = impl_window->input_window;
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
Packit Service fb6fa5
					&root_x, &root_y);
Packit Service fb6fa5
Packit Service fb6fa5
  input_window->root_x = root_x;
Packit Service fb6fa5
  input_window->root_y = root_y;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Get the currently active keyboard modifiers (ignoring the mouse buttons)
Packit Service fb6fa5
 * We could use gdk_window_get_pointer but that function does a lot of other
Packit Service fb6fa5
 * expensive things besides getting the modifiers. This code is somewhat based
Packit Service fb6fa5
 * on build_pointer_event_state from gdkevents-win32.c
Packit Service fb6fa5
 */
Packit Service fb6fa5
static guint
Packit Service fb6fa5
get_modifier_key_state (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guint state;
Packit Service fb6fa5
  
Packit Service fb6fa5
  state = 0;
Packit Service fb6fa5
  /* High-order bit is up/down, low order bit is toggled/untoggled */
Packit Service fb6fa5
  if (GetKeyState (VK_CONTROL) < 0)
Packit Service fb6fa5
    state |= GDK_CONTROL_MASK;
Packit Service fb6fa5
  if (GetKeyState (VK_SHIFT) < 0)
Packit Service fb6fa5
    state |= GDK_SHIFT_MASK;
Packit Service fb6fa5
  if (GetKeyState (VK_MENU) < 0)
Packit Service fb6fa5
    state |= GDK_MOD1_MASK;
Packit Service fb6fa5
  if (GetKeyState (VK_CAPITAL) & 0x1)
Packit Service fb6fa5
    state |= GDK_LOCK_MASK;
Packit Service fb6fa5
Packit Service fb6fa5
  return state;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#if 0
Packit Service fb6fa5
static guint ignore_core_timer = 0;
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
ignore_core_timefunc (gpointer data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* The delay has passed */
Packit Service fb6fa5
  _gdk_input_ignore_core = FALSE;
Packit Service fb6fa5
  ignore_core_timer = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  return FALSE; /* remove timeout */
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Set or unset the _gdk_input_ignore_core variable that tells GDK
Packit Service fb6fa5
 * to ignore events for the core pointer when the tablet is in proximity
Packit Service fb6fa5
 * The unsetting is delayed slightly so that if a tablet event arrives
Packit Service fb6fa5
 * just after proximity out, it does not cause a core pointer event
Packit Service fb6fa5
 * which e.g. causes GIMP to switch tools.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void
Packit Service fb6fa5
set_ignore_core (gboolean ignore)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (ignore)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      _gdk_input_ignore_core = TRUE;
Packit Service fb6fa5
      /* Remove any pending clear */
Packit Service fb6fa5
      if (ignore_core_timer)
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  g_source_remove (ignore_core_timer);
Packit Service fb6fa5
	  ignore_core_timer = 0;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    if (!ignore_core_timer)
Packit Service fb6fa5
      ignore_core_timer = gdk_threads_add_timeout (PROXIMITY_OUT_DELAY,
Packit Service fb6fa5
					 ignore_core_timefunc, NULL);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev)
Packit Service fb6fa5
{
Packit Service fb6fa5
  LOGCONTEXT lc;
Packit Service fb6fa5
Packit Service fb6fa5
  if (gdkdev != _gdk_device_in_proximity)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  if (p_WTGetA (gdkdev->hctx, &lc))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (gdkdev->info.mode == GDK_MODE_SCREEN &&
Packit Service fb6fa5
	  (lc.lcOptions & CXO_SYSTEM) == 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  lc.lcOptions |= CXO_SYSTEM;
Packit Service fb6fa5
	  p_WTSetA (gdkdev->hctx, &lc);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else if (gdkdev->info.mode == GDK_MODE_WINDOW &&
Packit Service fb6fa5
	       (lc.lcOptions & CXO_SYSTEM) != 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  lc.lcOptions &= ~CXO_SYSTEM;
Packit Service fb6fa5
	  p_WTSetA (gdkdev->hctx, &lc);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkWindow *
Packit Service fb6fa5
find_window_for_input_event (MSG* msg, int *x, int *y)
Packit Service fb6fa5
{
Packit Service fb6fa5
  POINT pt;
Packit Service fb6fa5
  GdkWindow *window;
Packit Service fb6fa5
  HWND hwnd;
Packit Service fb6fa5
  RECT rect;
Packit Service fb6fa5
Packit Service fb6fa5
  pt = msg->pt;
Packit Service fb6fa5
Packit Service fb6fa5
  window = NULL;
Packit Service fb6fa5
  hwnd = WindowFromPoint (pt);
Packit Service fb6fa5
  if (hwnd != NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      POINT client_pt = pt;
Packit Service fb6fa5
Packit Service fb6fa5
      ScreenToClient (hwnd, &client_pt);
Packit Service fb6fa5
      GetClientRect (hwnd, &rect);
Packit Service fb6fa5
      if (PtInRect (&rect, client_pt))
Packit Service fb6fa5
	window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* need to also adjust the coordinates to the new window */
Packit Service fb6fa5
  if (window)
Packit Service fb6fa5
    ScreenToClient (GDK_WINDOW_HWND (window), &pt;;
Packit Service fb6fa5
Packit Service fb6fa5
  *x = pt.x;
Packit Service fb6fa5
  *y = pt.y;
Packit Service fb6fa5
Packit Service fb6fa5
  if (window)
Packit Service fb6fa5
    return window;
Packit Service fb6fa5
Packit Service fb6fa5
  return _gdk_root;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean 
Packit Service fb6fa5
_gdk_input_other_event (GdkEvent  *event,
Packit Service fb6fa5
			MSG       *msg,
Packit Service fb6fa5
			GdkWindow *window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindowObject *obj, *impl_window;
Packit Service fb6fa5
  GdkWindow *native_window;
Packit Service fb6fa5
  GdkInputWindow *input_window;
Packit Service fb6fa5
  GdkDevicePrivate *gdkdev = NULL;
Packit Service fb6fa5
  guint key_state;
Packit Service fb6fa5
Packit Service fb6fa5
  PACKET packet;
Packit Service fb6fa5
  gint k;
Packit Service fb6fa5
  gint x, y;
Packit Service fb6fa5
  guint translated_buttons, button_diff, button_mask;
Packit Service fb6fa5
  /* Translation from tablet button state to GDK button state for
Packit Service fb6fa5
   * buttons 1-3 - swap button 2 and 3.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
Packit Service fb6fa5
Packit Service fb6fa5
  if (window != wintab_window)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning ("_gdk_input_other_event: not wintab_window?");
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  native_window = find_window_for_input_event (msg, &x, &y);
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (EVENTS_OR_INPUT,
Packit Service fb6fa5
	    g_print ("_gdk_input_other_event: native_window=%p %+d%+d\n",
Packit Service fb6fa5
		     GDK_WINDOW_HWND (native_window), x, y));
Packit Service fb6fa5
Packit Service fb6fa5
  if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  switch (msg->message)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case WT_PACKET:
Packit Service fb6fa5
      /* Don't produce any button or motion events while a window is being
Packit Service fb6fa5
       * moved or resized, see bug #151090.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (_modal_operation_in_progress)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
Packit Service fb6fa5
	  return FALSE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
Packit Service fb6fa5
						 packet.pkCursor)) == NULL)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      if (gdkdev->info.mode == GDK_MODE_DISABLED)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
      
Packit Service fb6fa5
      k = 0;
Packit Service fb6fa5
      if (gdkdev->pktdata & PK_X)
Packit Service fb6fa5
	gdkdev->last_axis_data[k++] = packet.pkX;
Packit Service fb6fa5
      if (gdkdev->pktdata & PK_Y)
Packit Service fb6fa5
	gdkdev->last_axis_data[k++] = packet.pkY;
Packit Service fb6fa5
      if (gdkdev->pktdata & PK_NORMAL_PRESSURE)
Packit Service fb6fa5
	gdkdev->last_axis_data[k++] = packet.pkNormalPressure;
Packit Service fb6fa5
      if (gdkdev->pktdata & PK_ORIENTATION)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  decode_tilt (gdkdev->last_axis_data + k,
Packit Service fb6fa5
		       gdkdev->orientation_axes, &packet);
Packit Service fb6fa5
	  k += 2;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      g_assert (k == gdkdev->info.num_axes);
Packit Service fb6fa5
Packit Service fb6fa5
      translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
Packit Service fb6fa5
Packit Service fb6fa5
      if (translated_buttons != gdkdev->button_state)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* At least one button has changed state so produce a button event
Packit Service fb6fa5
	   * If more than one button has changed state (unlikely),
Packit Service fb6fa5
	   * just care about the first and act on the next the next time
Packit Service fb6fa5
	   * we get a packet
Packit Service fb6fa5
	   */
Packit Service fb6fa5
	  button_diff = translated_buttons ^ gdkdev->button_state;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  /* Gdk buttons are numbered 1.. */
Packit Service fb6fa5
	  event->button.button = 1;
Packit Service fb6fa5
Packit Service fb6fa5
	  for (button_mask = 1; button_mask != 0x80000000;
Packit Service fb6fa5
	       button_mask <<= 1, event->button.button++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      if (button_diff & button_mask)
Packit Service fb6fa5
	        {
Packit Service fb6fa5
		  /* Found a button that has changed state */
Packit Service fb6fa5
		  break;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  if (!(translated_buttons & button_mask))
Packit Service fb6fa5
	    event->any.type = GDK_BUTTON_RELEASE;
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    event->any.type = GDK_BUTTON_PRESS;
Packit Service fb6fa5
	  gdkdev->button_state ^= button_mask;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  event->any.type = GDK_MOTION_NOTIFY;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      if (native_window == _gdk_root)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      window = _gdk_window_get_input_window_for_event (native_window,
Packit Service fb6fa5
						       event->any.type,
Packit Service fb6fa5
						       gdkdev->button_state << 8,
Packit Service fb6fa5
						       x, y, 0);
Packit Service fb6fa5
Packit Service fb6fa5
      obj = GDK_WINDOW_OBJECT (window);
Packit Service fb6fa5
Packit Service fb6fa5
      if (window == NULL ||
Packit Service fb6fa5
	  obj->extension_events == 0)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
      
Packit Service fb6fa5
      impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
Packit Service fb6fa5
      input_window = impl_window->input_window;
Packit Service fb6fa5
Packit Service fb6fa5
      g_assert (input_window != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
      if (gdkdev->info.mode == GDK_MODE_WINDOW && 
Packit Service fb6fa5
	  (obj->extension_events & GDK_ALL_DEVICES_MASK) == 0)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      event->any.window = window;
Packit Service fb6fa5
      key_state = get_modifier_key_state ();
Packit Service fb6fa5
      if (event->any.type == GDK_BUTTON_PRESS || 
Packit Service fb6fa5
	  event->any.type == GDK_BUTTON_RELEASE)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  event->button.time = _gdk_win32_get_next_tick (msg->time);
Packit Service fb6fa5
	  event->button.device = &gdkdev->info;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
Packit Service fb6fa5
Packit Service fb6fa5
	  gdk_input_translate_coordinates (gdkdev, window,
Packit Service fb6fa5
					   gdkdev->last_axis_data,
Packit Service fb6fa5
					   event->button.axes,
Packit Service fb6fa5
					   &event->button.x, 
Packit Service fb6fa5
					   &event->button.y);
Packit Service fb6fa5
Packit Service fb6fa5
	  /* Also calculate root coordinates. Note that input_window->root_x
Packit Service fb6fa5
	     is in GDK root coordinates. */
Packit Service fb6fa5
	  event->button.x_root = event->button.x + input_window->root_x;
Packit Service fb6fa5
	  event->button.y_root = event->button.y + input_window->root_y;
Packit Service fb6fa5
Packit Service fb6fa5
	  event->button.state = ((gdkdev->button_state << 8)
Packit Service fb6fa5
				 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
Packit Service fb6fa5
				    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
Packit Service fb6fa5
				    | GDK_BUTTON5_MASK))
Packit Service fb6fa5
				| key_state;
Packit Service fb6fa5
	  GDK_NOTE (EVENTS_OR_INPUT,
Packit Service fb6fa5
		    g_print ("WINTAB button %s:%d %g,%g\n",
Packit Service fb6fa5
			     (event->button.type == GDK_BUTTON_PRESS ?
Packit Service fb6fa5
			      "press" : "release"),
Packit Service fb6fa5
			     event->button.button,
Packit Service fb6fa5
			     event->button.x, event->button.y));
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  event->motion.time = _gdk_win32_get_next_tick (msg->time);
Packit Service fb6fa5
	  event->motion.is_hint = FALSE;
Packit Service fb6fa5
	  event->motion.device = &gdkdev->info;
Packit Service fb6fa5
Packit Service fb6fa5
	  event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
Packit Service fb6fa5
Packit Service fb6fa5
	  gdk_input_translate_coordinates (gdkdev, window,
Packit Service fb6fa5
					   gdkdev->last_axis_data,
Packit Service fb6fa5
					   event->motion.axes,
Packit Service fb6fa5
					   &event->motion.x, 
Packit Service fb6fa5
					   &event->motion.y);
Packit Service fb6fa5
Packit Service fb6fa5
	  /* Also calculate root coordinates. Note that input_window->root_x
Packit Service fb6fa5
	     is in GDK root coordinates. */
Packit Service fb6fa5
	  event->motion.x_root = event->motion.x + input_window->root_x;
Packit Service fb6fa5
	  event->motion.y_root = event->motion.y + input_window->root_y;
Packit Service fb6fa5
Packit Service fb6fa5
	  event->motion.state = ((gdkdev->button_state << 8)
Packit Service fb6fa5
				 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
Packit Service fb6fa5
				    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
Packit Service fb6fa5
				    | GDK_BUTTON5_MASK))
Packit Service fb6fa5
				| key_state;
Packit Service fb6fa5
Packit Service fb6fa5
	  GDK_NOTE (EVENTS_OR_INPUT,
Packit Service fb6fa5
		    g_print ("WINTAB motion: %g,%g\n",
Packit Service fb6fa5
			     event->motion.x, event->motion.y));
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
    case WT_CSRCHANGE:
Packit Service fb6fa5
      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
Packit Service fb6fa5
						 packet.pkCursor)) == NULL)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      _gdk_device_in_proximity = gdkdev;
Packit Service fb6fa5
Packit Service fb6fa5
      _gdk_input_update_for_device_mode (gdkdev);
Packit Service fb6fa5
Packit Service fb6fa5
      window = NULL;
Packit Service fb6fa5
      if (native_window != _gdk_root)
Packit Service fb6fa5
	window = _gdk_window_get_input_window_for_event (native_window,
Packit Service fb6fa5
							 GDK_PROXIMITY_IN,
Packit Service fb6fa5
							 0,
Packit Service fb6fa5
							 x, y, 0);
Packit Service fb6fa5
      if (window)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  event->proximity.type = GDK_PROXIMITY_IN;
Packit Service fb6fa5
	  event->proximity.window = window;
Packit Service fb6fa5
	  event->proximity.time = _gdk_win32_get_next_tick (msg->time);
Packit Service fb6fa5
	  event->proximity.device = &_gdk_device_in_proximity->info;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      GDK_NOTE (EVENTS_OR_INPUT,
Packit Service fb6fa5
		g_print ("WINTAB proximity in\n"));
Packit Service fb6fa5
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
    case WT_PROXIMITY:
Packit Service fb6fa5
      /* TODO: Set ignore_core if in input_window */
Packit Service fb6fa5
      if (LOWORD (msg->lParam) == 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  _gdk_input_in_proximity = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
	  window = NULL;
Packit Service fb6fa5
	  if (native_window != _gdk_root)
Packit Service fb6fa5
	    window = _gdk_window_get_input_window_for_event (native_window,
Packit Service fb6fa5
							     GDK_PROXIMITY_IN,
Packit Service fb6fa5
							     0,
Packit Service fb6fa5
							     x, y, 0);
Packit Service fb6fa5
	  if (window)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      event->proximity.type = GDK_PROXIMITY_OUT;
Packit Service fb6fa5
	      event->proximity.window = window;
Packit Service fb6fa5
	      event->proximity.time = _gdk_win32_get_next_tick (msg->time);
Packit Service fb6fa5
	      event->proximity.device = &_gdk_device_in_proximity->info;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  GDK_NOTE (EVENTS_OR_INPUT,
Packit Service fb6fa5
		    g_print ("WINTAB proximity out\n"));
Packit Service fb6fa5
Packit Service fb6fa5
	  return TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	_gdk_input_in_proximity = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
      _gdk_input_check_proximity ();
Packit Service fb6fa5
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_select_events (GdkWindow *impl_window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guint event_mask;
Packit Service fb6fa5
  GdkWindowObject *w;
Packit Service fb6fa5
  GdkInputWindow *iw;
Packit Service fb6fa5
  GList *l, *dev_list;
Packit Service fb6fa5
  
Packit Service fb6fa5
Packit Service fb6fa5
  iw = ((GdkWindowObject *)impl_window)->input_window;
Packit Service fb6fa5
Packit Service fb6fa5
  event_mask = 0;
Packit Service fb6fa5
  for (dev_list = _gdk_input_devices; dev_list; dev_list = dev_list->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkDevicePrivate *gdkdev = dev_list->data;
Packit Service fb6fa5
Packit Service fb6fa5
      if (!GDK_IS_CORE (gdkdev) &&
Packit Service fb6fa5
	  gdkdev->info.mode != GDK_MODE_DISABLED &&
Packit Service fb6fa5
	  iw != NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  for (l = iw->windows; l != NULL; l = l->next)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      w = l->data;
Packit Service fb6fa5
	      if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
Packit Service fb6fa5
		event_mask |= w->extension_events;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  event_mask &= ~GDK_ALL_DEVICES_MASK;
Packit Service fb6fa5
  if (event_mask)
Packit Service fb6fa5
    event_mask |= 
Packit Service fb6fa5
      GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *)impl_window)->impl)->extension_events_mask = event_mask;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint
Packit Service fb6fa5
_gdk_input_grab_pointer (GdkWindow    *window,
Packit Service fb6fa5
			 gint          owner_events,
Packit Service fb6fa5
			 GdkEventMask  event_mask,
Packit Service fb6fa5
			 GdkWindow    *confine_to,
Packit Service fb6fa5
			 guint32       time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GDK_NOTE (INPUT, g_print ("_gdk_input_grab_pointer: %p %d %p\n",
Packit Service fb6fa5
			   GDK_WINDOW_HWND (window),
Packit Service fb6fa5
			   owner_events,
Packit Service fb6fa5
			   (confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
Packit Service fb6fa5
Packit Service fb6fa5
  return GDK_GRAB_SUCCESS;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void 
Packit Service fb6fa5
_gdk_input_ungrab_pointer (guint32 time)
Packit Service fb6fa5
{
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (INPUT, g_print ("_gdk_input_ungrab_pointer\n"));
Packit Service fb6fa5
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gdk_device_get_history (GdkDevice         *device,
Packit Service fb6fa5
			 GdkWindow         *window,
Packit Service fb6fa5
			 guint32            start,
Packit Service fb6fa5
			 guint32            stop,
Packit Service fb6fa5
			 GdkTimeCoord    ***events,
Packit Service fb6fa5
			 gint              *n_events)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void 
Packit Service fb6fa5
gdk_device_get_state (GdkDevice       *device,
Packit Service fb6fa5
		      GdkWindow       *window,
Packit Service fb6fa5
		      gdouble         *axes,
Packit Service fb6fa5
		      GdkModifierType *mask)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (device != NULL);
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_WINDOW (window));
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_CORE (device))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gint x_int, y_int;
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_window_get_pointer (window, &x_int, &y_int, mask);
Packit Service fb6fa5
Packit Service fb6fa5
      if (axes)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  axes[0] = x_int;
Packit Service fb6fa5
	  axes[1] = y_int;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkDevicePrivate *gdkdev;
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdkdev = (GdkDevicePrivate *)device;
Packit Service fb6fa5
      /* For now just use the last known button and axis state of the device.
Packit Service fb6fa5
       * Since graphical tablets send an insane amount of motion events each
Packit Service fb6fa5
       * second, the info should be fairly up to date */
Packit Service fb6fa5
      if (mask)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdk_window_get_pointer (window, NULL, NULL, mask);
Packit Service fb6fa5
	  *mask &= 0xFF; /* Mask away core pointer buttons */
Packit Service fb6fa5
	  *mask |= ((gdkdev->button_state << 8)
Packit Service fb6fa5
		    & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
Packit Service fb6fa5
		       | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
Packit Service fb6fa5
		       | GDK_BUTTON5_MASK));
Packit Service fb6fa5
	}
Packit Service fb6fa5
      /* For some reason, input_window is sometimes NULL when I use The GIMP 2
Packit Service fb6fa5
       * (bug #141543?). Avoid crashing if debugging is disabled. */
Packit Service fb6fa5
      if (axes && gdkdev->last_axis_data)
Packit Service fb6fa5
	gdk_input_translate_coordinates (gdkdev, window,
Packit Service fb6fa5
					 gdkdev->last_axis_data,
Packit Service fb6fa5
					 axes, NULL, NULL);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_input_set_tablet_active (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  HCTX *hctx;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Bring the contexts to the top of the overlap order when one of the
Packit Service fb6fa5
   * application's windows is activated */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!wintab_contexts)
Packit Service fb6fa5
    return; /* No tablet devices found, or Wintab not initialized yet */
Packit Service fb6fa5
  
Packit Service fb6fa5
  GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
Packit Service fb6fa5
	"Bringing Wintab contexts to the top of the overlap order\n"));
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = wintab_contexts;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      hctx = (HCTX *) (tmp_list->data);
Packit Service fb6fa5
      (*p_WTOverlap) (*hctx, TRUE);
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void 
Packit Service fb6fa5
_gdk_input_init (GdkDisplay *display)
Packit Service fb6fa5
{
Packit Service fb6fa5
  _gdk_input_devices = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  _gdk_init_input_core (display);
Packit Service fb6fa5
#ifdef WINTAB_NO_LAZY_INIT
Packit Service fb6fa5
  /* Normally, Wintab is only initialized when the application performs
Packit Service fb6fa5
   * an action that requires it, such as enabling extended input events
Packit Service fb6fa5
   * for a window or enumerating the devices.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  _gdk_input_wintab_init_check ();
Packit Service fb6fa5
#endif /* WINTAB_NO_LAZY_INIT */
Packit Service fb6fa5
Packit Service fb6fa5
  _gdk_input_devices = g_list_append (_gdk_input_devices, display->core_pointer);
Packit Service fb6fa5
}
Packit Service fb6fa5