Fixed some bugs in thread safeness for wnd struct.

This commit is contained in:
Francois Boisvert 1999-03-28 12:42:52 +00:00 committed by Alexandre Julliard
parent 0dddc09bc4
commit 3a3cd9fab1
12 changed files with 305 additions and 122 deletions

View File

@ -3544,8 +3544,6 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
(!pTPWnd || (lppop->hWnd != pTPWnd->hwndSelf)))
DestroyWindow( lppop->hWnd );
MENU_ReleaseTopPopupWnd();
if (lppop->items) /* recursively destroy submenus */
{
int i;
@ -3558,8 +3556,13 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
HeapFree( SystemHeap, 0, lppop->items );
}
USER_HEAP_FREE( hMenu );
MENU_ReleaseTopPopupWnd();
}
else return FALSE;
else
{
MENU_ReleaseTopPopupWnd();
return FALSE;
}
}
return (hMenu != MENU_DefSysPopup);
}

View File

@ -410,13 +410,9 @@ static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
if( pWndStart->pDriver->pIsSelfClipping( pWndStart ) )
return TRUE; /* The driver itself will do the clipping */
for (; pWndStart != pWndEnd; pWndStart = WIN_LockWndPtr(pWndStart->next))
for (WIN_LockWndPtr(pWndStart); pWndStart != pWndEnd; WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
{
if( !(pWndStart->dwStyle & WS_VISIBLE) )
{
WIN_ReleaseWndPtr(pWndStart);
continue;
}
if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
rect.left = pWndStart->rectWindow.left + x;
rect.top = pWndStart->rectWindow.top + y;
@ -424,13 +420,11 @@ static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
rect.bottom = pWndStart->rectWindow.bottom + y;
if( IntersectRect( &rect, &rect, lpRect ))
if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
{
WIN_ReleaseWndPtr(pWndStart);
break;
}
WIN_ReleaseWndPtr(pWndStart);
{
if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
}
}
WIN_ReleaseWndPtr(pWndStart);
return (pWndStart == pWndEnd);
}

View File

@ -1598,14 +1598,15 @@ BOOL WINAPI CheckRadioButton( HWND hwndDlg, UINT firstID,
UINT lastID, UINT checkID )
{
WND *pWnd = WIN_FindWndPtr( hwndDlg );
if (!pWnd) return FALSE;
for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID))
{
WIN_ReleaseWndPtr(pWnd);
break;
}
if (!pWnd) return FALSE;
if (pWnd->wIDmenu == lastID)

View File

@ -87,7 +87,8 @@ HWND WINAPI SetFocus( HWND hwnd )
{
if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) )
goto CLEANUP;
if (!(wndPtr = wndPtr->parent)) goto CLEANUP;
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
if (!wndPtr) goto CLEANUP;
hwndTop = wndPtr->hwndSelf;
}

View File

