Files
RetroArch/input/drivers/android_input.h
T
M00NR00STERandLibretroAdmin 4592b490bd Android: Samsung S-Pen stylus support (#19076)
* android: Add Samsung S-Pen stylus input support

Stylus input for the Android driver, squashed from PR #19076 and
rebased onto current master (three conflicts, all additive: the
hover-guard block in android_input.c, an include in runloop.c and the
stylus rows in tools/settings_table.reference).

- toolType-based stylus/finger classification with an input-source
  fallback
- hover, contact and click handled separately; hover can move the
  pointer without pressing
- phantom-touch suppression for Samsung pens (hover guard, proximity
  window)
- both barrel buttons read
- four Android-only settings: input_stylus_enable,
  input_stylus_require_contact_for_click,
  input_stylus_hover_moves_pointer, input_stylus_pressure_sensitivity
- android_mouse_calculate_deltas computed its fallback delta from the
  zeroed delta instead of the event position; fixed

Closes #15490
Closes #18194

* overlay: hide for a stylus without unloading the pack

The S-Pen support unloaded the on-screen overlay from the run loop
whenever a stylus became active and loaded it again two seconds after
the last pen event. A pen that leaves and returns does that over and
over, and each round is the pack's file and texture work, triggered by
input while a core runs.

It was a full unload because a soft-hidden overlay still took over
pointer input: with input_overlay_pointer_enable the overlay poll
tracks every touch as its own pointing device and sets
INP_FLAG_BLOCK_POINTER_INPUT, so input_state never reaches the driver
and the pen's native state (hover included) is lost.

Add INPUT_OVERLAY_STYLUS_HIDDEN and make it complete. While it is set
the overlay:
- is not drawn (alpha 0, as the gamepad soft-hide does);
- reads no touches, so the poll releases whatever a finger was holding
  the way lifting it would, and no hitbox or pointing device sees the
  pen;
- does not answer mouse, lightgun or pointer queries and does not
  block pointer input.

The run loop sets and clears the flag each frame on the current
overlay, the way the gamepad soft-hide is driven. Nothing is unloaded
or reloaded.

* android: report a pen as one pointer, its barrel button as the right mouse button

The S-Pen support gave pointer indices a meaning of its own: index 0
was the cursor, index 1 the tip pressing and index 2 the barrel
button, with the pointer count raised to 2 or 3 to match. Only a core
written for that contract can read it. Everywhere else an index is a
separate touch, so a pressing pen looked like two fingers and a press
with the barrel button like three - to cores that count pointers, to
the on-screen overlay, and to this driver's own lightgun mapping,
where two pointers are turbo and three are reload. With the barrel
button held but the tip not pressing, index 1 was stale and still
inside the count.

Map the pen onto the devices the driver already reports instead:

- position is pointer 0, and moves without a press while hovering
  (input_stylus_hover_moves_pointer);
- a press is pointer 0 pressed with a count of 1: the tip pressing
  past the pressure threshold, or, with
  input_stylus_require_contact_for_click off, the barrel button,
  touching or hovering;
- the barrel button is the right mouse button.

This also puts two settings to work. The contact-for-click option and
the pressure threshold only fed a latch nothing read; they now decide
the press, as their menu text says.

The pen no longer switches the driver into mouse mode
(mouse_activated). That flag is never cleared, and once set the
lightgun position is read from the mouse coordinates, which a pen does
not update, so lightgun aim went stale after the first pen contact.
The mouse_x_viewport/mouse_y_viewport values it wrote alongside are
not read anywhere.

A cancelled pen gesture now releases the press like a lift does;
before it fell through to the touchscreen path and left the pen's
contact latched.

Compiled with the NDK through the Android unity build. Not run on a
device: it needs a pass on S-Pen hardware before merging.

* android: let a mouse's hover events reach the mouse path again

The S-Pen support drops every hover event before the source is looked
at, so hover cannot be taken for a touch. A mouse moved with no button
held reports its motion as hover events too, and they were dropped
with the rest: the pointer only moved while a button was down.

Drop hover events after the mouse branch instead. Mouse motion is
handled as before the stylus work, and hover from any other source is
still kept out of the touchscreen path.

---------

Co-authored-by: LibretroAdmin <[email protected]>
2026-10-02 05:48:02 +02:00

28 lines
1.0 KiB
C

/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2012-2015 - Michael Lelli
* Copyright (C) 2013-2014 - Steven Crowe
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ANDROID_INPUT_H__
#define __ANDROID_INPUT_H__
#include <boolean.h>
/* True for ~2s after the last stylus event. */
bool android_input_stylus_recently_active(void);
#endif