mirror of
https://github.com/vale981/VoiDPlugins
synced 2025-03-04 08:41:40 -05:00
Repurpose WindowsInk to TouchEmu
This commit is contained in:
parent
64e2271750
commit
b30c73f52b
8 changed files with 118 additions and 104 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule ".modules/OpenTabletDriver"]
|
||||
path = .modules/OpenTabletDriver
|
||||
url = https://github.com/InfinityGhost/OpenTabletDriver
|
1
.modules/OpenTabletDriver
Submodule
1
.modules/OpenTabletDriver
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 5ee2bae3d188cf6c468cf93df9a5815d2daa5ef1
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
84
TouchEmu/TouchEmu.cs
Normal file
84
TouchEmu/TouchEmu.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TabletDriverPlugin" Version="0.3.2" />
|
||||
<ProjectReference Include="../.modules/OpenTabletDriver/TabletDriverPlugin/TabletDriverPlugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue