Add resync capability

This commit is contained in:
X9VoiD 2022-05-19 14:32:25 +08:00
parent bbc7c721da
commit 93370f1cc6
7 changed files with 120 additions and 26 deletions

View file

@ -21,15 +21,23 @@ namespace VoiDPlugins.OutputMode
public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen)
{
_instance = new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
SharedStore.GetStore(tabletReference, STORE_KEY).Add(INSTANCE, _instance);
if (SharedStore.GetStore(tabletReference, STORE_KEY).TryAdd(INSTANCE, _instance))
{
_rawPointer = _instance.Pointer;
_conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height);
}
else
{
_instance = null;
}
}
public void SetPosition(Vector2 pos)
{
if (pos == _prev)
return;
if (_rawPointer is null)
return;
pos *= _conversionFactor;
_rawPointer->X = (ushort)pos.X;
@ -44,10 +52,10 @@ namespace VoiDPlugins.OutputMode
public void Flush()
{
if (_dirty)
if (_dirty && _instance is not null)
{
_dirty = false;
_instance!.Write();
_instance.Write();
}
}
}

View file

@ -19,14 +19,22 @@ namespace VoiDPlugins.OutputMode
public VMultiRelativePointer(TabletReference tabletReference)
{
_instance = new VMultiInstance<RelativeInputReport>("VMultiRel", new RelativeInputReport());
SharedStore.GetStore(tabletReference, STORE_KEY).Add(INSTANCE, _instance);
if (SharedStore.GetStore(tabletReference, STORE_KEY).TryAdd(INSTANCE, _instance))
{
_rawPointer = _instance.Pointer;
}
else
{
_instance = null;
}
}
public void SetPosition(Vector2 delta)
{
if (delta == Vector2.Zero && _prev == Vector2.Zero)
return;
if (_rawPointer is null)
return;
delta += _error;
_error = new Vector2(delta.X % 1, delta.Y % 1);
@ -42,10 +50,10 @@ namespace VoiDPlugins.OutputMode
public void Flush()
{
if (_dirty)
if (_dirty && _instance is not null)
{
_dirty = false;
_instance!.Write();
_instance.Write();
}
}
}

View file

@ -0,0 +1,29 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using VoiDPlugins.Library.VMulti;
using VoiDPlugins.Library.VMulti.Device;
namespace VoiDPlugins.OutputMode
{
internal unsafe class ThinVMultiAbsPointer
{
private readonly AbsoluteInputReport* _rawPointer;
private readonly VMultiInstance<AbsoluteInputReport>? _instance;
private Vector2 _conversionFactor;
public ThinVMultiAbsPointer(IVirtualScreen virtualScreen)
{
_instance = new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
_rawPointer = _instance.Pointer;
_conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height);
}
public void SetPosition(Vector2 pos)
{
pos *= _conversionFactor;
_rawPointer->X = (ushort)pos.X;
_rawPointer->Y = (ushort)pos.Y;
_instance!.Write();
}
}
}

View file

