- Changing MESSAGEQUEUE structure according to Ulrich proposition.
- One message queue for every thread needing it. - Messages in the message queue are now stored in a linked list - Messages are allocated in the system heap. - Messages in the message queue are 32 bits (MSG32). - All read/write operations regarding messages in the message queue are thread safe.
This commit is contained in:
parent
d68d50142f
commit
a4c8445ba3
107
include/queue.h
107
include/queue.h
|
@ -9,12 +9,17 @@
|
|||
|
||||
#include "wine/winuser16.h"
|
||||
#include "windows.h"
|
||||
#include "thread.h"
|
||||
|
||||
|
||||
/* Message as stored in the queue (contains the extraInfo field) */
|
||||
typedef struct tagQMSG
|
||||
{
|
||||
MSG32 msg;
|
||||
DWORD extraInfo; /* Only in 3.1 */
|
||||
MSG16 msg;
|
||||
|
||||
struct tagQMSG *nextMsg;
|
||||
struct tagQMSG *prevMsg;
|
||||
} QMSG;
|
||||
|
||||
typedef struct
|
||||
|
@ -23,49 +28,63 @@ typedef struct
|
|||
BOOL16 bPending;
|
||||
} QSMCTRL;
|
||||
|
||||
#pragma pack(1)
|
||||
/* Per-queue system windows */
|
||||
typedef struct tagPERQUEUEDATA
|
||||
{
|
||||
HWND32 hWndCapture;
|
||||
HWND32 hWndFocus;
|
||||
HWND32 hWndActive;
|
||||
} PERQUEUEDATA;
|
||||
|
||||
typedef struct tagMESSAGEQUEUE
|
||||
{
|
||||
HQUEUE16 next; /* 00 Next queue */
|
||||
HTASK16 hTask; /* 02 hTask owning the queue */
|
||||
WORD msgSize; /* 04 Size of messages in the queue */
|
||||
WORD msgCount; /* 06 Number of waiting messages */
|
||||
WORD nextMessage; /* 08 Next message to be retrieved */
|
||||
WORD nextFreeMessage; /* 0a Next available slot in the queue */
|
||||
WORD queueSize; /* 0c Size of the queue */
|
||||
DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */
|
||||
DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */
|
||||
HQUEUE16 self; /* 16 Handle to self (was: reserved) */
|
||||
DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
|
||||
WORD wParamHigh; /* 1c High word of wParam (was: reserved)*/
|
||||
LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */
|
||||
WPARAM16 wParam; /* 22 */
|
||||
UINT16 msg; /* 24 */
|
||||
HWND16 hWnd; /* 26 */
|
||||
DWORD SendMessageReturn; /* 28 Return value for SendMessage */
|
||||
WORD wPostQMsg; /* 2c PostQuitMessage flag */
|
||||
WORD wExitCode; /* 2e PostQuitMessage exit code */
|
||||
WORD flags; /* 30 Queue flags */
|
||||
QSMCTRL* smResultInit; /* 32 1st LRESULT ptr - was: reserved */
|
||||
WORD wWinVersion; /* 36 Expected Windows version */
|
||||
HQUEUE16 InSendMessageHandle; /* 38 Queue of task that sent a message */
|
||||
HTASK16 hSendingTask; /* 3a Handle of task that sent a message */
|
||||
HTASK16 hPrevSendingTask; /* 3c Handle of previous sender */
|
||||
WORD wPaintCount; /* 3e Number of WM_PAINT needed */
|
||||
WORD wTimerCount; /* 40 Number of timers for this task */
|
||||
WORD changeBits; /* 42 Changed wake-up bits */
|
||||
WORD wakeBits; /* 44 Queue wake-up bits */
|
||||
WORD wakeMask; /* 46 Queue wake-up mask */
|
||||
QSMCTRL* smResultCurrent; /* 48 ptrs to SendMessage() LRESULT - point to */
|
||||
WORD SendMsgReturnPtr[1]; /* values on stack */
|
||||
HANDLE16 hCurHook; /* 4e Current hook */
|
||||
HANDLE16 hooks[WH_NB_HOOKS]; /* 50 Task hooks list */
|
||||
QSMCTRL* smResult; /* 6c 3rd LRESULT ptr - was: reserved */
|
||||
QMSG messages[1]; /* 70 Queue messages */
|
||||
HQUEUE16 next; /* NNext queue */
|
||||
HQUEUE16 self; /* Handle to self (was: reserved) */
|
||||
THDB* thdb; /* Thread owning queue */
|
||||
HANDLE32 hEvent; /* Event handle */
|
||||
CRITICAL_SECTION cSection; /* Queue access critical section */
|
||||
|
||||
WORD flags; /* Queue flags */
|
||||
WORD wWinVersion; /* Expected Windows version */
|
||||
|
||||
WORD msgCount; /* Number of waiting messages */
|
||||
QMSG* firstMsg; /* First message in linked list */
|
||||
QMSG* lastMsg; /* Last message in linked list */
|
||||
|
||||
WORD wPostQMsg; /* PostQuitMessage flag */
|
||||
WORD wExitCode; /* PostQuitMessage exit code */
|
||||
WORD wPaintCount; /* Number of WM_PAINT needed */
|
||||
WORD wTimerCount; /* Number of timers for this task */
|
||||
|
||||
WORD changeBits; /* Changed wake-up bits */
|
||||
WORD wakeBits; /* Queue wake-up bits */
|
||||
WORD wakeMask; /* Queue wake-up mask */
|
||||
|
||||
DWORD GetMessageTimeVal; /* Value for GetMessageTime */
|
||||
DWORD GetMessagePosVal; /* Value for GetMessagePos */
|
||||
DWORD GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
|
||||
|
||||
HQUEUE16 InSendMessageHandle; /* Queue of task that sent a message */
|
||||
HTASK16 hSendingTask; /* Handle of task that sent a message */
|
||||
HTASK16 hPrevSendingTask; /* Handle of previous sender */
|
||||
|
||||
HWND32 hWnd32; /* Send message arguments */
|
||||
UINT32 msg32;
|
||||
WPARAM32 wParam32;
|
||||
LPARAM lParam;
|
||||
DWORD SendMessageReturn; /* Return value for SendMessage */
|
||||
|
||||
QSMCTRL* smResultInit; /* SendMesage result pointers */
|
||||
QSMCTRL* smResultCurrent;
|
||||
QSMCTRL* smResult;
|
||||
|
||||
HANDLE16 hCurHook; /* Current hook */
|
||||
HANDLE16 hooks[WH_NB_HOOKS]; /* Task hooks list */
|
||||
|
||||
HANDLE16 hPerQueue; /* handle on PERQUEUEDATA structure */
|
||||
|
||||
} MESSAGEQUEUE;
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
/* Extra (undocumented) queue wake bits - see "Undoc. Windows" */
|
||||
#define QS_SMRESULT 0x8000 /* Queue has a SendMessage() result */
|
||||
|
@ -80,7 +99,7 @@ extern void QUEUE_WalkQueues(void);
|
|||
extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue );
|
||||
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
|
||||
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
|
||||
extern void QUEUE_Signal( HTASK16 hTask );
|
||||
extern void QUEUE_Signal( THDB *thdb );
|
||||
extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
|
||||
extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
|
||||
extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
|
||||
|
@ -89,13 +108,13 @@ extern void QUEUE_IncPaintCount( HQUEUE16 hQueue );
|
|||
extern void QUEUE_DecPaintCount( HQUEUE16 hQueue );
|
||||
extern void QUEUE_IncTimerCount( HQUEUE16 hQueue );
|
||||
extern void QUEUE_DecTimerCount( HQUEUE16 hQueue );
|
||||
extern BOOL32 QUEUE_CreateSysMsgQueue( int size );
|
||||
extern BOOL32 QUEUE_CreateSysMsgQueue( );
|
||||
extern BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue );
|
||||
extern HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue );
|
||||
extern BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG16 * msg, DWORD extraInfo );
|
||||
extern int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd,
|
||||
extern BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG32 * msg, DWORD extraInfo );
|
||||
extern QMSG* QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd,
|
||||
int first, int last );
|
||||
extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos );
|
||||
extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg );
|
||||
extern void QUEUE_FlushMessages(HQUEUE16);
|
||||
extern void hardware_event( WORD message, WORD wParam, LONG lParam,
|
||||
int xPos, int yPos, DWORD time, DWORD extraInfo );
|
||||
|
|
|
@ -441,9 +441,12 @@ static int MSG_JournalPlayBackMsg(void)
|
|||
static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
||||
BOOL32 remove )
|
||||
{
|
||||
/* FIXME: should deal with MSG32 instead of MSG16 */
|
||||
|
||||
DWORD status = SYSQ_MSG_ACCEPT;
|
||||
MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
|
||||
int i, kbd_msg, pos = sysMsgQueue->nextMessage;
|
||||
int kbd_msg;
|
||||
QMSG *nextqmsg, *qmsg = sysMsgQueue->firstMsg;
|
||||
|
||||
/* FIXME: there has to be a better way to do this */
|
||||
joySendMessages();
|
||||
|
@ -453,16 +456,20 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
|||
&& EVENT_Pending())
|
||||
EVENT_WaitNetEvent( FALSE, FALSE );
|
||||
|
||||
for (i = kbd_msg = 0; i < sysMsgQueue->msgCount; i++, pos++)
|
||||
for ( kbd_msg = 0; qmsg; qmsg = nextqmsg)
|
||||
{
|
||||
if (pos >= sysMsgQueue->queueSize) pos = 0;
|
||||
*msg = sysMsgQueue->messages[pos].msg;
|
||||
|
||||
/* FIXME: this line will be reenabled when msg will be a MSG32 */
|
||||
/* *msg = qmsg->msg; */
|
||||
STRUCT32_MSG32to16(&qmsg->msg, msg);
|
||||
|
||||
nextqmsg = qmsg->nextMsg;
|
||||
|
||||
/* Translate message */
|
||||
|
||||
if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
|
||||
{
|
||||
HWND32 hWndScope = (HWND32)sysMsgQueue->messages[pos].extraInfo;
|
||||
HWND32 hWndScope = (HWND32)qmsg->extraInfo;
|
||||
|
||||
status = MSG_TranslateMouseMsg(hwnd, filter, msg, remove,
|
||||
(Options.managed && IsWindow32(hWndScope) )
|
||||
|
@ -490,7 +497,7 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
|||
SEGPTR_FREE(hook);
|
||||
if (ret)
|
||||
{
|
||||
QUEUE_RemoveMsg( sysMsgQueue, pos );
|
||||
QUEUE_RemoveMsg( sysMsgQueue, qmsg );
|
||||
continue;
|
||||
}
|
||||
status = SYSQ_MSG_ACCEPT;
|
||||
|
@ -525,7 +532,7 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
|||
}
|
||||
|
||||
if (remove)
|
||||
QUEUE_RemoveMsg( sysMsgQueue, pos );
|
||||
QUEUE_RemoveMsg( sysMsgQueue, qmsg );
|
||||
/* continue */
|
||||
|
||||
case SYSQ_MSG_CONTINUE:
|
||||
|
@ -538,7 +545,7 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
|||
if (remove)
|
||||
{
|
||||
if (HOOK_IsHooked( WH_JOURNALRECORD )) MSG_JournalRecordMsg( msg );
|
||||
QUEUE_RemoveMsg( sysMsgQueue, pos );
|
||||
QUEUE_RemoveMsg( sysMsgQueue, qmsg );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -546,6 +553,7 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetDoubleClickTime16 (USER.20)
|
||||
*/
|
||||
|
@ -611,11 +619,9 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg,
|
|||
}
|
||||
|
||||
/* resume sending */
|
||||
|
||||
queue->hWnd = hwnd;
|
||||
queue->msg = msg;
|
||||
queue->wParam = LOWORD(wParam);
|
||||
queue->wParamHigh = HIWORD(wParam);
|
||||
queue->hWnd32 = hwnd;
|
||||
queue->msg32 = msg;
|
||||
queue->wParam32 = wParam;
|
||||
queue->lParam = lParam;
|
||||
queue->hPrevSendingTask = destQ->hSendingTask;
|
||||
destQ->hSendingTask = GetFastQueue();
|
||||
|
@ -635,7 +641,8 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg,
|
|||
{
|
||||
if (!(queue->wakeBits & QS_SMRESULT))
|
||||
{
|
||||
if (THREAD_IsWin16( THREAD_Current() )) DirectedYield( destQ->hTask );
|
||||
if (THREAD_IsWin16( THREAD_Current() ))
|
||||
DirectedYield( destQ->thdb->teb.htask16 );
|
||||
QUEUE_WaitBits( QS_SMRESULT );
|
||||
TRACE(sendmsg,"\tsm: have result!\n");
|
||||
}
|
||||
|
@ -675,8 +682,8 @@ void WINAPI ReplyMessage16( LRESULT result )
|
|||
|
||||
while( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
|
||||
{
|
||||
TRACE(msg,"\trpm: replying to %04x (%04x -> %04x)\n",
|
||||
queue->msg, queue->self, senderQ->self);
|
||||
TRACE(msg,"\trpm: replying to %08x (%04x -> %04x)\n",
|
||||
queue->msg32, queue->self, senderQ->self);
|
||||
|
||||
if( queue->wakeBits & QS_SENDMESSAGE )
|
||||
{
|
||||
|
@ -697,7 +704,8 @@ void WINAPI ReplyMessage16( LRESULT result )
|
|||
queue->InSendMessageHandle = 0;
|
||||
|
||||
QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
|
||||
if (THREAD_IsWin16(THREAD_Current())) DirectedYield( senderQ->hTask );
|
||||
if (THREAD_IsWin16( THREAD_Current() ))
|
||||
DirectedYield( senderQ->thdb->teb.htask16 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -707,7 +715,7 @@ void WINAPI ReplyMessage16( LRESULT result )
|
|||
static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
|
||||
WORD flags, BOOL32 peek )
|
||||
{
|
||||
int pos, mask;
|
||||
int mask;
|
||||
MESSAGEQUEUE *msgQueue;
|
||||
HQUEUE16 hQueue;
|
||||
|
||||
|
@ -735,6 +743,8 @@ static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
|
|||
|
||||
while(1)
|
||||
{
|
||||
QMSG *qmsg;
|
||||
|
||||
hQueue = GetFastQueue();
|
||||
msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
|
||||
if (!msgQueue) return FALSE;
|
||||
|
@ -762,15 +772,17 @@ static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
|
|||
/* Now find a normal message */
|
||||
|
||||
if (((msgQueue->wakeBits & mask) & QS_POSTMESSAGE) &&
|
||||
((pos = QUEUE_FindMsg( msgQueue, hwnd, first, last )) != -1))
|
||||
((qmsg = QUEUE_FindMsg( msgQueue, hwnd, first, last )) != 0))
|
||||
{
|
||||
QMSG *qmsg = &msgQueue->messages[pos];
|
||||
*msg = qmsg->msg;
|
||||
/* FIXME: this line will be reenabled when msg will be a MSG32 */
|
||||
/* *msg = qmsg->msg; */
|
||||
STRUCT32_MSG32to16(&qmsg->msg, msg);
|
||||
|
||||
msgQueue->GetMessageTimeVal = msg->time;
|
||||
msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
|
||||
msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
|
||||
|
||||
if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos );
|
||||
if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, qmsg );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1129,7 +1141,7 @@ BOOL32 WINAPI GetMessage32W(
|
|||
BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 message, WPARAM16 wParam,
|
||||
LPARAM lParam )
|
||||
{
|
||||
MSG16 msg;
|
||||
MSG32 msg;
|
||||
WND *wndPtr;
|
||||
|
||||
msg.hwnd = hwnd;
|
||||
|
@ -1204,7 +1216,7 @@ BOOL32 WINAPI PostMessage32W( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
|
|||
BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 message, WPARAM16 wParam,
|
||||
LPARAM lParam )
|
||||
{
|
||||
MSG16 msg;
|
||||
MSG32 msg;
|
||||
|
||||
if (GetTaskQueue(hTask) == 0) return FALSE;
|
||||
msg.hwnd = 0;
|
||||
|
|
341
windows/queue.c
341
windows/queue.c
|
@ -39,28 +39,27 @@ void QUEUE_DumpQueue( HQUEUE16 hQueue )
|
|||
MESSAGEQUEUE *pq;
|
||||
|
||||
if (!(pq = (MESSAGEQUEUE*) GlobalLock16( hQueue )) ||
|
||||
GlobalSize16(hQueue) < sizeof(MESSAGEQUEUE)+pq->queueSize*sizeof(QMSG))
|
||||
GlobalSize16(hQueue) != sizeof(MESSAGEQUEUE))
|
||||
{
|
||||
WARN(msg, "%04x is not a queue handle\n", hQueue );
|
||||
return;
|
||||
}
|
||||
|
||||
DUMP( "next: %12.4x Intertask SendMessage:\n"
|
||||
"hTask: %11.4x ----------------------\n"
|
||||
"msgSize: %9.4x hWnd: %10.4x\n"
|
||||
"msgCount: %8.4x msg: %11.4x\n"
|
||||
"msgNext: %9.4x wParam: %8.4x\n"
|
||||
"msgFree: %9.4x lParam: %8.8x\n"
|
||||
"qSize: %11.4x lRet: %10.8x\n"
|
||||
"thread: %10p ----------------------\n"
|
||||
"hWnd: %12.8x\n"
|
||||
"firstMsg: %8p lastMsg: %8p"
|
||||
"msgCount: %8.4x msg: %11.8x\n"
|
||||
"wParam: %10.8x lParam: %8.8x\n"
|
||||
"lRet: %12.8x\n"
|
||||
"wWinVer: %9.4x ISMH: %10.4x\n"
|
||||
"paints: %10.4x hSendTask: %5.4x\n"
|
||||
"timers: %10.4x hPrevSend: %5.4x\n"
|
||||
"wakeBits: %8.4x\n"
|
||||
"wakeMask: %8.4x\n"
|
||||
"hCurHook: %8.4x\n",
|
||||
pq->next, pq->hTask, pq->msgSize, pq->hWnd,
|
||||
pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
|
||||
pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
|
||||
pq->next, pq->thdb, pq->hWnd32, pq->firstMsg, pq->lastMsg,
|
||||
pq->msgCount, pq->msg32, pq->wParam32,(unsigned)pq->lParam,
|
||||
(unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
|
||||
pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
|
||||
pq->hPrevSendingTask, pq->wakeBits, pq->wakeMask, pq->hCurHook);
|
||||
|
@ -75,7 +74,7 @@ void QUEUE_WalkQueues(void)
|
|||
char module[10];
|
||||
HQUEUE16 hQueue = hFirstQueue;
|
||||
|
||||
DUMP( "Queue Size Msgs Task\n" );
|
||||
DUMP( "Queue Msgs Thread Task Module\n" );
|
||||
while (hQueue)
|
||||
{
|
||||
MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
|
||||
|
@ -84,10 +83,10 @@ void QUEUE_WalkQueues(void)
|
|||
WARN( msg, "Bad queue handle %04x\n", hQueue );
|
||||
return;
|
||||
}
|
||||
if (!GetModuleName( queue->hTask, module, sizeof(module )))
|
||||
if (!GetModuleName( queue->thdb->process->task, module, sizeof(module )))
|
||||
strcpy( module, "???" );
|
||||
DUMP( "%04x %5d %4d %04x %s\n", hQueue, queue->msgSize,
|
||||
queue->msgCount, queue->hTask, module );
|
||||
DUMP( "%04x %4d %p %04x %s\n", hQueue,queue->msgCount,
|
||||
queue->thdb, queue->thdb->process->task, module );
|
||||
hQueue = queue->next;
|
||||
}
|
||||
DUMP( "\n" );
|
||||
|
@ -117,25 +116,25 @@ void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
|
|||
*
|
||||
* Creates a message queue. Doesn't link it into queue list!
|
||||
*/
|
||||
static HQUEUE16 QUEUE_CreateMsgQueue( int size )
|
||||
static HQUEUE16 QUEUE_CreateMsgQueue( )
|
||||
{
|
||||
HQUEUE16 hQueue;
|
||||
MESSAGEQUEUE * msgQueue;
|
||||
int queueSize;
|
||||
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||
|
||||
TRACE(msg,"Creating message queue...\n");
|
||||
|
||||
queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
|
||||
if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
|
||||
if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT,
|
||||
sizeof(MESSAGEQUEUE) )))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
|
||||
InitializeCriticalSection( &msgQueue->cSection );
|
||||
msgQueue->self = hQueue;
|
||||
msgQueue->msgSize = sizeof(QMSG);
|
||||
msgQueue->queueSize = size;
|
||||
msgQueue->wakeBits = msgQueue->changeBits = QS_SMPARAMSFREE;
|
||||
msgQueue->wWinVersion = pTask ? pTask->version : 0;
|
||||
GlobalUnlock16( hQueue );
|
||||
return hQueue;
|
||||
}
|
||||
|
||||
|
@ -201,9 +200,7 @@ BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
|
|||
*/
|
||||
BOOL32 QUEUE_CreateSysMsgQueue( int size )
|
||||
{
|
||||
if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
|
||||
else if (size <= 0) size = 1;
|
||||
if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( size ))) return FALSE;
|
||||
if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( ))) return FALSE;
|
||||
sysMsgQueue = (MESSAGEQUEUE *) GlobalLock16( hmemSysMsgQueue );
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -220,18 +217,12 @@ MESSAGEQUEUE *QUEUE_GetSysQueue(void)
|
|||
/***********************************************************************
|
||||
* QUEUE_Signal
|
||||
*/
|
||||
void QUEUE_Signal( HTASK16 hTask )
|
||||
void QUEUE_Signal( THDB *thdb )
|
||||
{
|
||||
PDB32 *pdb;
|
||||
THREAD_ENTRY *entry;
|
||||
|
||||
TDB *pTask = (TDB *)GlobalLock16( hTask );
|
||||
if ( !pTask ) return;
|
||||
|
||||
/* Wake up thread waiting for message */
|
||||
SetEvent( pTask->thdb->event );
|
||||
SetEvent( thdb->event );
|
||||
|
||||
PostEvent( hTask );
|
||||
PostEvent( thdb->process->task );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -250,7 +241,7 @@ static void QUEUE_Wait( DWORD wait_mask )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_SetWakeBit
|
||||
* QUEUE_SetWakeBit `
|
||||
*
|
||||
* See "Windows Internals", p.449
|
||||
*/
|
||||
|
@ -266,7 +257,7 @@ void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
|
|||
if (queue->wakeMask & bit)
|
||||
{
|
||||
queue->wakeMask = 0;
|
||||
QUEUE_Signal( queue->hTask );
|
||||
QUEUE_Signal( queue->thdb );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,33 +345,34 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
|
|||
(unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
|
||||
QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
|
||||
|
||||
TRACE(msg, "\trcm: calling wndproc - %04x %04x %04x%04x %08x\n",
|
||||
senderQ->hWnd, senderQ->msg, senderQ->wParamHigh,
|
||||
senderQ->wParam, (unsigned)senderQ->lParam );
|
||||
TRACE(msg, "\trcm: calling wndproc - %08x %08x %08x %08x\n",
|
||||
senderQ->hWnd32, senderQ->msg32,
|
||||
senderQ->wParam32, (unsigned)senderQ->lParam );
|
||||
|
||||
if (IsWindow32( senderQ->hWnd ))
|
||||
if (IsWindow32( senderQ->hWnd32 ))
|
||||
{
|
||||
WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd );
|
||||
WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd32 );
|
||||
DWORD extraInfo = queue->GetMessageExtraInfoVal;
|
||||
queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
|
||||
|
||||
if (senderQ->flags & QUEUE_SM_WIN32)
|
||||
{
|
||||
WPARAM32 wParam = MAKELONG( senderQ->wParam, senderQ->wParamHigh );
|
||||
TRACE(msg, "\trcm: msg is Win32\n" );
|
||||
if (senderQ->flags & QUEUE_SM_UNICODE)
|
||||
result = CallWindowProc32W( wndPtr->winproc,
|
||||
senderQ->hWnd, senderQ->msg,
|
||||
wParam, senderQ->lParam );
|
||||
senderQ->hWnd32, senderQ->msg32,
|
||||
senderQ->wParam32, senderQ->lParam );
|
||||
else
|
||||
result = CallWindowProc32A( wndPtr->winproc,
|
||||
senderQ->hWnd, senderQ->msg,
|
||||
wParam, senderQ->lParam );
|
||||
senderQ->hWnd32, senderQ->msg32,
|
||||
senderQ->wParam32, senderQ->lParam );
|
||||
}
|
||||
else /* Win16 message */
|
||||
result = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
|
||||
senderQ->hWnd, senderQ->msg,
|
||||
senderQ->wParam, senderQ->lParam );
|
||||
(HWND16) senderQ->hWnd32,
|
||||
(UINT16) senderQ->msg32,
|
||||
LOWORD (senderQ->wParam32),
|
||||
senderQ->lParam );
|
||||
|
||||
queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
|
||||
TRACE(msg,"\trcm: result = %08x\n", (unsigned)result );
|
||||
|
@ -443,97 +435,115 @@ void QUEUE_FlushMessages( HQUEUE16 hQueue )
|
|||
*
|
||||
* Add a message to the queue. Return FALSE if queue is full.
|
||||
*/
|
||||
BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG16 * msg, DWORD extraInfo )
|
||||
BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG32 *msg, DWORD extraInfo )
|
||||
{
|
||||
int pos;
|
||||
MESSAGEQUEUE *msgQueue;
|
||||
QMSG *qmsg;
|
||||
|
||||
SIGNAL_MaskAsyncEvents( TRUE );
|
||||
|
||||
if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
|
||||
pos = msgQueue->nextFreeMessage;
|
||||
|
||||
/* Check if queue is full */
|
||||
if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
|
||||
{
|
||||
SIGNAL_MaskAsyncEvents( FALSE );
|
||||
WARN( msg,"Queue is full!\n" );
|
||||
return FALSE;
|
||||
}
|
||||
/* allocate new message in global heap for now */
|
||||
if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
|
||||
return 0;
|
||||
|
||||
EnterCriticalSection( &msgQueue->cSection );
|
||||
|
||||
/* Store message */
|
||||
msgQueue->messages[pos].msg = *msg;
|
||||
msgQueue->messages[pos].extraInfo = extraInfo;
|
||||
if (pos < msgQueue->queueSize-1) pos++;
|
||||
else pos = 0;
|
||||
msgQueue->nextFreeMessage = pos;
|
||||
qmsg->msg = *msg;
|
||||
qmsg->extraInfo = extraInfo;
|
||||
|
||||
/* insert the message in the link list */
|
||||
qmsg->nextMsg = 0;
|
||||
qmsg->prevMsg = msgQueue->lastMsg;
|
||||
|
||||
if (msgQueue->lastMsg)
|
||||
msgQueue->lastMsg->nextMsg = qmsg;
|
||||
|
||||
/* update first and last anchor in message queue */
|
||||
msgQueue->lastMsg = qmsg;
|
||||
if (!msgQueue->firstMsg)
|
||||
msgQueue->firstMsg = qmsg;
|
||||
|
||||
msgQueue->msgCount++;
|
||||
|
||||
SIGNAL_MaskAsyncEvents( FALSE );
|
||||
LeaveCriticalSection( &msgQueue->cSection );
|
||||
|
||||
QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_FindMsg
|
||||
*
|
||||
* Find a message matching the given parameters. Return -1 if none available.
|
||||
*/
|
||||
int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
|
||||
QMSG* QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
|
||||
{
|
||||
int i, pos = msgQueue->nextMessage;
|
||||
QMSG* qmsg;
|
||||
|
||||
TRACE(msg,"hwnd=%04x pos=%d\n", hwnd, pos );
|
||||
EnterCriticalSection( &msgQueue->cSection );
|
||||
|
||||
if (!msgQueue->msgCount) return -1;
|
||||
if (!hwnd && !first && !last) return pos;
|
||||
|
||||
for (i = 0; i < msgQueue->msgCount; i++)
|
||||
if (!msgQueue->msgCount)
|
||||
qmsg = 0;
|
||||
else if (!hwnd && !first && !last)
|
||||
qmsg = msgQueue->firstMsg;
|
||||
else
|
||||
{
|
||||
MSG16 * msg = &msgQueue->messages[pos].msg;
|
||||
/* look in linked list for message matching first and last criteria */
|
||||
for (qmsg = msgQueue->firstMsg; qmsg; qmsg = qmsg->nextMsg)
|
||||
{
|
||||
MSG32 *msg = &(qmsg->msg);
|
||||
|
||||
if (!hwnd || (msg->hwnd == hwnd))
|
||||
{
|
||||
if (!first && !last) return pos;
|
||||
if ((msg->message >= first) && (msg->message <= last)) return pos;
|
||||
if (!first && !last)
|
||||
break; /* found it */
|
||||
|
||||
if ((msg->message >= first) && (msg->message <= last))
|
||||
break; /* found it */
|
||||
}
|
||||
}
|
||||
if (pos < msgQueue->queueSize-1) pos++;
|
||||
else pos = 0;
|
||||
}
|
||||
return -1;
|
||||
|
||||
LeaveCriticalSection( &msgQueue->cSection );
|
||||
|
||||
return qmsg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_RemoveMsg
|
||||
*
|
||||
* Remove a message from the queue (pos must be a valid position).
|
||||
*/
|
||||
void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
|
||||
void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg )
|
||||
{
|
||||
SIGNAL_MaskAsyncEvents( TRUE );
|
||||
EnterCriticalSection( &msgQueue->cSection );
|
||||
|
||||
if (pos >= msgQueue->nextMessage)
|
||||
{
|
||||
for ( ; pos > msgQueue->nextMessage; pos--)
|
||||
msgQueue->messages[pos] = msgQueue->messages[pos-1];
|
||||
msgQueue->nextMessage++;
|
||||
if (msgQueue->nextMessage >= msgQueue->queueSize)
|
||||
msgQueue->nextMessage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( ; pos < msgQueue->nextFreeMessage; pos++)
|
||||
msgQueue->messages[pos] = msgQueue->messages[pos+1];
|
||||
if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
|
||||
else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
|
||||
}
|
||||
/* set the linked list */
|
||||
if (qmsg->prevMsg)
|
||||
qmsg->prevMsg->nextMsg = qmsg->nextMsg;
|
||||
|
||||
if (qmsg->nextMsg)
|
||||
qmsg->nextMsg->prevMsg = qmsg->prevMsg;
|
||||
|
||||
if (msgQueue->firstMsg == qmsg)
|
||||
msgQueue->firstMsg = qmsg->nextMsg;
|
||||
|
||||
if (msgQueue->lastMsg == qmsg)
|
||||
msgQueue->lastMsg = qmsg->prevMsg;
|
||||
|
||||
/* deallocate the memory for the message */
|
||||
HeapFree( SystemHeap, 0, qmsg );
|
||||
|
||||
msgQueue->msgCount--;
|
||||
if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
|
||||
|
||||
SIGNAL_MaskAsyncEvents( FALSE );
|
||||
LeaveCriticalSection( &msgQueue->cSection );
|
||||
}
|
||||
|
||||
|
||||
|
@ -594,49 +604,62 @@ static void QUEUE_WakeSomeone( UINT32 message )
|
|||
void hardware_event( WORD message, WORD wParam, LONG lParam,
|
||||
int xPos, int yPos, DWORD time, DWORD extraInfo )
|
||||
{
|
||||
MSG16 *msg;
|
||||
int pos;
|
||||
MSG32 *msg;
|
||||
QMSG *qmsg = sysMsgQueue->lastMsg;
|
||||
int mergeMsg = 0;
|
||||
|
||||
if (!sysMsgQueue) return;
|
||||
pos = sysMsgQueue->nextFreeMessage;
|
||||
|
||||
/* Merge with previous event if possible */
|
||||
|
||||
if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
|
||||
if ((message == WM_MOUSEMOVE) && sysMsgQueue->lastMsg)
|
||||
{
|
||||
if (pos > 0) pos--;
|
||||
else pos = sysMsgQueue->queueSize - 1;
|
||||
msg = &sysMsgQueue->messages[pos].msg;
|
||||
msg = &(sysMsgQueue->lastMsg->msg);
|
||||
|
||||
if ((msg->message == message) && (msg->wParam == wParam))
|
||||
sysMsgQueue->msgCount--; /* Merge events */
|
||||
else
|
||||
pos = sysMsgQueue->nextFreeMessage; /* Don't merge */
|
||||
{
|
||||
/* Merge events */
|
||||
qmsg = sysMsgQueue->lastMsg;
|
||||
mergeMsg = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if queue is full */
|
||||
|
||||
if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
|
||||
if (!mergeMsg)
|
||||
{
|
||||
/* Queue is full, beep (but not on every mouse motion...) */
|
||||
if (message != WM_MOUSEMOVE) MessageBeep32(0);
|
||||
/* Should I limit the number of message in
|
||||
the system message queue??? */
|
||||
|
||||
/* Don't merge allocate a new msg in the global heap */
|
||||
|
||||
if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
|
||||
return;
|
||||
|
||||
/* put message at the end of the linked list */
|
||||
qmsg->nextMsg = 0;
|
||||
qmsg->prevMsg = sysMsgQueue->lastMsg;
|
||||
|
||||
if (sysMsgQueue->lastMsg)
|
||||
sysMsgQueue->lastMsg->nextMsg = qmsg;
|
||||
|
||||
/* set last and first anchor index in system message queue */
|
||||
sysMsgQueue->lastMsg = qmsg;
|
||||
if (!sysMsgQueue->firstMsg)
|
||||
sysMsgQueue->firstMsg = qmsg;
|
||||
|
||||
sysMsgQueue->msgCount++;
|
||||
}
|
||||
|
||||
/* Store message */
|
||||
|
||||
msg = &sysMsgQueue->messages[pos].msg;
|
||||
msg = &(qmsg->msg);
|
||||
msg->hwnd = 0;
|
||||
msg->message = message;
|
||||
msg->wParam = wParam;
|
||||
msg->lParam = lParam;
|
||||
msg->time = time;
|
||||
msg->pt.x = xPos & 0xffff;
|
||||
msg->pt.y = yPos & 0xffff;
|
||||
sysMsgQueue->messages[pos].extraInfo = extraInfo;
|
||||
if (pos < sysMsgQueue->queueSize - 1) pos++;
|
||||
else pos = 0;
|
||||
sysMsgQueue->nextFreeMessage = pos;
|
||||
sysMsgQueue->msgCount++;
|
||||
msg->pt.x = xPos;
|
||||
msg->pt.y = yPos;
|
||||
qmsg->extraInfo = extraInfo;
|
||||
|
||||
QUEUE_WakeSomeone( message );
|
||||
}
|
||||
|
||||
|
@ -647,7 +670,7 @@ void hardware_event( WORD message, WORD wParam, LONG lParam,
|
|||
HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
|
||||
{
|
||||
MESSAGEQUEUE *queue = GlobalLock16( hQueue );
|
||||
return (queue) ? queue->hTask : 0 ;
|
||||
return (queue) ? queue->thdb->process->task : 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -780,45 +803,12 @@ BOOL16 WINAPI SetMessageQueue16( INT16 size )
|
|||
*/
|
||||
BOOL32 WINAPI SetMessageQueue32( INT32 size )
|
||||
{
|
||||
HQUEUE16 hQueue, hNewQueue;
|
||||
MESSAGEQUEUE *queuePtr;
|
||||
/* now obsolete the message queue will be expanded dynamically
|
||||
as necessary */
|
||||
|
||||
TRACE(msg,"task %04x size %i\n", GetCurrentTask(), size);
|
||||
/* access the queue to create it if it's not existing */
|
||||
GetFastQueue();
|
||||
|
||||
if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE;
|
||||
|
||||
if( !(hNewQueue = QUEUE_CreateMsgQueue( size )))
|
||||
{
|
||||
WARN(msg, "failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
|
||||
|
||||
SIGNAL_MaskAsyncEvents( TRUE );
|
||||
|
||||
/* Copy data and free the old message queue */
|
||||
if ((hQueue = GetThreadQueue(0)) != 0)
|
||||
{
|
||||
MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
|
||||
memcpy( &queuePtr->wParamHigh, &oldQ->wParamHigh,
|
||||
(int)oldQ->messages - (int)(&oldQ->wParamHigh) );
|
||||
HOOK_ResetQueueHooks( hNewQueue );
|
||||
if( WIN_GetDesktop()->hmemTaskQ == hQueue )
|
||||
WIN_GetDesktop()->hmemTaskQ = hNewQueue;
|
||||
WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
|
||||
CLIPBOARD_ResetLock( hQueue, hNewQueue );
|
||||
QUEUE_DeleteMsgQueue( hQueue );
|
||||
}
|
||||
|
||||
/* Link new queue into list */
|
||||
queuePtr->hTask = GetCurrentTask();
|
||||
queuePtr->next = hFirstQueue;
|
||||
hFirstQueue = hNewQueue;
|
||||
|
||||
if( !queuePtr->next ) pCursorQueue = queuePtr;
|
||||
SetThreadQueue( 0, hNewQueue );
|
||||
|
||||
SIGNAL_MaskAsyncEvents( FALSE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -827,19 +817,38 @@ BOOL32 WINAPI SetMessageQueue32( INT32 size )
|
|||
*/
|
||||
HQUEUE16 WINAPI InitThreadInput( WORD unknown, WORD flags )
|
||||
{
|
||||
HQUEUE16 hQueue = GetTaskQueue( 0 );
|
||||
HQUEUE16 hQueue;
|
||||
MESSAGEQUEUE *queuePtr;
|
||||
|
||||
THDB *thdb = THREAD_Current();
|
||||
|
||||
if (!thdb)
|
||||
return 0;
|
||||
|
||||
hQueue = thdb->teb.queue;
|
||||
|
||||
if ( !hQueue )
|
||||
{
|
||||
/* Create task message queue */
|
||||
int queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
|
||||
SetMessageQueue32( queueSize );
|
||||
return GetTaskQueue( 0 );
|
||||
/* Create thread message queue */
|
||||
if( !(hQueue = QUEUE_CreateMsgQueue( 0 )))
|
||||
{
|
||||
WARN(msg, "failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Link new queue into list */
|
||||
queuePtr = (MESSAGEQUEUE *)GlobalLock16( hQueue );
|
||||
queuePtr->thdb = THREAD_Current();
|
||||
|
||||
SIGNAL_MaskAsyncEvents( TRUE );
|
||||
SetThreadQueue( 0, hQueue );
|
||||
thdb->teb.queue = hQueue;
|
||||
|
||||
queuePtr->next = hFirstQueue;
|
||||
hFirstQueue = hQueue;
|
||||
SIGNAL_MaskAsyncEvents( FALSE );
|
||||
}
|
||||
|
||||
FIXME( msg, "(%04X,%04X): should create thread-local message queue!\n",
|
||||
unknown, flags );
|
||||
|
||||
SetFastQueue( 0, hQueue );
|
||||
return hQueue;
|
||||
}
|
||||
|
||||
|
|
|
@ -292,19 +292,19 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
|
|||
|
||||
if( wndPtr->hmemTaskQ )
|
||||
{
|
||||
int pos;
|
||||
BOOL32 bPostQuit = FALSE;
|
||||
WPARAM32 wQuitParam = 0;
|
||||
MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
|
||||
QMSG *qmsg;
|
||||
|
||||
while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
|
||||
while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
|
||||
{
|
||||
if( msgQ->messages[pos].msg.message == WM_QUIT )
|
||||
if( qmsg->msg.message == WM_QUIT )
|
||||
{
|
||||
bPostQuit = TRUE;
|
||||
wQuitParam = msgQ->messages[pos].msg.wParam;
|
||||
wQuitParam = qmsg->msg.wParam;
|
||||
}
|
||||
QUEUE_RemoveMsg(msgQ, pos);
|
||||
QUEUE_RemoveMsg(msgQ, qmsg);
|
||||
}
|
||||
/* repost WM_QUIT to make sure this app exits its message loop */
|
||||
if( bPostQuit ) PostQuitMessage32(wQuitParam);
|
||||
|
|
Loading…
Reference in New Issue