Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Controlling Synaptics Touchpad using COM API


  • Please log in to reply
49 replies to this topic
j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
Hi everyone, this is my first post so: greetings to you all':)'

Actually i'm looking for a way to capture data from touchpad (finger position) so i could make a custom tap zones using autohotkey but can't find any. But after some googling i stumble upon this Synaptics SDK, which enable touchpad access through COM API.

Based on the SDK documentation we could for example:
- retrieve our finger position (absolute/raw X,Y position)
- detect tap gesture eg. one,two,three finger tap, & more
- detect how much force is applied on touchpad, eg. light/medium/heavy, full touch(aka palm gesture)
- enable/disable touchpad
- a lot more
which perfectly needs my need':D'

I know that AHK already support COM API, and also the needed dlls (SynCom.dll&SynCtrl.dll) is already installed/registered by default during Synaptics driver installation. In other word if you're using synaptics touchpad then you're ready to go, you don't have to install anything except AHK & Sean COM Standard Library.

For more information:
Synaptics Developer Resources: http://www.synaptics...elopers/manuals
You can get the full SDK here http://www.synaptics...nCOMAPIv1_0.zip which come with full documentation and samples written on VB & C

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
this is what i got so far

Using CLSID Registry Scanner i found this ProgID:

COM:
SynCom.SynAPI.1
SynCom.PointingDevice.3
SynCom.SynPacket.3
SynCom.SynDisplay.1

ActiveX:
SynCtrl.SynAPICtrl.1
SynCtrl.SynPacketCtrl.1
SynCtrl.SynDeviceCtrl.2
SynCtrl.SynDisplayCtrl.1

This is the original VB Code snippet from SDK
  SynAPICtrl1.Initialize
  SynAPICtrl1.Activate ' Activate to receive device notifications
  DeviceHandle = SynAPICtrl1.FindDevice(SE_ConnectionAny, SE_DevicecPad, -1)
  If DeviceHandle = -1 Then
    MsgBox "Unable to find a Synaptics cPad"
    End
  End If
        
  SynDeviceCtrl1.Select (DeviceHandle)
  SynDeviceCtrl1.Activate 'Activate to receive pointing packets
    
  ZTouchThreshold = SynDeviceCtrl1.GetLongProperty(SP_ZTouchThreshold)