@ -10,7 +10,8 @@ namespace VoiDPlugins.OutputMode
private readonly Vector2 _conversionFactor;
private Vector2 _prev;
public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen) : base("Windows Ink", tabletReference)
public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen)
: base("Windows Ink", tabletReference, screen)
{
_conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height);
}
@ -19,6 +20,8 @@ namespace VoiDPlugins.OutputMode
{
if (pos == _prev)
return;
if (Instance is null)
return;
Instance!.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
pos *= _conversionFactor;

View file

@ -1,4 +1,6 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Attributes;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
using OpenTabletDriver.Plugin.Tablet;
using VoiDPlugins.Library.VMulti;
@ -10,50 +12,86 @@ namespace VoiDPlugins.OutputMode
{
public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer
{
private readonly IVirtualScreen _screen;
private ThinVMultiAbsPointer? _osPointer;
protected DigitizerInputReport* RawPointer { get; }
protected VMultiInstance<DigitizerInputReport> Instance { get; }
protected SharedStore SharedStore { get; }
protected VMultiInstance<DigitizerInputReport>? Instance { get; }
protected SharedStore? SharedStore { get; }
protected bool Dirty { get; set; }
public WinInkBasePointer(string name, TabletReference tabletReference)
[Property("Sync")]
[ToolTip("Synchronize OS cursor with Windows Ink's current position when pen goes out of range.")]
[DefaultPropertyValue(true)]
public bool Sync
{
set => _osPointer = value ? new ThinVMultiAbsPointer(_screen) : null;
}
[Property("Forced Sync")]
[ToolTip("If this and \"Sync\" is enabled, the OS cursor will always be resynced with Windows Ink's current position.")]
[DefaultPropertyValue(false)]
public bool ForcedSync { get; set; }
public WinInkBasePointer(string name, TabletReference tabletReference, IVirtualScreen screen)
{
_screen = screen;
Instance = new VMultiInstance<DigitizerInputReport>(name, new DigitizerInputReport());
SharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
SharedStore.Add(INSTANCE, Instance);
SharedStore.Add(POINTER, this);
SharedStore.Add(ERASER_STATE, false);
SharedStore.Add(MANUAL_ERASER, false);
if (SharedStore.TryAdd(INSTANCE, Instance))
{
SharedStore.TryAdd(POINTER, this);
SharedStore.TryAdd(ERASER_STATE, false);
SharedStore.TryAdd(MANUAL_ERASER, false);
RawPointer = Instance.Pointer;
}
else
{
Instance = null;
SharedStore = null;
RawPointer = null;
}
}
public void SetEraser(bool isEraser)
{
if (!SharedStore.Get<bool>(MANUAL_ERASER))
if (!SharedStore?.Get<bool>(MANUAL_ERASER) ?? false)
{
WindowsInkButtonHandler.EraserStateTransition(SharedStore, Instance, isEraser);
WindowsInkButtonHandler.EraserStateTransition(SharedStore!, Instance!, isEraser);
}
}
public void SetPressure(float percentage)
{
if (RawPointer != null)
RawPointer->Pressure = (ushort)(percentage * 8191);
}
public void SetTilt(Vector2 tilt)
{
if (RawPointer != null)
{
RawPointer->XTilt = (byte)tilt.X;
RawPointer->YTilt = (byte)tilt.Y;
}
}
public void Reset()
{
if (RawPointer is not null && _osPointer is not null && !ForcedSync)
{
_osPointer.SetPosition(new Vector2(RawPointer->X, RawPointer->Y));
}
}
public void Flush()
{
if (Dirty)
if (RawPointer is not null && Dirty)
{
Dirty = false;
if (ForcedSync)
_osPointer?.SetPosition(new Vector2(RawPointer->X, RawPointer->Y));
Instance!.Write();
}
}

View file

@ -12,7 +12,8 @@ namespace VoiDPlugins.OutputMode
private Vector2 _error;
private Vector2 _prev;
public WinInkRelativePointer(TabletReference tabletReference, IVirtualScreen screen) : base("Windows Ink", tabletReference)
public WinInkRelativePointer(TabletReference tabletReference, IVirtualScreen screen)
: base("Windows Ink", tabletReference, screen)
{
_maxPoint = new Vector2(screen.Width, screen.Height);
_currentPoint = _maxPoint / 2;
@ -22,8 +23,10 @@ namespace VoiDPlugins.OutputMode
{
if (_prev == Vector2.Zero && delta == Vector2.Zero)
return;
if (Instance is null)
return;
Instance!.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
delta += _error;
_error = new Vector2(delta.X % 1, delta.Y % 1);
_currentPoint = Vector2.Clamp(_currentPoint + delta, Vector2.Zero, _maxPoint);

View file

@ -49,6 +49,11 @@ namespace VoiDPlugins.Library.VoiD
((IDictionary<int, object>)_sharedStore).Add(key, value);
}
public bool TryAdd(int key, object value)
{
return _sharedStore.TryAdd(key, value);
}
public void Add(KeyValuePair<int, object> item)
{
((ICollection<KeyValuePair<int, object>>)_sharedStore).Add(item);