dgm5555 Posted August 26, 2017 Share Posted August 26, 2017 (edited) I'm trying to use AutoIt to monitor outputs from a Wacom digitizer tablet. Running the _WinAPI_EnumRawInputDevices demo produces the following output relevant to the tablet (I think this will be mouse, pen, eraser, touchpad, +??) \\?\HID#VID_056A&PID_0314&Col01#6&1a48d70e&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd} \\?\HID#VID_056A&PID_0314&Col05#6&1a48d70e&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030} \\?\HID#VID_056A&PID_0314&Col04#6&1a48d70e&0&0003#{4d1e55b2-f16f-11cf-88cb-001111000030} \\?\HID#VID_056A&PID_0314&Col03#6&1a48d70e&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030} \\?\HID#VID_056A&PID_0314&Col02#6&1a48d70e&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} Attached is a file with linux wacom driver info which would seem like a good start for constants etc http://www.usb.org/developers/hidpage/Hut1_12v2.pdf page 103 lists the Digitiser page for HID devices as 0D, with various devices, but I can't figure out which is relevant to the tablet. (I also looked at (HID) Human Interface Device Communications in XP but this was a post from 2009 and seems to have been superseded by updates to AutoIt, and basically just does the same as the _WinAPI_EnumRawInputDevices demo) This is my most current code which registers HID devices and consoleWrites out the raw input information. There are still some problems - 1. It doesn't label all the extracted raw data 2. Some of the information from the Tablet can be seen using HIDTrace.exe, but I can't extract it with this current code (eg the touchring and hotkeys):- expandcollapse popup#include <APISysConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> ; NB The following tags are a hack due to typos in the autoit core code (in WinAPISys.au3) $atagRID_DEVICE_INFO_MOUSE = 'struct;dword Id;dword NumberOfButtons;dword SampleRate;int HasHorizontalWheel;endstruct' $atagRID_DEVICE_INFO_KEYBOARD = 'struct;dword KbType;dword KbSubType;dword KeyboardMode;dword NumberOfFunctionKeys;dword NumberOfIndicators;dword NumberOfKeysTotal;endstruct' $atagRID_DEVICE_INFO_HID = 'struct;dword VendorId;dword ProductId;dword VersionNumber;ushort UsagePage;ushort Usage;endstruct' $atagRID_INFO_MOUSE = 'dword Size;dword Type;' & $atagRID_DEVICE_INFO_MOUSE & ';dword Unused[2];' $atagRID_INFO_KEYBOARD = 'dword Size;dword Type;' & $atagRID_DEVICE_INFO_KEYBOARD $atagRID_INFO_HID = 'dword Size;dword Type;' & $atagRID_DEVICE_INFO_HID & ';dword Unused[2]' Opt('TrayAutoPause', 0) ;RID = Raw Input Data ; Create GUI Global $g_hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), 160, 212, @DesktopWidth - 179, @DesktopHeight - 283, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), $WS_EX_TOPMOST) ;ConsoleWrite($tagRAWINPUTDEVICE & @CRLF) ; struct;ushort UsagePage;ushort Usage;dword Flags;hwnd hTarget;endstruct ; Digitizer pen works correctly ; Now iterate through all HID devices and register them ; To obtain the values of "UsagePage" and "Usage" members of this structure read HID Usage Tables documentation ; www.usb.org/developers/hidpage/Hut1_12v2.pdf Local $tRID = DllStructCreate($tagRAWINPUTDEVICE) DllStructSetData($tRID, 'Flags', $RIDEV_INPUTSINK) DllStructSetData($tRID, 'hTarget', $g_hForm) #cs \\?\HID#VID_056A&PID_0314&Col05#6&1a48d70e&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030} Device Info:- VendorId: 056A ProductId: 0314 VersionNumber: 256 UsagePage: 00 Usage: 0B \\?\HID#VID_056A&PID_0314&Col04#6&1a48d70e&0&0003#{4d1e55b2-f16f-11cf-88cb-001111000030} Device Info:- VendorId: 056A ProductId: 0314 VersionNumber: 256 UsagePage: 0D Usage: 01 \\?\HID#VID_056A&PID_0314&Col03#6&1a48d70e&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030} Device Info:- VendorId: 056A ProductId: 0314 VersionNumber: 256 UsagePage: 0D Usage: 02 \\?\HID#VID_056A&PID_0314&Col02#6&1a48d70e&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} Device Info:- VendorId: 056A ProductId: 0314 VersionNumber: 256 UsagePage: 00 Usage: 0A \\?\HID#VID_056A&PID_0314&Col01#6&1a48d70e&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd} Mouse Info:- Id: 256 NumberOfButtons: 5 SampleRate: 0 HasHorizontalWheel: 0 #ce ; Register tablet mouse DllStructSetData($tRID, 'UsagePage', 0x01) ; Generic Desktop Controls DllStructSetData($tRID, 'Usage', 0x02) ; Mouse _WinAPI_RegisterRawInputDevices($tRID) ; Register keyboard DllStructSetData($tRID, 'UsagePage', 0x01) ; Generic Desktop Controls DllStructSetData($tRID, 'Usage', 0x06) ; Keyboard _WinAPI_RegisterRawInputDevices($tRID) ; Register tablet digitizer DllStructSetData($tRID, 'UsagePage', 0x0D) ; Digitizers DllStructSetData($tRID, 'Usage', 0x01) ; Digitizer _WinAPI_RegisterRawInputDevices($tRID) ; Register tablet ?? DllStructSetData($tRID, 'UsagePage', 0x00) ; Undefined DllStructSetData($tRID, 'Usage', 0x0B) ; ?? _WinAPI_RegisterRawInputDevices($tRID) ; Register tablet pen DllStructSetData($tRID, 'UsagePage', 0x0D) ; Digitizers DllStructSetData($tRID, 'Usage', 0x02) ; Pen _WinAPI_RegisterRawInputDevices($tRID) ; Register tablet ?? DllStructSetData($tRID, 'UsagePage', 0x00) ; Undefined DllStructSetData($tRID, 'Usage', 0x0A) ; _WinAPI_RegisterRawInputDevices($tRID) #cs ; Now iterate to find other devices Local $tText, $aData = _WinAPI_EnumRawInputDevices() If IsArray($aData) Then ReDim $aData[$aData[0][0] + 1][3] $tText = DllStructCreate('wchar[256]') For $i = 1 To $aData[0][0] If _WinAPI_GetRawInputDeviceInfo($aData[$i][0], $tText, 256, $RIDI_DEVICENAME) Then $aData[$i][2] = DllStructGetData($tText, 1) ConsoleWrite ($aData[$i][2] & @CRLF) Else $aData[$i][2] = '' EndIf If $aData[$i][1] = $RIM_TYPEHID Then $devInf = DllStructCreate($atagRID_INFO_HID) If _WinAPI_GetRawInputDeviceInfo($aData[$i][0], $devInf, DllStructGetSize($devInf), $RIDI_DEVICEINFO ) Then If DllStructGetData($devInf, 'VendorId') = 0x056A And DllStructGetData($devInf, 'ProductId') = 0x0314 then ConsoleWrite ("Device Info:-" & @CRLF) ; see http://www.usb.org/developers/hidpage/Hut1_12v2.pdf for UsagePage and UsageID ConsoleWrite ('VendorId: ' & Hex(DllStructGetData($devInf, 'VendorId'),4) & @CRLF) ConsoleWrite ('ProductId: ' & Hex(DllStructGetData($devInf, 'ProductId'),4) & @CRLF) ConsoleWrite ('VersionNumber: ' & DllStructGetData($devInf, 'VersionNumber') & @CRLF) ConsoleWrite ('UsagePage: ' & Hex(DllStructGetData($devInf, 'UsagePage'),2) & @CRLF) ConsoleWrite ('Usage: ' & Hex(DllStructGetData($devInf, 'Usage'),2) & @CRLF) DllStructSetData($tRID, 'UsagePage', DllStructGetData($devInf, 'UsagePage')) DllStructSetData($tRID, 'Usage', DllStructGetData($devInf, 'Usage')) _WinAPI_RegisterRawInputDevices($tRID) EndIf EndIf EndIf Next EndIf #ce ; Register WM_INPUT message GUIRegisterMsg($WM_INPUT, 'WM_INPUT') GUISetState(@SW_SHOW) ; ConsoleWrite($structWACOM_HID_DATA & @CRLF) ; ConsoleWrite("W" & @CRLF) ; ConsoleWrite($hWnd & @CRLF) ; ConsoleWrite($iMsg & @CRLF) ; ConsoleWrite($wParam & @CRLF) ; ConsoleWrite($lParam & @CRLF) ;lParam has the handle to the RAWINPUT structure, not a pointer to it. To get the raw data, use the handle in the call to GetRawInputData. ; ConsoleWrite($tagRAWINPUTMOUSE & @CRLF) ; struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;ushort Flags;ushort Alignment;ushort ButtonFlags;ushort ButtonData;ulong RawButtons;long LastX;long LastY;ulong ExtraInformation; ; ConsoleWrite($tagRAWINPUTHID & @CRLF) ; struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;dword SizeHid;dword Count; ; from https://raw.githubusercontent.com/torvalds/linux/master/drivers/hid/wacom_wac.c ;static const struct wacom_features wacom_features_0x314 = { "Wacom Intuos Pro S", 31496, 19685, 2047, 63, INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16, .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; ; from https://raw.githubusercontent.com/torvalds/linux/master/drivers/hid/wacom_wac.h Global $nameArr[45] $nameArr[1] = "dword Type; (mouse=0,keyboard=1,HID=2)" $nameArr[2] = "dword Size; (entire packet bytes, incl headers)" $nameArr[3] = "handle hDevice;" $nameArr[4] = "wparam wParam;" $nameArr[5] = "dword dwSizeHid (in bytes);" $nameArr[6] = "dword dwCount; (num of HID inputs for device)" for $i = 0 to 37 $nameArr[$i+7] = $i Next ;local $nameArr[35] = ["", "dword Type; (mouse=0,keyboard=1,HID=2)", "dword Size; (entire packet bytes, incl headers)", "handle hDevice;", "wparam wParam;", "dword dwSizeHid (in bytes);", "dword dwCount; (num of HID inputs for device)", "ubyte bRawData; (as arr of bytes)", "SHORT inputmode;", "SHORT inputmode_index;", "BOOL sense_state;", "BOOL inrange_state;", "BOOL invert_state;", "BOOL tipswitch;", "INT x;", "INT y;", "INT pressure;", "INT width;", "INT height;", "INT id;", "INT cc_report;", "INT cc_index;", "INT cc_value_index;", "INT last_slot_field;", "INT num_expected;", "INT num_received;", "INT bat_status;", "INT battery_capacity;", "INT bat_charging;", "INT bat_connected;", "INT ps_connected;", "BOOL pad_input_event_flag;" ] $nameArr[8] = "penvsEraser: 30+p=2,e=6 pen=32,bl=33,bs=35,Eraser=36,bl=44,bs=46" $nameArr[9] = "x (5080lpi, 6.2 inches = 32768 = 15 bits)" $nameArr[10] = "y (5080lpi, 3.9 inches)" $nameArr[11] = "proximity (1024)" $nameArr[12] = "pressure (2048)" $nameArr[34] = "tilt(buttonaxis) [+/- 60]" $nameArr[36] = "tilt(noaxis) [+/- 60]" Global $structHID_DATA = "struct;" & _ "dword Type;" & _ "dword Size;" & _ "handle hDevice;" & _ "wparam wParam;" & _ "dword dwSizeHid;" & _ "dword dwCount;" & _ "endstruct;" Global $structWACOM_PEN_DATA = "struct;" & _ "dword Type;" & _ "dword Size;" & _ "handle hDevice;" & _ "wparam wParam;" & _ "dword dwSizeHid;" & _ "dword dwCount;" & _ "ubyte bRawData00;" & _ "ubyte penvsEraser;" & _ "word x;" & _ "word y;" & _ "word proximity;" & _ "word pressure;" & _ "ubyte bRawData09;" & _ "ubyte bRawData10;" & _ "ubyte bRawData11;" & _ "ubyte bRawData12;" & _ "ubyte bRawData13;" & _ "ubyte bRawData14;" & _ "ubyte bRawData15;" & _ "ubyte bRawData16;" & _ "ubyte bRawData17;" & _ "ubyte bRawData18;" & _ "ubyte bRawData19;" & _ "ubyte bRawData20;" & _ "ubyte bRawData21;" & _ "ubyte bRawData22;" & _ "ubyte bRawData23;" & _ "ubyte bRawData24;" & _ "ubyte bRawData25;" & _ "ubyte bRawData26;" & _ "ubyte bRawData27;" & _ "ubyte bRawData28;" & _ "ubyte bRawData29;" & _ "ubyte bRawData30;" & _ "ubyte bRawData31;" & _ "ubyte bRawData32;" & _ "ubyte bRawData33;" & _ "ubyte tilt_ba;" & _ "ubyte bRawData35;" & _ "ubyte tilt_na;" & _ "ubyte bRawData37;" & _ "endstruct;" ;Global $tRIM = DllStructCreate($structWACOM_PEN_DATA) ; Local $tRIM = DllStructCreate($structRAW_HID_DATA) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam Switch $hWnd Case $g_hForm ConsoleWrite("*** New WM_INPUT Recieved ***" & @CRLF) ; Retrieve the device header information Local $tRIM = DllStructCreate($tagRAWINPUTHEADER) If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) Then ; Retrieves the raw input from the specified device $devType = DllStructGetData($tRIM, 'Type') $devSize = DllStructGetData($tRIM, 'Size') Else ConsoleWrite ("Device Header Retrieval Failed" & @CRLF) Return EndIf ; Now use the handle to the device to get it's name ; The tablet seems to spoof the keyboard or the mouse for some of it's functions, in which case there is no device name available Local $tText = DllStructCreate('wchar[256]') If _WinAPI_GetRawInputDeviceInfo(DllStructGetData($tRIM, 'hDevice'), $tText, 256, $RIDI_DEVICENAME) Then $devName = DllStructGetData($tText, 1) ConsoleWrite ($devName & @CRLF) Else ConsoleWrite ("Device Name Retrieval Failed" & @CRLF) EndIf ConsoleWrite ('Raw Input Device Type: ' & $devType & @CRLF) ConsoleWrite ('Input Packet Size (bytes): ' & $devSize & @CRLF) if $devType = $RIM_TYPEMOUSE Then ;$tagRAWINPUTMOUSE = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;ushort Flags;ushort Alignment;ushort ButtonFlags;ushort ButtonData;ulong RawButtons;long LastX;long LastY;ulong ExtraInformation;' Local $tRIM = DllStructCreate($tagRAWINPUTMOUSE) If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then ; Retrieves the raw input from the specified device ConsoleWrite ("Mouse Info:-" & @CRLF) ConsoleWrite ('Flags: ' & DllStructGetData($tRIM, 'Flags') & @CRLF) ConsoleWrite ('Alignment: ' & DllStructGetData($tRIM, 'Alignment') & @CRLF) ConsoleWrite ('ButtonFlags: ' & DllStructGetData($tRIM, 'ButtonFlags') & @CRLF) ConsoleWrite ('ButtonData: ' & DllStructGetData($tRIM, 'ButtonData') & @CRLF) ConsoleWrite ('RawButtons: ' & DllStructGetData($tRIM, 'RawButtons') & @CRLF) ConsoleWrite ('LastX: ' & DllStructGetData($tRIM, 'LastX') & @CRLF) ConsoleWrite ('LastY: ' & DllStructGetData($tRIM, 'LastY') & @CRLF) ConsoleWrite ('ExtraInformation: ' & DllStructGetData($tRIM, 'ExtraInformation') & @CRLF) EndIf EndIf if $devType = $RIM_TYPEKEYBOARD Then ;$tagRAWINPUTMOUSE = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;ushort MakeCode;ushort Flags;ushort Reserved;ushort VKey;ushort;uint Message;ulong ExtraInformation;' Local $tRIM = DllStructCreate($tagRAWINPUTKEYBOARD) If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then ; Retrieves the raw input from the specified device ConsoleWrite ("Keyboard Info:-" & @CRLF) ConsoleWrite ('MakeCode: ' & DllStructGetData($tRIM, 'MakeCode') & " MakeCode = The scan code from the key depression." & @CRLF) ConsoleWrite ('Flags: ' & DllStructGetData($tRIM, 'Flags') & @CRLF) ConsoleWrite ('VKey: ' & DllStructGetData($tRIM, 'VKey') & " VKey = Windows message compatible virtual-key code." & @CRLF) ConsoleWrite ('Message: ' & DllStructGetData($tRIM, 'Message') & @CRLF) ConsoleWrite ('ExtraInformation: ' & DllStructGetData($tRIM, 'ExtraInformation') & @CRLF) EndIf EndIf if $devType = $RIM_TYPEHID Then $tRIM = DllStructCreate($structWACOM_PEN_DATA) ; If _WinAPI_GetRawInputDeviceInfo($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then ; Retrieves the raw input from the specified device If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then ; Retrieves the raw input from the specified device ConsoleWrite ("HID Info:-" & @CRLF) ; Print out all possible variables ; for $i = 1 to UBound($nameArr)-1 ; ConsoleWrite($i & ":" & $nameArr[$i] & ": " & DllStructGetData($tRIM, $i) & " @@@: " & @error & @CRLF) ; Next ; Print out identified variables For $i = 8 to 12 ConsoleWrite($i & ":" & $nameArr[$i] & ": " & DllStructGetData($tRIM, $i) & @CRLF) Next ConsoleWrite(34 & ":" & $nameArr[34] & ": " & DllStructGetData($tRIM, 34) & @CRLF) ConsoleWrite(36 & ":" & $nameArr[36] & ": " & DllStructGetData($tRIM, 36) & @CRLF) EndIf EndIf EndSwitch sleep(500) Return $GUI_RUNDEFMSG EndFunc ;==>WM_INPUT wacom_wac.c Edited September 6, 2017 by dgm5555 Link to comment Share on other sites More sharing options...
dgm5555 Posted September 5, 2017 Author Share Posted September 5, 2017 (edited) deleted Edited September 6, 2017 by dgm5555 Link to comment Share on other sites More sharing options...
mLipok Posted September 5, 2017 Share Posted September 5, 2017 I'm not an expert in your problem but I want to say: This is nice that you share your knowlege. Thanks. Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now