Source code for wolfhece.wintab.wintab

import logging

[docs] WT_PACKET = 0x7FF0
# Information categories
[docs] WTI_INTERFACE = 1
[docs] WTI_STATUS = 2
[docs] WTI_DEFCONTEXT = 3
[docs] WTI_DEFSYSCTX = 4
[docs] WTI_DDCTXS = 400
[docs] WTI_DSCTXS = 500
[docs] WTI_DEVICES = 100
[docs] WTI_CURSORS = 200
[docs] WTI_EXTENSIONS = 300
# Hardware capabilities
[docs] HWC_INTEGRATED = 0x0001
[docs] HWC_TOUCH = 0x0002
[docs] HWC_HARDPROX = 0x0004
[docs] HWC_PHYSID_CURSORS = 0x0008
# Unit specifiers
[docs] TU_NONE = 0
[docs] TU_INCHES = 1
[docs] TU_CENTIMETERS = 2
[docs] TU_CIRCLE = 3
# Cursor capabilities
[docs] CRC_MULTIMODE = 0x0001
[docs] CRC_AGGREGATE = 0x0002
[docs] CRC_INVERT = 0x0004
# System button assignment values
[docs] SBN_NONE = 0x00
[docs] SBN_LCLICK = 0x01
[docs] SBN_LDBLCLICK = 0x02
[docs] SBN_LDRAG = 0x03
[docs] SBN_RCLICK = 0x04
[docs] SBN_RDBLCLICK = 0x05
[docs] SBN_RDRAG = 0x06
[docs] SBN_MCLICK = 0x07
[docs] SBN_MDBLCLICK = 0x08
[docs] SBN_MDRAG = 0x09
# for Pen Windows
[docs] SBN_PTCLICK = 0x10
[docs] SBN_PTDBLCLICK = 0x20
[docs] SBN_PTDRAG = 0x30
[docs] SBN_PNCLICK = 0x40
[docs] SBN_PNDBLCLICK = 0x50
[docs] SBN_PNDRAG = 0x60
[docs] SBN_P1CLICK = 0x70
[docs] SBN_P1DBLCLICK = 0x80
[docs] SBN_P1DRAG = 0x90
[docs] SBN_P2CLICK = 0xA0
[docs] SBN_P2DBLCLICK = 0xB0
[docs] SBN_P2DRAG = 0xC0
[docs] SBN_P3CLICK = 0xD0
[docs] SBN_P3DBLCLICK = 0xE0
[docs] SBN_P3DRAG = 0xF0
# Context option values
[docs] CXO_SYSTEM = 0x0001
[docs] CXO_PEN = 0x0002
[docs] CXO_MESSAGES = 0x0004
[docs] CXO_MARGIN = 0x8000
[docs] CXO_MGNINSIDE = 0x4000
[docs] CXO_CSRMESSAGES = 0x0008
# Context status values
[docs] CXS_DISABLED = 0x0001
[docs] CXS_OBSCURED = 0x0002
[docs] CXS_ONTOP = 0x0004
# Context lock values
[docs] CXL_INSIZE = 0x0001
[docs] CXL_INASPECT = 0x0002
[docs] CXL_SENSITIVITY = 0x0004
[docs] CXL_MARGIN = 0x0008
[docs] CXL_SYSOUT = 0x0010
# WTPKT bits
[docs] PK_CONTEXT = 0x0001 # reporting context
[docs] PK_STATUS = 0x0002 # status bits
[docs] PK_TIME = 0x0004 # time stamp
[docs] PK_CHANGED = 0x0008 # change bit vector
[docs] PK_SERIAL_NUMBER = 0x0010 # packet serial number
[docs] PK_CURSOR = 0x0020 # reporting cursor
[docs] PK_BUTTONS = 0x0040 # button information
[docs] PK_X = 0x0080 # x axis
[docs] PK_Y = 0x0100 # y axis
[docs] PK_Z = 0x0200 # z axis
[docs] PK_NORMAL_PRESSURE = 0x0400 # normal or tip pressure
[docs] PK_TANGENT_PRESSURE = 0x0800 # tangential or barrel pressure
[docs] PK_ORIENTATION = 0x1000 # orientation info: tilts */
[docs] PK_ROTATION = 0x2000 # rotation info; 1.1
# Packet status values
[docs] TPS_PROXIMITY = 0x0001
[docs] TPS_QUEUE_ERR = 0x0002
[docs] TPS_MARGIN = 0x0004
[docs] TPS_GRAB = 0x0008
[docs] TPS_INVERT = 0x0010
# Relative buttons
[docs] TBN_NONE = 0
[docs] TBN_UP = 1
[docs] TBN_DOWN = 2
[docs] class Wintab(): def __init__(self, hwnd): import ctypes from ctypes import wintypes, c_char, c_int, POINTER from ctypes.wintypes import HWND, UINT, DWORD, LONG, HANDLE, BOOL, LPVOID HCTX = HANDLE WTPKT = DWORD FIX32 = DWORD class LOGCONTEXTA(ctypes.Structure): _fields_ = [ ('lcName', 40*c_char), ('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', c_int), ('lcSysOrgY', c_int), ('lcSysExtX', c_int), ('lcSysExtY', c_int), ('lcSysSensX', FIX32), ('lcSysSensY', FIX32) ] # 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 */ lcPktData = (PK_CHANGED | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE) lcPktMode = 0 class PACKET(ctypes.Structure): _fields_ = [ ('pkChanged', WTPKT), ('pkCursor', UINT), ('pkButtons', DWORD), ('pkX', LONG), ('pkY', LONG), ('pkNormalPressure', UINT) ] # WTI_DEFCONTEXT = 3 # CXO_SYSTEM = 0x0001 # CXO_PEN = 0x0002 # CXO_MESSAGES = 0x0004 # CXO_MARGIN = 0x8000 try: self.dll = ctypes.WinDLL("wintab32.dll") self._wintab = True self.dll.WTInfoA.argtypes = [UINT, UINT, POINTER(LOGCONTEXTA)] self.dll.WTInfoA.restype = UINT self.dll.WTOpenA.argtypes = [HWND, POINTER(LOGCONTEXTA), BOOL] self.dll.WTOpenA.restype = HCTX self.dll.WTClose.argtypes = [HCTX] self.dll.WTClose.restype = BOOL self.dll.WTPacketsGet.argtypes = [HCTX, c_int, POINTER(PACKET)] self.dll.WTPacketsGet.restype = c_int self.dll.WTPacket.argtypes = [HCTX, UINT, POINTER(PACKET)] self.dll.WTPacket.restype = BOOL self.lc = LOGCONTEXTA() rslt = self.dll.WTInfoA(WTI_DEFCONTEXT, 0, self.lc) # logging.info(self.lc.lcOptions) self.lc.lcPktData = lcPktData self.lc.lcPktMode = lcPktMode self.lc.lcOptions = (CXO_SYSTEM | CXO_MESSAGES) # logging.info(self.lc.lcOptions) self.hctx = self.dll.WTOpenA(HWND(hwnd), self.lc, 1) self.buf = (1*PACKET)() except: self._wintab = False
[docs] def get_xypressure(self): if self._wintab: n = self.dll.WTPacketsGet(self.hctx, 1, self.buf) if n > 0: return self.buf[0].pkX, self.buf[0].pkY, self.buf[0].pkNormalPressure else: return None, None, None else: return None, None, None
if __name__ == "__main__":
[docs] loc = Wintab()
while True: x, y, p = loc.get_xypressure() if x is not None: print(x, y, p) # else: # print("No data")