Fix problem where you need mouse activity to unlock some 16 bits
thread with multi-threaded apps.

diff --git a/include/message.h b/include/message.h
index 63b3259..a6c8dd2 100644
--- a/include/message.h
+++ b/include/message.h
@@ -43,6 +43,7 @@
   void   (*pDummyMotionNotify)(void);
   BOOL32 (*pPending)(void);
   BOOL16 (*pIsUserIdle)(void);
+  void   (*pWakeUp)(void);
 } EVENT_DRIVER;
 
 extern void EVENT_AddIO( int fd, unsigned flag );
@@ -54,6 +55,7 @@
 extern BOOL32 EVENT_QueryPointer(DWORD *posX, DWORD *posY, DWORD *state);
 extern void EVENT_DummyMotionNotify(void);
 extern BOOL32 EVENT_Pending(void);
+extern void EVENT_WakeUp(void);
 
 /* input.c */
 
diff --git a/include/ttydrv.h b/include/ttydrv.h
index 1c38239..8600722 100644
--- a/include/ttydrv.h
+++ b/include/ttydrv.h
@@ -5,7 +5,7 @@
 #ifndef __WINE_TTYDRV_H
 #define __WINE_TTYDRV_H
 
-#include "windows.h"
+#include "wintypes.h"
 #include "wine/winuser16.h"
 
 struct tagCLASS;
@@ -57,6 +57,7 @@
 extern void TTYDRV_EVENT_DummyMotionNotify(void);
 extern BOOL32 TTYDRV_EVENT_Pending(void);
 extern BOOL16 TTYDRV_EVENT_IsUserIdle(void);
+extern void TTYDRV_EVENT_WakeUp(void);
 
 /* TTY keyboard driver */
 
diff --git a/include/x11drv.h b/include/x11drv.h
index a49e5e4..b3bf74d 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -262,6 +262,7 @@
 extern void X11DRV_EVENT_DummyMotionNotify(void);
 extern BOOL32 X11DRV_EVENT_Pending(void);
 extern BOOL16 X11DRV_EVENT_IsUserIdle(void);
+extern void X11DRV_EVENT_WakeUp(void);
 
 /* X11 keyboard driver */
 
diff --git a/loader/task.c b/loader/task.c
index 3bb95ad..2d65a29 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -500,7 +500,8 @@
     if ( THREAD_IsWin16( THREAD_Current() ) )
         OldYield();
     else
-        FIXME(task, "Don't know how to start 16-bit task from 32-bit thread. Move the mouse!\n");
+        /* wake-up the scheduler waiting in EVENT_WaitNetEvent */
+        EVENT_WakeUp();
 }
 
 
@@ -944,13 +945,13 @@
     if (!hTask) hTask = GetCurrentTask();
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
 
+    pTask->nEvents++;
+    
     if ( !THREAD_IsWin16( THREAD_Current() ) )
     {
-        WARN(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
-        /* return; */
+        /* wake-up the scheduler waiting in EVENT_WaitNetEvent */
+        EVENT_WakeUp();
     }
-
-    pTask->nEvents++;
 }
 
 
diff --git a/windows/event.c b/windows/event.c
index 5e683b0..eeefc6e 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -119,3 +119,15 @@
 {
   return EVENT_GetDriver()->pIsUserIdle();
 }
+
+/***********************************************************************
+ *		EVENT_WakeUp
+ *
+ * Wake up the scheduler (EVENT_WaitNetEvent). Use by 32 bit thread
+ * when thew want signaled an event to a 16 bit task. This function
+ * will become obsolete when an Asynchronous thread will be implemented
+ */
+void EVENT_WakeUp(void)
+{
+  EVENT_GetDriver()->pWakeUp();
+}
diff --git a/windows/ttydrv/event.c b/windows/ttydrv/event.c
index 5ebb5b6..9d73e86 100644
--- a/windows/ttydrv/event.c
+++ b/windows/ttydrv/event.c
@@ -91,3 +91,9 @@
   return TRUE;
 }
 
+/**********************************************************************
+ *		TTYDRV_EVENT_WakeUp
+ */
+void TTYDRV_EVENT_WakeUp(void)
+{
+}
diff --git a/windows/ttydrv/init.c b/windows/ttydrv/init.c
index 0e1db00..a5203d7 100644
--- a/windows/ttydrv/init.c
+++ b/windows/ttydrv/init.c
@@ -37,7 +37,8 @@
   TTYDRV_EVENT_QueryPointer,
   TTYDRV_EVENT_DummyMotionNotify,
   TTYDRV_EVENT_Pending,
-  TTYDRV_EVENT_IsUserIdle
+  TTYDRV_EVENT_IsUserIdle,
+  TTYDRV_EVENT_WakeUp
 };
 
 KEYBOARD_DRIVER TTYDRV_KEYBOARD_Driver =
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index c12a205..a032932 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -16,6 +16,7 @@
 
 #include <assert.h>
 #include <string.h>
+#include <unistd.h>
 #include "callback.h"
 #include "class.h"
 #include "clipboard.h"
@@ -67,6 +68,7 @@
 static fd_set __event_io_set[3];
 static int    __event_max_fd = 0;
 static int    __event_x_connection = 0;
