Cleaned up CreateSystemTimer interface for use with 32-bit callbacks.
(NOTE: 16-bit callbacks still don't work!)

diff --git a/if1632/system.spec b/if1632/system.spec
index 62ba8e6..c2702c2 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -2,7 +2,7 @@
 type	win16
 
 1 pascal   InquireSystem(word word) InquireSystem
-2 pascal16 CreateSystemTimer(word segptr) CreateSystemTimer
+2 pascal16 CreateSystemTimer(word segptr) WIN16_CreateSystemTimer
 3 pascal16 KillSystemTimer(word) SYSTEM_KillSystemTimer
 4 pascal16 EnableSystemTimers() EnableSystemTimers
 5 pascal16 DisableSystemTimers() DisableSystemTimers
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 48c68e6..6db8d4a 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -157,7 +157,6 @@
     (void *)CallTo16_word_ww,              /* CallBootAppProc */
     (void *)CallTo16_word_www,             /* CallLoadAppSegProc */
     (void *)CallTo16_word_www,             /* CallLocalNotifyFunc */
-    (void *)CallTo16_word_,                /* CallSystemTimerProc */
     (void *)CallTo16_word_www,             /* CallResourceHandlerProc */
     (void *)CallTo16_word_wwwl,            /* CallPostAppMessageProc */
     (void *)CallTo16_long_l,               /* CallWOWCallbackProc */
@@ -815,6 +814,42 @@
 }
 
 
+/***********************************************************************
+ *           WIN16_CreateSystemTimer   (SYSTEM.2)
+ */
+static void CALLBACK THUNK_CallSystemTimerProc( FARPROC16 proc, WORD timer )
+{
+    CONTEXT context;
+    memset( &context, '\0', sizeof(context) );
+
+    CS_reg( &context ) = SELECTOROF( proc );
+    IP_reg( &context ) = OFFSETOF( proc );
+    BP_reg( &context ) = OFFSETOF( THREAD_Current()->cur_stack )
+                         + (WORD)&((STACK16FRAME*)0)->bp;
+
+    AX_reg( &context ) = timer;
+
+    CallTo16_sreg_( &context, 0 ); 
+
+    /* FIXME: This does not work if the signal occurs while some thread
+              is currently in 16-bit code. With the current structure
+              of the Wine thunking code, this seems to be hard to fix ... */
+}
+WORD WINAPI WIN16_CreateSystemTimer( WORD rate, FARPROC16 proc )
+{
+    THUNK *thunk = THUNK_Alloc( proc, (RELAY)THUNK_CallSystemTimerProc );
+    WORD timer = 0;
+
+#if 1
+    FIXME(system,"are currently broken, returning 0.\n");
+#else
+    timer = CreateSystemTimer( rate, (SYSTEMTIMERPROC)thunk );
+#endif
+
+    if (!timer) THUNK_Free( thunk );
+    return timer;
+}
+
 
 /***********************************************************************
  * 16->32 Flat Thunk routines:
diff --git a/include/callback.h b/include/callback.h
index 1b46d6f..98d8935 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -37,7 +37,6 @@
     VOID (CALLBACK *CallBootAppProc)( FARPROC16, HANDLE16, HFILE16 );
     WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
     WORD (CALLBACK *CallLocalNotifyFunc)( FARPROC16, WORD, HLOCAL16, WORD );
-    VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
     HGLOBAL16 (CALLBACK *CallResourceHandlerProc)( FARPROC16, HGLOBAL16, HMODULE16, HRSRC16 );
     BOOL16 (CALLBACK *CallPostAppMessageProc)( FARPROC16, HTASK16, UINT16, WPARAM16, LPARAM );
     DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD );
diff --git a/include/windows.h b/include/windows.h
index f04d350..62537ee 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -6585,6 +6585,8 @@
 /* Declarations for functions that exist only in Win16 */
 
 #ifdef __WINE__
+typedef VOID (*SYSTEMTIMERPROC)(WORD);
+
 WORD        WINAPI AllocCStoDSAlias(WORD);
 WORD        WINAPI AllocDStoCSAlias(WORD);
 HGLOBAL16   WINAPI AllocResource(HINSTANCE16,HRSRC16,DWORD);
@@ -6595,7 +6597,7 @@
 INT16       WINAPI CloseComm(INT16);
 HGLOBAL16   WINAPI CreateCursorIconIndirect(HINSTANCE16,CURSORICONINFO*,
                                             LPCVOID,LPCVOID);