@ -120,23 +120,25 @@ static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
for( index = id+1; index <= clientInfo->nActiveChildren +
clientInfo->idFirstChild; index++ )
{
wndPtr = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
if( !wndPtr )
WND *tmpWnd = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
if( !tmpWnd )
{
TRACE(mdi,"no window for id=%i\n",index);
WIN_ReleaseWndPtr(tmpWnd);
continue;
}
/* set correct id */
wndPtr->wIDmenu--;
tmpWnd->wIDmenu--;
n = sprintf(buffer, "%d ",index - clientInfo->idFirstChild);
if (wndPtr->text)
lstrcpynA(buffer + n, wndPtr->text, sizeof(buffer) - n );
if (tmpWnd->text)
lstrcpynA(buffer + n, tmpWnd->text, sizeof(buffer) - n );
/* change menu */
ModifyMenuA(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
index - 1 , buffer );
WIN_ReleaseWndPtr(tmpWnd);
}
retvalue = TRUE;
END:
@ -711,7 +713,7 @@ static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
}
}
HeapFree( SystemHeap, 0, heapPtr );
WIN_ReleaseWinArray(heapPtr);
}
if( total < ci->nActiveChildren )
@ -787,7 +789,7 @@ static void MDITile( WND* wndClient, MDICLIENTINFO *ci, WPARAM wParam )
x += xsize;
}
}
HeapFree( SystemHeap, 0, heapPtr );
WIN_ReleaseWinArray(heapPtr);
}
if( total < ci->nActiveChildren ) ArrangeIconicWindows( wndClient->hwndSelf );
@ -902,10 +904,12 @@ static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
if (!clientWnd)
return;
WIN_ReleaseWndPtr(clientWnd);
if (!ci)
{
WIN_ReleaseWndPtr(clientWnd);
return;
}
/* store new "default" title if lpTitle is not NULL */
if (lpTitle)
@ -944,13 +948,14 @@ static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
strcat( lpBuffer, "]" );
}
}
WIN_ReleaseWndPtr(childWnd);
}
else
{
strncpy(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH );
lpBuffer[MDI_MAXTITLELENGTH]='\0';
}
WIN_ReleaseWndPtr(childWnd);
}
else
lpBuffer[0] = '\0';
@ -959,6 +964,9 @@ static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
if( repaint == MDI_REPAINTFRAME)
SetWindowPos( frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
WIN_ReleaseWndPtr(clientWnd);
}

View File

