Skip to content

Commit 9a2b735

Browse files
author
ubkp
authored
Fix mouse/touch/gestures for PLATFORM_DRM (#3515)
1 parent a57ac0b commit 9a2b735

File tree

1 file changed

+199
-31
lines changed

1 file changed

+199
-31
lines changed

src/platforms/rcore_drm.c

Lines changed: 199 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ typedef struct {
123123
// NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update
124124
char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
125125
bool cursorRelative; // Relative cursor mode
126+
int mouseFd; // File descriptor for the evdev mouse/touch/gestures
127+
Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
128+
int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
126129

127130
// Gamepad data
128131
pthread_t gamepadThreadId; // Gamepad reading thread id
@@ -170,11 +173,6 @@ static const int EvkeyToUnicodeLUT[] = {
170173
// LUT currently incomplete, just mapped the most essential keys
171174
};
172175

173-
#if defined(SUPPORT_GESTURES_SYSTEM)
174-
GestureEvent gestureEvent = { 0 }; // Gesture event to hold data between EventThread() and PollInputEvents()
175-
bool newGesture = false; // Var to trigger ProcessGestureEvent(gestureEvent) on PollInputEvents()
176-
#endif
177-
178176
//----------------------------------------------------------------------------------
179177
// Module Internal Functions Declaration
180178
//----------------------------------------------------------------------------------
@@ -448,7 +446,7 @@ void EnableCursor(void)
448446
void DisableCursor(void)
449447
{
450448
// Set cursor position in the middle
451-
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
449+
SetMousePosition(0, 0);
452450

453451
platform.cursorRelative = true;
454452
CORE.Input.Mouse.cursorHidden = true;
@@ -565,11 +563,8 @@ void PollInputEvents(void)
565563
PollKeyboardEvents();
566564

567565
// Register previous mouse position
568-
if (platform.cursorRelative)
569-
{
570-
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
571-
CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
572-
}
566+
if (platform.cursorRelative) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
567+
else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
573568

574569
// Register previous mouse states
575570
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
@@ -600,15 +595,6 @@ void PollInputEvents(void)
600595
// Map touch position to mouse position for convenience
601596
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
602597

603-
#if defined(SUPPORT_GESTURES_SYSTEM)
604-
// Call the ProcessGestureEvent here instead of on EventThread() to workaround the threads not matching
605-
if (newGesture)
606-
{
607-
ProcessGestureEvent(gestureEvent);
608-
newGesture = false;
609-
}
610-
#endif
611-
612598
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
613599
// NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.
614600
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
@@ -618,6 +604,183 @@ void PollInputEvents(void)
618604
// NOTE: Mouse input events polling is done asynchronously in another pthread - EventThread()
619605
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
620606
#endif
607+
608+
// Handle the mouse/touch/gestures events:
609+
// NOTE: Replaces the EventThread handling that is now commented.
610+
{
611+
int fd = platform.mouseFd;
612+
if (fd == -1) return;
613+
614+
struct input_event event = { 0 };
615+
616+
int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
617+
bool gestureUpdate = false; // Flag to note gestures require to update
618+
619+
// Try to read data from the mouse/touch/gesture and only continue if successful
620+
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
621+
{
622+
// Relative movement parsing
623+
if (event.type == EV_REL)
624+
{
625+
if (event.code == REL_X)
626+
{
627+
if (platform.cursorRelative)
628+
{
629+
CORE.Input.Mouse.currentPosition.x = event.value;
630+
CORE.Input.Mouse.previousPosition.x = 0.0f;
631+
}
632+
else CORE.Input.Mouse.currentPosition.x += event.value;
633+
CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;
634+
635+
touchAction = 2; // TOUCH_ACTION_MOVE
636+
gestureUpdate = true;
637+
}
638+
639+
if (event.code == REL_Y)
640+
{
641+
if (platform.cursorRelative)
642+
{
643+
CORE.Input.Mouse.currentPosition.y = event.value;
644+
CORE.Input.Mouse.previousPosition.y = 0.0f;
645+
}
646+
else CORE.Input.Mouse.currentPosition.y += event.value;
647+
CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;
648+
649+
touchAction = 2; // TOUCH_ACTION_MOVE
650+
gestureUpdate = true;
651+
}
652+
653+
if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;
654+
}
655+
656+
// Absolute movement parsing
657+
if (event.type == EV_ABS)
658+
{
659+
// Basic movement
660+
if (event.code == ABS_X)
661+
{
662+
CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
663+
CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
664+
665+
touchAction = 2; // TOUCH_ACTION_MOVE
666+
gestureUpdate = true;
667+
}
668+
669+
if (event.code == ABS_Y)
670+
{
671+
CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
672+
CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
673+
674+
touchAction = 2; // TOUCH_ACTION_MOVE
675+
gestureUpdate = true;
676+
}
677+
678+
// Multitouch movement
679+
if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events
680+
681+
if (event.code == ABS_MT_POSITION_X)
682+
{
683+
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
684+
}
685+
686+
if (event.code == ABS_MT_POSITION_Y)
687+
{
688+
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
689+
}
690+
691+
if (event.code == ABS_MT_TRACKING_ID)
692+
{
693+
if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS))
694+
{
695+
// Touch has ended for this point
696+
CORE.Input.Touch.position[platform.touchSlot].x = -1;
697+
CORE.Input.Touch.position[platform.touchSlot].y = -1;
698+
}
699+
}
700+
701+
// Touchscreen tap
702+
if (event.code == ABS_PRESSURE)
703+
{
704+
int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];
705+
706+
if (!event.value && previousMouseLeftButtonState)
707+
{
708+
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
709+
710+
touchAction = 0; // TOUCH_ACTION_UP
711+
gestureUpdate = true;
712+
}
713+
714+
if (event.value && !previousMouseLeftButtonState)
715+
{
716+
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
717+
718+
touchAction = 1; // TOUCH_ACTION_DOWN
719+
gestureUpdate = true;
720+
}
721+
}
722+
723+
}
724+
725+
// Button parsing
726+
if (event.type == EV_KEY)
727+
{
728+
// Mouse button parsing
729+
if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))
730+
{
731+
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
732+
733+
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN
734+
else touchAction = 0; // TOUCH_ACTION_UP
735+
gestureUpdate = true;
736+
}
737+
738+
if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
739+
if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;
740+
if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;
741+
if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;
742+
if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;
743+
if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;
744+
}
745+
746+
// Screen confinement
747+
if (!CORE.Input.Mouse.cursorHidden)
748+
{
749+
if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;
750+
if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;
751+
752+
if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;
753+
if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;
754+
}
755+
756+
// Update touch point count
757+
CORE.Input.Touch.pointCount = 0;
758+
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
759+
{
760+
if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++;
761+
}
762+
763+
#if defined(SUPPORT_GESTURES_SYSTEM)
764+
if (gestureUpdate)
765+
{
766+
GestureEvent gestureEvent = { 0 };
767+
768+
gestureEvent.touchAction = touchAction;
769+
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
770+
771+
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
772+
{
773+
gestureEvent.pointId[i] = i;
774+
gestureEvent.position[i] = CORE.Input.Touch.position[i];
775+
}
776+
777+
ProcessGestureEvent(gestureEvent);
778+
779+
gestureUpdate = false;
780+
}
781+
#endif
782+
}
783+
}
621784
}
622785

