mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
348 lines
10 KiB
C#
348 lines
10 KiB
C#
using Remotely.Desktop.Core.Interfaces;
|
|
using Remotely.Desktop.Core.Services;
|
|
using Remotely.Desktop.Linux.X11Interop;
|
|
using System;
|
|
using Remotely.Desktop.Core.Models;
|
|
using Remotely.Shared.Utilities;
|
|
|
|
namespace Remotely.Desktop.Linux.Services
|
|
{
|
|
public class KeyboardMouseInputLinux : IKeyboardMouseInput
|
|
{
|
|
public KeyboardMouseInputLinux()
|
|
{
|
|
Display = LibX11.XOpenDisplay(null);
|
|
}
|
|
|
|
public IntPtr Display { get; }
|
|
|
|
public void SendKeyDown(string key, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
key = ConvertJavaScriptKeyToX11Key(key);
|
|
var keySim = LibX11.XStringToKeysym(key);
|
|
if (keySim == null)
|
|
{
|
|
Logger.Write($"Key not mapped: {key}");
|
|
return;
|
|
}
|
|
|
|
var keyCode = LibX11.XKeysymToKeycode(Display, keySim);
|
|
LibXtst.XTestFakeKeyEvent(Display, keyCode, true, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendKeyUp(string key, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
key = ConvertJavaScriptKeyToX11Key(key);
|
|
var keySim = LibX11.XStringToKeysym(key);
|
|
if (keySim == null)
|
|
{
|
|
Logger.Write($"Key not mapped: {key}");
|
|
return;
|
|
}
|
|
|
|
var keyCode = LibX11.XKeysymToKeycode(Display, keySim);
|
|
LibXtst.XTestFakeKeyEvent(Display, keyCode, false, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
|
|
}
|
|
|
|
public void SendLeftMouseDown(double percentX, double percentY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
SendMouseMove(percentX, percentY, viewer);
|
|
LibXtst.XTestFakeButtonEvent(Display, 1, true, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendLeftMouseUp(double percentX, double percentY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
SendMouseMove(percentX, percentY, viewer);
|
|
LibXtst.XTestFakeButtonEvent(Display, 1, false, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendMouseMove(double percentX, double percentY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
LibXtst.XTestFakeMotionEvent(Display,
|
|
viewer.Capturer.GetSelectedScreenIndex(),
|
|
(int)(viewer.Capturer.CurrentScreenBounds.Width * percentX),
|
|
(int)(viewer.Capturer.CurrentScreenBounds.Height * percentY),
|
|
0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendMouseWheel(int deltaY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
if (deltaY > 0)
|
|
{
|
|
LibXtst.XTestFakeButtonEvent(Display, 4, true, 0);
|
|
LibXtst.XTestFakeButtonEvent(Display, 4, false, 0);
|
|
}
|
|
else
|
|
{
|
|
LibXtst.XTestFakeButtonEvent(Display, 5, true, 0);
|
|
LibXtst.XTestFakeButtonEvent(Display, 5, false, 0);
|
|
}
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendRightMouseDown(double percentX, double percentY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
SendMouseMove(percentX, percentY, viewer);
|
|
LibXtst.XTestFakeButtonEvent(Display, 3, true, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendRightMouseUp(double percentX, double percentY, Viewer viewer)
|
|
{
|
|
try
|
|
{
|
|
SendMouseMove(percentX, percentY, viewer);
|
|
LibXtst.XTestFakeButtonEvent(Display, 3, false, 0);
|
|
LibX11.XSync(Display, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public void SendText(string transferText, Viewer viewer)
|
|
{
|
|
foreach (var key in transferText)
|
|
{
|
|
SendKeyDown(key.ToString(), viewer);
|
|
SendKeyUp(key.ToString(), viewer);
|
|
}
|
|
}
|
|
|
|
public void SetKeyStatesUp()
|
|
{
|
|
// Not implemented.
|
|
}
|
|
|
|
public void ToggleBlockInput(bool toggleOn)
|
|
{
|
|
// Not implemented.
|
|
}
|
|
|
|
private string ConvertJavaScriptKeyToX11Key(string key)
|
|
{
|
|
string keySym;
|
|
switch (key)
|
|
{
|
|
case "ArrowDown":
|
|
keySym = "Down";
|
|
break;
|
|
case "ArrowUp":
|
|
keySym = "Up";
|
|
break;
|
|
case "ArrowLeft":
|
|
keySym = "Left";
|
|
break;
|
|
case "ArrowRight":
|
|
keySym = "Right";
|
|
break;
|
|
case "Enter":
|
|
keySym = "Return";
|
|
break;
|
|
case "Esc":
|
|
keySym = "Escape";
|
|
break;
|
|
case "Alt":
|
|
keySym = "Alt_L";
|
|
break;
|
|
case "Control":
|
|
keySym = "Control_L";
|
|
break;
|
|
case "Shift":
|
|
keySym = "Shift_L";
|
|
break;
|
|
case "PAUSE":
|
|
keySym = "Pause";
|
|
break;
|
|
case "BREAK":
|
|
keySym = "Break";
|
|
break;
|
|
case "Backspace":
|
|
keySym = "BackSpace";
|
|
break;
|
|
case "Tab":
|
|
keySym = "Tab";
|
|
break;
|
|
case "CapsLock":
|
|
keySym = "Caps_Lock";
|
|
break;
|
|
case "Delete":
|
|
keySym = "Delete";
|
|
break;
|
|
case "PageUp":
|
|
keySym = "Page_Up";
|
|
break;
|
|
case "PageDown":
|
|
keySym = "Page_Down";
|
|
break;
|
|
case "NumLock":
|
|
keySym = "Num_Lock";
|
|
break;
|
|
case "ScrollLock":
|
|
keySym = "Scroll_Lock";
|
|
break;
|
|
case "ContextMenu":
|
|
keySym = "Menu";
|
|
break;
|
|
case " ":
|
|
keySym = "space";
|
|
break;
|
|
case "!":
|
|
keySym = "exclam";
|
|
break;
|
|
case "\"":
|
|
keySym = "quotedbl";
|
|
break;
|
|
case "#":
|
|
keySym = "numbersign";
|
|
break;
|
|
case "$":
|
|
keySym = "dollar";
|
|
break;
|
|
case "%":
|
|
keySym = "percent";
|
|
break;
|
|
case "&":
|
|
keySym = "ampersand";
|
|
break;
|
|
case "'":
|
|
keySym = "apostrophe";
|
|
break;
|
|
case "(":
|
|
keySym = "parenleft";
|
|
break;
|
|
case ")":
|
|
keySym = "parenright";
|
|
break;
|
|
case "*":
|
|
keySym = "asterisk";
|
|
break;
|
|
case "+":
|
|
keySym = "plus";
|
|
break;
|
|
case ",":
|
|
keySym = "comma";
|
|
break;
|
|
case "-":
|
|
keySym = "minus";
|
|
break;
|
|
case ".":
|
|
keySym = "period";
|
|
break;
|
|
case "/":
|
|
keySym = "slash";
|
|
break;
|
|
case ":":
|
|
keySym = "colon";
|
|
break;
|
|
case ";":
|
|
keySym = "semicolon";
|
|
break;
|
|
case "<":
|
|
keySym = "less";
|
|
break;
|
|
case "=":
|
|
keySym = "equal";
|
|
break;
|
|
case ">":
|
|
keySym = "greater";
|
|
break;
|
|
case "?":
|
|
keySym = "question";
|
|
break;
|
|
case "@":
|
|
keySym = "at";
|
|
break;
|
|
case "[":
|
|
keySym = "bracketleft";
|
|
break;
|
|
case "\\":
|
|
keySym = "backslash";
|
|
break;
|
|
case "]":
|
|
keySym = "bracketright";
|
|
break;
|
|
case "_":
|
|
keySym = "underscore";
|
|
break;
|
|
case "`":
|
|
keySym = "grave";
|
|
break;
|
|
case "{":
|
|
keySym = "braceleft";
|
|
break;
|
|
case "|":
|
|
keySym = "bar";
|
|
break;
|
|
case "}":
|
|
keySym = "braceright";
|
|
break;
|
|
case "~":
|
|
keySym = "asciitilde";
|
|
break;
|
|
default:
|
|
keySym = key;
|
|
break;
|
|
}
|
|
return keySym;
|
|
}
|
|
|
|
}
|
|
}
|