@ -64,17 +64,23 @@ static void MSG_SendParentNotify(WND* wndPtr, WORD event, WORD idChild, LPARAM l
#define lppt ((LPPOINT16)&lValue)
/* pt has to be in the client coordinates of the parent window */
WND *tmpWnd = WIN_LockWndPtr(wndPtr);
MapWindowPoints16( 0, wndPtr->hwndSelf, lppt, 1 );
while (wndPtr)
MapWindowPoints16( 0, tmpWnd->hwndSelf, lppt, 1 );
while (tmpWnd)
{
if (!(wndPtr->dwStyle & WS_CHILD) || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) break;
lppt->x += wndPtr->rectClient.left;
lppt->y += wndPtr->rectClient.top;
wndPtr = wndPtr->parent;
SendMessageA( wndPtr->hwndSelf, WM_PARENTNOTIFY,
if (!(tmpWnd->dwStyle & WS_CHILD) || (tmpWnd->dwExStyle & WS_EX_NOPARENTNOTIFY))
{
WIN_ReleaseWndPtr(tmpWnd);
break;
}
lppt->x += tmpWnd->rectClient.left;
lppt->y += tmpWnd->rectClient.top;
WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
SendMessageA( tmpWnd->hwndSelf, WM_PARENTNOTIFY,
MAKEWPARAM( event, idChild ), lValue );
}
#undef lppt
}
@ -107,6 +113,7 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
(message == WM_RBUTTONDOWN) ||
(message == WM_MBUTTONDOWN))?1:0;
SYSQ_STATUS ret = 0;
DWORD retvalue;
/* Find the window */
@ -118,6 +125,7 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
{
ht = hittest = WINPOS_WindowFromPoint( pWndScope, pt, &pWnd );
if( !pWnd ) pWnd = WIN_GetDesktop();
else WIN_LockWndPtr(pWnd);
hWnd = pWnd->hwndSelf;
sendSC = 1;
}
@ -140,7 +148,8 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
QUEUE_Unlock( queue );
return SYSQ_MSG_ABANDON;
retvalue = SYSQ_MSG_ABANDON;
goto END;
}
/* check if hWnd is within hWndScope */
@ -149,7 +158,8 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
if( !IsChild(hTopWnd, hWnd) )
{
QUEUE_Unlock( queue );
return SYSQ_MSG_CONTINUE;
retvalue = SYSQ_MSG_CONTINUE;
goto END;
}
if( mouseClick )
@ -184,12 +194,14 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
if (!MSG_CheckFilter(message, first, last))
{
QUEUE_Unlock(queue);
return SYSQ_MSG_CONTINUE;
retvalue = SYSQ_MSG_CONTINUE;
goto END;
}
hCursorQueue = queue->self;
QUEUE_Unlock(queue);
/* call WH_MOUSE */
if (HOOK_IsHooked( WH_MOUSE ))
@ -205,9 +217,15 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
message, (LPARAM)SEGPTR_GET(hook) );
SEGPTR_FREE(hook);
}
if( ret ) return MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
if( ret )
{
retvalue = MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
goto END;
}
}
if ((hittest == HTERROR) || (hittest == HTNOWHERE))
eatMsg = sendSC = 1;
else if( remove && mouseClick )
@ -257,12 +275,20 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
if (sendSC)
SendMessageA( hWnd, WM_SETCURSOR, hWnd,
MAKELONG( hittest, message ));
if (eatMsg) return MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
if (eatMsg)
{
retvalue = MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
goto END;
}
msg->hwnd = hWnd;
msg->message = message;
msg->lParam = MAKELONG( pt.x, pt.y );
return SYSQ_MSG_ACCEPT;
retvalue = SYSQ_MSG_ACCEPT;
END:
WIN_ReleaseWndPtr(pWnd);
return retvalue;
}
@ -302,8 +328,10 @@ static DWORD MSG_TranslateKbdMsg( HWND hTopWnd, DWORD first, DWORD last,
queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
QUEUE_Unlock( queue );
WIN_ReleaseWndPtr(pWnd);
return SYSQ_MSG_ABANDON;
}
WIN_ReleaseWndPtr(pWnd);
if (hTopWnd && hWnd != hTopWnd)
if (!IsChild(hTopWnd, hWnd)) return SYSQ_MSG_CONTINUE;
@ -490,12 +518,16 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, DWORD first, DWORD last,
if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
{
HWND hWndScope = (HWND)qmsg->extraInfo;
status = MSG_TranslateMouseMsg(hwnd, first, last, msg, remove,
(Options.managed && IsWindow(hWndScope) )
? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop() );
HWND hWndScope = (HWND)qmsg->extraInfo;
WND *tmpWnd = (Options.managed && IsWindow(hWndScope) )
? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop();
status = MSG_TranslateMouseMsg(hwnd, first, last, msg, remove,tmpWnd );
kbd_msg = 0;
WIN_ReleaseWndPtr(tmpWnd);
}
else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
{
@ -631,6 +663,7 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue,
MESSAGEQUEUE *queue, *destQ;
SMSG *smsg;
LRESULT retVal = 1;
int iWndsLocks;
*pRes = 0;
@ -669,6 +702,8 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue,
if (QUEUE_AddSMSG(destQ, SM_PENDING_LIST, smsg) == FALSE)
return 0;
iWndsLocks = WIN_SuspendWndsLock();
/* force destination task to run next, if 16 bit threads */
if ( THREAD_IsWin16(THREAD_Current()) && THREAD_IsWin16(destQ->thdb) )
DirectedYield16( destQ->thdb->teb.htask16 );
@ -710,6 +745,7 @@ got:
break;
}
}
WIN_RestoreWndsLock(iWndsLocks);
/* remove the smsg from the processingg list of the source queue */
QUEUE_RemoveSMSG( queue, SM_PROCESSING_LIST, smsg );
@ -758,10 +794,12 @@ BOOL WINAPI ReplyMessage( LRESULT result )
SMSG *smsg;
BOOL ret = FALSE;
if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() ))) return FALSE;
if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() )))
return FALSE;
TRACE(sendmsg,"ReplyMessage, queue %04x\n", queue->self);
if ( !(smsg = queue->smWaiting)
|| !(senderQ = QUEUE_Lock( smsg->hSrcQueue )) )
goto ReplyMessageEnd;
@ -838,6 +876,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
MESSAGEQUEUE *msgQueue;
HQUEUE16 hQueue;
POINT16 pt16;
int iWndsLocks;
#ifdef CONFIG_IPC
DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
@ -861,13 +900,19 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
/* Never yield on Win32 threads */
if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD;
iWndsLocks = WIN_SuspendWndsLock();
while(1)
{
QMSG *qmsg;
hQueue = GetFastQueue16();
msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
if (!msgQueue) return FALSE;
if (!msgQueue)
{
WIN_RestoreWndsLock(iWndsLocks);
return FALSE;
}
msgQueue->changeBits = 0;
/* First handle a message put by SendMessage() */
@ -951,8 +996,10 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
wndPtr->flags &= ~WIN_INTERNAL_PAINT;
QUEUE_DecPaintCount( hQueue );
}
WIN_ReleaseWndPtr(wndPtr);
break;
}
WIN_ReleaseWndPtr(wndPtr);
}
}
@ -974,6 +1021,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
if (!(flags & PM_NOYIELD)) UserYield16();
QUEUE_Unlock( msgQueue );
WIN_RestoreWndsLock(iWndsLocks);
return FALSE;
}
msgQueue->wakeMask = mask;
@ -981,6 +1029,8 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
QUEUE_Unlock( msgQueue );
}
WIN_RestoreWndsLock(iWndsLocks);
/* instead of unlocking queue for every break condition, all break
condition will fall here */
QUEUE_Unlock( msgQueue );
@ -1001,8 +1051,12 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
QueueKeyStateTable[msg->wParam & 0xff] &= ~0x80;
}
if (peek) return TRUE;
else return (msg->message != WM_QUIT);
if (peek)
return TRUE;
else
return (msg->message != WM_QUIT);
}
/***********************************************************************
@ -1277,6 +1331,7 @@ BOOL WINAPI PostMessageA( HWND hwnd, UINT message, WPARAM wParam,
{
MSG msg;
WND *wndPtr;
BOOL retvalue;
msg.hwnd = hwnd;
msg.message = message;
@ -1293,8 +1348,10 @@ BOOL WINAPI PostMessageA( HWND hwnd, UINT message, WPARAM wParam,
if (hwnd == HWND_BROADCAST)
{
WND *pDesktop = WIN_GetDesktop();
TRACE(msg,"HWND_BROADCAST !\n");
for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
for (wndPtr=WIN_LockWndPtr(pDesktop->child); wndPtr; WIN_UpdateWndPtr(&wndPtr,wndPtr->next))
{
if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
{
@ -1303,14 +1360,22 @@ BOOL WINAPI PostMessageA( HWND hwnd, UINT message, WPARAM wParam,
PostMessageA( wndPtr->hwndSelf, message, wParam, lParam );
}
}
WIN_ReleaseDesktop();
TRACE(msg,"End of HWND_BROADCAST !\n");
return TRUE;
}
wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
if (!wndPtr || !wndPtr->hmemTaskQ)
{
retvalue = FALSE;
goto END;
}
return QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
retvalue = QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
END:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
@ -1377,7 +1442,7 @@ LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, DWORD timeout, WORD flags,
LRESULT *pRes)
{
WND * wndPtr;
WND * wndPtr = 0;
WND **list, **ppWnd;
LRESULT ret = 1;
@ -1388,11 +1453,16 @@ LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
*pRes = 1;
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
{
WIN_ReleaseDesktop();
return 1;
}
WIN_ReleaseDesktop();
TRACE(msg,"HWND_BROADCAST !\n");
for (ppWnd = list; *ppWnd; ppWnd++)
{
wndPtr = *ppWnd;
WIN_UpdateWndPtr(&wndPtr,*ppWnd);
if (!IsWindow(wndPtr->hwndSelf)) continue;
if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
{
@ -1402,7 +1472,8 @@ LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
timeout, flags, pRes);
}
}
HeapFree( SystemHeap, 0, list );
WIN_ReleaseWndPtr(wndPtr);
WIN_ReleaseWinArray(list);
TRACE(msg,"End of HWND_BROADCAST !\n");
return 1;
}
@ -1440,8 +1511,10 @@ LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
return 0;
}
if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
return 0; /* Don't send anything if the task is dying */
{
ret = 0; /* Don't send anything if the task is dying */
goto END;
}
if (flags & SMSG_WIN32)
SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam );
else
@ -1469,7 +1542,8 @@ LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, ret );
else
SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
END:
WIN_ReleaseWndPtr(wndPtr);
return ret;
}
@ -2005,7 +2079,11 @@ LONG WINAPI DispatchMessage16( const MSG16* msg )
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
if (!wndPtr->winproc) return 0;
if (!wndPtr->winproc)
{
retval = 0;
goto END;
}
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
@ -2016,7 +2094,9 @@ LONG WINAPI DispatchMessage16( const MSG16* msg )
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );
if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
WIN_ReleaseWndPtr(wndPtr);
wndPtr = WIN_FindWndPtr(msg->hwnd);
if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@ -2025,6 +2105,8 @@ LONG WINAPI DispatchMessage16( const MSG16* msg )
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
END:
WIN_ReleaseWndPtr(wndPtr);
return retval;
}
@ -2073,7 +2155,11 @@ LONG WINAPI DispatchMessageA( const MSG* msg )
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
if (!wndPtr->winproc) return 0;
if (!wndPtr->winproc)
{
retval = 0;
goto END;
}
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/* HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
@ -2085,7 +2171,10 @@ LONG WINAPI DispatchMessageA( const MSG* msg )
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );
if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
WIN_ReleaseWndPtr(wndPtr);
wndPtr = WIN_FindWndPtr(msg->hwnd);
if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@ -2094,6 +2183,8 @@ LONG WINAPI DispatchMessageA( const MSG* msg )
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
END:
WIN_ReleaseWndPtr(wndPtr);
return retval;
}
@ -2138,7 +2229,11 @@ LONG WINAPI DispatchMessageW( const MSG* msg )
if (!msg->hwnd) return 0;
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
if (!wndPtr->winproc) return 0;
if (!wndPtr->winproc)
{
retval = 0;
goto END;
}
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
@ -2150,7 +2245,10 @@ LONG WINAPI DispatchMessageW( const MSG* msg )
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );
if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
WIN_ReleaseWndPtr(wndPtr);
wndPtr = WIN_FindWndPtr(msg->hwnd);
if (painting && wndPtr &&
(wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
{
ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
@ -2159,6 +2257,8 @@ LONG WINAPI DispatchMessageW( const MSG* msg )
/* Validate the update region to avoid infinite WM_PAINT loop */
ValidateRect( msg->hwnd, NULL );
}
END:
WIN_ReleaseWndPtr(wndPtr);
return retval;
}

