From b30c73f52b128d1e22324ee9fe6ba121264a4b8a Mon Sep 17 00:00:00 2001 From: X9VoiD Date: Fri, 28 Aug 2020 02:33:48 +0800 Subject: [PATCH] Repurpose WindowsInk to TouchEmu --- .gitmodules | 3 + .modules/OpenTabletDriver | 1 + OTDPlugins.sln | 2 +- {WindowsInk => TouchEmu}/NativeMethods.cs | 14 ++-- WindowsInk/Pen.cs => TouchEmu/Touch.cs | 36 ++++---- TouchEmu/TouchEmu.cs | 84 +++++++++++++++++++ .../TouchEmu.csproj | 2 +- WindowsInk/WindowsInk.cs | 80 ------------------ 8 files changed, 118 insertions(+), 104 deletions(-) create mode 100644 .gitmodules create mode 160000 .modules/OpenTabletDriver rename {WindowsInk => TouchEmu}/NativeMethods.cs (89%) rename WindowsInk/Pen.cs => TouchEmu/Touch.cs (78%) create mode 100644 TouchEmu/TouchEmu.cs rename WindowsInk/WindowsInk.csproj => TouchEmu/TouchEmu.csproj (67%) delete mode 100644 WindowsInk/WindowsInk.cs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e4826f6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".modules/OpenTabletDriver"] + path = .modules/OpenTabletDriver + url = https://github.com/InfinityGhost/OpenTabletDriver \ No newline at end of file diff --git a/.modules/OpenTabletDriver b/.modules/OpenTabletDriver new file mode 160000 index 0000000..5ee2bae --- /dev/null +++ b/.modules/OpenTabletDriver @@ -0,0 +1 @@ +Subproject commit 5ee2bae3d188cf6c468cf93df9a5815d2daa5ef1 diff --git a/OTDPlugins.sln b/OTDPlugins.sln index c5e1a84..425be81 100644 --- a/OTDPlugins.sln +++ b/OTDPlugins.sln @@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MLFilter", "MLFilter\MLFilt EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OemKill", "OemKill\OemKill.csproj", "{4EC8FA2D-0CCC-4FC3-A32A-BC063924A803}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInk", "WindowsInk\WindowsInk.csproj", "{FC135341-4870-4555-8917-7248CFE07FCC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TouchEmu", "TouchEmu\TouchEmu.csproj", "{FC135341-4870-4555-8917-7248CFE07FCC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/WindowsInk/NativeMethods.cs b/TouchEmu/NativeMethods.cs similarity index 89% rename from WindowsInk/NativeMethods.cs rename to TouchEmu/NativeMethods.cs index b6f8004..5b491fa 100644 --- a/WindowsInk/NativeMethods.cs +++ b/TouchEmu/NativeMethods.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace WindowsInk +namespace TouchEmu { using HANDLE = IntPtr; using HWND = IntPtr; @@ -143,10 +143,10 @@ namespace WindowsInk public unsafe struct POINTER_DEVICE_INFO { public DWORD displayOrientation; - public IntPtr device; + public void* device; public POINTER_DEVICE_TYPE pointerDeviceType; - public IntPtr monitor; - public ulong startingCursorId; + public void* monitor; + public uint startingCursorId; public ushort maxActiveContacts; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 520)] @@ -164,6 +164,10 @@ namespace WindowsInk public static extern bool InjectSyntheticPointerInput(IntPtr device, [In, MarshalAs(UnmanagedType.LPArray)] POINTER_TYPE_INFO[] pointerInfo, uint count); [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] - public static extern bool GetPointerDevices(ref uint deviceCount, IntPtr pointerDevices); + [return: MarshalAs(UnmanagedType.Bool)] + public static unsafe extern bool GetPointerDevices(out uint deviceCount, [In, Out, MarshalAs(UnmanagedType.LPArray)] POINTER_DEVICE_INFO[] pointerDevices); + + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr GetForegroundWindow(); } } \ No newline at end of file diff --git a/WindowsInk/Pen.cs b/TouchEmu/Touch.cs similarity index 78% rename from WindowsInk/Pen.cs rename to TouchEmu/Touch.cs index 14dd348..96a3e0e 100644 --- a/WindowsInk/Pen.cs +++ b/TouchEmu/Touch.cs @@ -2,38 +2,39 @@ using System; using System.Runtime.InteropServices; using TabletDriverPlugin; -namespace WindowsInk +namespace TouchEmu { - public static class Pen + public static class Touch { private static IntPtr _penHandle; private static POINTER_TYPE_INFO[] pointer; private static uint _pointerId; private static IntPtr _sourceDevice; - public static void Init() + public static unsafe void Init() { - uint count = 0; - NativeMethods.GetPointerDevices(ref count, out var pointerDevices); - foreach (var device in pointerDevices) + NativeMethods.GetPointerDevices(out uint count, null); + POINTER_DEVICE_INFO[] pointerDevices = new POINTER_DEVICE_INFO[count]; + NativeMethods.GetPointerDevices(out count, pointerDevices); + for (int i = 0; i < count; i++) { + var device = pointerDevices[i]; if (device.pointerDeviceType == POINTER_DEVICE_TYPE.EXTERNAL_PEN || device.pointerDeviceType == POINTER_DEVICE_TYPE.INTEGRATED_PEN) { _pointerId = (uint)device.startingCursorId; - _sourceDevice = device.device; + _sourceDevice = new IntPtr(device.device); } } - Log.Write("WindowsInk", "Pen created", LogLevel.Debug); var _pointerInfo = new POINTER_INFO { pointerType = POINTER_INPUT_TYPE.PT_PEN, pointerId = _pointerId, frameId = 0, pointerFlags = POINTER_FLAGS.NONE, - sourceDevice = IntPtr.Zero, - hwndTarget = IntPtr.Zero, + sourceDevice = _sourceDevice, + hwndTarget = NativeMethods.GetForegroundWindow(), ptPixelLocation = new POINT(), ptPixelLocationRaw = new POINT(), dwTime = 0, @@ -67,9 +68,7 @@ namespace WindowsInk _penHandle = NativeMethods.CreateSyntheticPointerDevice(POINTER_INPUT_TYPE.PT_PEN, 1, POINTER_FEEDBACK_MODE.INDIRECT); var err = Marshal.GetLastWin32Error(); if (err < 0 || _penHandle == IntPtr.Zero) - Log.Write("WindowsInk", "Failed creating synthetic pointer. Reason: " + err, LogLevel.Error); - else - Log.Write("WindowsInk", "Pen handle retrieved successfully", LogLevel.Debug); + throw new Exception("Failed to create handle."); // Notify WindowsInk ClearPointerFlags(POINTER_FLAGS.NEW); @@ -83,16 +82,19 @@ namespace WindowsInk { if (!NativeMethods.InjectSyntheticPointerInput(_penHandle, pointer, 1)) { - Log.Write("WindowsInk", "Injection Failed. Reason: " + Marshal.GetLastWin32Error()); + throw new Exception($"Input injection failed. Reason: {Marshal.GetLastWin32Error()}"); } } + public static void SetTarget() + { + pointer[0].penInfo.pointerInfo.hwndTarget = NativeMethods.GetForegroundWindow(); + } + public static void SetPosition(POINT point) { pointer[0].penInfo.pointerInfo.ptPixelLocation = point; pointer[0].penInfo.pointerInfo.ptPixelLocationRaw = point; - // pointer[0].penInfo.pointerInfo.ptHimetricLocation = point; - // pointer[0].penInfo.pointerInfo.ptHimetricLocationRaw = point; } public static void SetPressure(uint pressure) @@ -120,4 +122,4 @@ namespace WindowsInk pointer[0].penInfo.pointerInfo.pointerFlags = flags; } } -} \ No newline at end of file +} diff --git a/TouchEmu/TouchEmu.cs b/TouchEmu/TouchEmu.cs new file mode 100644 index 0000000..0a84ba9 --- /dev/null +++ b/TouchEmu/TouchEmu.cs @@ -0,0 +1,84 @@ +using TabletDriverPlugin; +using TabletDriverPlugin.Attributes; +using TabletDriverPlugin.Output; +using TabletDriverPlugin.Platform.Pointer; + +namespace TouchEmu +{ + public static class TouchState + { + public static IVirtualTablet touchPointer = new TouchPointerHandler(); + } + + [PluginName("Touch Emu"), SupportedPlatform(PluginPlatform.Windows)] + public class TouchOutputMode : AbsoluteOutputMode + { + public override IVirtualTablet VirtualTablet => TouchState.touchPointer; + } + + public class TouchPointerHandler : IVirtualTablet, IPressureHandler + { + private bool _inContact; + private bool _lastContact; + + public TouchPointerHandler() + { + Touch.Init(); + _inContact = false; + _lastContact = false; + } + + public void MouseDown(MouseButton button) + { + return; + } + + public void MouseUp(MouseButton button) + { + return; + } + + public void SetPosition(Point pos) + { + Touch.SetPosition(new POINT((int)pos.X, (int)pos.Y)); + if (_inContact != _lastContact) + { + if (_inContact) + { + Touch.UnsetPointerFlags(POINTER_FLAGS.UP | POINTER_FLAGS.UPDATE); + Touch.SetPointerFlags(POINTER_FLAGS.DOWN); + _lastContact = _inContact; + } + else + { + Touch.UnsetPointerFlags(POINTER_FLAGS.DOWN | POINTER_FLAGS.UPDATE); + Touch.SetPointerFlags(POINTER_FLAGS.UP); + _lastContact = _inContact; + } + } + else + { + Touch.SetPointerFlags(POINTER_FLAGS.UPDATE); + } + Touch.SetTarget(); + Touch.Inject(); + } + + public void SetPressure(float percentage) + { + var pressure = (uint)(percentage * 1024); + if (pressure > 0) + { + Touch.SetPressure(pressure); + Touch.SetPointerFlags(POINTER_FLAGS.INCONTACT | POINTER_FLAGS.FIRSTBUTTON); + _inContact = true; + } + else + { + Touch.SetPressure(1); + Touch.UnsetPointerFlags(POINTER_FLAGS.INCONTACT | POINTER_FLAGS.FIRSTBUTTON); + _inContact = false; + } + } + } +} \ No newline at end of file diff --git a/WindowsInk/WindowsInk.csproj b/TouchEmu/TouchEmu.csproj similarity index 67% rename from WindowsInk/WindowsInk.csproj rename to TouchEmu/TouchEmu.csproj index 83617eb..594a67d 100644 --- a/WindowsInk/WindowsInk.csproj +++ b/TouchEmu/TouchEmu.csproj @@ -6,7 +6,7 @@ - + diff --git a/WindowsInk/WindowsInk.cs b/WindowsInk/WindowsInk.cs deleted file mode 100644 index 1e436d6..0000000 --- a/WindowsInk/WindowsInk.cs +++ /dev/null @@ -1,80 +0,0 @@ -using TabletDriverPlugin; -using TabletDriverPlugin.Attributes; -using TabletDriverPlugin.Output; -using TabletDriverPlugin.Platform.Pointer; - -namespace WindowsInk -{ - public static class InkState - { - public static IPointerHandler inkPointer = new InkPointerHandler(); - } - - [PluginName("Windows Ink"), SupportedPlatform(PluginPlatform.Windows)] - public class InkOutputMode : AbsoluteOutputMode - { - public override IPointerHandler PointerHandler => InkState.inkPointer; - } - - public class InkPointerHandler : IPointerHandler, IPressureHandler - { - private Point _lastPos; - private bool _inContact; - private bool _lastContact; - - public InkPointerHandler() - { - Pen.Init(); - _inContact = false; - _lastContact = false; - } - - public Point GetPosition() - { - return _lastPos; - } - - public void SetPosition(Point pos) - { - Pen.SetPosition(new POINT((int)pos.X, (int)pos.Y)); - if (_inContact != _lastContact) - { - if (_inContact) - { - Pen.UnsetPointerFlags(POINTER_FLAGS.UP | POINTER_FLAGS.UPDATE); - Pen.SetPointerFlags(POINTER_FLAGS.DOWN); - _lastContact = _inContact; - } - else - { - Pen.UnsetPointerFlags(POINTER_FLAGS.DOWN | POINTER_FLAGS.UPDATE); - Pen.SetPointerFlags(POINTER_FLAGS.UP); - _lastContact = _inContact; - } - } - else - { - Pen.SetPointerFlags(POINTER_FLAGS.UPDATE); - } - Pen.Inject(); - _lastPos = pos; - } - - public void SetPressure(float percentage) - { - var pressure = (uint)(percentage * 1024); - if (pressure > 0) - { - Pen.SetPressure(pressure); - Pen.SetPointerFlags(POINTER_FLAGS.INCONTACT | POINTER_FLAGS.FIRSTBUTTON); - _inContact = true; - } - else - { - Pen.SetPressure(1); - Pen.UnsetPointerFlags(POINTER_FLAGS.INCONTACT | POINTER_FLAGS.FIRSTBUTTON); - _inContact = false; - } - } - } -} \ No newline at end of file