Better implementation of [GS]etForegroundWindow.
Fixed focus handling on inter-thread activation.
Adapted FocusIn/Out event handling to per-queue focus.

diff --git a/windows/winpos.c b/windows/winpos.c
index 11d365e..5954f18 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -899,17 +899,27 @@
  */
 HWND WINAPI GetForegroundWindow(void)
 {
-    return GetActiveWindow();
-}
+    HWND hwndActive = 0;
 
+    /* Get the foreground window (active window of hActiveQueue) */
+    if ( hActiveQueue )
+    {
+        MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
+        if ( pActiveQueue )
+            hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
+
+        QUEUE_Unlock( pActiveQueue );
+    }
+
+    return hwndActive;
+}
 
 /*******************************************************************
  *         SetForegroundWindow    (USER32.482)
  */
 BOOL WINAPI SetForegroundWindow( HWND hwnd )
 {
-    SetActiveWindow( hwnd );
-    return TRUE;
+    return WINPOS_ChangeActiveWindow( hwnd, FALSE );
 }
 
 
@@ -1643,6 +1653,8 @@
     HWND     hwndActive = 0;
     BOOL     bRet = 0;
 
+    TRACE( win, "(%04x, %d, %d)\n", hWnd, fMouse, fChangeFocus );
+
     /* Get current active window from the active queue */
     if ( hActiveQueue )
     {
@@ -1784,7 +1796,7 @@
         }
         WIN_ReleaseDesktop();
         
-	if (!IsWindow(hWnd)) goto CLEANUP;
+	if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
     }
 
     if (hWnd)
@@ -1808,13 +1820,27 @@
     }
 
     /* change focus if possible */
-    if( fChangeFocus && GetFocus() )
-	if( WIN_GetTopParent(GetFocus()) != hwndActive )
-	    FOCUS_SwitchFocus( pNewActiveQueue, GetFocus(),
-			       (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
-			       0:
-			       hwndActive
-	    );
+    if ( fChangeFocus )
+    {
+        if ( pNewActiveQueue )
+        {
+            HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
+
+            if ( WIN_GetTopParent( hOldFocus ) != hwndActive )
+                FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus, 
+                                   (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
+                                   0 : hwndActive );
+        }
+
+        if ( pOldActiveQueue && 
+             ( !pNewActiveQueue || 
+                pNewActiveQueue->pQData != pOldActiveQueue->pQData ) )
+        {
+            HWND hOldFocus = PERQDATA_GetFocusWnd( pOldActiveQueue->pQData );
+            if ( hOldFocus )
+                FOCUS_SwitchFocus( pOldActiveQueue, hOldFocus, 0 );
+        }
+    }
 
     if( !hwndPrevActive && wndPtr )
         (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 15bed2a..bde0155 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -660,18 +660,12 @@
  */
 static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event )
 {
-  if (Options.managed) EVENT_QueryZOrder( hWnd );
-  
-  if (event->detail != NotifyPointer)
-    { 
-      if (hWnd != GetActiveWindow())
+    if (event->detail != NotifyPointer)
+        if (hWnd != GetForegroundWindow())
         {
-	  WINPOS_ChangeActiveWindow( hWnd, FALSE );
-	  X11DRV_KEYBOARD_UpdateState();
+            SetForegroundWindow( hWnd );
+	    X11DRV_KEYBOARD_UpdateState();
         }
-      if ((hWnd != GetFocus()) && !IsChild( hWnd, GetFocus()))
-            SetFocus( hWnd );
-    }
 }
 
 
@@ -683,15 +677,11 @@
 static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event )
 {
     if (event->detail != NotifyPointer)
-    {
-        if (hWnd == GetActiveWindow())
+        if (hWnd == GetForegroundWindow())
 	{
 	    SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
-	    WINPOS_ChangeActiveWindow( 0, FALSE );
+	    SetForegroundWindow( 0 );
 	}
-        if ((hWnd == GetFocus()) || IsChild( hWnd, GetFocus()))
-	    SetFocus( 0 );
-    }
 }
 
 /**********************************************************************
@@ -699,13 +689,13 @@
  */
 BOOL X11DRV_EVENT_CheckFocus(void)
 {
-  WND*   pWnd;
+  HWND   hWnd;
   Window xW;
   int	   state;
   
   TSXGetInputFocus(display, &xW, &state);
     if( xW == None ||
-        TSXFindContext(display, xW, winContext, (char **)&pWnd) ) 
+        TSXFindContext(display, xW, winContext, (char **)&hWnd) ) 
       return FALSE;
     return TRUE;
 }