# UseMyPhone — wireless touchpad helper # # A web page cannot move your mouse pointer. This small script can, so it is # the piece that turns your phone into a real trackpad for this computer. # # What it does: connects to your own UseMyPhone session with the code shown # on your screen, waits for you to approve it there, and then # moves the pointer / clicks / scrolls / types exactly what # your phone sends. # What it never does: read your screen, read your files, send anything out, # or run in the background. Close the window and it is gone. # # It needs no install and no administrator rights. Read it before you run it — # it is short on purpose. param( [string]$Code = '', [string]$Server = 'https://usemyphone.com' ) $ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Write-Host '' Write-Host ' UseMyPhone — wireless touchpad' -ForegroundColor Green Write-Host ' Your phone becomes a trackpad for this computer.' Write-Host '' if (-not $Code) { $Code = Read-Host ' Enter the 6-digit code shown on your screen' } $Code = ($Code -replace '[^0-9]', '') if ($Code.Length -ne 6) { Write-Host ' That is not a 6-digit code.' -ForegroundColor Red; exit 1 } # ── Windows input ───────────────────────────────────────────────────────── # mouse_event and keybd_event are the small, stable corner of user32 for this: # relative movement, buttons, wheel, and layout-aware typing, with none of the # struct marshalling SendInput needs. Add-Type -Namespace UMP -Name Input -MemberDefinition @' [DllImport("user32.dll")] public static extern void mouse_event(uint dwFlags, int dx, int dy, int dwData, System.IntPtr dwExtraInfo); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, System.IntPtr dwExtraInfo); [DllImport("user32.dll")] public static extern short VkKeyScanW(char ch); '@ $MOUSEEVENTF_MOVE = 0x0001 $MOUSEEVENTF_LEFTDOWN = 0x0002 $MOUSEEVENTF_LEFTUP = 0x0004 $MOUSEEVENTF_RIGHTDOWN = 0x0008 $MOUSEEVENTF_RIGHTUP = 0x0010 $MOUSEEVENTF_MIDDLEDOWN = 0x0020 $MOUSEEVENTF_MIDDLEUP = 0x0040 $MOUSEEVENTF_WHEEL = 0x0800 $KEYEVENTF_KEYUP = 0x0002 # Named keys the phone's keyboard row can send. Anything else arrives as text. $VK = @{ 'enter' = 0x0D; 'back' = 0x08; 'tab' = 0x09; 'esc' = 0x1B; 'space' = 0x20; 'up' = 0x26; 'down' = 0x28; 'left' = 0x25; 'right' = 0x27; 'home' = 0x24; 'end' = 0x23; 'pgup' = 0x21; 'pgdn' = 0x22; 'del' = 0x2E; 'win' = 0x5B; 'f5' = 0x74; 'f11' = 0x7A } function Send-Key([int]$vk, [bool]$shift) { if ($shift) { [UMP.Input]::keybd_event(0x10, 0, 0, [IntPtr]::Zero) } [UMP.Input]::keybd_event([byte]$vk, 0, 0, [IntPtr]::Zero) [UMP.Input]::keybd_event([byte]$vk, 0, $KEYEVENTF_KEYUP, [IntPtr]::Zero) if ($shift) { [UMP.Input]::keybd_event(0x10, 0, $KEYEVENTF_KEYUP, [IntPtr]::Zero) } } function Send-Text([string]$text) { foreach ($ch in $text.ToCharArray()) { $scan = [UMP.Input]::VkKeyScanW($ch) if ($scan -eq -1) { continue } # not on this keyboard layout Send-Key ($scan -band 0xFF) ((($scan -shr 8) -band 1) -eq 1) } } # One pad event → one Windows action. function Invoke-PadEvent($e) { switch ($e.t) { 'm' { [UMP.Input]::mouse_event($MOUSEEVENTF_MOVE, [int]$e.x, [int]$e.y, 0, [IntPtr]::Zero) } 'w' { [UMP.Input]::mouse_event($MOUSEEVENTF_WHEEL, 0, 0, [int]$e.d, [IntPtr]::Zero) } 'l' { [UMP.Input]::mouse_event($MOUSEEVENTF_LEFTDOWN, 0, 0, 0, [IntPtr]::Zero) [UMP.Input]::mouse_event($MOUSEEVENTF_LEFTUP, 0, 0, 0, [IntPtr]::Zero) } 'r' { [UMP.Input]::mouse_event($MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, [IntPtr]::Zero) [UMP.Input]::mouse_event($MOUSEEVENTF_RIGHTUP, 0, 0, 0, [IntPtr]::Zero) } 'i' { [UMP.Input]::mouse_event($MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, [IntPtr]::Zero) [UMP.Input]::mouse_event($MOUSEEVENTF_MIDDLEUP, 0, 0, 0, [IntPtr]::Zero) } 'dd' { [UMP.Input]::mouse_event($MOUSEEVENTF_LEFTDOWN, 0, 0, 0, [IntPtr]::Zero) } # drag start 'du' { [UMP.Input]::mouse_event($MOUSEEVENTF_LEFTUP, 0, 0, 0, [IntPtr]::Zero) } # drag end 'k' { if ($VK.ContainsKey([string]$e.k)) { Send-Key $VK[[string]$e.k] $false } } 'x' { Send-Text ([string]$e.s) } } } # ── connect ─────────────────────────────────────────────────────────────── $wsUrl = ($Server -replace '^http', 'ws') + '/ws' Write-Host " Connecting to $Server …" $ws = New-Object System.Net.WebSockets.ClientWebSocket # The server admits only clients from its own pages, so identify as one. $ws.Options.SetRequestHeader('Origin', $Server) $cts = New-Object System.Threading.CancellationTokenSource try { $ws.ConnectAsync([Uri]$wsUrl, $cts.Token).Wait() } catch { Write-Host " Could not reach $Server — check your internet connection." -ForegroundColor Red exit 1 } function Send-Json($obj) { $json = $obj | ConvertTo-Json -Compress $bytes = [Text.Encoding]::UTF8.GetBytes($json) $seg = New-Object System.ArraySegment[byte] -ArgumentList @(,$bytes) $ws.SendAsync($seg, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait() } Send-Json @{ t = 'helper'; code = $Code; name = $env:COMPUTERNAME } $buffer = New-Object byte[] 16384 $seg = New-Object System.ArraySegment[byte] -ArgumentList @(,$buffer) $approved = $false $events = 0 Write-Host ' Waiting for you to approve this helper on your screen…' -ForegroundColor Yellow while ($ws.State -eq 'Open') { $task = $ws.ReceiveAsync($seg, $cts.Token) try { $task.Wait() } catch { break } $result = $task.Result if ($result.MessageType -eq [System.Net.WebSockets.WebSocketMessageType]::Close) { break } $text = [Text.Encoding]::UTF8.GetString($buffer, 0, $result.Count) try { $msg = $text | ConvertFrom-Json } catch { continue } switch ($msg.t) { 'helper-wait' { } 'helper-no' { Write-Host " Refused: $($msg.reason)" -ForegroundColor Red $ws.Dispose(); exit 1 } 'helper-ok' { $approved = $true Write-Host '' Write-Host ' Connected. Your phone is now a trackpad.' -ForegroundColor Green Write-Host ' Close this window at any time to stop it instantly.' Write-Host '' } 'pad' { if (-not $approved) { continue } foreach ($e in $msg.a) { Invoke-PadEvent $e } $events += $msg.a.Count if ($events % 200 -lt $msg.a.Count) { Write-Host "`r active · $events movements" -NoNewline } } 'expired' { Write-Host ' That session has ended.' -ForegroundColor Yellow; break } } } Write-Host '' Write-Host ' Touchpad stopped. Nothing is left running.' -ForegroundColor Yellow try { $ws.Dispose() } catch { }