623786
//----------------------------------------------------------------------------------
@@ -1462,15 +1625,20 @@ static void ConfigureEvdevDevice(char *device)
14621625
worker->isMultitouch? "multitouch " : "",
14631626
worker->isTouch? "touchscreen " : "",
14641627
worker->isGamepad? "gamepad " : "");
1628+
platform.mouseFd = worker->fd;
1629+
1630+
// NOTE: moved the mouse/touch/gesture input to PollInputEvents()/
1631+
// so added the "platform.mouseFd = worker->fd;" line above
1632+
// and commented the thread code below:
14651633

14661634
// Create a thread for this device
1467-
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
1468-
if (error != 0)
1469-
{
1470-
TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread: %s (error: %d)", device, error);
1471-
worker->threadId = 0;
1472-
close(fd);
1473-
}
1635+
//int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
1636+
//if (error != 0)
1637+
//{
1638+
// TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread: %s (error: %d)", device, error);
1639+
// worker->threadId = 0;
1640+
// close(fd);
1641+
//}
14741642

14751643
#if defined(USE_LAST_TOUCH_DEVICE)
14761644
// Find touchscreen with the highest index
@@ -1570,6 +1738,7 @@ static void PollKeyboardEvents(void)
15701738
// Input device events reading thread
15711739
static void *EventThread(void *arg)
15721740
{
1741+
/*
15731742
struct input_event event = { 0 };
15741743
InputEventWorker *worker = (InputEventWorker *)arg;
15751744
@@ -1731,7 +1900,7 @@ static void *EventThread(void *arg)
17311900
#if defined(SUPPORT_GESTURES_SYSTEM)
17321901
if (gestureUpdate)
17331902
{
1734-
//GestureEvent gestureEvent = { 0 };
1903+
GestureEvent gestureEvent = { 0 };
17351904
17361905
gestureEvent.touchAction = touchAction;
17371906
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
@@ -1742,8 +1911,7 @@ static void *EventThread(void *arg)
17421911
gestureEvent.position[i] = CORE.Input.Touch.position[i];
17431912
}
17441913
1745-
//ProcessGestureEvent(gestureEvent);
1746-
newGesture = true;
1914+
ProcessGestureEvent(gestureEvent);
17471915
}
17481916
#endif
17491917
}
@@ -1752,7 +1920,7 @@ static void *EventThread(void *arg)
17521920
}
17531921
17541922
close(worker->fd);
1755-
1923+
*/
17561924
return NULL;
17571925
}
17581926

0 commit comments

Comments
 (0)