From c941effc248517fb5bad5b3b86ab83cd5811bac8 Mon Sep 17 00:00:00 2001
From: Andreas Mohr <a.mohr@mailto.de>
Date: Fri, 22 Sep 2000 22:37:56 +0000
Subject: [PATCH] Make GetTickCount not use the whole Unix epoch (since 1970)
 any more, since that crashed several games or caused problems with them as
 they aren't used to a high Windows uptime of more than 24.9 days.

---
 dlls/x11drv/x11drv_main.c | 19 +++++++++++++++++++
 include/options.h         |  1 +
 include/server.h          |  3 ++-
 include/x11drv.h          |  4 +++-
 misc/main.c               |  4 ++--
 scheduler/process.c       |  2 ++
 server/main.c             | 11 +++++++++++
 server/object.h           |  6 +++++-
 server/process.c          |  1 +
 server/trace.c            |  1 +
 windows/x11drv/event.c    | 14 +++++++-------
 windows/x11drv/keyboard.c |  4 ++--
 12 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c
index 3326c1a81d8..40b42ac20e5 100644
--- a/dlls/x11drv/x11drv_main.c
+++ b/dlls/x11drv/x11drv_main.c
@@ -10,6 +10,8 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
 #include <X11/cursorfont.h>
 #include "ts_xlib.h"
 #include "ts_xutil.h"
@@ -40,6 +42,8 @@ unsigned int screen_height;
 unsigned int screen_depth;
 Window root_window;
 
+unsigned int X11DRV_server_startticks;
+
 /***********************************************************************
  *		error_handler
  */
@@ -50,6 +54,20 @@ static int error_handler(Display *display, XErrorEvent *error_evt)
 }
 
 
+/***********************************************************************
+ *		get_server_startup
+ *
+ * Get the server startup time 
+ * Won't be exact, but should be sufficient
+ */
+static void get_server_startup(void)
+{
+    struct timeval t;
+    gettimeofday( &t, NULL );
+    X11DRV_server_startticks = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - GetTickCount();
+}
+
+
 /***********************************************************************
  *		setup_options
  *
@@ -216,6 +234,7 @@ static void process_attach(void)
 {
     WND_Driver       = &X11DRV_WND_Driver;
 
+    get_server_startup();
     setup_options();
 
     /* Open display */
diff --git a/include/options.h b/include/options.h
index 550028681ec..4ba621aafe8 100644
--- a/include/options.h
+++ b/include/options.h
@@ -22,6 +22,7 @@ struct options
 extern struct options Options;
 extern const char *argv0;
 extern const char *full_argv0;
+extern unsigned int server_startticks;
 
 extern void OPTIONS_Usage(void) WINE_NORETURN;
 extern void OPTIONS_ParseOptions( char *argv[] );
diff --git a/include/server.h b/include/server.h
index d79c50407dc..a9fbd62815c 100644
--- a/include/server.h
+++ b/include/server.h
@@ -181,6 +181,7 @@ struct init_process_request
     IN  void*        ldt_flags;    /* addr of LDT flags */
     IN  int          ppid;         /* parent Unix pid */
     OUT int          start_flags;  /* flags from startup info */
+    OUT unsigned int server_start; /* server start time (GetTickCount) */
     OUT int          exe_file;     /* file handle for main exe */
     OUT int          hstdin;       /* handle for stdin */
     OUT int          hstdout;      /* handle for stdout */
@@ -1586,7 +1587,7 @@ union generic_request
     struct set_serial_info_request set_serial_info;
 };
 
-#define SERVER_PROTOCOL_VERSION 22
+#define SERVER_PROTOCOL_VERSION 23
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
diff --git a/include/x11drv.h b/include/x11drv.h
index ac9680ff051..1e5e6e2cb01 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -83,6 +83,8 @@ extern GC BITMAP_monoGC, BITMAP_colorGC;
 
 extern DeviceCaps X11DRV_DevCaps;
 
+extern unsigned int X11DRV_server_startticks;
+
 /* Wine driver X11 functions */
 
 extern const DC_FUNCTIONS X11DRV_DC_Funcs;
