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
50 replies to this topic
Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Can you find the hex or decimal value of SP_FingerState? You can test it in this program if you get it.

CoordMode, Tooltip, Screen
GoSub, Constants
SynAPI := ComObjCreate("SynCtrl.SynAPICtrl")
SynDev := ComObjCreate("SynCtrl.SynDeviceCtrl")
SynAPI.Initialize
SynDev.Select( SynAPI.FindDevice(0,2,-1) )
SynPac := ComObjCreate("SynCtrl.SynPacketCtrl")
Loop
{
	SynDev.LoadPacket(SynPac)
	FingerState := SynPac.GetLongProperty(268436243) ; This value is wrong, I was trying to follow enums in a header file to get it...
	Loop, Parse, SF_List, `n
		If (%A_LoopField% = FingerState)
			ToolTip, FingerState: %FingerState% `nActon: %A_LoopField% `n, 0, 0
	Sleep 0
}
return

Esc::ExitApp

Constants:
SF_FingerProx := 0x00000200
SF_FingerTouch := 0x00000400 
SF_FingerHeavy := 0x00000800 
SF_FingerPress := 0x00001000 
SF_FingerPresent := 0x00002000 
SF_FingerPossTap := 0x00004000 
SF_FingerStylus := 0x00008000 

SF_FingerTap := 0x00010000 
SF_FingerDrag := 0x00020000 
SF_FingerDragLock := 0x00040000 
SF_FingerPrimGest := 0x00080000 
SF_FingerSecGest := 0x00100000 
SF_FingerAuxGest := 0x00200000 
SF_FingerMotion := 0x00400000 
SF_FingerMoving := 0x00800000 

SF_FingerTopLeftTap := 0x01000000 
SF_FingerTopRightTap := 0x02000000 
SF_FingerBottomLeftTap := 0x04000000 
SF_FingerBottomRightTap := 0x08000000 

SF_FingerTap2 := 0x40000000 
SF_FingerTap3 := 0x80000000 

SF_FingerAllCorner := 0x0F000000 
SF_FingerAllTap := 0xCF000000 
SF_FingerAsButton := 0xCF380000 
SF_FingerAllGest := 0xCF3F1000

SF_List =
(
SF_FingerProx 
SF_FingerTouch 
SF_FingerHeavy 
SF_FingerPress 
SF_FingerPresent 
SF_FingerPossTap 
SF_FingerStylus
SF_FingerTap 
SF_FingerDrag 
SF_FingerDragLock 
SF_FingerPrimGest 
SF_FingerSecGest 
SF_FingerAuxGest 
SF_FingerMotion 
SF_FingerMoving
SF_FingerTopLeftTap 
SF_FingerTopRightTap 
SF_FingerBottomLeftTap 
SF_FingerBottomRightTap
SF_FingerTap2 
SF_FingerTap3
SF_FingerAllCorner 
SF_FingerAllTap 
SF_FingerAsButton 
SF_FingerAllGest 
)
return

Edit: Wow, looks like you have some documentation work ahead of you. This will be helpful when finished. Thanks.
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

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

Can you find the hex or decimal value of SP_FingerState?

Here it is:
On Hex:
  SF_FingerProx           = 0x00000200, // Z exceeds proximity threshold.
  SF_FingerTouch          = 0x00000400, // Z exceeds touch threshold.
  SF_FingerHeavy          = 0x00000800, // Z exceeds heavy touch threshold.
  SF_FingerPress          = 0x00001000, // "Press hard" gesture in progress.
  SF_FingerPresent        = 0x00002000, // Finger present on TouchPad.
  SF_FingerPossTap        = 0x00004000, // Early stroke, tap still possible.
  SF_FingerStylus         = 0x00008000, // Stylus present on TouchPad.

  SF_FingerTap            = 0x00010000, // Tap gesture in progress.
  SF_FingerDrag           = 0x00020000, // Drag gesture in progress.
  SF_FingerDragLock       = 0x00040000, // Drag-lock gesture in progress.
  SF_FingerPrimGest       = 0x00080000, // Primary gesture in progress.
  SF_FingerSecGest        = 0x00100000, // Secondary gesture in progress.
  SF_FingerAuxGest        = 0x00200000, // Auxiliary gesture in progress.
  SF_FingerMotion         = 0x00400000, // Motion deltas are non-zero.
  SF_FingerMoving         = 0x00800000, // Significant finger motion.

  SF_FingerTopLeftTap     = 0x01000000, // Tap in zone in progress.
  SF_FingerTopRightTap    = 0x02000000, // Tap in zone in progress.
  SF_FingerBottomLeftTap  = 0x04000000, // Tap in zone in progress.
  SF_FingerBottomRightTap = 0x08000000, // Tap in zone in progress.

  // Flags for multi finger pads
  SF_FingerTap2           = 0x40000000, // 2 finger tap
  SF_FingerTap3           = 0x80000000, // 3+ finger tap

  SF_FingerAllCorner      = 0x0F000000, // Corner gestures.
  SF_FingerAllTap         = 0xCF000000, // Any and all taps
  SF_FingerAsButton       = 0xCF380000, // Finger state as buttons
  SF_FingerAllGest        = 0xCF3F1000, // Any and all gestures.
On Integer
SF_FingerProx := 512
SF_FingerTouch := 1024
SF_FingerHeavy := 2048
SF_FingerPress := 4096
SF_FingerPresent := 8192
SF_FingerPossTap := 16384
SF_FingerStylus := 32768
SF_FingerTap := 65536
SF_FingerDrag := 131072
SF_FingerDragLock := 262144
SF_FingerPrimGest := 524288
SF_FingerSecGest := 1048576
SF_FingerAuxGest := 2097152
SF_FingerMotion := 4194304
SF_FingerMoving := 8388608
SF_FingerTopLeftTap := 16777216
SF_FingerTopRightTap := 33554432
SF_FingerBottomLeftTap := 67108864
SF_FingerBottomRightTap := 134217728
SF_FingerTap2 := 1073741824
SF_FingerTap3 := -2147483648
SF_FingerAllCorner := 251658240
SF_FingerAllTap := -822083584
SF_FingerAsButton := -818413568
SF_FingerAllGest := -817950720
SF_FingerAll := -805306880
SP_FingerState was a bitfield value, i have a hard time figuring/interprete the combination :roll:

	FingerState := SynPac.GetLongProperty(268436243) ; This value is wrong, I was trying to follow enums in a header file to get it...

The correct value would be 268436242, try it....

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008

The correct value would be 268436242, try it....

I think you're right, thanks.

It doesn't give the same values as are listed in SynComDefs.h, but I'll figure it out. For example I get values like 9728 (0x2600) and 4204032 (0x402600) which aren't listed. The only value which is a constant is SF_FingerProx (0x0200).
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

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

It doesn't give the same values as are listed in SynComDefs.h, but I'll figure it out. For example I get values like 9728 (0x2600) and 4204032 (0x402600) which aren't listed. The only value which is a constant is SF_FingerProx (0x0200).

That's because

SP_FingerState was a bitfield value.

So it's not only reporting one kind of gesture one at a time, but its a combination. For example, 9728(512+1024+8192) means below flags are detected/active (which simply means your hand were touching the touchpad).
  SF_FingerProx           = 512
  SF_FingerTouch          = 1024
  SF_FingerPresent        = 8192
4204032(512+1024+8192+4194304) that indicates below flags are detected/active (which simply means, API sense a motion [continous movement] on touchpad).
  SF_FingerProx           = 512
  SF_FingerTouch          = 1024
  SF_FingerPresent        = 8192
  SF_FingerMotion         = 4194304
Another example is 12592640 & 12609024 that correspond to SF_FingerMoving, which indicates large movement has occured. The active flags would be:
;12592640:
  SF_FingerProx           = 512
  SF_FingerTouch          = 1024
  SF_FingerPresent        = 8192
  SF_FingerMotion         = 4194304
  SF_FingerMoving         = 8388608
;12609024
  SF_FingerPossTap        = 16384
:!: Remark : So if (for example) you want to detect a movement(SF_FingerMoving) using the independent value listed (eg. 8388608) it won't work, because there would be no movement without motion, no motion without touch, no touch without finger presence, etc. Well, you get my point. :wink:

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Thank you, I got it working with the & operator. I didn't know what "bitfield" meant when you used it earlier :oops:
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

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

Thank you, I got it working with the & operator. I didn't know what "bitfield" meant when you used it earlier :oops:

Sorry for the confusion :oops:. I don't know what "bit field" mean either at the first time :lol:. I found it written somewhere on the manuals.

EDIT:
Ahh, found it

SP_Gestures : Specifies the gestures generated by a Synaptics device. This property is a bitfield. See the SynGestures enumeration for the list of supported gestures.

And also

SynActions Enumeration ... This enumeration is a bit field. Each action is specified with a unique bit in the field. At any given time, only a single action can be associated with a device gesture or button.

So i assume FingerState is also bitfield, i might be wrong though :roll:

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
I've made some reference (it's not complete yet though) of Synaptics COM on page 2, if anyone interested.

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

I want to record raw touchpad movement (gesture) and use it as a shorcut/hotkey, just like Scrybe / Stroke it. But i don't know how to do it.

This code basically monitoring all packet data / raw finger position, number of finger, etc. :
#SingleInstance, Force
;-------------------------------------------------------------------------------
; Create GUI
  Gui, Add, Text, % "x12 y" 20*1-8  " w160 h20", X Raw
  Gui, Add, Text, % "x12 y" 20*2-8  " w160 h20", Y Raw
  Gui, Add, Text, % "x12 y" 20*3-8  " w160 h20", Z Raw
  Gui, Add, Text, % "x12 y" 20*4-8  " w160 h20", W (Width)
  Gui, Add, Text, % "x12 y" 20*5-8  " w160 h20", X Filtered
  Gui, Add, Text, % "x12 y" 20*6-8  " w160 h20", Y Filtered
  Gui, Add, Text, % "x12 y" 20*7-8  " w160 h20", Z Filtered
  Gui, Add, Text, % "x12 y" 20*8-8  " w160 h20", X Delta
  Gui, Add, Text, % "x12 y" 20*9-8  " w160 h20", Y Delta
  Gui, Add, Text, % "x12 y" 20*10-8 " w160 h20", Z Delta
  Gui, Add, Text, % "x12 y" 20*11-8 " w160 h20", X Mickeys
  Gui, Add, Text, % "x12 y" 20*12-8 " w160 h20", Y Mickeys
  Gui, Add, Text, % "x12 y" 20*13-8 " w160 h20", AnachronisticState
  Gui, Add, Text, % "x12 y" 20*14-8 " w160 h20", FingerState
  Gui, Add, Text, % "x12 y" 20*15-8 " w160 h20", ExtendedState
  Gui, Add, Text, % "x12 y" 20*16-8 " w160 h20", ButtonState
  Gui, Add, Text, % "x12 y" 20*17-8 " w160 h20", ExtraFingerState
  Gui, Add, Text, % "x12 y" 20*18-8 " w160 h20", WheelDelta
  Gui, Add, Text, % "x12 y" 20*19-8 " w160 h20", FingerIndex
  Gui, Add, Text, % "x12 y" 20*20-8 " w160 h20", Sequence No
  Gui, Add, Text, % "x12 y" 20*21-8 " w160 h20", Time Stamp

Loop, 21 {
   Gui, Add, Edit, % "x120 y" 20*A_Index-10 " w90 h20 v" A_Index
}
Gui, Show,x0 y20,SynPacket Monitor
Gui -SysMenu

;-------------------------------------------------------------------------------
; Create COM Object
SynAPI := ComObjCreate("SynCtrl.SynAPICtrl")
SynDev := ComObjCreate("SynCtrl.SynDeviceCtrl")

; Initialize ISynAPICtrl instance
SynAPI.Initialize

; Finding Synaptics Touchpad to be used by ISynDeviceCtrl
DeviceHandle := SynAPI.FindDevice(0,2,-1)

; Pointing DeviceHandle to ISynDeviceCtrl instance
SynDev.Select(DeviceHandle)

; Connects SynDeviceCtrl related events with the prefix "SynDev_". So we could
; use SynDeviceCtrl_OnPacket events to obtain synchronous reports of Synaptics
; device data
ComObjConnect(SynDev, "SynDev_")
;-------------------------------------------------------------------------------
; <------ Routine Started ........
Loop {
;-------------------------------------------------------------------------------
; Packet Monitor
	If UpdateGui=1
	{
    GuiControl, , 1, % GetXRaw
    GuiControl, , 2, % GetYRaw
    GuiControl, , 3, % GetZRaw
    GuiControl, , 4, % GetW
    GuiControl, , 5, % GetX
    GuiControl, , 6, % GetY
    GuiControl, , 7, % GetZ
    GuiControl, , 8, % GetXDelta
    GuiControl, , 9, % GetYDelta
    GuiControl, , 10, % GetZDelta
    GuiControl, , 11, % GetXMickeys
    GuiControl, , 12, % GetYMickeys
    GuiControl, , 13, % GetAnachronisticState
    GuiControl, , 14, % GetFingerState FingerStateAct
    GuiControl, , 15, % GetExtendedState
    GuiControl, , 16, % GetButtonState
    GuiControl, , 17, % GetExtraFingerState
    GuiControl, , 18, % GetWheelDelta
    GuiControl, , 19, % GetFingerIndex
    GuiControl, , 20, % GetSequenceNumber
    GuiControl, , 21, % GetTimeStamp
	}
Sleep, 1
}
; <------ End Of Routine ........
; <-----------------------------------------------------------------------------

;-------------------------------------------------------------------------------
; HotKeys

; Toogle GUI update
^1::
If UpdateGui<>1
{
	UpdateGui:=1
	Return
}
UpdateGui:=0
Return

; Exit App
~Esc::
ComObjConnect(SynDev)
Gui, Destroy
ExitApp


;-------------------------------------------------------------------------------
; Function

SynDev_OnPacket(SynDev) {
 ; Create SynPacketCtrl (Synaptics Packet Control) COM Object
   static SynPac := ComObjCreate("SynCtrl.SynPacketCtrl")

 ; read the device packet queue and export packet data to an ISynPacketCtrl instance
   SynDev.LoadPacket(SynPac)

 ; set Global variable so we can use it outside this function
   global GetAssociatedDeviceHandle, GetSequenceNumber, GetTimeStamp, GetXRaw, GetYRaw, GetZRaw, GetZYRaw, GetW, GetX, GetY, GetZ, GetXDelta, GetYDelta, GetZDelta, GetXMickeys, GetYMickeys, GetAnachronisticState, GetFingerState, GetExtendedState, GetButtonState, GetExtraFingerState, GetWheelDelta, GetFingerIndex

 ; retrieve packet value
			GetAssociatedDeviceHandle := SynPac.GetLongProperty(268436225)
			GetSequenceNumber         := SynPac.GetLongProperty(268436226)
			GetTimeStamp              := SynPac.GetLongProperty(268436227)
			GetXRaw                   := SynPac.GetLongProperty(268436228)
			GetYRaw                   := SynPac.GetLongProperty(268436229)
			GetZRaw                   := SynPac.GetLongProperty(268436230)
			GetZYRaw                  := SynPac.GetLongProperty(268436231)
			GetW                      := SynPac.GetLongProperty(268436232)
			GetX                      := SynPac.GetLongProperty(268436233)
			GetY                      := SynPac.GetLongProperty(268436234)
			GetZ                      := SynPac.GetLongProperty(268436235)
			GetXDelta                 := SynPac.GetLongProperty(268436236)
			GetYDelta                 := SynPac.GetLongProperty(268436237)
			GetZDelta                 := SynPac.GetLongProperty(268436238)
			GetXMickeys               := SynPac.GetLongProperty(268436239)
			GetYMickeys               := SynPac.GetLongProperty(268436240)
			GetAnachronisticState     := SynPac.GetLongProperty(268436241)
			GetFingerState            := SynPac.GetLongProperty(268436242)
			GetExtendedState          := SynPac.GetLongProperty(268436243)
			GetButtonState            := SynPac.GetLongProperty(268436244)
			GetExtraFingerState       := SynPac.GetLongProperty(268436245)
			GetWheelDelta             := SynPac.GetLongProperty(268436246)
			GetFingerIndex            := SynPac.GetLongProperty(268436247)
}

And I've manage to visualize finger position on touchpad almost like scrybe, but without cursor trail (i don't know how to make a cursor trail, I've read tic example but it's to complicated for me). Press ctrl+1 to activate / use 3 finger tap(still not reliable tough). Red cursor represent one finger, Green cursor represent two finger, and Blue cursor represent three finger, width of the cursor represent applied pressure & width of finger
Process, Priority, , Realtime
Enabled := ComObjError(False)
SynAPI := ComObjCreate("SynCtrl.SynAPICtrl")
SynDev := ComObjCreate("SynCtrl.SynDeviceCtrl")
SynAPI.Initialize
SynDev.Select(SynAPI.FindDevice(0,0,-1))
ComObjConnect(SynDev, "SynDev_")

; Absolute Coordinate limit
XLoSensor                    :=  SynDev.GetLongProperty(268435733)
YLoSensor                    :=  SynDev.GetLongProperty(268435734)
XHiSensor                    :=  SynDev.GetLongProperty(268435735)
YHiSensor                    :=  SynDev.GetLongProperty(268435736)

; Bezel Coordinate limit
XLoRim                       :=  SynDev.GetLongProperty(268435737)
YLoRim                       :=  SynDev.GetLongProperty(268435738)
XHiRim                       :=  SynDev.GetLongProperty(268435739)
YHiRim                       :=  SynDev.GetLongProperty(268435740)

; Edge margin (x,y) ->>> EdgeMotion Rectangle
XLoBorder                    :=  SynDev.GetLongProperty(268435741)
YLoBorder                    :=  SynDev.GetLongProperty(268435742)
XHiBorder                    :=  SynDev.GetLongProperty(268435743)
YHiBorder                    :=  SynDev.GetLongProperty(268435744)

; Wide Border ???????
XLoWideBorder                :=  SynDev.GetLongProperty(268435747)
YLoWideBorder                :=  SynDev.GetLongProperty(268435748)
XHiWideBorder                :=  SynDev.GetLongProperty(268435749)
YHiWideBorder                :=  SynDev.GetLongProperty(268435750)

; Set the width and height we want as our drawing area, to draw everything in.
Width  := (XHiSensor-XLoSensor)/14 ; AbsoluteWidth
Height := (YHiSensor-YLoSensor)/17 ; AbsoluteHeight
RimWidth  := (XHiRim-XLoRim)/14
RimHeight := (YHiRim-YLoRim)/17
EdgeWidth  := (XHiBorder-XLoBorder)/14
EdgeHeight := (YHiBorder-YLoBorder)/17
WideWidth  := (XHiWideBorder-XLoWideBorder)/14
wideHeight := (YHiWideBorder-YLoWideBorder)/17

xRim  := (XLoRim-XLoSensor)/14
yRim  := (YLoRim-YLoSensor)/17
xEdge := (XLoBorder-XLoSensor)/14
yEdge := (YLoBorder-YLoSensor)/17
xWide := (XLoWideBorder-XLoSensor)/14
yWide := (YLoWideBorder-YLoSensor)/17

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}

Loop
{
	If GetExtraFingerState = 3	; detect 3 finger tap
	{
		ActivateGUI:=0
		ActivateTimeOut:= A_TickCount
		3F_Tap:=1
	}
	
	If (3F_Tap = 1) and (A_TickCount - ActivateTimeOut > 100) ; if 3 fingertap detected, wait 100 ticks, then Activate GUI
	{
		3F_Tap:=0
		ActivateGUI:=1
	}
	
	If (UpdateGui = 1) or (ActivateGUI = 1)
	{
		If GetFingerState > 0   ; if finger presence detected, draw cursor
		{
			Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
			
			hwnd1 := WinExist()
			hbm := CreateDIBSection(Width, Height)
			hdc := CreateCompatibleDC()
			obm := SelectObject(hdc, hbm)
			
			G := Gdip_GraphicsFromHDC(hdc)
			Gdip_SetSmoothingMode(G, 4)
			
			;xCoord   := (GetX-XLoSensor)/14	; crosshair x coordinate
			;yCoord   := (YHiSensor-GetY)/17	; crosshair y coordinate
			xWidth   := (GetZ/3)*(GetW/3) ; translate finger pressure(Z) & finger width (W) to cursor size
			yHeight  := (GetZ/3)*(GetW/3) ; translate finger pressure(Z) & finger width (W) to cursor size
			xFinger  := ((GetX-XLoSensor)/14)-(xWidth/2)   ; translate touchpad X coordinate to canvas
			yFinger  := ((YHiSensor-GetY)/17)-(yHeight/2)  ; translate touchpad y coordinate to canvas
			
			;   :: Canvas ::
			pBrush := Gdip_BrushCreateSolid(0x77000000)
			Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20)
			Gdip_DeleteBrush(pBrush)
			
			;   :: Bezel Margin ::
			pPen   := Gdip_CreatePen(0x77ffffff, 1)
			Gdip_DrawRoundedRectangle(G, pPen, xRim, yRim, RimWidth, RimHeight, 20)
			Gdip_DeletePen(pPen)
			
			/*
			;   :: EdgeMotion Margin ::
			pPen   := Gdip_CreatePen(0x77dddddd, 1)
			Gdip_DrawRoundedRectangle(G, pPen, xEdge, yEdge, EdgeWidth, EdgeHeight, 20)
			Gdip_DeletePen(pPen)
			;   :: WideBorder Margin ::
			pPen   := Gdip_CreatePen(0x77bbbbbb, 1)
			Gdip_DrawRoundedRectangle(G, pPen, xWide, yWide, WideWidth, WideHeight, 20)
			Gdip_DeletePen(pPen)
			;   :: CrossHair ::
			pPen   := Gdip_CreatePen(0x77ffffff, 1)
			Gdip_DrawLine(G, pPen, xCoord, 0, xCoord, Height)
			Gdip_DrawLine(G, pPen, 0, yCoord, Width, yCoord)
			Gdip_DeletePen(pPen)
			*/
			
			;   :: Cursor ::
			CursorColor := (GetExtraFingerState = 1) ? "0x77ff0000" : (GetExtraFingerState = 257) ? "0x77ff0000" : (GetExtraFingerState = 513) ? "0x77ff0000" : (GetExtraFingerState = 769) ? "0x77ff0000" : (GetExtraFingerState = 2) ? "0x7700ff00" : (GetExtraFingerState = 258) ? "0x7700ff00" : (GetExtraFingerState = 514) ? "0x7700ff00" : (GetExtraFingerState = 770) ? "0x7700ff00" : (GetExtraFingerState = 3) ? "0x770000ff" : (GetExtraFingerState = 259) ? "0x770000ff" : (GetExtraFingerState = 515) ? "0x770000ff" : (GetExtraFingerState = 771) ? "0x770000ff" : "0x77ffffff"
			pBrush := Gdip_BrushCreateSolid(CursorColor)
			Gdip_FillEllipse(G, pBrush, xFinger, yFinger, xWidth, yHeight)
			Gdip_DeleteBrush(pBrush)
			
			UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)
			Gui, 1: Show, NA			
			SelectObject(hdc, obm) ; Select the object back into the hdc
			DeleteObject(hbm)      ; Now the bitmap may be deleted
			DeleteDC(hdc)          ; Also the device context related to the bitmap may be deleted
			Gdip_DeleteGraphics(G) ; The graphics may now be deleted
			
			CanvasTimeOut := A_TickCount
		}
		
		If GetFingerState < 9728 ; if finger not present, 
		{
			If A_TickCount - CanvasTimeOut > 600  ; wait until 600 tick
			{
				ActivateGUI:=0
				Gui, 1: Destroy ; and destroy the canvas
			}
		}
	}
Sleep, 1
}
Return

; Toogle GUI

~^1::
UpdateGui != 1 ? UpdateGui:=1 : UpdateGui:=0
Return

~Esc::
Gdip_Shutdown(pToken)
ExitApp
Return


SynDev_OnPacket(SynDev) {
   static SynPac := ComObjCreate("SynCtrl.SynPacketCtrl")
   SynDev.LoadPacket(SynPac)
   global GetW, GetX, GetY, GetZ, GetFingerState, GetExtraFingerState
			GetW                      := SynPac.GetLongProperty(268436232)
			GetX                      := SynPac.GetLongProperty(268436233)
			GetY                      := SynPac.GetLongProperty(268436234)
			GetZ                      := SynPac.GetLongProperty(268436235)
			GetFingerState            := SynPac.GetLongProperty(268436242)
			GetExtraFingerState       := SynPac.GetLongProperty(268436245)
}

Suggestions???

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
There's some basic mouse gesture scripts on the forums. You could modify one of them to work with input from your touch pad.

Links:
<!-- m -->http://www.autohotke...topic25892.html<!-- m --> (best one afaik)
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

j--hn
  • Members
  • 176 posts
  • Last active: Oct 26 2011 02:42 PM
  • Joined: 16 Apr 2011
Hi Frankie... Good to see you again :D

Thanks for the suggestion, i'll study it.

maeiky
  • Members
  • 2 posts
  • Last active: Feb 17 2012 03:52 AM
  • Joined: 29 Dec 2011
I made a script to control mouse and touch pad speed independently and I added the missing middle button on the top left corner.
Enjoy. :D

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

; Pointer Speed (1-20)
PadSpeed = 20
MouseSpeed = 4

; Enhance Pointer Precision
PadEnhance = 1
MouseEnhance = 1

; Precision Thresholds
PadThreshold1 = 6
PadThreshold2 = 10
MouseThreshold1 = 6
MouseThreshold2 = 10


;Middle button zone
MiddleMinX := 1350
MiddleMaxX := 1700
MiddleMinY := 4100
MiddleMaxY := 4750

; Use a tray icon?
TrayIcon = 1

; Tray Icons
; If you want the tray icon to reflect the current settings, enter a valid
; PadIcon and PadIconGroup. To use the only standard AutoHotkey icon, comment
; out all the icon locations.

MouseIcon = %A_WinDir%\system32\main.cpl
MouseIconGroup = 1
MouseName = Mouse

; The likely location of the Synaptics Touch Pad icon.
PadIcon = %ProgramFiles%\Synaptics\SynTP\SynTPEnh.exe
PadIconGroup = 1
PadName = Touch Pad

If !TrayIcon
   Menu, Tray, NoIcon
   
; Constants
; Read more at the following:
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
; http://www.pinvoke.net/search.aspx?search=SPI&namespace=%5BAll%5D
SPI_GETMOUSE =      0x0003
SPI_SETMOUSE =      0x0004
SPI_GETMOUSESPEED =   0x0070
SPI_SETMOUSESPEED =   0x0071

; :: NotePAD ::  musical Note on touchPAD
;
; This plain script demonstrate Synaptics COM usage to retrieve raw input from
; touchpad. It detect finger presence on x,y coordinate and match match them
; with predefined zone, and play some musical note (SoundBeep) accordingly.
;
; The predefined zone in this script was harcoded but actually it's calculated as follow:
;
;        4864+-----------+-----+-----+-----------+ <-- SP_YHiSensor
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;            +-----------+-----+-----+-----------+ <-- SP_YLoSensor+((SP_YHiSensor-SP_YLoSensor)/2) = 2944
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;            |           |           |           |
;        1024+-----------+-----+-----+-----------+ <-- SP_YLoSensor
;            1024        ^           ^           5888
;            ^           |           |            ^
;            SP_XLoSensor|           |           SP_XHiSensor
;                        |           |
;                        |           SP_X_LoSensor+(((SP_YLoSensor-SP_YLoSensor)/3)*2) = 4267
;                        |
;                        SP_X_LoSensor+(((SP_YLoSensor-SP_YLoSensor)/3)*1) = 2646
;
;
;
;-------------------------------------------------------------------------------
; Create COM Object
SynAPI := ComObjCreate("SynCtrl.SynAPICtrl")
SynDev := ComObjCreate("SynCtrl.SynDeviceCtrl")

; Initialize ISynAPICtrl instance
SynAPI.Initialize

; Finding Synaptics Touchpad to be used by ISynDeviceCtrl
DeviceHandle := SynAPI.FindDevice(0,2,-1)

; Pointing DeviceHandle to ISynDeviceCtrl instance
SynDev.Select(DeviceHandle)

; Connects SynDeviceCtrl related events with the prefix "SynDev_". So we could
; use SynDeviceCtrl_OnPacket events to obtain synchronous reports of Synaptics
; device data
ComObjConnect(SynDev, "SynDev_")
bLoop := TRUE
nStart := 0

MinX := SynDev.GetLongProperty(268435733) ; SP_XLoSensor <-- LowerX Limit
MinY := SynDev.GetLongProperty(268435734) ; SP_YLoSensor <-- LowerY Limit
MaxX := SynDev.GetLongProperty(268435735) ; SP_XHiSensor <-- UpperX Limit
MaxY := SynDev.GetLongProperty(268435736) ; SP_YHiSensor <-- UpperY Limit

MousePresent := TRUE
Gosub, ChangeSettings

;-------------------------------------------------------------------------------
; <------ Routine Started ........
Loop {

;-------------------------------------------------------------------------------
; CustomTapZone (9 Area)
;
;        4864+-----------+-----------+-----------+
;            |           |           |           |
;            |     7     |     8     |     9     |
;            |           |           |           |
;        3584+-----------+-----------+-----------+
;            |           |           |           |
;            |     4     |     5     |     6     |
;            |           |           |           |
;        2304+-----------+-----------+-----------+
;            |           |           |           |
;            |     1     |     2     |     3     |
;            |           |           |           |
;        1024+-----------+-----------+-----------+
;            1024        2646        4267        5888
;

	If(nPosY != GetY or  nPosX != GetX)
	{
		nPosY := GetY
		nPosX := GetX
	
		bAnyPress := FALSE
		If (nPosY > MinY and nPosY < MaxY)
		{
			If (nPosX > MinX and nPosX < MaxX)
			{	
				bAnyPress := TRUE
				If(bLoop )
				{
					MousePresent := FALSE
					Gosub, ChangeSettings
				}
			}
		}

			
		If (bAnyPress )
		{
			;--------------MIDDLE CLICK-------------
			If(bLoop )
			{
				bLoop := FALSE
				
				If (nPosY > MiddleMinY and nPosY < MiddleMaxY)
				{
					If (nPosX > MiddleMinX and nPosX < MiddleMaxX)        
					{		
						MouseClick, Middle
						;SoundBeep, 988, 150
					}
				}
				
			} 
			;----------------------------------------
		}
		else
		{
			;Mouse speed value return
			bLoop := TRUE
			MousePresent := TRUE
			Gosub, ChangeSettings
		}

	}  

	Sleep -1  
}


; <------ End Of Routine ........
; <-----------------------------------------------------------------------------


; ============================================================
; FUNCTIONS & SUBROUTINES
; ============================================================
ChangeSettings:
   If MousePresent
   {
      CurrentName = %MouseName%
      DeviceSpeed = %MouseSpeed%
      DeviceEnhance = %MouseEnhance%
      DeviceThreshold1 = %MouseThreshold1%
      DeviceThreshold2 = %MouseThreshold2%
      If TrayIcon and FileExist(MouseIcon)
         Menu, Tray, Icon, %MouseIcon%, %MouseIconGroup%
      Menu, Tray, Tip, Current Pointer Settings: %CurrentName%
   }
   Else
   {
      CurrentName = %PadName%
      DeviceSpeed = %PadSpeed%
      DeviceEnhance = %PadEnhance%
      DeviceThreshold1 = %PadThreshold1%
      DeviceThreshold2 = %PadThreshold2%
      If TrayIcon and FileExist(PadIcon)
         Menu, Tray, Icon, %PadIcon%, %PadIconGroup%
      Menu, Tray, Tip, Current Pointer Settings: %CurrentName%
   }

   VarSetCapacity(DeviceArray, 12, 0)
   InsertInteger(DeviceThreshold1, DeviceArray, 0)   ; Reg. Value MouseThreshold1
   InsertInteger(DeviceThreshold2, DeviceArray, 4)   ; Reg. Value MouseThreshold2
   InsertInteger(DeviceEnhance, DeviceArray, 8)      ; Reg. Value MouseSpeed

   InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
   ; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest,
   ; only pSize number of bytes starting at pOffset are altered in it.
   {
      Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
         DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
   }

   ; Keep this here for future reference.
   ; DllCall("SystemParametersInfo", UInt, SPI_GETMOUSESPEED, UInt, 0, UIntP, SpeedCurrent, UInt, 0)

   ; Change the pointer speed.
   DllCall("SystemParametersInfo", UInt, SPI_SETMOUSESPEED, UInt, 0, UInt, DeviceSpeed, UInt, 1)
   ; Change the pointer precision settings.
   DllCall("SystemParametersInfo", UInt, SPI_SETMOUSE, UInt, 0, Str, DeviceArray, UInt, 1)
   Return


; Receives synchronous notification of Synaptics pointing device reports.
SynDev_OnPacket(SynDev) {

 ; Create SynPacketCtrl (Synaptics Packet Control) COM Object
   static SynPac := ComObjCreate("SynCtrl.SynPacketCtrl")

 ; read the device packet queue and export packet data to an ISynPacketCtrl instance
   SynDev.LoadPacket(SynPac)

 ; set Global variable so we can use it outside this function
   global GetAssociatedDeviceHandle, GetX, GetY

 ; retrieve packet value
         GetX                      := SynPac.GetLongProperty(268436233)
         GetY                      := SynPac.GetLongProperty(268436234)
}
:D :D :D :D :D :D :D :D


Edit : I made another version here :
http://www.autohotke...pic.php?t=75992

automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
Left mouse click on untouch would be interesting. See example below, it shows the principle, but there is still some "flickered clicking". If some experts can remove this flickered clicking it might be interesting, in my opinion.

After each mouse move, when untouching there should be a left click, but only ONE, not many as in my example below.


#Persistent
#include COM.ahk

OldMouseState := GetMouseState()

CoordMode, Tooltip, Screen
OnExit, Cleanup
Com_Init()
SynAPI := Com_CreateObject("SynCtrl.SynAPICtrl")
SynDev := Com_CreateObject("SynCtrl.SynDeviceCtrl")
Com_Invoke(SynAPI, "Initialize")
DeviceHandle := Com_Invoke(SynAPI, "FindDevice", 0,2,-1)
Com_Invoke(SynDev, "Select", DeviceHandle) ; is DeviceHandle always zero?
sink := Com_ConnectObject(SynDev, "SynDev_")
return

Cleanup:
   Com_DisconnectObject(sink)
   Com_Release(SynApi)
   Com_Release(SynDev)
   Com_Release(SynPac)
   Com_Term()
   ExitApp

SynDev_OnPacket() {
   global SynPac, SynDev
   if Not SynPac
      SynPac := Com_CreateObject("SynCtrl.SynPacketCtrl")
   Com_Invoke(SynDev, "LoadPacket", "+" SynPac)
   data .=   "XRaw:`t" Com_Invoke(SynPac, "XRaw")
      .   "`nYRaw:`t" Com_Invoke(SynPac, "YRaw")
      .   "`nZRaw:`t" Com_Invoke(SynPac, "ZRaw")
      .   "`nWidth:`t" Com_Invoke(SynPac, "W")
   ToolTip, %data%, 0, 0
   
   trigger := Com_Invoke(SynPac, "W") 
   CurrentMouseState := GetMouseState()
   if ( trigger == 0) && (CurrentMouseState != OldMouseState)
   {
       OldMouseState := CurrentMouseState
    
       Click
       }
   
}


GetMouseState()
{
    MouseGetPos, xpos, ypos
    Return xpos+ypos
}

Esc::ExitApp


sharethewisdom
  • Members
  • 57 posts
  • Last active: Dec 18 2014 08:44 AM
  • Joined: 24 Feb 2008
This is great! I would like to figure out how to invert the mouse movement to match the mousepad movement with the tilted screen orientation (If I can get the rotation feature of the Intel graphics driver to work on my Acer laptop; VERY FRUSTRATING)
using MouseMove by itself was not a good solution since it's in conflict with the Synaptics cursor control
Should I disable synaptics pointing device, is one able to access the touchpad then?

dotm
  • Members
  • 2 posts
  • Last active:
  • Joined: 02 Aug 2012

Should I disable synaptics pointing device, is one able to access the touchpad then?


Btw I've successfully disabled OS from getting the mouse data, just as API tells
SynDev.Acquire(0)
It was nice alternative to Gloovepie's "shallow"

The device can be enabled with

SynDev.Unacquire

It will be re-enabled anyway when the object is destroyed

Very enlightening topic indeed. Thanks to the posters for in-depth API study

automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
There will be soon also a newer version from Synaptics, ForcePad, allowing pressure sensitivity up to 1000 g, in steps of 15 g, resolution of 6 bits = 64 steps.

See also following video: <!-- m --><!-- m -->

Great news I would say.