SDL: Don't assume evdev events and SDL_GetTicks() use the same time source

From 75f1eb92168e0a3253555de847d8e683e5a642f3 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 5 Dec 2022 10:40:16 -0800
Subject: [PATCH] Don't assume evdev events and SDL_GetTicks() use the same
 time source

The evdev events are in the same time base as gettimeofday(), but SDL_GetTicks() might be using clock_gettime()
---
 src/core/linux/SDL_evdev.c | 13 ++++++++++---
 src/timer/SDL_timer.c      | 16 ----------------
 src/timer/SDL_timer_c.h    |  1 -
 3 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c
index a8e96cfaef67..92907075e669 100644
--- a/src/core/linux/SDL_evdev.c
+++ b/src/core/linux/SDL_evdev.c
@@ -38,7 +38,6 @@
 #include <sys/ioctl.h>
 #include <linux/input.h>
 
-#include "../../timer/SDL_timer_c.h"
 #include "../../events/SDL_events_c.h"
 #include "../../events/SDL_scancode_tables_c.h"
 #include "../../core/linux/SDL_evdev_capabilities.h"
@@ -876,7 +875,9 @@ static int SDL_EVDEV_device_removed(const char *dev_path)
 
 Uint64 SDL_EVDEV_GetEventTimestamp(struct input_event *event)
 {
+    static Uint64 timestamp_offset;
     Uint64 timestamp;
+    Uint64 now = SDL_GetTicksNS();
 
     /* The kernel internally has nanosecond timestamps, but converts it
        to microseconds when delivering the events */
@@ -884,9 +885,15 @@ Uint64 SDL_EVDEV_GetEventTimestamp(struct input_event *event)
     timestamp *= SDL_NS_PER_SECOND;
     timestamp += SDL_US_TO_NS(event->time.tv_usec);
 
-    /* Let's assume for now that we're using the same time base */
-    timestamp -= SDL_GetTickStartNS();
+    if (!timestamp_offset) {
+        timestamp_offset = (now - timestamp);
+    }
+    timestamp += timestamp_offset;
 
+    if (timestamp > now) {
+        timestamp_offset -= (timestamp - now);
+        timestamp = now;
+    }
     return timestamp;
 }
 
diff --git a/src/timer/SDL_timer.c b/src/timer/SDL_timer.c
index 01704ca603fc..7a49276d9149 100644
--- a/src/timer/SDL_timer.c
+++ b/src/timer/SDL_timer.c
@@ -565,22 +565,6 @@ void SDL_TicksQuit(void)
     tick_start = 0;
 }
 
-Uint64
-SDL_GetTickStartNS(void)
-{
-    Uint64 starting_value, value;
-
-    if (!tick_start) {
-        SDL_TicksInit();
-    }
-
-    starting_value = tick_start;
-    value = (starting_value * tick_numerator_ns);
-    SDL_assert(value >= starting_value);
-    value /= tick_denominator_ns;
-    return value;
-}
-
 Uint64
 SDL_GetTicksNS(void)
 {
diff --git a/src/timer/SDL_timer_c.h b/src/timer/SDL_timer_c.h
index c69717c8e562..05e530db87a0 100644
--- a/src/timer/SDL_timer_c.h
+++ b/src/timer/SDL_timer_c.h
@@ -33,7 +33,6 @@ extern void SDL_TicksInit(void);
 extern void SDL_TicksQuit(void);
 extern int SDL_TimerInit(void);
 extern void SDL_TimerQuit(void);
-extern Uint64 SDL_GetTickStartNS(void);
 
 #endif /* SDL_timer_c_h_ */