@@ -288,7 +290,7 @@ void X11DRV_GDI_Finalize(void);
 
 /* X11 GDI palette driver */
 
-#define X11DRV_PALETTE_FIXED    0x0001 /* read-only colormap - have to use XAllocColor (if not virtual)*/
+#define X11DRV_PALETTE_FIXED    0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */
 #define X11DRV_PALETTE_VIRTUAL  0x0002 /* no mapping needed - pixel == pixel color */
 
 #define X11DRV_PALETTE_PRIVATE  0x1000 /* private colormap, identity mapping */
diff --git a/misc/main.c b/misc/main.c
index 64588e0662e..3a51ea1e9fe 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -229,11 +229,11 @@ FARPROC16 WINAPI FileCDR16(FARPROC16 x)
  *           GetTickCount   (USER.13) (KERNEL32.299)
  *
  * Returns the number of milliseconds, modulo 2^32, since the start
- * of the current session.
+ * of the wineserver.
  */
 DWORD WINAPI GetTickCount(void)
 {
     struct timeval t;
     gettimeofday( &t, NULL );
-    return (t.tv_sec * 1000) + (t.tv_usec / 1000);
+    return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - server_startticks;
 }
diff --git a/scheduler/process.c b/scheduler/process.c
index 019756cedbf..1ce4e7d4cca 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -42,6 +42,7 @@ static char **main_exe_argv;
 static char main_exe_name[MAX_PATH];
 static HFILE main_exe_file = INVALID_HANDLE_VALUE;
 
+unsigned int server_startticks;
 
 /***********************************************************************
  *           PROCESS_CallUserSignalProc
@@ -198,6 +199,7 @@ static BOOL process_init( char *argv[] )
             main_exe_name[len] = 0;
             main_exe_file = req->exe_file;
             current_startupinfo.dwFlags     = req->start_flags;
+            server_startticks               = req->server_start;
             current_startupinfo.wShowWindow = req->cmd_show;
             current_envdb.hStdin   = current_startupinfo.hStdInput  = req->hstdin;
             current_envdb.hStdout  = current_startupinfo.hStdOutput = req->hstdout;
diff --git a/server/main.c b/server/main.c
index f92c852a28b..49f181cd458 100644
--- a/server/main.c
+++ b/server/main.c
@@ -21,6 +21,8 @@
 int debug_level = 0;
 int persistent_server = 0;
 
+unsigned int server_start_ticks = 0;
+
 /* parse-line args */
 /* FIXME: should probably use getopt, and add a help option */
 static void parse_args( int argc, char *argv[] )
@@ -68,6 +70,14 @@ static void signal_init(void)
     signal( SIGABRT, sigterm_handler );
 }
 
+/* get server start ticks used to calculate GetTickCount() in Wine clients */
+static void get_start_ticks(void)
+{
+    struct timeval t;
+    gettimeofday( &t, NULL );
+    server_start_ticks = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+}
+
 int main( int argc, char *argv[] )
 {
     parse_args( argc, argv );
@@ -76,6 +86,7 @@ int main( int argc, char *argv[] )
     setvbuf( stderr, NULL, _IOLBF, 0 );
 
     if (debug_level) fprintf( stderr, "Server: starting (pid=%ld)\n", (long) getpid() );
+    get_start_ticks();
     init_registry();
     select_loop();
     close_registry();
diff --git a/server/object.h b/server/object.h
index f90d8ac6821..ab52ed6a461 100644
--- a/server/object.h
+++ b/server/object.h
@@ -181,9 +181,13 @@ extern void close_registry(void);
 
 extern void close_atom_table(void);
 
-/* global variables (command-line options) */
+/* global variables */
 
+  /* command-line options */
 extern int debug_level;
 extern int persistent_server;
 
+  /* server start time used for GetTickCount() */
+extern unsigned int server_start_ticks;
+
 #endif  /* __WINE_SERVER_OBJECT_H */
diff --git a/server/process.c b/server/process.c
index 4376d3d19f0..dc6d1cf0c74 100644
--- a/server/process.c
+++ b/server/process.c
@@ -275,6 +275,7 @@ static void init_process( int ppid, struct init_process_request *req )
         req->cmd_show     = 0;
         set_req_data_size( req, 0 );
     }