-WORD        WINAPI CreateSystemTimer(WORD,FARPROC16);
+WORD        WINAPI CreateSystemTimer(WORD,SYSTEMTIMERPROC);
 BOOL16      WINAPI DCHook(HDC16,WORD,DWORD,LPARAM);
 VOID        WINAPI DirectedYield(HTASK16);
 HGLOBAL16   WINAPI DirectResAlloc(HINSTANCE16,WORD,UINT16);
diff --git a/misc/callback.c b/misc/callback.c
index 0449c70..e1b9b4c 100644
--- a/misc/callback.c
+++ b/misc/callback.c
@@ -121,14 +121,6 @@
 
 
 /**********************************************************************
- *	     CALLBACK_CallSystemTimerProc
- */
-static void WINAPI CALLBACK_CallSystemTimerProc( FARPROC16 proc )
-{
-    proc();
-}
-
-/**********************************************************************
  *	     CALLBACK_CallResourceHandlerProc
  */
 static HGLOBAL16 WINAPI CALLBACK_CallResourceHandlerProc( FARPROC16 proc,
@@ -274,7 +266,6 @@
     CALLBACK_CallBootAppProc,         /* CallBootAppProc */
     CALLBACK_CallLoadAppSegProc,      /* CallLoadAppSegProc */
     CALLBACK_CallLocalNotifyFunc,     /* CallLocalNotifyFunc */
-    CALLBACK_CallSystemTimerProc,     /* CallSystemTimerProc */
     CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */
     NULL,                             /* CallPostAppMessageProc */
     CALLBACK_CallWOWCallbackProc,     /* CallWOWCallbackProc */
diff --git a/misc/system.c b/misc/system.c
index b9588fc..b29a62d 100644
--- a/misc/system.c
+++ b/misc/system.c
@@ -12,18 +12,15 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#include "callback.h"
 #include "windows.h"
-#include "miscemu.h"
-#include "dosexe.h"
-#include "vga.h"
 #include "selectors.h"
 #include "sig_context.h"
+#include "miscemu.h"
 #include "debug.h"
 
 typedef struct
 {
-    FARPROC16 callback;  /* NULL if not in use */
+    SYSTEMTIMERPROC callback;  /* NULL if not in use */
     INT32     rate;
     INT32     ticks;
 } SYSTEM_TIMER;
@@ -35,14 +32,9 @@
 static int SYS_NbTimers = 0;
 static BOOL32 SYS_TimersDisabled = FALSE;
 
+
 /***********************************************************************
  *           SYSTEM_TimerTick
- * FIXME: It is a very bad idea to call 16bit code in a signal handler:
- *	  If the signal reached us in 16 bit code, we could have a broken
- *	  %FS, which is in turned saved into the single global
- *	  CALLTO16_Current_fs temporary storage, so a single misplaced
- *	  signal crashes the whole WINE process.
- *	  This needs more thought. -MM
  */
 static HANDLER_DEF(SYSTEM_TimerTick)
 {
@@ -55,17 +47,7 @@
         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
         {
             SYS_Timers[i].ticks += SYS_Timers[i].rate;
-
-	    if (SYS_Timers[i].callback == (FARPROC16)DOSMEM_Tick) {
-	    	DOSMEM_Tick();
-	    } else
-	    if (SYS_Timers[i].callback == (FARPROC16)MZ_Tick) {
-	    	MZ_Tick(i+1);
-	    } else
-	    if (SYS_Timers[i].callback == (FARPROC16)VGA_Poll) {
-	    	VGA_Poll();
-	    } else
-		Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
+            SYS_Timers[i].callback( i+1 );
         }
     }
 }
@@ -146,20 +128,9 @@
 /***********************************************************************
  *           CreateSystemTimer   (SYSTEM.2)
  */
-WORD WINAPI CreateSystemTimer( WORD rate, FARPROC16 callback )
+WORD WINAPI CreateSystemTimer( WORD rate, SYSTEMTIMERPROC callback )
 {
     int i;
-
-    /* FIXME: HACK: do not create system timers due to problems mentioned
-     * above, except DOSMEM_Tick(), MZ_Tick(), and VGA_Poll().
-     */
-    if ((callback!=(FARPROC16)DOSMEM_Tick)&&
-        (callback!=(FARPROC16)MZ_Tick)&&
-        (callback!=(FARPROC16)VGA_Poll)) {
-    	FIXME(system,"are currently broken, returning 0.\n");
-    	return 0;
-    }
-
     for (i = 0; i < NB_SYS_TIMERS; i++)
         if (!SYS_Timers[i].callback)  /* Found one */
         {