VoiDPlugins/TouchEmu/Touch.cs

125 lines
4.1 KiB
C#
Raw Normal View History

using System;
2020-08-15 22:21:08 +08:00
using System.Runtime.InteropServices;
2020-10-15 21:25:17 +08:00
namespace VoiDPlugins.TouchEmu
{
2020-08-28 02:33:48 +08:00
public static class Touch
{
2020-08-15 22:21:08 +08:00
private static IntPtr _penHandle;
private static POINTER_TYPE_INFO[] pointer;
private static uint _pointerId;
private static IntPtr _sourceDevice;
2020-08-28 02:33:48 +08:00
public static unsafe void Init()
{
2020-08-28 02:33:48 +08:00
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++)
2020-08-15 22:21:08 +08:00
{
2020-08-28 02:33:48 +08:00
var device = pointerDevices[i];
2020-08-15 22:21:08 +08:00
if (device.pointerDeviceType == POINTER_DEVICE_TYPE.EXTERNAL_PEN ||
device.pointerDeviceType == POINTER_DEVICE_TYPE.INTEGRATED_PEN)
{
_pointerId = (uint)device.startingCursorId;
2020-08-28 02:33:48 +08:00
_sourceDevice = new IntPtr(device.device);
2020-08-15 22:21:08 +08:00
}
}
var _pointerInfo = new POINTER_INFO
{
pointerType = POINTER_INPUT_TYPE.PT_PEN,
2020-08-15 22:21:08 +08:00
pointerId = _pointerId,
frameId = 0,
2020-08-15 22:21:08 +08:00
pointerFlags = POINTER_FLAGS.NONE,
2020-08-28 02:33:48 +08:00
sourceDevice = _sourceDevice,
hwndTarget = NativeMethods.GetForegroundWindow(),
ptPixelLocation = new POINT(),
ptPixelLocationRaw = new POINT(),
dwTime = 0,
2020-08-15 22:21:08 +08:00
historyCount = 0,
dwKeyStates = 0,
PerformanceCount = 0,
ButtonChangeType = POINTER_BUTTON_CHANGE_TYPE.NONE
};
2020-08-15 22:21:08 +08:00
var _penInfo = new POINTER_PEN_INFO
{
pointerInfo = _pointerInfo,
pointerFlags = PEN_FLAGS.NONE,
2020-08-15 22:21:08 +08:00
penMask = PEN_MASK.PRESSURE,
pressure = 512,
rotation = 0,
tiltX = 0,
tiltY = 0
};
2020-08-15 22:21:08 +08:00
pointer = new POINTER_TYPE_INFO[]
{
new POINTER_TYPE_INFO
{
type = POINTER_INPUT_TYPE.PT_PEN,
penInfo = _penInfo
}
};
// Retrieve handle to custom pen
_penHandle = NativeMethods.CreateSyntheticPointerDevice(POINTER_INPUT_TYPE.PT_PEN, 1, POINTER_FEEDBACK_MODE.INDIRECT);
2020-08-15 22:21:08 +08:00
var err = Marshal.GetLastWin32Error();
if (err < 0 || _penHandle == IntPtr.Zero)
2020-08-28 02:33:48 +08:00
throw new Exception("Failed to create handle.");
// Notify WindowsInk
2020-08-15 22:21:08 +08:00
ClearPointerFlags(POINTER_FLAGS.NEW);
Inject();
// Back to normal state
2020-08-15 22:21:08 +08:00
ClearPointerFlags(POINTER_FLAGS.INRANGE | POINTER_FLAGS.PRIMARY);
}
2020-08-15 22:21:08 +08:00
public static void Inject()
{
2020-08-15 22:21:08 +08:00
if (!NativeMethods.InjectSyntheticPointerInput(_penHandle, pointer, 1))
{
2020-08-28 02:33:48 +08:00
throw new Exception($"Input injection failed. Reason: {Marshal.GetLastWin32Error()}");
}
}
2020-08-28 02:33:48 +08:00
public static void SetTarget()
{
pointer[0].penInfo.pointerInfo.hwndTarget = NativeMethods.GetForegroundWindow();
}
2020-08-15 22:21:08 +08:00
public static void SetPosition(POINT point)
{
pointer[0].penInfo.pointerInfo.ptPixelLocation = point;
pointer[0].penInfo.pointerInfo.ptPixelLocationRaw = point;
}
public static void SetPressure(uint pressure)
{
2020-08-15 22:21:08 +08:00
pointer[0].penInfo.pressure = pressure;
}
2020-08-15 22:21:08 +08:00
public static void SetPointerFlags(POINTER_FLAGS flags)
{
2020-08-15 22:21:08 +08:00
pointer[0].penInfo.pointerInfo.pointerFlags |= flags;
}
2020-08-15 22:21:08 +08:00
public static void UnsetPointerFlags(POINTER_FLAGS flags)
{
2020-08-15 22:21:08 +08:00
pointer[0].penInfo.pointerInfo.pointerFlags &= ~flags;
}
2020-08-15 22:21:08 +08:00
public static void ClearPointerFlags()
{
2020-08-15 22:21:08 +08:00
pointer[0].penInfo.pointerInfo.pointerFlags = 0;
}
2020-08-15 22:21:08 +08:00
public static void ClearPointerFlags(POINTER_FLAGS flags)
{
2020-08-15 22:21:08 +08:00
pointer[0].penInfo.pointerInfo.pointerFlags = flags;
}
}
2020-08-28 02:33:48 +08:00
}