Compare commits

..

No commits in common. "master" and "v0.9" have entirely different histories.
master ... v0.9

7 changed files with 110 additions and 177 deletions

View File

@ -13,9 +13,6 @@
<setting name="listenport" serializeAs="String"> <setting name="listenport" serializeAs="String">
<value>8080</value> <value>8080</value>
</setting> </setting>
<setting name="taptolerance" serializeAs="String">
<value>5</value>
</setting>
</webcrab.My.MySettings> </webcrab.My.MySettings>
</userSettings> </userSettings>
</configuration> </configuration>

View File

@ -65,18 +65,6 @@ Namespace My
Me("listenport") = value Me("listenport") = value
End Set End Set
End Property End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("5")> _
Public Property taptolerance() As Integer
Get
Return CType(Me("taptolerance"),Integer)
End Get
Set
Me("taptolerance") = value
End Set
End Property
End Class End Class
End Namespace End Namespace

View File

@ -5,8 +5,5 @@
<Setting Name="listenport" Type="System.UInt16" Scope="User"> <Setting Name="listenport" Type="System.UInt16" Scope="User">
<Value Profile="(Default)">8080</Value> <Value Profile="(Default)">8080</Value>
</Setting> </Setting>
<Setting Name="taptolerance" Type="System.Int32" Scope="User">
<Value Profile="(Default)">5</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@ -5,8 +5,7 @@ Public Class main
Dim weblistener As HttpListener Dim weblistener As HttpListener
Dim lastpos As New Point(0, 0) Dim lastpos As New Point(0, 0)
Dim startpos As New Point(0, 0) Dim startpos As New Point(0, 0)
Dim lastmouseseq As Integer = 0 Dim leftclicking As Boolean = False
Dim nexttoggleclick As UInteger = MouseEventFlags.MOUSEEVENTF_LEFTDOWN Or MouseEventFlags.MOUSEEVENTF_RIGHTDOWN Or MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN Or MouseEventFlags.MOUSEEVENTF_XDOWN
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles StartButton.Click Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles StartButton.Click
If Not weblistener Is Nothing Then If Not weblistener Is Nothing Then
@ -20,13 +19,9 @@ Public Class main
Else Else
Dim listenport As UShort = My.Settings("listenport") Dim listenport As UShort = My.Settings("listenport")
PortInput.Value = listenport PortInput.Value = listenport
Try weblistener = New HttpListener
weblistener = New HttpListener weblistener.Prefixes.Add("http://*:" & listenport & "/")
weblistener.Prefixes.Add("http://*:" & listenport & "/") weblistener.Start()
weblistener.Start()
Catch ex As Exception
log(ex.ToString)
End Try
Dim listenthread As New Thread(AddressOf listenforconnection) Dim listenthread As New Thread(AddressOf listenforconnection)
listenthread.Start() listenthread.Start()
log("Started") log("Started")
@ -40,6 +35,8 @@ Public Class main
Dim context As HttpListenerContext = Nothing Dim context As HttpListenerContext = Nothing
Dim resp As HttpListenerResponse Dim resp As HttpListenerResponse
Dim respstr As String = String.Empty Dim respstr As String = String.Empty
Dim lastpacket As Long = -1
Dim lastpack As Long
Dim leftclicking As Boolean = False Dim leftclicking As Boolean = False
While weblistener.IsListening While weblistener.IsListening
Try Try
@ -56,8 +53,13 @@ Public Class main
If path = "/" Then If path = "/" Then
respstr = FileIO.FileSystem.ReadAllText("res/page.html") respstr = FileIO.FileSystem.ReadAllText("res/page.html")
lastpacket = 0
Else Else
respstr = handleinput(context.Request) Dim pack As Long = context.Request.QueryString("seq")
If pack > lastpack Then
respstr = handleinput(context.Request)
lastpack = pack
End If
End If End If
If String.IsNullOrEmpty(respstr) Then If String.IsNullOrEmpty(respstr) Then
@ -73,7 +75,6 @@ Public Class main
End Sub End Sub
Private Sub Form1_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing Private Sub Form1_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
My.Settings.taptolerance = TapInput.Value
If Not weblistener Is Nothing Then If Not weblistener Is Nothing Then
weblistener.Abort() weblistener.Abort()
End If End If
@ -81,8 +82,6 @@ Public Class main
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False Control.CheckForIllegalCrossThreadCalls = False
Dim taptolerance As Integer = My.Settings.taptolerance
TapInput.Value = taptolerance
Button1_Click(sender, e) Button1_Click(sender, e)
End Sub End Sub
Private Sub log(str As String) Private Sub log(str As String)
@ -111,16 +110,11 @@ Public Class main
lastpos.Y = req.QueryString("y") lastpos.Y = req.QueryString("y")
startpos.X = req.QueryString("x") startpos.X = req.QueryString("x")
startpos.Y = req.QueryString("y") startpos.Y = req.QueryString("y")
lastmouseseq = 0
Case "move" 'trackpad touch move Case "move" 'trackpad touch move
Dim seq As Integer = req.QueryString("seq") mouse_event(MouseEventFlags.MOUSEEVENTF_MOVE, req.QueryString("x") - lastpos.X, req.QueryString("y") - lastpos.Y, 0, 0)
If seq > lastmouseseq Then lastpos.X = req.QueryString("x")
mouse_event(MouseEventFlags.MOUSEEVENTF_MOVE, req.QueryString("x") - lastpos.X, req.QueryString("y") - lastpos.Y, 0, 0) lastpos.Y = req.QueryString("y")
lastpos.X = req.QueryString("x")
lastpos.Y = req.QueryString("y")
lastmouseseq = seq
End If
Case "end" Case "end"
Dim tol As Integer = TapInput.Value Dim tol As Integer = TapInput.Value
@ -130,77 +124,64 @@ Public Class main
mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
End If End If
Case "click" Case "left"
Dim eventflag As UInteger = 0 If leftclicking Then
Select Case req.QueryString("button") mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
Case "left" leftclicking = False
eventflag = MouseEventFlags.MOUSEEVENTF_LEFTDOWN Else
Case "right" mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
eventflag = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN leftclicking = True
Case "middle" End If
eventflag = MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN
Case "x" Case "middle"
eventflag = MouseEventFlags.MOUSEEVENTF_XDOWN mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0)
Case Else
Return "unknown mouse button"
End Select
mouse_event(eventflag, 0, 0, 0, 0)
System.Threading.Thread.Sleep(10) System.Threading.Thread.Sleep(10)
' bit shift to the left is the corresponding button up event mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
mouse_event(eventflag << 1, 0, 0, 0, 0)
Case "toggle" Case "right"
Dim eventflagmask As UInteger = 0 mouse_event(MouseEventFlags.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
'buttonmask is just the 2 bits for the selected button System.Threading.Thread.Sleep(10)
Select Case req.QueryString("button") mouse_event(MouseEventFlags.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
Case "left"
eventflagmask = MouseEventFlags.MOUSEEVENTF_LEFTDOWN Or MouseEventFlags.MOUSEEVENTF_LEFTUP
Case "right"
eventflagmask = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN Or MouseEventFlags.MOUSEEVENTF_RIGHTUP
Case "middle"
eventflagmask = MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN Or MouseEventFlags.MOUSEEVENTF_MIDDLEUP
Case "x"
eventflagmask = MouseEventFlags.MOUSEEVENTF_XDOWN Or MouseEventFlags.MOUSEEVENTF_XUP
Case Else
Return "unknown mouse button"
End Select
'nexttoggleclick is either button up or down for each button
mouse_event(eventflagmask And nexttoggleclick, 0, 0, 0, 0)
'invert nexttoggleclick for the selected button only
nexttoggleclick = nexttoggleclick Xor eventflagmask
Case "wheel" Case "wheel"
Dim eventflag As UInteger = 0 mouse_event(MouseEventFlags.MOUSEEVENTF_WHEEL, 0, 0, WHEEL_DELTA * req.QueryString("d"), 0)
Select Case req.QueryString("axis")
Case "vert"
eventflag = MouseEventFlags.MOUSEEVENTF_WHEEL
Case "horiz"
eventflag = MouseEventFlags.MOUSEEVENTF_HWHEEL
Case "volume"
If req.QueryString("d") = -1 Then
keybd_press(VK.VOLUME_DOWN)
ElseIf req.QueryString("d") = 0 Then
keybd_press(VK.VOLUME_MUTE)
ElseIf req.QueryString("d") = 1 Then
keybd_press(VK.VOLUME_UP)
End If
Case "media"
Select Case req.QueryString("act")
Case "stop"
keybd_press(VK.MEDIA_STOP)
Case "prev"
keybd_press(VK.MEDIA_PREV_TRACK)
Case "play"
keybd_press(VK.MEDIA_PLAY_PAUSE)
Case "next"
keybd_press(VK.MEDIA_NEXT_TRACK)
End Select End Select
mouse_event(eventflag, 0, 0, req.QueryString("delta"), 0)
Case "key" Case "key"
Try Select Case req.QueryString("k")
Dim vk As Byte = req.QueryString("code") Case "del"
keybd_press(vk) keybd_press(VK.DELETE)
Catch ex As Exception Case "bksp"
log(ex.ToString) keybd_press(VK.KEY_BACK)
End Try Case "enter"
keybd_press(VK.RETURN_KEY)
End Select
Case "text" Case "text"
Dim text As String = req.QueryString("text") Dim encodedtext As String = req.QueryString("t")
Dim decodedtext As String = Uri.UnescapeDataString(encodedtext)
Try Try
SendKeysEscaped(text) SendKeysEscaped(decodedtext)
Catch ex As Exception
log(ex.ToString)
End Try
Case "sendkeys"
Dim keys As String = req.QueryString("keys")
Try
SendKeys.SendWait(keys)
Catch ex As Exception Catch ex As Exception
log(ex.ToString) log(ex.ToString)
End Try End Try

View File

@ -14,9 +14,6 @@ body {
margin: 0; margin: 0;
background-color: black; background-color: black;
color: gray; color: gray;
display: flex;
flex-direction: column;
} }
button{ button{
text-align: center; text-align: center;
@ -30,61 +27,64 @@ button{
button:active { button:active {
background-color: silver; background-color: silver;
} }
button:focus, button:hover, button:focus-visible {
}
.touchpad { .touchpad {
height: 60%;
display: flex; display: flex;
} }
#canvas { #canvas {
width: 100%; width: 100%;
background-color: #111; background-color: #111;
outline: gray solid 1px;
} }
div{ .buttonrow {
height: 10%;
display: flex; display: flex;
align-items: stretch;
} }
input{ .buttonrow input{
background-color: #111; background-color: #111;
color: gray; color: gray;
border: 1px solid gray; outline: gray solid 1px;
border: none; border: none;
} }
</style> </style>
</head> </head>
<body> <body>
<div style="flex:2"> <div class="buttonrow">
<button onclick="fetch('/key?code=46')" style="flex:1">del</button> <button style="flex:1">menu</button>
<button onclick="fetch('/key?code=8')" style="flex:1">bksp</button> <button onclick="sendmessage('key', 'k=del')" style="flex:1">del</button>
<button onclick="fetch('/key?code=13')" style="flex:1">enter</button> <button onclick="sendmessage('key', 'k=bksp')" style="flex:1">bksp</button>
<button onclick="sendmessage('key', 'k=enter')" style="flex:1">enter</button>
<input id="typebox" placeholder="type here" size=8 style="flex:2"> <input id="typebox" placeholder="type here" size=8 style="flex:2">
</div> </div>
<div style="flex:1"> <div class="touchpad">
<button onclick="fetch('/sendkeys?keys=j')" style="flex:1">j</button>
<button onclick="fetch('/sendkeys?keys={LEFT}')" style="flex:1">&larr;</button>
<button onclick="fetch('/sendkeys?keys=k')" style="flex:1">k</button>
<button onclick="fetch('/sendkeys?keys={RIGHT}')" style="flex:1">&rarr;</button>
<button onclick="fetch('/sendkeys?keys=l')" style="flex:1">l</button>
</div>
<div style="flex:12">
<span id="canvas"></span> <span id="canvas"></span>
</div> </div>
<div style="flex:2"> <div class="buttonrow">
<button onclick="fetch('/toggle?button=left')" style="flex:2">left (toggle)</button> <button onclick="sendmessage('left', '')" style="flex:2">left (toggle)</button>
<button onclick="fetch('/wheel?axis=vert&delta=120')" style="flex:1">up</button> <button onclick="sendmessage('wheel', 'd=1')" style="flex:1">up</button>
<button onclick="fetch('/click?button=middle')" style="flex:1">mid</button> <button onclick="sendmessage('middle', '')" style="flex:1">mid</button>
<button onclick="fetch('/wheel?axis=vert&delta=-120')" style="flex:1">dn</button> <button onclick="sendmessage('wheel', 'd=-1')" style="flex:1">dn</button>
<button onclick="fetch('/click?button=right')" style="flex:2">right</button> <button onclick="sendmessage('right', '')" style="flex:2">right</button>
</div> </div>
<div style="flex:2"> <div class="buttonrow">
<button onclick="fetch('/key?code=174')" style="flex:2">vol -</button> <button onclick="sendmessage('volume', 'd=-1')" style="flex:2">vol -</button>
<button onclick="fetch('/key?code=173')" style="flex:1">mute</button> <button onclick="sendmessage('volume', 'd=0')" style="flex:1">mute</button>
<button onclick="fetch('/key?code=175')" style="flex:2">vol +</button> <button onclick="sendmessage('volume', 'd=1')" style="flex:2">vol +</button>
<!--<button onclick="sendmessage('volume', 1, 0)" style="flex:2">vol +</button>-->
</div> </div>
<div style="flex:2"> <div class="buttonrow">
<button onclick="fetch('/key?code=178')" style="flex:1">stop</button> <button onclick="sendmessage('media', 'act=stop')" style="flex:1">stop</button>
<button onclick="fetch('/key?code=177')" style="flex:1">prev</button> <button onclick="sendmessage('media', 'act=prev')" style="flex:1">prev</button>
<button onclick="fetch('/key?code=179')" style="flex:1">play/pause</button> <button onclick="sendmessage('media', 'act=play')" style="flex:1">play/pause</button>
<button onclick="fetch('/key?code=176')" style="flex:1">next</button> <button onclick="sendmessage('media', 'act=next')" style="flex:1">next</button>
</div> </div>
<script type="text/javascript"> <script>
function startup() { function startup() {
var el = document.getElementById("canvas"); var el = document.getElementById("canvas");
el.addEventListener("touchstart", handleStart, false); el.addEventListener("touchstart", handleStart, false);
@ -105,9 +105,8 @@ var packetnum = 0;
function handleStart(evt) { function handleStart(evt) {
if (currenttouch == null) { if (currenttouch == null) {
currenttouch = evt.changedTouches[0]; currenttouch = evt.changedTouches[0];
packetnum = 0; sendmessage("start", "x=" + currenttouch.pageX + "&y=" + currenttouch.pageY)
fetch("/start?x=" + currenttouch.pageX + "&y=" + currenttouch.pageY);
} }
} }
@ -118,9 +117,8 @@ function handleMove(evt) {
} }
for (var i = 0; i < touches.length; i++) { for (var i = 0; i < touches.length; i++) {
if (touches[i].identifier == currenttouch.identifier) { if (touches[i].identifier == currenttouch.identifier) {
currenttouch = evt.changedTouches[0]; currenttouch = evt.changedTouches[0];
packetnum++; sendmessage("move", "x=" + currenttouch.pageX + "&y=" + currenttouch.pageY)
fetch("/move?x=" + currenttouch.pageX + "&y=" + currenttouch.pageY + "&seq=" + packetnum);
} }
} }
} }
@ -130,7 +128,7 @@ function handleEnd(evt) {
for (var i = 0; i < touches.length; i++) { for (var i = 0; i < touches.length; i++) {
if (touches[i].identifier == currenttouch.identifier) { if (touches[i].identifier == currenttouch.identifier) {
currenttouch = evt.changedTouches[0]; currenttouch = evt.changedTouches[0];
fetch("/end?x=" + currenttouch.pageX + "&y=" + currenttouch.pageY) sendmessage("end", "x=" + currenttouch.pageX + "&y=" + currenttouch.pageY)
currenttouch = null; currenttouch = null;
} }
} }
@ -141,7 +139,7 @@ function handleCancel(evt) {
for (var i = 0; i < touches.length; i++) { for (var i = 0; i < touches.length; i++) {
if (touches[i].identifier == currenttouch.identifier) { if (touches[i].identifier == currenttouch.identifier) {
currenttouch = evt.changedTouches[0]; currenttouch = evt.changedTouches[0];
fetch("/end?x=" + currenttouch.pageX + "&y=" + currenttouch.pageY) sendmessage("end", "x=" + currenttouch.pageX + "&y=" + currenttouch.pageY)
currenttouch = null; currenttouch = null;
} }
} }
@ -149,10 +147,17 @@ function handleCancel(evt) {
function handlekeypress(evt) { function handlekeypress(evt) {
evt.preventDefault(); evt.preventDefault();
fetch("/text?text=" + encodeURIComponent(evt.target.value)); sendmessage("text", "t=" + encodeURIComponent(evt.target.value));
evt.target.value = ""; evt.target.value = "";
} }
function sendmessage(opt, q) {
fetch("/" + opt + "/?" + q + "&seq=" + packetnum);
packetnum++;
}
</script> </script>
</body> </body>

View File

@ -1,32 +0,0 @@
Page.html is the page sent to the browser when the control site is opened.
It is easy to customize to add or remove buttons, actions, clicks, etc. to your page.
The PC side of the program recognizes several actions.
Mouse messages are:
start - start a trackpad movement
move - continue a trackpad movement
end - end a trackpad movement
All of the above take 2 arguments: x and y.
Each touch has a "seq" argument that starts at 0 and increments with each move, to avoid out-of-order movements.
Mouse movement is relative so don't worry about the absolute values.
X is positive left, and Y is positive down.
Mouse button messages are:
click - click and release a mouse button
toggle - toggle a mouse button to either the clicked or released state
Both take a single argument: "button", which can be any of "left", "right", "middle", or "x".
Mouse wheel is a single message type:
wheel - command a mouse wheel movement
It takes two arguments: "axis" which is either "vert" or "horiz", and "delta" which is how far the wheel moves.
The default delta in Windows is 120.
Vert is positive away from the user, horiz is positive to the right.
Keyboard input has several message types:
key - send a single keystroke via the numeric key code (argument "code")
text - send raw typed text (argument "text", make sure to use encodeURIComponent() or similar)
sendkeys - send typed text but escaped according to the SendKeys() method (argument "keys")
"key" can be used to send off keys such as media and IME keys not available through the other methods. A full list of codes is here: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
"text" sends raw text, such as those typed using the phone keyboard.
"sendkeys" send keystrokes, but can use modifiers or non-text keys using escape characters. See more information here: https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.devices.keyboard.sendkeys

View File

@ -153,9 +153,6 @@
<Content Include="res\page.html"> <Content Include="res\page.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="res\readme.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.