View File

@ -2552,6 +2552,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
break;
case SC_CLOSE:
WIN_ReleaseWndPtr(wndPtr);
return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
case SC_VSCROLL:

View File

@ -145,6 +145,8 @@ void USER_QueueCleanup( HQUEUE16 hQueue )
/* Free the message queue */
QUEUE_DeleteMsgQueue( hQueue );
WIN_ReleaseDesktop();
}
}
@ -170,6 +172,8 @@ static void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue
hInstance = GetExePtr( hInstance );
if( GetModuleUsage16( hInstance ) <= 1 )
USER_ModuleUnload( hInstance );
WIN_ReleaseDesktop();
}
@ -249,7 +253,11 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
/* We have to build a list of all windows first, as in EnumWindows */
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL ))) return FALSE;
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
{
WIN_ReleaseDesktop();
return FALSE;
}
/* Send a WM_QUERYENDSESSION message to every window */
@ -269,9 +277,10 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
SendMessage16( (*ppWnd)->hwndSelf, WM_ENDSESSION, result, 0 );
}
HeapFree( SystemHeap, 0, list );
WIN_ReleaseWinArray(list);
if (result) USER_ExitWindows();
WIN_ReleaseDesktop();
return FALSE;
}

View File

@ -54,7 +54,6 @@ static WORD wDragHeight= 3;
/* thread safeness */
static CRITICAL_SECTION WIN_CritSection;
static int ilockCounter = 0;
/***********************************************************************
* WIN_LockWnds
@ -64,6 +63,9 @@ static int ilockCounter = 0;
void WIN_LockWnds()
{
/*
This code will be released in the future
info : francois@macadamian.com
EnterCriticalSection(&WIN_CritSection);
*/
}
@ -76,6 +78,9 @@ void WIN_LockWnds()
void WIN_UnlockWnds()
{
/*
This code will be released in the future
info : francois@macadamian.com
LeaveCriticalSection(&WIN_CritSection);
*/
}
@ -87,12 +92,24 @@ void WIN_UnlockWnds()
*/
int WIN_SuspendWndsLock()
{
/*
int isuspendedLocks = WIN_CritSection.RecursionCount;
WIN_CritSection.RecursionCount = 0;
LeaveCriticalSection(&WIN_CritSection);
int isuspendedLocks = 0;
/* make sure that the lock is not suspended by different thread than
the owning thread */
if(WIN_CritSection.OwningThread != GetCurrentThreadId())
{
return 0;
}
/* set the value of isuspendedlock to the actual recursion count
of the critical section */
isuspendedLocks = WIN_CritSection.RecursionCount;
/* set the recursion count of the critical section to 1
so the owning thread will be able to leave it */
WIN_CritSection.RecursionCount = 1;
/* leave critical section*/
WIN_UnlockWnds();
return isuspendedLocks;
*/
}
/***********************************************************************
@ -100,13 +117,20 @@ int WIN_SuspendWndsLock()
*
* Restore the suspended locks on WND structures
*/
void WIN_RestoreWndslock(int ipreviousLocks)
void WIN_RestoreWndsLock(int ipreviousLocks)
{
/*
EnterCriticalSection(&WIN_CritSection);
if(!ipreviousLocks)
{
return;
}
/* restore the lock */
WIN_LockWnds();
/* set the recursion count of the critical section to the
value of suspended locks (given by WIN_SuspendWndsLock())*/
WIN_CritSection.RecursionCount = ipreviousLocks;
*/
}
/***********************************************************************
* WIN_FindWndPtr
*
@ -118,25 +142,25 @@ WND * WIN_FindWndPtr( HWND hwnd )
if (!hwnd || HIWORD(hwnd)) goto error2;
ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
/* Lock all WND structures for thread safeness
WIN_LockWnds(ptr);
and increment destruction monitoring
/* Lock all WND structures for thread safeness*/
WIN_LockWnds();
/*and increment destruction monitoring*/
ptr->irefCount++;
*/
if (ptr->dwMagic != WND_MAGIC) goto error;
if (ptr->hwndSelf != hwnd)
{
ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
hwnd, ptr->hwndSelf );
ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",hwnd, ptr->hwndSelf );
goto error;
}
/* returns a locked pointer */
return ptr;
error:
/* Unlock all WND structures for thread safeness
WIN_UnlockWnds(ptr);
and decrement destruction monitoring value
/* Unlock all WND structures for thread safeness*/
WIN_UnlockWnds();
/* and decrement destruction monitoring value */
ptr->irefCount--;
*/
error2:
if ( hwnd!=0 )
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
@ -152,12 +176,13 @@ error2:
*/
WND *WIN_LockWndPtr(WND *initWndPtr)
{
if(!initWndPtr) return 0;
/*
/* Lock all WND structures for thread safeness*/
WIN_LockWnds();
/*and increment destruction monitoring*/
initWndPtr->irefCount++;
*/
return initWndPtr;
}
@ -169,22 +194,26 @@ WND *WIN_LockWndPtr(WND *initWndPtr)
*/
void WIN_ReleaseWndPtr(WND *wndPtr)
{
if(!wndPtr) return;
/*Decrement destruction monitoring value
/*Decrement destruction monitoring value*/
wndPtr->irefCount--;
Check if it's time to release the memory
/* Check if it's time to release the memory*/
if(wndPtr->irefCount == 0)
{
Add memory releasing code here
/*Add memory releasing code here*/
}
unlock all WND structures for thread safeness
else if(wndPtr->irefCount < 0)
{
/* This else if is useful to monitor the WIN_ReleaseWndPtr function */
TRACE(win,"forgot a Lock on %p somewhere\n",wndPtr);
}
/*unlock all WND structures for thread safeness*/
WIN_UnlockWnds();
*/
}
/***********************************************************************
* WIN_ReleaseWndPtr
* WIN_UpdateWndPtr
*
* Updates the value of oldPtr to newPtr.
*/
@ -376,17 +405,21 @@ HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue )
pWnd->hwndSelf );
}
else if ((pWnd->hmemTaskQ == hQueue) &&
(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)))
break;
else if (pWnd->child )
if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
goto end;
{
WIN_ReleaseWndPtr(pWnd);
return hwndRet;
}
}
if(!pWnd)
{
hwndRet = 0;
goto end;
return 0;
}
hwndRet = pWnd->hwndSelf;
@ -397,10 +430,12 @@ HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue )
{
WIN_UpdateWndPtr(&pWnd,pWnd->next);
}
if (pWnd) hwndRet = pWnd->hwndSelf;
TRACE(win,"found %04x\n",hwndRet);
end:
if (pWnd)
{
hwndRet = pWnd->hwndSelf;
WIN_ReleaseWndPtr(pWnd);
}
TRACE(win,"found %04x\n",hwndRet);
return hwndRet;
}
@ -574,6 +609,11 @@ BOOL WIN_CreateDesktopWindow(void)
TRACE(win,"Creating desktop window\n");
/* Initialisation of the critical section for thread safeness */
InitializeCriticalSection(&WIN_CritSection);
MakeCriticalSectionGlobal(&WIN_CritSection);
if (!ICONTITLE_Init() ||
!WINPOS_CreateInternalPosAtom() ||
!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
@ -632,11 +672,6 @@ BOOL WIN_CreateDesktopWindow(void)
return FALSE;
SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
/* Initialisation of the critical section for thread safeness
InitializeCriticalSection(&WIN_CritSection);
MakeCriticalSectionGlobal(&WIN_CritSection);
*/
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
return TRUE;
}
@ -748,8 +783,10 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->owner = NULL;
else
{
wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
WIN_ReleaseWndPtr(wndPtr->owner);
WIN_ReleaseWndPtr(tmpWnd);
}
}
@ -776,6 +813,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->userdata = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
? MENU_GetSysMenu( hwnd, 0 ) : 0;
wndPtr->irefCount = 1;
if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
@ -967,10 +1005,11 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Abort window creation */
WARN(win, "aborted by WM_xxCREATE!\n");
WIN_DestroyWindow( wndPtr );
WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
retvalue = 0;
end:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
@ -1318,7 +1357,11 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
}
WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
}
if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
if (siblingPtr)
{
DestroyWindow( siblingPtr->hwndSelf );
WIN_ReleaseWndPtr(siblingPtr);
}
else break;
}
@ -1345,7 +1388,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
/* Destroy the window storage */
WIN_DestroyWindow( wndPtr );
WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
retvalue = TRUE;
end:
WIN_ReleaseWndPtr(wndPtr);
@ -2312,11 +2355,13 @@ HWND WINAPI GetParent( HWND hwnd )
*/
WND* WIN_GetTopParentPtr( WND* pWnd )
{
while( pWnd && (pWnd->dwStyle & WS_CHILD))
WND *tmpWnd = WIN_LockWndPtr(pWnd);
while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
{
WIN_UpdateWndPtr(&pWnd,pWnd->parent);
WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
}
return pWnd;
return tmpWnd;
}
/*****************************************************************

View File

@ -660,6 +660,7 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
offset->y += wndPtr->rectClient.top;
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
}
WIN_ReleaseWndPtr(wndPtr);
}
/* Translate origin to destination window coords */
@ -676,8 +677,8 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
offset->y -= wndPtr->rectClient.top;
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
}
WIN_ReleaseWndPtr(wndPtr);
}
WIN_ReleaseWndPtr(wndPtr);
}
@ -1632,10 +1633,13 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
hOldActiveQueue = hActiveQueue;
if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
{
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
WIN_ReleaseWndPtr(wndTemp);
}
else
TRACE(win,"no current active window.\n");
WIN_ReleaseWndPtr(wndTemp);
/* call CBT hook chain */
if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
{
@ -1650,6 +1654,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
/* Unlock the active queue before returning */
if ( pOldActiveQueue )
QUEUE_Unlock( pOldActiveQueue );
WIN_ReleaseWndPtr(wndPtr);
return wRet;
}
}
@ -1775,6 +1780,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
wndTemp->hwndLastActive = hWnd;
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
WIN_ReleaseWndPtr(wndTemp);
SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
#if 1
SendMessageA( hWnd, WM_ACTIVATE,
@ -1855,10 +1861,8 @@ BOOL WINPOS_ActivateOtherWindow(WND* pWnd)
while( !WINPOS_CanActivate(pWndTo) )
{
/* by now owned windows should've been taken care of */
WIN_ReleaseWndPtr(pWndTo);
pWndTo = WIN_LockWndPtr(pWndPtr->next);
WIN_ReleaseWndPtr(pWndPtr);
pWndPtr = WIN_LockWndPtr(pWndTo);
WIN_UpdateWndPtr(&pWndTo,pWndPtr->next);
WIN_UpdateWndPtr(&pWndPtr,pWndTo);
if( !pWndTo ) break;
}
WIN_ReleaseWndPtr(pWndPtr);

View File

@ -416,6 +416,7 @@ static void EVENT_ProcessEvent( XEvent *event )
pWnd = NULL; /* Not for a registered window */
}
}
WIN_LockWndPtr(pWnd);
if ( !pWnd && event->xany.window != X11DRV_GetXRootWindow() )
ERR( event, "Got event %s for unknown Window %08lx\n",
@ -515,6 +516,7 @@ static void EVENT_ProcessEvent( XEvent *event )
event_names[event->type], pWnd? pWnd->hwndSelf : 0 );
break;
}
WIN_ReleaseWndPtr(pWnd);
}
/***********************************************************************
@ -586,11 +588,21 @@ static BOOL EVENT_QueryZOrder( WND* pWndCheck )
{
BOOL bRet = FALSE;
HWND hwndInsertAfter = HWND_TOP;
WND* pWnd, *pWndZ = WIN_GetDesktop()->child;
WND *pDesktop = WIN_GetDesktop();
WND *pWnd, *pWndZ = WIN_LockWndPtr(pDesktop->child);
Window w, parent, *children = NULL;
unsigned total, check, pos, best;
if( !__check_query_condition(&pWndZ, &pWnd) ) return TRUE;
if( !__check_query_condition(&pWndZ, &pWnd) )
{
WIN_ReleaseWndPtr(pDesktop->child);
WIN_ReleaseDesktop();
return TRUE;
}
WIN_LockWndPtr(pWndZ);
WIN_LockWndPtr(pWnd);
WIN_ReleaseWndPtr(pDesktop->child);
WIN_ReleaseDesktop();
parent = __get_common_ancestor( X11DRV_WND_GetXWindow(pWndZ),
X11DRV_WND_GetXWindow(pWnd),
@ -607,7 +619,7 @@ static BOOL EVENT_QueryZOrder( WND* pWndCheck )
check = __td_lookup( w, children, total );
best = total;
for( pWnd = pWndZ; pWnd; pWnd = pWnd->next )
for( WIN_UpdateWndPtr(&pWnd,pWndZ); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
{
/* go through all windows in Wine z-order... */
@ -633,6 +645,8 @@ static BOOL EVENT_QueryZOrder( WND* pWndCheck )
WIN_LinkWindow( pWndCheck->hwndSelf, hwndInsertAfter);
}
if( children ) TSXFree( children );
WIN_ReleaseWndPtr(pWnd);
WIN_ReleaseWndPtr(pWndZ);
return bRet;
}

View File

@ -378,7 +378,10 @@ void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
WND *wndPrev,*pDesktop = WIN_GetDesktop();
if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->flags & WIN_MANAGED) )
{
WIN_ReleaseDesktop();
return;
}
/* Raise all windows up to wndPtr according to their Z order.
* (it would be easier with sibling-related Below but it doesn't