@ -42,10 +42,15 @@ namespace Avalonia.X11
public DeviceInfo ( XIDeviceInfo info )
{
Id = info . Deviceid ;
Update ( info . Classes , info . NumClasses ) ;
UpdateCore ( info . Classes , info . NumClasses ) ;
}
public virtual void Update ( XIAnyClassInfo * * classes , int num )
{
UpdateCore ( classes , num ) ;
}
private void UpdateCore ( XIAnyClassInfo * * classes , int num )
{
var valuators = new List < XIValuatorClassInfo > ( ) ;
var scrollers = new List < XIScrollClassInfo > ( ) ;
@ -73,8 +78,49 @@ namespace Avalonia.X11
private class PointerDeviceInfo : DeviceInfo
{
public PointerDeviceInfo ( XIDeviceInfo info ) : base ( info )
public PointerDeviceInfo ( XIDeviceInfo info , X11Info x11Info ) : base ( info )
{
_ x11 = x11Info ;
UpdateKnownValuator ( ) ;
}
private readonly X11Info _ x11 ;
private void UpdateKnownValuator ( )
{
// ABS_MT_TOUCH_MAJOR ABS_MT_TOUCH_MINOR
// https://www.kernel.org/doc/html/latest/input/multi-touch-protocol.html
var touchMajorAtom = XInternAtom ( _ x11 . Display , "Abs MT Touch Major" , false ) ;
var touchMinorAtom = XInternAtom ( _ x11 . Display , "Abs MT Touch Minor" , false ) ;
var pressureAtom = XInternAtom ( _ x11 . Display , "Abs MT Pressure" , false ) ;
PressureXIValuatorClassInfo = null ;
TouchMajorXIValuatorClassInfo = null ;
TouchMinorXIValuatorClassInfo = null ;
foreach ( var xiValuatorClassInfo in Valuators )
{
if ( xiValuatorClassInfo . Label = = pressureAtom )
{
PressureXIValuatorClassInfo = xiValuatorClassInfo ;
}
else if ( xiValuatorClassInfo . Label = = touchMajorAtom )
{
TouchMajorXIValuatorClassInfo = xiValuatorClassInfo ;
}
else if ( xiValuatorClassInfo . Label = = touchMinorAtom )
{
TouchMinorXIValuatorClassInfo = xiValuatorClassInfo ;
}
}
}
public override void Update ( XIAnyClassInfo * * classes , int num )
{
base . Update ( classes , num ) ;
UpdateKnownValuator ( ) ;
}
public bool HasScroll ( ParsedDeviceEvent ev )
@ -94,16 +140,15 @@ namespace Avalonia.X11
return false ;
}
public XIValuatorClassInfo ? PressureXIValuatorClassInfo { get ; private set ; }
public XIValuatorClassInfo ? TouchMajorXIValuatorClassInfo { get ; private set ; }
public XIValuatorClassInfo ? TouchMinorXIValuatorClassInfo { get ; private set ; }
}
private PointerDeviceInfo _ pointerDevice ;
private AvaloniaX11Platform _ platform ;
private XIValuatorClassInfo ? _ pressureXIValuatorClassInfo ;
private XIValuatorClassInfo ? _ touchMajorXIValuatorClassInfo ;
private XIValuatorClassInfo ? _ touchMinorXIValuatorClassInfo ;
public bool Init ( AvaloniaX11Platform platform )
{
_ platform = platform ;
@ -115,42 +160,12 @@ namespace Avalonia.X11
{
if ( devices [ c ] . Use = = XiDeviceType . XIMasterPointer )
{
_ pointerDevice = new PointerDeviceInfo ( devices [ c ] ) ;
_ pointerDevice = new PointerDeviceInfo ( devices [ c ] , _ x11 ) ;
break ;
}
}
if ( _ pointerDevice = = null )
return false ;
if ( _ multitouch )
{
// ABS_MT_TOUCH_MAJOR ABS_MT_TOUCH_MINOR
// https://www.kernel.org/doc/html/latest/input/multi-touch-protocol.html
var touchMajorAtom = XInternAtom ( _ x11 . Display , "Abs MT Touch Major" , false ) ;
var touchMinorAtom = XInternAtom ( _ x11 . Display , "Abs MT Touch Minor" , false ) ;
var pressureAtom = XInternAtom ( _ x11 . Display , "Abs MT Pressure" , false ) ;
var pressureXIValuatorClassInfo = _ pointerDevice . Valuators . FirstOrDefault ( t = > t . Label = = pressureAtom ) ;
if ( pressureXIValuatorClassInfo . Label = = pressureAtom )
{
// Why check twice? The XIValuatorClassInfo is struct, so the FirstOrDefault will return the default struct when not found.
_ pressureXIValuatorClassInfo = pressureXIValuatorClassInfo ;
}
var touchMajorXIValuatorClassInfo = _ pointerDevice . Valuators . FirstOrDefault ( t = > t . Label = = touchMajorAtom ) ;
if ( touchMajorXIValuatorClassInfo . Label = = touchMajorAtom )
{
_ touchMajorXIValuatorClassInfo = touchMajorXIValuatorClassInfo ;
}
var touchMinorXIValuatorClassInfo = _ pointerDevice . Valuators . FirstOrDefault ( t = > t . Label = = touchMinorAtom ) ;
if ( touchMinorXIValuatorClassInfo . Label = = touchMinorAtom )
{
_ touchMinorXIValuatorClassInfo = touchMinorXIValuatorClassInfo ;
}
}
/ *
int mask = 0 ;
@ -275,7 +290,7 @@ namespace Avalonia.X11
Position = ev . Position
} ;
if ( _ pressureXIValuatorClassInfo is { } valuatorClassInfo )
if ( _ pointerDevice . P ressureXIValuatorClassInfo is { } valuatorClassInfo )
{
if ( ev . Valuators . TryGetValue ( valuatorClassInfo . Number , out var pressureValue ) )
{
@ -285,7 +300,7 @@ namespace Avalonia.X11
}
}
if ( _ touchMajorXIValuatorClassInfo is { } touchMajorXIValuatorClassInfo )
if ( _ poin terDevice . T ouchMajorXIValuatorClassInfo is { } touchMajorXIValuatorClassInfo )
{
double? touchMajor = null ;
double? touchMinor = null ;
@ -308,7 +323,7 @@ namespace Avalonia.X11
if ( touchMajor ! = null )
{
if ( _ touchMinorXIValuatorClassInfo is { } touchMinorXIValuatorClassInfo )
if ( _ poin terDevice . T ouchMinorXIValuatorClassInfo is { } touchMinorXIValuatorClassInfo )
{
if ( ev . Valuators . TryGetValue ( touchMinorXIValuatorClassInfo . Number , out var touchMinorValue ) )
{