import ctypes from ctypes.wintypes import HANDLE, BYTE, HWND, BOOL, UINT, LONG, WORD, DWORD, WCHAR, LPVOID lib = ctypes.windll.wintab32 FIX32 = DWORD WTPKT = DWORD HCTX = HANDLE # CONTEXT HANDLE LCNAMELEN = 40 class AXIS(ctypes.Structure): _fields_ = ( ('axMin', LONG), ('axMax', LONG), ('axUnits', UINT), ('axResolution', FIX32) ) def get_scale(self): return 1 / float(self.axMax - self.axMin) def get_bias(self): return -self.axMin class ORIENTATION(ctypes.Structure): _fields_ = ( ('orAzimuth', ctypes.c_int), ('orAltitude', ctypes.c_int), ('orTwist', ctypes.c_int) ) class ROTATION(ctypes.Structure): _fields_ = ( ('roPitch', ctypes.c_int), ('roRoll', ctypes.c_int), ('roYaw', ctypes.c_int), ) class LOGCONTEXT(ctypes.Structure): _fields_ = ( ('lcName', WCHAR * LCNAMELEN), ('lcOptions', UINT), ('lcStatus', UINT), ('lcLocks', UINT), ('lcMsgBase', UINT), ('lcDevice', UINT), ('lcPktRate', UINT), ('lcPktData', WTPKT), ('lcPktMode', WTPKT), ('lcMoveMask', WTPKT), ('lcBtnDnMask', DWORD), ('lcBtnUpMask', DWORD), ('lcInOrgX', LONG), ('lcInOrgY', LONG), ('lcInOrgZ', LONG), ('lcInExtX', LONG), ('lcInExtY', LONG), ('lcInExtZ', LONG), ('lcOutOrgX', LONG), ('lcOutOrgY', LONG), ('lcOutOrgZ', LONG), ('lcOutExtX', LONG), ('lcOutExtY', LONG), ('lcOutExtZ', LONG), ('lcSensX', FIX32), ('lcSensY', FIX32), ('lcSensZ', FIX32), ('lcSysMode', BOOL), ('lcSysOrgX', ctypes.c_int), ('lcSysOrgY', ctypes.c_int), ('lcSysExtX', ctypes.c_int), ('lcSysExtY', ctypes.c_int), ('lcSysSensX', FIX32), ('lcSysSensY', FIX32), ) class TILT(ctypes.Structure): # 1.1 _fields_ = ( ('tiltX', ctypes.c_int), ('tiltY', ctypes.c_int), ) class EXTENSIONBASE(ctypes.Structure): # 1.4 _fields_ = ( ('nContext', HCTX), # Specifies the Wintab context to which these properties apply. ('nStatus', UINT), # Status of setting/getting properties. ('nTime', DWORD), # Timestamp applied to property transaction. ('nSerialNumber', UINT), # Reserved - not use ) class EXPKEYSDATA(ctypes.Structure): # 1.4 _fields_ = ( ('nTablet', BYTE), # Tablet index where control is found. ('nControl', BYTE), # Zero-based control index. ('nLocation', BYTE), # Zero-based index indicating side of tablet where control found (0 = left, 1 = right). ('nReserved', BYTE), # Reserved - not used ('nState', DWORD) # Indicates Express Key button press (1 = pressed, 0 = released) ) class SLIDERDATA(ctypes.Structure): # 1.4 _fields_ = ( ('nTablet', BYTE), # Tablet index where control is found. ('nControl', BYTE), # Zero-based control index. ('nMode', BYTE), # Zero-based current active mode of control. Mode selected by control's toggle button. ('nReserved', BYTE), # Reserved - not used ('nPosition', DWORD) # An integer representing the position of the user's finger on the control. # When there is no finger on the control, this value is negative. ) class EXTPROPERTY(ctypes.Structure): # 1.4 _fields_ = ( ('version', BYTE), # Structure version, 0 for now ('tabletIndex', BYTE), # 0-based index for tablet ('controlIndex', BYTE), # 0-based index for control ('functionIndex', BYTE), # 0-based index for control's sub-function ('propertyID', WORD), # property ID ('reserved', WORD), # DWORD-alignment filler ('dataSize', DWORD), # number of bytes in data[] buffer ('data', BYTE * 1), # raw data ) # Custom packet format with fields # PK_CHANGED # PK_CURSOR # PK_BUTTONS # PK_X # PK_Y # PK_Z # PK_NORMAL_PRESSURE # PK_TANGENT_PRESSURE # PK_ORIENTATION (check for tilt extension instead)? class PACKET(ctypes.Structure): _fields_ = ( ('pkChanged', WTPKT), ('pkCursor', UINT), ('pkButtons', DWORD), ('pkX', LONG), ('pkY', LONG), ('pkZ', LONG), ('pkNormalPressure', UINT), ('pkTangentPressure', UINT), ('pkOrientation', ORIENTATION), ) class PACKETEXT(ctypes.Structure): _fields_ = ( ('pkBase', EXTENSIONBASE), # Extension control properties common to all control types. ('pkExpKeys', EXPKEYSDATA), # Extension data for one Express Key. ('pkTouchStrip', SLIDERDATA), # Extension data for one Touch Strip. ('pkTouchRing', SLIDERDATA) # Extension data for one Touch Ring. ) PK_CONTEXT = 0x0001 # reporting context PK_STATUS = 0x0002 # status bits PK_TIME = 0x0004 # time stamp PK_CHANGED = 0x0008 # change bit vector PK_SERIAL_NUMBER = 0x0010 # packet serial number PK_CURSOR = 0x0020 # reporting cursor PK_BUTTONS = 0x0040 # button information PK_X = 0x0080 # x axis PK_Y = 0x0100 # y axis PK_Z = 0x0200 # z axis PK_NORMAL_PRESSURE = 0x0400 # normal or tip pressure PK_TANGENT_PRESSURE = 0x0800 # tangential or barrel pressure PK_ORIENTATION = 0x1000 # orientation info: tilts PK_ROTATION = 0x2000 # rotation info; 1.1 TU_NONE = 0 TU_INCHES = 1 TU_CENTIMETERS = 2 TU_CIRCLE = 3 # messages WT_DEFBASE = 0x7ff0 WT_MAXOFFSET = 0xf WT_PACKET = 0 # remember to add base WT_CTXOPEN = 1 WT_CTXCLOSE = 2 WT_CTXUPDATE = 3 WT_CTXOVERLAP = 4 WT_PROXIMITY = 5 WT_INFOCHANGE = 6 WT_CSRCHANGE = 7 WT_PACKETEXT = 8 # system button assignment values SBN_NONE = 0x00 SBN_LCLICK = 0x01 SBN_LDBLCLICK = 0x02 SBN_LDRAG = 0x03 SBN_RCLICK = 0x04 SBN_RDBLCLICK = 0x05 SBN_RDRAG = 0x06 SBN_MCLICK = 0x07 SBN_MDBLCLICK = 0x08 SBN_MDRAG = 0x09 # for Pen Windows SBN_PTCLICK = 0x10 SBN_PTDBLCLICK = 0x20 SBN_PTDRAG = 0x30 SBN_PNCLICK = 0x40 SBN_PNDBLCLICK = 0x50 SBN_PNDRAG = 0x60 SBN_P1CLICK = 0x70 SBN_P1DBLCLICK = 0x80 SBN_P1DRAG = 0x90 SBN_P2CLICK = 0xA0 SBN_P2DBLCLICK = 0xB0 SBN_P2DRAG = 0xC0 SBN_P3CLICK = 0xD0 SBN_P3DBLCLICK = 0xE0 SBN_P3DRAG = 0xF0 HWC_INTEGRATED = 0x0001 HWC_TOUCH = 0x0002 HWC_HARDPROX = 0x0004 HWC_PHYSID_CURSORS = 0x0008 # 1.1 CRC_MULTIMODE = 0x0001 # 1.1 CRC_AGGREGATE = 0x0002 # 1.1 CRC_INVERT = 0x0004 # 1.1 WTI_INTERFACE = 1 IFC_WINTABID = 1 IFC_SPECVERSION = 2 IFC_IMPLVERSION = 3 IFC_NDEVICES = 4 IFC_NCURSORS = 5 IFC_NCONTEXTS = 6 IFC_CTXOPTIONS = 7 IFC_CTXSAVESIZE = 8 IFC_NEXTENSIONS = 9 IFC_NMANAGERS = 10 IFC_MAX = 10 WTI_STATUS = 2 STA_CONTEXTS = 1 STA_SYSCTXS = 2 STA_PKTRATE = 3 STA_PKTDATA = 4 STA_MANAGERS = 5 STA_SYSTEM = 6 STA_BUTTONUSE = 7 STA_SYSBTNUSE = 8 STA_MAX = 8 WTI_DEFCONTEXT = 3 WTI_DEFSYSCTX = 4 WTI_DDCTXS = 400 # 1.1 WTI_DSCTXS = 500 # 1.1 CTX_NAME = 1 CTX_OPTIONS = 2 CTX_STATUS = 3 CTX_LOCKS = 4 CTX_MSGBASE = 5 CTX_DEVICE = 6 CTX_PKTRATE = 7 CTX_PKTDATA = 8 CTX_PKTMODE = 9 CTX_MOVEMASK = 10 CTX_BTNDNMASK = 11 CTX_BTNUPMASK = 12 CTX_INORGX = 13 CTX_INORGY = 14 CTX_INORGZ = 15 CTX_INEXTX = 16 CTX_INEXTY = 17 CTX_INEXTZ = 18 CTX_OUTORGX = 19 CTX_OUTORGY = 20 CTX_OUTORGZ = 21 CTX_OUTEXTX = 22 CTX_OUTEXTY = 23 CTX_OUTEXTZ = 24 CTX_SENSX = 25 CTX_SENSY = 26 CTX_SENSZ = 27 CTX_SYSMODE = 28 CTX_SYSORGX = 29 CTX_SYSORGY = 30 CTX_SYSEXTX = 31 CTX_SYSEXTY = 32 CTX_SYSSENSX = 33 CTX_SYSSENSY = 34 CTX_MAX = 34 WTI_DEVICES = 100 DVC_NAME = 1 DVC_HARDWARE = 2 DVC_NCSRTYPES = 3 DVC_FIRSTCSR = 4 DVC_PKTRATE = 5 DVC_PKTDATA = 6 DVC_PKTMODE = 7 DVC_CSRDATA = 8 DVC_XMARGIN = 9 DVC_YMARGIN = 10 DVC_ZMARGIN = 11 DVC_X = 12 DVC_Y = 13 DVC_Z = 14 DVC_NPRESSURE = 15 DVC_TPRESSURE = 16 DVC_ORIENTATION = 17 DVC_ROTATION = 18 # 1.1 DVC_PNPID = 19 # 1.1 DVC_MAX = 19 WTI_CURSORS = 200 CSR_NAME = 1 CSR_ACTIVE = 2 CSR_PKTDATA = 3 CSR_BUTTONS = 4 CSR_BUTTONBITS = 5 CSR_BTNNAMES = 6 CSR_BUTTONMAP = 7 CSR_SYSBTNMAP = 8 CSR_NPBUTTON = 9 CSR_NPBTNMARKS = 10 CSR_NPRESPONSE = 11 CSR_TPBUTTON = 12 CSR_TPBTNMARKS = 13 CSR_TPRESPONSE = 14 CSR_PHYSID = 15 # 1.1 CSR_MODE = 16 # 1.1 CSR_MINPKTDATA = 17 # 1.1 CSR_MINBUTTONS = 18 # 1.1 CSR_CAPABILITIES = 19 # 1.1 CSR_TYPE = 20 # 1.2 CSR_MAX = 20 WTI_EXTENSIONS = 300 EXT_NAME = 1 EXT_TAG = 2 EXT_MASK = 3 EXT_SIZE = 4 EXT_AXES = 5 EXT_DEFAULT = 6 EXT_DEFCONTEXT = 7 EXT_DEFSYSCTX = 8 EXT_CURSORS = 9 EXT_MAX = 109 # Allow 100 cursors CXO_SYSTEM = 0x0001 CXO_PEN = 0x0002 CXO_MESSAGES = 0x0004 CXO_MARGIN = 0x8000 CXO_MGNINSIDE = 0x4000 CXO_CSRMESSAGES = 0x0008 # 1.1 # context status values CXS_DISABLED = 0x0001 CXS_OBSCURED = 0x0002 CXS_ONTOP = 0x0004 # context lock values CXL_INSIZE = 0x0001 CXL_INASPECT = 0x0002 CXL_SENSITIVITY = 0x0004 CXL_MARGIN = 0x0008 CXL_SYSOUT = 0x0010 # packet status values TPS_PROXIMITY = 0x0001 TPS_QUEUE_ERR = 0x0002 TPS_MARGIN = 0x0004 TPS_GRAB = 0x0008 TPS_INVERT = 0x0010 # 1.1 TBN_NONE = 0 TBN_UP = 1 TBN_DOWN = 2 PKEXT_ABSOLUTE = 1 PKEXT_RELATIVE = 2 # Extension tags. WTX_OBT = 0 # Out of bounds tracking WTX_FKEYS = 1 # Function keys WTX_TILT = 2 # Raw Cartesian tilt; 1.1 WTX_CSRMASK = 3 # select input by cursor type; 1.1 WTX_XBTNMASK = 4 # Extended button mask; 1.1 WTX_EXPKEYS = 5 # ExpressKeys; 1.3 - DEPRECATED USE 2 WTX_TOUCHSTRIP = 6 # TouchStrips; 1.4 WTX_TOUCHRING = 7 # TouchRings; 1.4 WTX_EXPKEYS2 = 8 # ExpressKeys; 1.4 TABLET_PROPERTY_CONTROLCOUNT = 0 # UINT32: number of physical controls on tablet TABLET_PROPERTY_FUNCCOUNT = 1 # UINT32: number of functions of control TABLET_PROPERTY_AVAILABLE = 2 # BOOL: control/mode is available for override TABLET_PROPERTY_MIN = 3 # UINT32: minimum value TABLET_PROPERTY_MAX = 4 # UINT32: maximum value TABLET_PROPERTY_OVERRIDE = 5 # BOOL: control is overridden TABLET_PROPERTY_OVERRIDE_NAME = 6 # UTF-8: Displayable name when control is overridden TABLET_PROPERTY_OVERRIDE_ICON = 7 # Image: Icon to show when control is overridden TABLET_PROPERTY_ICON_WIDTH = 8 # UINT32: Pixel width of icon display TABLET_PROPERTY_ICON_HEIGHT = 9 # UINT32: Pixel height of icon display TABLET_PROPERTY_ICON_FORMAT = 10 # UINT32: UINT32: Pixel format of icon display (see TABLET_ICON_FMT_*) TABLET_PROPERTY_LOCATION = 11 # UINT32: Physical location of control (see TABLET_LOC_*) TABLET_LOC_LEFT = 0 TABLET_LOC_RIGHT = 1 TABLET_LOC_TOP = 2 TABLET_LOC_BOTTOM = 3 TABLET_LOC_TRANSDUCER = 4 lib.WTOpenW.restype = HCTX lib.WTOpenW.argtypes = [HWND, ctypes.POINTER(LOGCONTEXT), BOOL] lib.WTClose.restype = BOOL lib.WTClose.argtypes = [HCTX] lib.WTInfoW.restype = UINT lib.WTInfoW.argtypes = [UINT, UINT, LPVOID] lib.WTPacket.restype = BOOL lib.WTPacket.argtypes = [HCTX, UINT, LPVOID] lib.WTGetW.restype = BOOL lib.WTGetW.argtypes = [HCTX, BOOL] lib.WTExtGet.restype = BOOL lib.WTExtGet.argtypes = [HCTX, UINT, LPVOID] lib.WTExtSet.restype = BOOL lib.WTExtSet.argtypes = [HCTX, UINT, LPVOID]