22// See the LICENCE file in the repository root for full licence text.
33
44using System ;
5+ using System . Diagnostics ;
56using Android . Content ;
67using Android . Runtime ;
78using Org . Libsdl . App ;
1112using Android . Views ;
1213using AndroidX . Core . View ;
1314using AndroidX . Window . Layout ;
15+ using osu . Framework . Input . StateChanges ;
1416
1517namespace osu . Framework . Android
1618{
@@ -20,6 +22,10 @@ internal class AndroidGameSurface : SDLSurface
2022
2123 public BindableSafeArea SafeAreaPadding { get ; } = new BindableSafeArea ( ) ;
2224
25+ private const TabletPenDeviceType default_pen_device_type = TabletPenDeviceType . Direct ;
26+
27+ public volatile TabletPenDeviceType LastPenDeviceType = default_pen_device_type ;
28+
2329 public AndroidGameSurface ( AndroidGameActivity activity , Context ? context )
2430 : base ( context )
2531 {
@@ -117,5 +123,61 @@ private void updateSafeArea(WindowInsets? windowInsets)
117123 Bottom = windowArea . Bottom - usableWindowArea . Bottom ,
118124 } ;
119125 }
126+
127+ private TabletPenDeviceType getPenDeviceType ( MotionEvent e )
128+ {
129+ var device = e . Device ;
130+
131+ if ( device == null )
132+ return default_pen_device_type ;
133+
134+ return device . IsExternal ? TabletPenDeviceType . Indirect : TabletPenDeviceType . Direct ;
135+ }
136+
137+ /// <summary>
138+ /// Sets <see cref="LastPenDeviceType"/> iff <c>SDLGenericMotionListener_API14.onGenericMotion()</c> would call <c>onNativePen()</c>.
139+ /// </summary>
140+ public override bool DispatchGenericMotionEvent ( MotionEvent ? e )
141+ {
142+ Debug . Assert ( e != null ) ;
143+
144+ switch ( e . ActionMasked )
145+ {
146+ case MotionEventActions . HoverEnter :
147+ case MotionEventActions . HoverMove :
148+ case MotionEventActions . HoverExit :
149+ for ( int i = 0 ; i < e . PointerCount ; i ++ )
150+ {
151+ var toolType = e . GetToolType ( i ) ;
152+
153+ if ( toolType == MotionEventToolType . Stylus || toolType == MotionEventToolType . Eraser )
154+ LastPenDeviceType = getPenDeviceType ( e ) ;
155+ }
156+
157+ break ;
158+ }
159+
160+ return base . DispatchGenericMotionEvent ( e ) ;
161+ }
162+
163+ /// <summary>
164+ /// Sets <see cref="LastPenDeviceType"/> iff <c>SDLSurface.onGenericMotion()</c> would call <c>onNativePen()</c>.
165+ /// </summary>
166+ public override bool OnTouch ( View ? view , MotionEvent ? e )
167+ {
168+ Debug . Assert ( e != null ) ;
169+
170+ // SDLSurface does some weird checks here for event action index, but it doesn't really matter as we only expect one pen at a time
171+
172+ for ( int i = 0 ; i < e . PointerCount ; i ++ )
173+ {
174+ var toolType = e . GetToolType ( i ) ;
175+
176+ if ( toolType == MotionEventToolType . Stylus || toolType == MotionEventToolType . Eraser )
177+ LastPenDeviceType = getPenDeviceType ( e ) ;
178+ }
179+
180+ return base . OnTouch ( view , e ) ;
181+ }
120182 }
121183}
0 commit comments