+    req->server_start = server_start_ticks;
  error:
 }
 
diff --git a/server/trace.c b/server/trace.c
index 786c8b42715..9bbd3387d03 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -315,6 +315,7 @@ static void dump_init_process_request( const struct init_process_request *req )
 static void dump_init_process_reply( const struct init_process_request *req )
 {
     fprintf( stderr, " start_flags=%d,", req->start_flags );
+    fprintf( stderr, " server_start=%08x,", req->server_start );
     fprintf( stderr, " exe_file=%d,", req->exe_file );
     fprintf( stderr, " hstdin=%d,", req->hstdin );
     fprintf( stderr, " hstdout=%d,", req->hstdout );
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index caec8a947c3..fb059fbbabc 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -717,12 +717,12 @@ static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event )
     X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, 
                             xOffset + event->x, yOffset + event->y,
                             X11DRV_EVENT_XStateToKeyState( event->state ), 
-                            event->time, hWnd);
+                            event->time - X11DRV_server_startticks, hWnd);
   } else {
     X11DRV_SendEvent( MOUSEEVENTF_MOVE,
                             event->x_root, event->y_root,
                             X11DRV_EVENT_XStateToKeyState( event->state ), 
-                            event->time, hWnd);
+                            event->time - X11DRV_server_startticks, hWnd);
   }
 }
 
@@ -776,7 +776,7 @@ static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event )
   X11DRV_SendEvent( statusCodes[buttonNum], 
                           xOffset + event->x, yOffset + event->y,
                           MAKEWPARAM(keystate,wData),
-                          event->time, hWnd);
+                          event->time - X11DRV_server_startticks, hWnd);
 }
 
 
@@ -823,7 +823,7 @@ static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event )
 
   X11DRV_SendEvent( statusCodes[buttonNum], 
                           xOffset + event->x, yOffset + event->y,
-                          keystate, event->time, hWnd);
+                          keystate, event->time - X11DRV_server_startticks, hWnd);
 }
 
 
@@ -1942,7 +1942,7 @@ static void EVENT_DGAMotionEvent( XDGAMotionEvent *event )
   X11DRV_SendEvent( MOUSEEVENTF_MOVE, 
 		   event->dx, event->dy,
 		   X11DRV_EVENT_XStateToKeyState( event->state ), 
-		   event->time, DGAhwnd );
+		   event->time - X11DRV_server_startticks, DGAhwnd );
 }
 
 static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event )
@@ -1970,7 +1970,7 @@ static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event )
       break;
   }
   
-  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, event->time, DGAhwnd );
+  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, event->time - X11DRV_server_startticks, DGAhwnd );
 }
 
 static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event )
@@ -1998,7 +1998,7 @@ static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event )
       break;
   }
   
-  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, event->time, DGAhwnd );
+  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, event->time - X11DRV_server_startticks, DGAhwnd );
 }
 
 #endif
diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c
index 3b48fb2defe..0e2e9014d20 100644
--- a/windows/x11drv/keyboard.c
+++ b/windows/x11drv/keyboard.c
@@ -606,7 +606,7 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
 
     INT event_x = (pWnd? pWnd->rectWindow.left : 0) + event->x;
     INT event_y = (pWnd? pWnd->rectWindow.top  : 0) + event->y;
-    DWORD event_time = event->time;
+    DWORD event_time = event->time - X11DRV_server_startticks;
 
     /* this allows support for dead keys */
     if ((event->keycode >> 8) == 0x10)
@@ -614,7 +614,7 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
 
     ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
 
-    TRACE_(key)("EVENT_key : state = %X\n", event->state);
+    TRACE_(key)("state = %X\n", event->state);
 
     /* If XKB extensions is used, the state mask for AltGr will used the group
        index instead of the modifier mask. The group index is set in bits
-- 
GitLab