my first attempt using activeX object (since i can't get COM object to work)
AHK Basic Code:
COM_Init()
SAPI := COM_ActiveXObject("SynCtrl.SynAPICtrl")
SDev := COM_ActiveXObject("SynCtrl.SynDeviceCtrl")
SPak := COM_ActiveXObject("SynCtrl.SynPacketCtrl")

COM_Invoke(SAPI,"Initialize")
COM_Invoke(SAPI,"Activate")
DeviceHandle := COM_Invoke(SAPI,"FindDevice","+" . SE_ConnectionAny,"+" . SE_DeviceTouchPad, -1)

COM_Invoke(SDev, "Select", DeviceHandle)
COM_Invoke(SDev, "Activate")

ZTouchThreshold := COM_Invoke(SDev, "GetLongProperty", "+" . SP_ZTouchThreshold)   

COM_Release(SAPI)
COM_Release(SDev)
COM_Release(SPak)
Com_Term()

which resulted in this error:
Function Name: "FindDevice"
ERROR: Type mismatch. (0x80020005)
ERROR2: Member not found (0x80020003)

DeviceHandle := COM_Invoke(SAPI,"FindDevice","+" . SE_ConnectionAny,"+" . SE_DeviceTouchPad, -1)
DeviceHandle := COM_Invoke(SAPI,"FindDevice", SE_ConnectionAny, SE_DeviceTouchPad, -1)
gave the same error, so i think i enter the wrong parameter, any ideas?

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
never mind i figured that out, apparently i enter the wrong value, it should be
DeviceHandle := COM_Invoke(SAPI,"FindDevice", 0, 2, -1)
first parameter is ConnectionType, 0 = Any Connection
second parameter is DeviceType, 2 = TouchPad Device
third parameter is QueryHandle, - 1 = automatically select the first device that meet criteria

i'm still unable retrieve packet info (eg. raw X,Y,Z data) but at least now i can access/obtain device info (eg. FirmWare, Multitouch capabilites, enable/disable touchpad)':D'

here is some working example :
Disable Touchpad:
COM_Init()

SAPI := COM_ActiveXObject("SynCtrl.SynAPICtrl")
SDev := COM_ActiveXObject("SynCtrl.SynDeviceCtrl")

COM_Invoke(SAPI,"Initialize")
COM_Invoke(SAPI,"Activate")

DeviceHandle := COM_Invoke(SAPI, "FindDevice", 0, 2, -1)

COM_Invoke(SDev, "Select", DeviceHandle)
COM_Invoke(SDev, "Activate")

COM_Invoke(SDev, "SetLongProperty", 268435825, 1)

COM_Release(SAPI)
COM_Release(SDev)
Com_Term()

Enable Touchpad
COM_Init()

SAPI := COM_ActiveXObject("SynCtrl.SynAPICtrl")
SDev := COM_ActiveXObject("SynCtrl.SynDeviceCtrl")

COM_Invoke(SAPI,"Initialize")
COM_Invoke(SAPI,"Activate")

DeviceHandle := COM_Invoke(SAPI, "FindDevice", 0, 2, -1)

COM_Invoke(SDev, "Select", DeviceHandle)
COM_Invoke(SDev, "Activate")

COM_Invoke(SDev, "SetLongProperty", 268435825, 0)

COM_Release(SAPI)
COM_Release(SDev)
Com_Term()
:D

jethrow
  • Moderators
  • 2813 posts
  • Last active:
  • Joined: 24 May 2009
Very nice work :) - we need more COM examples in the forums. Here's a functionalized version using AutoHotkey_L:
TouchPad(p=0) {
	[color=#107095]static[/color] option := {off:1, on:0, 1:1, 0:0}
		,	SynAPI := [color=#107095]ComObjCreate[/color]([color=#666666]"SynCtrl.SynAPICtrl"[/color])
		,	SynDev := [color=#107095]ComObjCreate[/color]([color=#666666]"SynCtrl.SynDeviceCtrl"[/color])
		,	init   := SynAPI.Initialize
			. SynDev.Select( SynAPI.FindDevice(0,2,-1) )
	[color=#107095]if[/color] option.HasKey(p)
		SynDev.SetLongProperty(268435825, option[p])
}
Note - I used the variable name *SynAPI* to avoid any possible confusion with Speech API.

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
Thank you very much, it's my first attempt using COM':oops:'

This is what i've learned so far, there are 4 control on SynCtrl.dll:
1. SynAPICtrl, provides a control for managing the global state of the Synaptics COM subsystem
2. SynDeviceCtrl, provides a control for managing Synaptics human interface devices
3. SynPacketCtrl, provides an interface for managing pointing device packet data
4. SynDisplayCtrl, provides a control for managing Synaptics cPad (ClearPad)

From SynAPICtrl we could obtain for example:
- The version of the Synaptics COM DLL.
- The maximum number of devices that may be simultaneously controlled via the Synaptics COM DLL.
- The number of devices currently known to the Synaptics COM DLL.
- The runtime version of the Synaptics Driver. This may differ from the COM DLL version.
or basically it contain general information about the drivers

From SynDeviceCtrl we could get general information about the devices, and also modifies varius feature of the device for example:
- The driver created string that display the device name, port number, port type, and device version.
- Device type (Touchpad, cPad, TouchScreen, ect.)
- Connection type (PS2, USB, etc.)
- The firmware version of the physical device.
- Attributes of the geometry of a Synaptics TouchPad.
- Attributes of the sensor underlying a Synaptics TouchPad.
- Controls of various option eg. (EdgeMotion option&speed, Horizontal&Vertical Scrolling the width of TapZone)
- Enable/disable Touchpad

But the most interesting part is SynPacketCtrl, where we could obtain:
- The raw X coordinate reported by the device.
- The raw Y coordinate reported by the device.
- The W value ("width" of the object touching the pad)
- The raw Z value ("pressured" applied on touchpad)
- Detect FingerState/TapGesture :
SF_FingerProx		The packet's Z value exceeds the proximity threshold.
SF_FingerTouch		The packet's Z value exceeds the touch threshold.
SF_FingerHeavy		The packet's Z value exceeds the heavy touch threshold.
SF_FingerPress		A "press hard" gesture is in progress.
SF_FingerPresent	A finger is present on the pointing device.
SF_FingerPossTap	A tap gesture is in progress but may not end up as a tap.
SF_FingerStylus		A stylus is present on the pointing device.
SF_FingerTap		A tap gesture is in progress.
SF_FingerDrag		A drag gesture is in progress.
SF_FingerDragLock	A drag-lock gesture is in progress.
SF_FingerPrimGest	A primary gesture is in progress.
SF_FingerSecGest	A secondary gesture is in progress.
SF_FingerAuxGest	An auxiliary gesture is in progress.
SF_FingerMotion		Packet motion deltas are non-zero.
SF_FingerMoving		Significant finger motion has occurred.
SF_FingerTopLeftTap	Upper left tap in progress.
SF_FingerTopRightTap	Upper right tap in progress.
SF_FingerBottomLeftTap	Bottom left tap in progress.
SF_FingerBottomRightTap	Botton right tap in progress.
SF_FingerTap2		A two finger tap is in progress.
SF_FingerTap3		A three or more finger tap is in progress

To get it to work, control must be called on sequence (CMIIW) SynAPICtrl ----> SynDeviceCtrl ----> SynPacketCtrl, for example:

COM Initialization
COM_Init()
SynTP_API := COM_ActiveXObject("SynCtrl.SynAPICtrl")
SynTP_Dev := COM_ActiveXObject("SynCtrl.SynDeviceCtrl")
SynTP_Pack := COM_ActiveXObject("SynCtrl.SynPacketCtrl")
SynAPICtrl
COM_Invoke(SynTP_API,"Initialize")  ; initialize an ISynAPI instance
COM_Invoke(SynTP_API,"Activate")  ; connect ISynAPICtrl events to the application's main message pump
DeviceHandle := COM_Invoke(SynTP_API, "FindDevice", 0, 2, -1) ; query handle for a particular type of device or for a device connected 
SynDeviceCtrl
COM_Invoke(SynTP_Dev, "Select", DeviceHandle) ; point an ISynDeviceCtrl instance to a particular physical device
COM_Invoke(SynTP_Dev, "Activate") ; connect ISynDeviceCtrl events to the application's main message pump

;  now we could retrieve device related information from this control
;  eg: is it multi touch?
TP_IsMulti := COM_Invoke(SynTP_Dev, "GetLongProperty", 268435782) ; Boolean value
;  modelID
TP_modelID := COM_Invoke(SynTP_Dev, "GetLongProperty", 268435824)

SynPacketCtrl
; Nothing yet, Sorry. Still can't figured how to get it done


Frankie
  • Members
  • 2930 posts
  • Last active:
  • Joined: 02 Nov 2008
If I want to get this working, what do I have to do? I'm trying jethrow's script and I get this COM error.

Error:  0x80040154 - Class not registered


	Line#
--->	008: SnyAPI := ComObjCreate("SynCtrl.SynAPICtrl")
	008: SnyDev := ComObjCreate("SynCtrl.SynDeviceCtrl")
	008: init := SnyAPI.Initialize
	003: TouchPad()  
	005: {
	006: if p not in 1,0,on,off
	007: Return
	011: SnyDev.Select( SnyAPI.FindDevice(0,2,-1) )  

Continue running the script?
---------------------------
Yes   No   
---------------------------


j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011

Error:  0x80040154 - Class not registered


well i don't use AHK.L so, i'm not so sure, but do you have SynCOM.dll & SynCtrl.dll on your system, it should be installed by default? if it's installed you may have to register the DLL

Frankie
  • Members
  • 2930 posts
  • Last active:
  • Joined: 02 Nov 2008
Hmm...I checked, it's already in my Windows\System folder.

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011

Hmm...I checked, it's already in my Windows\System folder.


Then try to re-register the dll, it might also indication of Permission problem.
Use CLSID Registry Scanner and put Synaptics for the description, to check if it's registered properly

Frankie
  • Members
  • 2930 posts
  • Last active:
  • Joined: 02 Nov 2008
Thanks, it works now. I've wondered about this in the past but never gotten anywhere with it.

I look forward to seeing the x/y positions extractable. That's the biggest use I can see for this. Good luck with it, it's way beyond my understanding of COM.

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011

Frankie wrote:
Thanks, it works now. I've wondered about this in the past but never gotten anywhere with it.

You're welcome':D'

Frankie wrote:
I look forward to seeing the x/y positions extractable. That's the biggest use I can see for this.

Exactly.':wink:'

Since I'm not a developer & i only know little about C&VB, i get this to work through trial 'n error, so I'm not sure if I'm doing it properly. If anyone know how to code on VB/C, Please..please.. download the SDK it contain some example on VB & C, and give some ideas/suggestion.

Anyway, here's another example (Controlling Tap Setting) :
; COM_Invoke(SynTP_Dev, "SetLongProperty", 268435726, ParameterValue)
; Parameter Value:
; 0 = Tap Gesture / Tapping Disabled 
; 1 = Tap Gesture / Tapping Enabled
; 2 = Tap & Hold to Drag Enabled
; 4 = Locking drag Enabled
; 3 = 1 & 2 Enabled
; 7 = 1, 2 & 4 Enabled

COM_Init()
SynTP_API := COM_ActiveXObject("SynCtrl.SynAPICtrl")
SynTP_Dev := COM_ActiveXObject("SynCtrl.SynDeviceCtrl")

COM_Invoke(SynTP_API,"Initialize")
COM_Invoke(SynTP_API,"Activate")

DeviceHandle := COM_Invoke(SynTP_API, "FindDevice", 0, 2, -1)

COM_Invoke(SynTP_Dev, "Select", DeviceHandle)
COM_Invoke(SynTP_Dev, "Activate")

TP_TapGesture := COM_Invoke(SynTP_Dev, "GetLongProperty", 268435726)

MsgBox, % "Current Tap Setting:" TP_TapGesture

COM_Invoke(SynTP_Dev, "SetLongProperty", 268435726, 0) ; Disable tapping

COM_Release(SynTP_API)
COM_Release(SynTP_Dev)
Com_Term()


jethrow
  • Moderators
  • 2813 posts
  • Last active:
  • Joined: 24 May 2009

well i don't use AHK.L ...

Well, you're doing pretty good using AHK Basic, but I'd highly recommend using AutoHotkey_L for working with COM...

I look forward to seeing the x/y positions extractable. That's the biggest use I can see for this.

Actually, I was wondering if this could be installed on older laptops to turn off the touchpad. Anyways, here's an example:
[color=#107095]#Persistent[/color]
[color=#107095]CoordMode[/color], [color=#107095]Tooltip[/color], Screen
SynAPI := [color=#107095]ComObjCreate[/color]([color=#666666]"SynCtrl.SynAPICtrl"[/color])
SynDev := [color=#107095]ComObjCreate[/color]([color=#666666]"SynCtrl.SynDeviceCtrl"[/color])
SynAPI.Initialize
SynDev.Select( SynAPI.FindDevice(0,2,-1) )
[color=#107095]ComObjConnect[/color](SynDev, [color=#666666]"SynDev_"[/color])
[color=#107095]return[/color]


SynDev_OnPacket(SynDev) {
	[color=#107095]static[/color] SynPac := [color=#107095]ComObjCreate[/color]([color=#666666]"SynCtrl.SynPacketCtrl"[/color])
	SynDev.LoadPacket(SynPac)
	data .=	[color=#666666]"XRaw:`t"[/color]    SynPac.XRaw
			.	[color=#666666]"`nYRaw:`t"[/color]  SynPac.YRaw
			.	[color=#666666]"`nZRaw:`t"[/color]  SynPac.ZRaw
			.	[color=#666666]"`nWidth:`t"[/color] SynPac.W
	[color=#107095]ToolTip[/color], %data%, 0, 0
}


j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
Yeah it works.......... :O :O :O :O :O :O tested using AHK_L and it works..
it last for a few second and close by itself, but still... it works

Questions:
1. If i understand correctly your example (mine included) still using ActiveX interfaces. Synaptics SDK provide two interface COM (the hard one) & ActiveX (the not so hard one), so which one is better COM interfaces or ActiveX interfaces? (in terms of reliability)
2. Is it possible to implement this functionality using AHK Basic?

Actually, I was wondering if this could be installed on older laptops to turn off the touchpad

the SDK/API has been around for years (since 2006), so i think it can be used on old laptop

jethrow
  • Moderators
  • 2813 posts
  • Last active:
  • Joined: 24 May 2009

Is it possible to implement this functionality using AHK Basic?

Sure, just rather cryptic:
[color=#107095]#Persistent[/color]
[color=#107095]CoordMode[/color], [color=#107095]Tooltip[/color], Screen
[color=#107095]OnExit[/color], Cleanup
Com_Init()
SynAPI := Com_CreateObject([color=#666666]"SynCtrl.SynAPICtrl"[/color])
SynDev := Com_CreateObject([color=#666666]"SynCtrl.SynDeviceCtrl"[/color])
Com_Invoke(SynAPI, [color=#666666]"Initialize"[/color])
DeviceHandle := Com_Invoke(SynAPI, [color=#666666]"FindDevice"[/color], 0,2,-1)
Com_Invoke(SynDev, [color=#666666]"Select"[/color], DeviceHandle) ; is DeviceHandle always zero?
sink := Com_ConnectObject(SynDev, [color=#666666]"SynDev_"[/color])
[color=#107095]return[/color]

Cleanup:
	Com_DisconnectObject(sink)
	Com_Release(SynApi)
	Com_Release(SynDev)
	Com_Release(SynPac)
	Com_Term()
	[color=#107095]ExitApp[/color]

SynDev_OnPacket() {
	[color=#107095]global[/color] SynPac, SynDev
	[color=#107095]if[/color] Not SynPac
		SynPac := Com_CreateObject([color=#666666]"SynCtrl.SynPacketCtrl"[/color])
	Com_Invoke(SynDev, [color=#666666]"LoadPacket"[/color], [color=#666666]"+"[/color] SynPac)
	data .=	[color=#666666]"XRaw:`t"[/color] Com_Invoke(SynPac, [color=#666666]"XRaw"[/color])
		.	[color=#666666]"`nYRaw:`t"[/color] Com_Invoke(SynPac, [color=#666666]"YRaw"[/color])
		.	[color=#666666]"`nZRaw:`t"[/color] Com_Invoke(SynPac, [color=#666666]"ZRaw"[/color])
		.	[color=#666666]"`nWidth:`t"[/color] Com_Invoke(SynPac, [color=#666666]"W"[/color])
	[color=#107095]ToolTip[/color], %data%, 0, 0
}


j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011

Is it possible to implement this functionality using AHK Basic?

Sure, just rather cryptic:

Work great :wink: , now i understand why you told me to use AHK_L. :D