Commit b427856b authored by Noel Borthwick's avatar Noel Borthwick Committed by Alexandre Julliard

Added management and allocation of the PERQUEUEDATA structure.

parent 4ef92519
...@@ -59,7 +59,6 @@ extern BOOL32 EVENT_Pending(void); ...@@ -59,7 +59,6 @@ extern BOOL32 EVENT_Pending(void);
/* input.c */ /* input.c */
extern HWND32 EVENT_Capture( HWND32, INT16 ); extern HWND32 EVENT_Capture( HWND32, INT16 );
extern INT16 EVENT_GetCaptureInfo(void);
extern BOOL32 EVENT_QueryPointer( DWORD *posX, DWORD *posY, DWORD *state ); extern BOOL32 EVENT_QueryPointer( DWORD *posX, DWORD *posY, DWORD *state );
extern void joySendMessages(void); extern void joySendMessages(void);
......
...@@ -28,17 +28,26 @@ typedef struct ...@@ -28,17 +28,26 @@ typedef struct
BOOL16 bPending; BOOL16 bPending;
} QSMCTRL; } QSMCTRL;
/* Per-queue system windows */ /* Per-queue data for the message queue
* Note that we currently only store the current values for
* Active, Capture and Focus windows currently.
* It might be necessary to store a pointer to the system message queue
* as well since windows 9x maintains per thread system message queues
*/
typedef struct tagPERQUEUEDATA typedef struct tagPERQUEUEDATA
{ {
HWND32 hWndCapture; HWND32 hWndFocus; /* Focus window */
HWND32 hWndFocus; HWND32 hWndActive; /* Active window */
HWND32 hWndActive; HWND32 hWndCapture; /* Capture window */
INT16 nCaptureHT; /* Capture info (hit-test) */
ULONG ulRefCount; /* Reference count */
CRITICAL_SECTION cSection; /* Critical section for thread safe access */
} PERQUEUEDATA; } PERQUEUEDATA;
/* Message queue */
typedef struct tagMESSAGEQUEUE typedef struct tagMESSAGEQUEUE
{ {
HQUEUE16 next; /* NNext queue */ HQUEUE16 next; /* Next queue */
HQUEUE16 self; /* Handle to self (was: reserved) */ HQUEUE16 self; /* Handle to self (was: reserved) */
THDB* thdb; /* Thread owning queue */ THDB* thdb; /* Thread owning queue */
HANDLE32 hEvent; /* Event handle */ HANDLE32 hEvent; /* Event handle */
...@@ -84,7 +93,7 @@ typedef struct tagMESSAGEQUEUE ...@@ -84,7 +93,7 @@ typedef struct tagMESSAGEQUEUE
HANDLE16 hCurHook; /* Current hook */ HANDLE16 hCurHook; /* Current hook */
HANDLE16 hooks[WH_NB_HOOKS]; /* Task hooks list */ HANDLE16 hooks[WH_NB_HOOKS]; /* Task hooks list */
HANDLE16 hPerQueue; /* handle on PERQUEUEDATA structure */ PERQUEUEDATA *pQData; /* pointer to (shared) PERQUEUEDATA structure */
} MESSAGEQUEUE; } MESSAGEQUEUE;
...@@ -99,6 +108,20 @@ typedef struct tagMESSAGEQUEUE ...@@ -99,6 +108,20 @@ typedef struct tagMESSAGEQUEUE
#define QUEUE_MAGIC 0xD46E80AF #define QUEUE_MAGIC 0xD46E80AF
/* Per queue data management methods */
PERQUEUEDATA* PERQDATA_CreateInstance( );
ULONG PERQDATA_Addref( PERQUEUEDATA* pQData );
ULONG PERQDATA_Release( PERQUEUEDATA* pQData );
HWND32 PERQDATA_GetFocusWnd( PERQUEUEDATA *pQData );
HWND32 PERQDATA_SetFocusWnd( PERQUEUEDATA *pQData, HWND32 hWndFocus );
HWND32 PERQDATA_GetActiveWnd( PERQUEUEDATA *pQData );
HWND32 PERQDATA_SetActiveWnd( PERQUEUEDATA *pQData, HWND32 hWndActive );
HWND32 PERQDATA_GetCaptureWnd( PERQUEUEDATA *pQData );
HWND32 PERQDATA_SetCaptureWnd( PERQUEUEDATA *pQData, HWND32 hWndCapture );
INT16 PERQDATA_GetCaptureInfo( PERQUEUEDATA *pQData );
INT16 PERQDATA_SetCaptureInfo( PERQUEUEDATA *pQData, INT16 nCaptureHT );
/* Message queue management methods */
extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue ); extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue );
extern void QUEUE_Unlock( MESSAGEQUEUE *queue ); extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
extern void QUEUE_DumpQueue( HQUEUE16 hQueue ); extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "ldt.h" #include "ldt.h"
#include "windows.h" #include "windows.h"
#include "winproc.h" #include "winproc.h"
#include "queue.h"
#define WND_MAGIC 0x444e4957 /* 'WIND' */ #define WND_MAGIC 0x444e4957 /* 'WIND' */
...@@ -172,6 +174,6 @@ extern HWND32 ICONTITLE_Create( WND* ); ...@@ -172,6 +174,6 @@ extern HWND32 ICONTITLE_Create( WND* );
extern BOOL32 ICONTITLE_Init( void ); extern BOOL32 ICONTITLE_Init( void );
/* windows/focus.c */ /* windows/focus.c */
extern void FOCUS_SwitchFocus( HWND32 , HWND32 ); extern void FOCUS_SwitchFocus( MESSAGEQUEUE *pMsgQ, HWND32 , HWND32 );
#endif /* __WINE_WIN_H */ #endif /* __WINE_WIN_H */
...@@ -41,7 +41,7 @@ extern LONG WINPOS_SendNCCalcSize(HWND32 hwnd, BOOL32 calcValidRect, ...@@ -41,7 +41,7 @@ extern LONG WINPOS_SendNCCalcSize(HWND32 hwnd, BOOL32 calcValidRect,
extern LONG WINPOS_HandleWindowPosChanging16(WND *wndPtr, WINDOWPOS16 *winpos); extern LONG WINPOS_HandleWindowPosChanging16(WND *wndPtr, WINDOWPOS16 *winpos);
extern LONG WINPOS_HandleWindowPosChanging32(WND *wndPtr, WINDOWPOS32 *winpos); extern LONG WINPOS_HandleWindowPosChanging32(WND *wndPtr, WINDOWPOS32 *winpos);
extern INT16 WINPOS_WindowFromPoint( WND* scopeWnd, POINT16 pt, WND **ppWnd ); extern INT16 WINPOS_WindowFromPoint( WND* scopeWnd, POINT16 pt, WND **ppWnd );
extern void WINPOS_CheckInternalPos( HWND32 hwnd ); extern void WINPOS_CheckInternalPos( WND* wndPtr );
extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd); extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
extern BOOL32 WINPOS_CreateInternalPosAtom(void); extern BOOL32 WINPOS_CreateInternalPosAtom(void);
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "server.h" #include "server.h"
#include "stackframe.h" #include "stackframe.h"
#include "debug.h" #include "debug.h"
#include "queue.h"
#include "hook.h"
#ifndef __i386__ #ifndef __i386__
THDB *pCurrentThread; THDB *pCurrentThread;
...@@ -788,25 +790,79 @@ BOOL32 WINAPI GetThreadTimes( ...@@ -788,25 +790,79 @@ BOOL32 WINAPI GetThreadTimes(
* RETURNS * RETURNS
* Success: TRUE * Success: TRUE
* Failure: FALSE * Failure: FALSE
*
* TODO:
* 1. Reset the Key State (currenly per thread key state is not maintained)
*/ */
BOOL32 WINAPI AttachThreadInput( BOOL32 WINAPI AttachThreadInput(
DWORD idAttach, /* [in] Thread to attach */ DWORD idAttach, /* [in] Thread to attach */
DWORD idAttachTo, /* [in] Thread to attach to */ DWORD idAttachTo, /* [in] Thread to attach to */
BOOL32 fAttach) /* [in] Attach or detach */ BOOL32 fAttach) /* [in] Attach or detach */
{ {
BOOL32 ret; MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
BOOL16 bRet = 0;
FIXME(thread, "(0x%08lx,0x%08lx,%d): stub\n",idAttach,idAttachTo,fAttach);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (fAttach) {
/* Attach threads */ /* A thread cannot attach to itself */
ret = FALSE; if ( idAttach == idAttachTo )
goto CLEANUP;
/* According to the docs this method should fail if a
* "Journal record" hook is installed. (attaches all input queues together)
*/
if ( HOOK_IsHooked( WH_JOURNALRECORD ) )
goto CLEANUP;
/* Retrieve message queues corresponding to the thread id's */
pTgtMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue( idAttach ) );
pSrcMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue( idAttachTo ) );
/* Ensure we have message queues and that Src and Tgt threads
* are not system threads.
*/
if ( !pSrcMsgQ || !pTgtMsgQ || !pSrcMsgQ->pQData || !pTgtMsgQ->pQData )
goto CLEANUP;
if (fAttach) /* Attach threads */
{
/* Only attach if currently detached */
if ( pTgtMsgQ->pQData != pSrcMsgQ->pQData )
{
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Share a reference to the source threads perQDATA */
PERQDATA_Addref( pSrcMsgQ->pQData );
pTgtMsgQ->pQData = pSrcMsgQ->pQData;
}
} }
else { else /* Detach threads */
/* Detach threads */ {
ret = FALSE; /* Only detach if currently attached */
}; if ( pTgtMsgQ->pQData == pSrcMsgQ->pQData )
return ret; {
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Give the target thread its own private perQDATA once more */
pTgtMsgQ->pQData = PERQDATA_CreateInstance();
}
}
/* TODO: Reset the Key State */
bRet = 1; // Success
CLEANUP:
/* Unlock the queues before returning */
if ( pSrcMsgQ )
QUEUE_Unlock( pSrcMsgQ );
if ( pTgtMsgQ )
QUEUE_Unlock( pTgtMsgQ );
return bRet;
} }
/********************************************************************** /**********************************************************************
......
...@@ -11,17 +11,20 @@ ...@@ -11,17 +11,20 @@
#include "winpos.h" #include "winpos.h"
#include "hook.h" #include "hook.h"
#include "message.h" #include "message.h"
#include "task.h"
#include "debug.h"
static HWND32 hwndFocus = 0;
/***************************************************************** /*****************************************************************
* FOCUS_SwitchFocus * FOCUS_SwitchFocus
* pMsgQ is the queue whose perQData focus is to be modified
*/ */
void FOCUS_SwitchFocus( HWND32 hFocusFrom, HWND32 hFocusTo ) void FOCUS_SwitchFocus( MESSAGEQUEUE *pMsgQ, HWND32 hFocusFrom, HWND32 hFocusTo )
{ {
WND *pFocusTo = WIN_FindWndPtr( hFocusTo ); WND *pFocusTo = WIN_FindWndPtr( hFocusTo );
hwndFocus = hFocusTo;
PERQDATA_SetFocusWnd( pMsgQ->pQData, hFocusTo );
#if 0 #if 0
if (hFocusFrom) SendMessage32A( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 ); if (hFocusFrom) SendMessage32A( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
#else #else
...@@ -29,7 +32,8 @@ void FOCUS_SwitchFocus( HWND32 hFocusFrom, HWND32 hFocusTo ) ...@@ -29,7 +32,8 @@ void FOCUS_SwitchFocus( HWND32 hFocusFrom, HWND32 hFocusTo )
* intertask at this time */ * intertask at this time */
if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 ); if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
#endif #endif
if( !pFocusTo || hFocusTo != hwndFocus )
if( !pFocusTo || hFocusTo != PERQDATA_GetFocusWnd( pMsgQ->pQData ) )
return; return;
/* According to API docs, the WM_SETFOCUS message is sent AFTER the window /* According to API docs, the WM_SETFOCUS message is sent AFTER the window
...@@ -59,8 +63,17 @@ HWND16 WINAPI SetFocus16( HWND16 hwnd ) ...@@ -59,8 +63,17 @@ HWND16 WINAPI SetFocus16( HWND16 hwnd )
*/ */
HWND32 WINAPI SetFocus32( HWND32 hwnd ) HWND32 WINAPI SetFocus32( HWND32 hwnd )
{ {
HWND32 hWndPrevFocus, hwndTop = hwnd; HWND32 hWndFocus = 0, hwndTop = hwnd;
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
BOOL16 bRet = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
{
WARN( win, "\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP;
}
if (wndPtr) if (wndPtr)
{ {
...@@ -69,35 +82,79 @@ HWND32 WINAPI SetFocus32( HWND32 hwnd ) ...@@ -69,35 +82,79 @@ HWND32 WINAPI SetFocus32( HWND32 hwnd )
while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD ) while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
{ {
if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) ) if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) )
return 0; goto CLEANUP;
if (!(wndPtr = wndPtr->parent)) return 0; if (!(wndPtr = wndPtr->parent)) goto CLEANUP;
hwndTop = wndPtr->hwndSelf; hwndTop = wndPtr->hwndSelf;
} }
if( hwnd == hwndFocus ) return hwnd; /* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
if ( !pMsgQ )
{
WARN( win, "\tMessage queue not found. Exiting!\n" );
goto CLEANUP;
}
/* Make sure that message queue for the window we are setting focus to
* shares the same perQ data as the current threads message queue.
* In other words you can't set focus to a window owned by a different
* thread unless AttachThreadInput has been called previously.
* (see AttachThreadInput and SetFocus docs)
*/
if ( pCurMsgQ->pQData != pMsgQ->pQData )
goto CLEANUP;
/* Get the current focus window from the perQ data */
hWndFocus = PERQDATA_GetFocusWnd( pMsgQ->pQData );
if( hwnd == hWndFocus )
{
bRet = 1; // Success
goto CLEANUP; // Nothing to do
}
/* call hooks */ /* call hooks */
if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, (WPARAM16)hwnd, if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, (WPARAM16)hwnd,
(LPARAM)hwndFocus) ) (LPARAM)hWndFocus) )
return 0; goto CLEANUP;
/* activate hwndTop if needed. */ /* activate hwndTop if needed. */
if (hwndTop != GetActiveWindow32()) if (hwndTop != GetActiveWindow32())
{ {
if (!WINPOS_SetActiveWindow(hwndTop, 0, 0)) return 0; if (!WINPOS_SetActiveWindow(hwndTop, 0, 0)) goto CLEANUP;
if (!IsWindow32( hwnd )) return 0; /* Abort if window destroyed */ if (!IsWindow32( hwnd )) goto CLEANUP; /* Abort if window destroyed */
} }
/* Get the current focus window from the perQ data */
hWndFocus = PERQDATA_GetFocusWnd( pMsgQ->pQData );
/* Change focus and send messages */
FOCUS_SwitchFocus( pMsgQ, hWndFocus, hwnd );
} }
else if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hwndFocus ) ) else /* NULL hwnd passed in */
return 0; {
if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hWndFocus ) )
goto CLEANUP;
/* Get the current focus from the perQ data of the current message Q */
hWndFocus = PERQDATA_GetFocusWnd( pCurMsgQ->pQData );
/* Change focus and send messages */ /* Change focus and send messages */
hWndPrevFocus = hwndFocus; FOCUS_SwitchFocus( pCurMsgQ, hWndFocus, hwnd );
}
bRet = 1; // Success
CLEANUP:
FOCUS_SwitchFocus( hwndFocus , hwnd ); /* Unlock the queues before returning */
if ( pMsgQ )
QUEUE_Unlock( pMsgQ );
if ( pCurMsgQ )
QUEUE_Unlock( pCurMsgQ );
return hWndPrevFocus; return bRet ? hWndFocus : 0;
} }
...@@ -106,7 +163,7 @@ HWND32 WINAPI SetFocus32( HWND32 hwnd ) ...@@ -106,7 +163,7 @@ HWND32 WINAPI SetFocus32( HWND32 hwnd )
*/ */
HWND16 WINAPI GetFocus16(void) HWND16 WINAPI GetFocus16(void)
{ {
return (HWND16)hwndFocus; return (HWND16)GetFocus32();
} }
...@@ -115,5 +172,20 @@ HWND16 WINAPI GetFocus16(void) ...@@ -115,5 +172,20 @@ HWND16 WINAPI GetFocus16(void)
*/ */
HWND32 WINAPI GetFocus32(void) HWND32 WINAPI GetFocus32(void)
{ {
MESSAGEQUEUE *pCurMsgQ = 0;
HWND32 hwndFocus = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
{
WARN( win, "\tCurrent message queue not found. Exiting!\n" );
return 0;
}
/* Get the current focus from the perQ data of the current message Q */
hwndFocus = PERQDATA_GetFocusWnd( pCurMsgQ->pQData );
QUEUE_Unlock( pCurMsgQ );
return hwndFocus; return hwndFocus;
} }
...@@ -27,9 +27,8 @@ ...@@ -27,9 +27,8 @@
#include "debugtools.h" #include "debugtools.h"
#include "struct32.h" #include "struct32.h"
#include "winerror.h" #include "winerror.h"
#include "task.h"
static INT16 captureHT = HTCLIENT;
static HWND32 captureWnd = 0;
static BOOL32 InputEnabled = TRUE; static BOOL32 InputEnabled = TRUE;
static BOOL32 SwappedButtons = FALSE; static BOOL32 SwappedButtons = FALSE;
...@@ -274,7 +273,20 @@ BOOL32 WINAPI SwapMouseButton32( BOOL32 fSwap ) ...@@ -274,7 +273,20 @@ BOOL32 WINAPI SwapMouseButton32( BOOL32 fSwap )
*/ */
HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht) HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
{ {
HWND32 capturePrev = captureWnd; HWND32 capturePrev = 0, captureWnd = 0;
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
WND* wndPtr = 0;
INT16 captureHT = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
{
WARN( win, "\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP;
}
/* Get the current capture window from the perQ data of the current message Q */
capturePrev = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
if (!hwnd) if (!hwnd)
{ {
...@@ -283,7 +295,7 @@ HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht) ...@@ -283,7 +295,7 @@ HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
} }
else else
{ {
WND* wndPtr = WIN_FindWndPtr( hwnd ); wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr) if (wndPtr)
{ {
TRACE(win, "(0x%04x)\n", hwnd ); TRACE(win, "(0x%04x)\n", hwnd );
...@@ -292,23 +304,48 @@ HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht) ...@@ -292,23 +304,48 @@ HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
} }
} }
if( capturePrev && capturePrev != captureWnd ) /* Update the perQ capture window and send messages */
if( capturePrev != captureWnd )
{
if (wndPtr)
{
/* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
if ( !pMsgQ )
{
WARN( win, "\tMessage queue not found. Exiting!\n" );
goto CLEANUP;
}
/* Make sure that message queue for the window we are setting capture to
* shares the same perQ data as the current threads message queue.
*/
if ( pCurMsgQ->pQData != pMsgQ->pQData )
goto CLEANUP;
}
PERQDATA_SetCaptureWnd( pCurMsgQ->pQData, captureWnd );
PERQDATA_SetCaptureInfo( pCurMsgQ->pQData, captureHT );
if( capturePrev )
{ {
WND* wndPtr = WIN_FindWndPtr( capturePrev ); WND* wndPtr = WIN_FindWndPtr( capturePrev );
if( wndPtr && (wndPtr->flags & WIN_ISWIN32) ) if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
SendMessage32A( capturePrev, WM_CAPTURECHANGED, 0L, hwnd); SendMessage32A( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
} }
return capturePrev;
} }
/********************************************************************** CLEANUP:
* EVENT_GetCaptureInfo /* Unlock the queues before returning */
*/ if ( pMsgQ )
INT16 EVENT_GetCaptureInfo() QUEUE_Unlock( pMsgQ );
{ if ( pCurMsgQ )
return captureHT; QUEUE_Unlock( pCurMsgQ );
return capturePrev;
} }
/********************************************************************** /**********************************************************************
* SetCapture16 (USER.18) * SetCapture16 (USER.18)
*/ */
...@@ -332,8 +369,7 @@ HWND32 WINAPI SetCapture32( HWND32 hwnd ) ...@@ -332,8 +369,7 @@ HWND32 WINAPI SetCapture32( HWND32 hwnd )
*/ */
void WINAPI ReleaseCapture(void) void WINAPI ReleaseCapture(void)
{ {
TRACE(win, "captureWnd=%04x\n", captureWnd ); EVENT_Capture( 0, 0 );
if( captureWnd ) EVENT_Capture( 0, 0 );
} }
...@@ -342,7 +378,7 @@ void WINAPI ReleaseCapture(void) ...@@ -342,7 +378,7 @@ void WINAPI ReleaseCapture(void)
*/ */
HWND16 WINAPI GetCapture16(void) HWND16 WINAPI GetCapture16(void)
{ {
return captureWnd; return (HWND16)GetCapture32();
} }
/********************************************************************** /**********************************************************************
...@@ -350,7 +386,21 @@ HWND16 WINAPI GetCapture16(void) ...@@ -350,7 +386,21 @@ HWND16 WINAPI GetCapture16(void)
*/ */
HWND32 WINAPI GetCapture32(void) HWND32 WINAPI GetCapture32(void)
{ {
return captureWnd; MESSAGEQUEUE *pCurMsgQ = 0;
HWND32 hwndCapture = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
{
TRACE( win, "GetCapture32: Current message queue not found. Exiting!\n" );
return 0;
}
/* Get the current capture window from the perQ data of the current message Q */
hwndCapture = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
QUEUE_Unlock( pCurMsgQ );
return hwndCapture;
} }
/********************************************************************** /**********************************************************************
......
...@@ -122,7 +122,8 @@ static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter, ...@@ -122,7 +122,8 @@ static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter,
else else
{ {
pWnd = WIN_FindWndPtr(hWnd); pWnd = WIN_FindWndPtr(hWnd);
ht = EVENT_GetCaptureInfo(); if (queue)
ht = PERQDATA_GetCaptureInfo( queue->pQData );
} }
/* stop if not the right queue */ /* stop if not the right queue */
......
...@@ -282,7 +282,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) ...@@ -282,7 +282,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */ /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
WINPOS_CheckInternalPos( hwnd ); WINPOS_CheckInternalPos( wndPtr );
if( hwnd == GetCapture32()) ReleaseCapture(); if( hwnd == GetCapture32()) ReleaseCapture();
/* free resources associated with the window */ /* free resources associated with the window */
...@@ -1322,6 +1322,8 @@ BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable ) ...@@ -1322,6 +1322,8 @@ BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
{ {
WND *wndPtr; WND *wndPtr;
TRACE(win,"EnableWindow32: ( %x, %d )\n", hwnd, enable);
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (enable && (wndPtr->dwStyle & WS_DISABLED)) if (enable && (wndPtr->dwStyle & WS_DISABLED))
{ {
...@@ -1335,9 +1337,13 @@ BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable ) ...@@ -1335,9 +1337,13 @@ BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
/* Disable window */ /* Disable window */
wndPtr->dwStyle |= WS_DISABLED; wndPtr->dwStyle |= WS_DISABLED;
if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() )) if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
{
SetFocus32( 0 ); /* A disabled window can't have the focus */ SetFocus32( 0 ); /* A disabled window can't have the focus */
}
if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() )) if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
{
ReleaseCapture(); /* A disabled window can't capture the mouse */ ReleaseCapture(); /* A disabled window can't capture the mouse */
}
SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 ); SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
return FALSE; return FALSE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment