Fix VMulti-based output modes

This commit is contained in:
X9VoiD 2022-01-12 23:25:16 +08:00
parent 148e542528
commit 8c96ec7537
15 changed files with 59 additions and 61 deletions

@ -1 +1 @@
Subproject commit 78e9d03766e61f986d3b510dfd3b23c74917d895
Subproject commit b8b346c4e50186f5f623beedb2fdb682600c2b61

View file

@ -11,17 +11,18 @@ namespace VoiDPlugins.OutputMode
public class VMultiAbsoluteMode : AbsoluteOutputMode
{
private VMultiAbsolutePointer? _pointer;
private IVirtualScreen? _virtualScreen;
[Resolved]
public IServiceProvider ServiceProvider
{
set => _pointer = new VMultiAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
set => _virtualScreen = (IVirtualScreen)value.GetService(typeof(IVirtualScreen))!;
}
[OnDependencyLoad]
public void Initialize()
{
_pointer!.Initialize(TabletReference);
_pointer = new VMultiAbsolutePointer(TabletReference, _virtualScreen!);
}
public override IAbsolutePointer Pointer

View file

@ -13,8 +13,7 @@ namespace VoiDPlugins.OutputMode
[OnDependencyLoad]
public void Initialize()
{
_pointer = new VMultiRelativePointer();
_pointer!.Initialize(TabletReference);
_pointer = new VMultiRelativePointer(TabletReference);
}
public override IRelativePointer Pointer

View file

@ -9,19 +9,15 @@ namespace VoiDPlugins.OutputMode
{
public unsafe class VMultiAbsolutePointer : IAbsolutePointer, ISynchronousPointer
{
private AbsoluteInputReport* _rawPointer;
private VMultiInstance<AbsoluteInputReport>? _instance;
private readonly AbsoluteInputReport* _rawPointer;
private readonly VMultiInstance<AbsoluteInputReport>? _instance;
private Vector2 _conversionFactor;
public VMultiAbsolutePointer(IVirtualScreen virtualScreen)
{
_conversionFactor = new Vector2(virtualScreen.Width, virtualScreen.Height) / (1 / 32767);
}
public void Initialize(TabletReference tabletReference)
public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen)
{
_instance = VMultiInstanceManager.RetrieveVMultiInstance("VMultiAbs", tabletReference, () => new AbsoluteInputReport());
_rawPointer = _instance.Pointer;
_conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height);
}
public void SetPosition(Vector2 pos)

View file

@ -8,11 +8,11 @@ namespace VoiDPlugins.OutputMode
{
public unsafe class VMultiRelativePointer : IRelativePointer, ISynchronousPointer
{
private RelativeInputReport* _rawPointer;
private VMultiInstance<RelativeInputReport>? _instance;
private readonly RelativeInputReport* _rawPointer;
private readonly VMultiInstance<RelativeInputReport>? _instance;
private Vector2 _error;
public void Initialize(TabletReference tabletReference)
public VMultiRelativePointer(TabletReference tabletReference)
{
_instance = VMultiInstanceManager.RetrieveVMultiInstance("VMultiRel", tabletReference, () => new RelativeInputReport());
_rawPointer = _instance.Pointer;

View file

@ -11,17 +11,18 @@ namespace VoiDPlugins.OutputMode
public class WinInkAbsoluteMode : AbsoluteOutputMode
{
private WinInkAbsolutePointer? _pointer;
private IVirtualScreen? _virtualScreen;
[Resolved]
public IServiceProvider ServiceProvider
{
set => _pointer = new WinInkAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
set => _virtualScreen = (IVirtualScreen)value.GetService(typeof(IVirtualScreen))!;
}
[OnDependencyLoad]
public void Initialize()
{
_pointer!.Initialize(TabletReference);
_pointer = new WinInkAbsolutePointer(TabletReference, _virtualScreen!);
}
public override IAbsolutePointer Pointer

View file

@ -11,17 +11,18 @@ namespace VoiDPlugins.OutputMode
public class WinInkRelativeMode : RelativeOutputMode
{
private WinInkRelativePointer? _pointer;
private IVirtualScreen? _virtualScreen;
[Resolved]
public IServiceProvider ServiceProvider
{
set => _pointer = new WinInkRelativePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
set => _virtualScreen = (IVirtualScreen)value.GetService(typeof(IVirtualScreen))!;
}
[OnDependencyLoad]
public void Initialize()
{
_pointer!.Initialize(TabletReference);
_pointer = new WinInkRelativePointer(TabletReference, _virtualScreen!);
}
public override IRelativePointer Pointer

View file

@ -1,6 +1,7 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
using OpenTabletDriver.Plugin.Tablet;
namespace VoiDPlugins.OutputMode
{
@ -8,13 +9,14 @@ namespace VoiDPlugins.OutputMode
{
private readonly Vector2 _conversionFactor;
public WinInkAbsolutePointer(IVirtualScreen screen)
public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen) : base(tabletReference)
{
_conversionFactor = new Vector2(screen.Width, screen.Height) / (1 / 32767);
_conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height);
}
public void SetPosition(Vector2 pos)
{
Instance!.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
pos *= _conversionFactor;
RawPointer->X = (ushort)pos.X;
RawPointer->Y = (ushort)pos.Y;

View file

@ -10,10 +10,10 @@ namespace VoiDPlugins.OutputMode
{
public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer
{
protected DigitizerInputReport* RawPointer { get; private set; }
protected VMultiInstance<DigitizerInputReport>? Instance { get; private set; }
protected DigitizerInputReport* RawPointer { get; }
protected VMultiInstance<DigitizerInputReport>? Instance { get; }
public void Initialize(TabletReference tabletReference)
public WinInkBasePointer(TabletReference tabletReference)
{
Instance = VMultiInstanceManager.RetrieveVMultiInstance("WindowsInk", tabletReference, () => new DigitizerInputReport());
Instance.InitializeData(POINTER, this);
@ -26,7 +26,7 @@ namespace VoiDPlugins.OutputMode
{
if (!Instance!.GetData<Boxed<bool>>(MANUAL_ERASER).Value)
{
WinInkButtonHandler.EraserStateTransition(Instance, ref GetEraser(), isEraser);
WindowsInkButtonHandler.EraserStateTransition(Instance, ref GetEraser(), isEraser);
}
}
@ -43,6 +43,7 @@ namespace VoiDPlugins.OutputMode
public void Reset()
{
Instance!.DisableButtonBit((int)WindowsInkButtonFlags.InRange);
}
public void Flush()

View file

@ -1,6 +1,7 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
using OpenTabletDriver.Plugin.Tablet;
namespace VoiDPlugins.OutputMode
{
@ -10,7 +11,7 @@ namespace VoiDPlugins.OutputMode
private Vector2 _currentPoint;
private Vector2 _error;
public WinInkRelativePointer(IVirtualScreen screen)
public WinInkRelativePointer(TabletReference tabletReference, IVirtualScreen screen) : base(tabletReference)
{
_maxPoint = new Vector2(screen.Width, screen.Height);
_currentPoint = _maxPoint / 2;
@ -18,6 +19,7 @@ namespace VoiDPlugins.OutputMode
public void SetPosition(Vector2 delta)
{
Instance!.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
delta += _error;
_error = new Vector2(delta.X % 1, delta.Y % 1);

View file

@ -1,4 +1,3 @@
using System;
using OpenTabletDriver.Plugin;
using OpenTabletDriver.Plugin.Attributes;
using OpenTabletDriver.Plugin.Tablet;
@ -10,7 +9,7 @@ using static VoiDPlugins.OutputMode.WindowsInkConstants;
namespace VoiDPlugins.OutputMode
{
[PluginName("Windows Ink")]
public unsafe class WinInkButtonHandler : IStateBinding
public unsafe partial class WindowsInkButtonHandler : IStateBinding
{
private VMultiInstance? _instance;
@ -25,16 +24,6 @@ namespace VoiDPlugins.OutputMode
[Property("Button"), PropertyValidated(nameof(ValidButtons))]
public string? Button { get; set; }
[Flags]
private enum ButtonBits : byte
{
Press = 1,
Barrel = 2,
Eraser = 4,
Invert = 8,
InRange = 16
}
public bool IsManuallySet { get; set; }
[TabletReference]
@ -51,11 +40,11 @@ namespace VoiDPlugins.OutputMode
switch (Button)
{
case "Pen Tip":
_instance!.EnableButtonBit((int)(eraserState.Value ? ButtonBits.Eraser : ButtonBits.Press));
_instance!.EnableButtonBit((int)(eraserState.Value ? WindowsInkButtonFlags.Eraser : WindowsInkButtonFlags.Press));
break;
case "Pen Button":
_instance!.EnableButtonBit((int)ButtonBits.Barrel);
_instance!.EnableButtonBit((int)WindowsInkButtonFlags.Barrel);
break;
case "Eraser (Toggle)":
@ -75,11 +64,11 @@ namespace VoiDPlugins.OutputMode
switch (Button)
{
case "Pen Tip":
_instance!.DisableButtonBit((int)(ButtonBits.Press | ButtonBits.Eraser));
_instance!.DisableButtonBit((int)(WindowsInkButtonFlags.Press | WindowsInkButtonFlags.Eraser));
break;
case "Pen Button":
_instance!.DisableButtonBit((int)ButtonBits.Barrel);
_instance!.DisableButtonBit((int)WindowsInkButtonFlags.Barrel);
break;
case "Eraser (Hold)":
@ -98,7 +87,7 @@ namespace VoiDPlugins.OutputMode
var pressure = report->Pressure;
// Send In-Range but no tips
instance.DisableButtonBit((int)(ButtonBits.Press | ButtonBits.Eraser));
instance.DisableButtonBit((int)(WindowsInkButtonFlags.Press | WindowsInkButtonFlags.Eraser));
report->Pressure = 0;
instance.Write();
@ -107,15 +96,15 @@ namespace VoiDPlugins.OutputMode
instance.Write();
// Send In-Range but no tips
instance.EnableButtonBit((int)ButtonBits.InRange);
instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
if (eraserState.Value)
instance.EnableButtonBit((int)ButtonBits.Invert);
instance.EnableButtonBit((int)WindowsInkButtonFlags.Invert);
instance.Write();
// Set Proper Report
if (VMultiInstance.HasBit(buttons, (int)(ButtonBits.Press | ButtonBits.Eraser)))
instance.EnableButtonBit((int)(eraserState.Value ? ButtonBits.Eraser : ButtonBits.Press));
if (VMultiInstance.HasBit(buttons, (int)(WindowsInkButtonFlags.Press | WindowsInkButtonFlags.Eraser)))
instance.EnableButtonBit((int)(eraserState.Value ? WindowsInkButtonFlags.Eraser : WindowsInkButtonFlags.Press));
report->Pressure = pressure;
}
}

View file

@ -0,0 +1,14 @@
using System;
namespace VoiDPlugins.OutputMode
{
[Flags]
public enum WindowsInkButtonFlags : byte
{
Press = 1,
Barrel = 2,
Eraser = 4,
Invert = 8,
InRange = 16
}
}

View file

@ -6,9 +6,9 @@ namespace VoiDPlugins.Library.VMulti.Device
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DigitizerInputReport
{
public DigitizerInputReport(byte reportID)
public DigitizerInputReport()
{
Header = new VMultiReportHeader(Unsafe.SizeOf<DigitizerInputReport>(), reportID);
Header = new VMultiReportHeader(Unsafe.SizeOf<DigitizerInputReport>(), 0x05);
X = 0;
Y = 0;
Pressure = 0;

View file

@ -6,9 +6,9 @@ namespace VoiDPlugins.Library.VMulti.Device
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct RelativeInputReport
{
public RelativeInputReport(byte reportID)
public RelativeInputReport()
{
Header = new VMultiReportHeader(Unsafe.SizeOf<RelativeInputReport>(), reportID);
Header = new VMultiReportHeader(Unsafe.SizeOf<RelativeInputReport>(), 0x04);
X = 0;
Y = 0;
WheelPos = 0;

View file

@ -19,7 +19,7 @@ namespace VoiDPlugins.Library.VMulti
Buffer = GC.AllocateArray<byte>(size, true);
Header = (VMultiReportHeader*)Unsafe.AsPointer(ref Buffer[0]);
_device = Retrieve(name);
_data = GC.AllocateArray<object>(32, true);
_data = new object[32];
}
public void Write()
@ -29,7 +29,6 @@ namespace VoiDPlugins.Library.VMulti
public void InitializeData<T>(int i, T data)
{
Check<T>();
_data[i] = data!;
}
@ -79,13 +78,6 @@ namespace VoiDPlugins.Library.VMulti
return VMultiDev;
}
[Conditional("DEBUG")]
private void Check<T>()
{
if (Unsafe.SizeOf<T>() > IntPtr.Size)
throw new InvalidOperationException();
}
}
public class VMultiInstance<T> : VMultiInstance where T : unmanaged