+static int    __wakeup_pipe[2];
 
 static const char * const event_names[] =
 {
@@ -119,6 +121,20 @@
   
   __event_max_fd = __event_x_connection = ConnectionNumber(display);
   FD_SET( __event_x_connection, &__event_io_set[EVENT_IO_READ] );
+
+  /* this pipe is used to be able to wake-up the scheduler(WaitNetEvent) by
+   a 32 bit thread, this will become obsolete when the input thread will be
+   implemented */
+  pipe(__wakeup_pipe);
+
+  /* make the pipe non-blocking */
+  fcntl(__wakeup_pipe[0], F_SETFL, O_NONBLOCK);
+  fcntl(__wakeup_pipe[1], F_SETFL, O_NONBLOCK);
+  
+  FD_SET( __wakeup_pipe[0], &__event_io_set[EVENT_IO_READ] );
+  if (__wakeup_pipe[0] > __event_max_fd)
+      __event_max_fd = __wakeup_pipe[0];
+      
   __event_max_fd++;
   return TRUE;
 }
@@ -155,6 +171,26 @@
   return FALSE;
 }
 
+
+/***********************************************************************
+ *           EVENT_ReadWakeUpPipe
+ *
+ * Empty the wake up pipe
+ */
+void EVENT_ReadWakeUpPipe(void)
+{
+    char tmpBuf[10];
+    ssize_t ret;
+          
+    EnterCriticalSection(&X11DRV_CritSection);
+    
+    /* Flush the wake-up pipe, it's just dummy data for waking-up this
+     thread. This will be obsolete when the input thread will be done */
+    while ( (ret = read(__wakeup_pipe[0], &tmpBuf, 10)) == 10 );
+
+    LeaveCriticalSection(&X11DRV_CritSection);
+}
+
 /***********************************************************************
  *           X11DRV_EVENT_WaitNetEvent
  *
@@ -209,6 +245,7 @@
       num_pending = select( __event_max_fd, &io_set[EVENT_IO_READ],
 			    &io_set[EVENT_IO_WRITE],
 			    &io_set[EVENT_IO_EXCEPT], &timeout );
+      
       if ( num_pending == 0)
         {
 	  /* Timeout or error */
@@ -217,6 +254,14 @@
         }
 #endif  /* CONFIG_IPC */
       
+      /* Flush the wake-up pipe, it's just dummy data for waking-up this
+       thread. This will be obsolete when the input thread will be done */
+      if ( FD_ISSET( __wakeup_pipe[0], &io_set[EVENT_IO_READ] ) )
+      {
+          num_pending--;
+          EVENT_ReadWakeUpPipe();
+      }
+       
       /*  Winsock asynchronous services */
       
       if( FD_ISSET( __event_x_connection, &io_set[EVENT_IO_READ]) ) 
@@ -234,10 +279,24 @@
   else if(!pending)
     {				/* Wait for X11 input. */
       fd_set set;
+      int max_fd;
       
       FD_ZERO(&set);
       FD_SET(__event_x_connection, &set);
-      select(__event_x_connection + 1, &set, 0, 0, 0 );
+
+      /* wait on wake-up pipe also */
+      FD_SET(__wakeup_pipe[0], &set);
+      if (__event_x_connection > __wakeup_pipe[0])
+          max_fd = __event_x_connection + 1;
+      else
+          max_fd = __wakeup_pipe[0] + 1;
+          
+      select(max_fd, &set, 0, 0, 0 );
+
+      /* Flush the wake-up pipe, it's just dummy data for waking-up this
+       thread. This will be obsolete when the input thread will be done */
+      if ( FD_ISSET( __wakeup_pipe[0], &set ) )
+          EVENT_ReadWakeUpPipe();
     }
   
   /* Process current X event (and possibly others that occurred in the meantime) */
@@ -1057,7 +1116,8 @@
   if( !lpDragInfo || !spDragInfo ) return;
   
   TSXQueryPointer( display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child, 
-		   &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
+                   &x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
+                   (unsigned int*)&aux_long);
   
   lpDragInfo->hScope = pWnd->hwndSelf;
   lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
@@ -1079,7 +1139,7 @@
     {
       TSXGetWindowProperty( display, DefaultRootWindow(display),
 			    dndSelection, 0, 65535, FALSE,
-			    AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
+			    AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
 			    &data_length, &aux_long, &p_data);
       
       if( !aux_long && p_data)	/* don't bother if > 64K */
@@ -1364,4 +1424,16 @@
   return TSXPending(display);
 }
 
+/**********************************************************************
+ *		X11DRV_EVENT_WakeUp
+ */
+void X11DRV_EVENT_WakeUp(void)
+{
+    /* wake-up EVENT_WaitNetEvent function, a 32 bit thread post an event
+     for a 16 bit task */
+    if (write (__wakeup_pipe[1], "A", 1) != 1)
+        ERR(event, "unable to write in wakeup_pipe\n");
+}
+
+
 #endif /* !defined(X_DISPLAY_MISSING) */
diff --git a/windows/x11drv/init.c b/windows/x11drv/init.c
index 31358d7..e7ac2db 100644
--- a/windows/x11drv/init.c
+++ b/windows/x11drv/init.c
@@ -42,7 +42,8 @@
   X11DRV_EVENT_QueryPointer,
   X11DRV_EVENT_DummyMotionNotify,
   X11DRV_EVENT_Pending,
-  X11DRV_EVENT_IsUserIdle
+  X11DRV_EVENT_IsUserIdle,
+  X11DRV_EVENT_WakeUp
 };
 
 KEYBOARD_DRIVER X11DRV_KEYBOARD_Driver =