2 * Message queues related functions
4 * Copyright 1993, 1994 Alexandre Julliard
14 #include "clipboard.h"
20 #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
22 static HQUEUE16 hFirstQueue = 0;
23 static HQUEUE16 hExitingQueue = 0;
24 static HQUEUE16 hmemSysMsgQueue = 0;
25 static MESSAGEQUEUE *sysMsgQueue = NULL;
27 static MESSAGEQUEUE *pMouseQueue = NULL; /* Queue for last mouse message */
28 static MESSAGEQUEUE *pKbdQueue = NULL; /* Queue for last kbd message */
30 MESSAGEQUEUE *pCursorQueue = NULL;
31 MESSAGEQUEUE *pActiveQueue = NULL;
33 /***********************************************************************
36 void QUEUE_DumpQueue( HQUEUE16 hQueue )
40 if (!(pq = (MESSAGEQUEUE*) GlobalLock16( hQueue )) ||
41 GlobalSize16(hQueue) < sizeof(MESSAGEQUEUE)+pq->queueSize*sizeof(QMSG))
43 fprintf( stderr, "%04x is not a queue handle\n", hQueue );
48 "next: %12.4x Intertask SendMessage:\n"
49 "hTask: %11.4x ----------------------\n"
50 "msgSize: %9.4x hWnd: %10.4x\n"
51 "msgCount: %8.4x msg: %11.4x\n"
52 "msgNext: %9.4x wParam: %8.4x\n"
53 "msgFree: %9.4x lParam: %8.8x\n"
54 "qSize: %11.4x lRet: %10.8x\n"
55 "wWinVer: %9.4x ISMH: %10.4x\n"
56 "paints: %10.4x hSendTask: %5.4x\n"
57 "timers: %10.4x hPrevSend: %5.4x\n"
61 pq->next, pq->hTask, pq->msgSize, pq->hWnd,
62 pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
63 pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
64 (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
65 pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
66 pq->hPrevSendingTask, pq->wakeBits, pq->wakeMask, pq->hCurHook);
70 /***********************************************************************
73 void QUEUE_WalkQueues(void)
76 HQUEUE16 hQueue = hFirstQueue;
78 fprintf( stderr, "Queue Size Msgs Task\n" );
81 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
84 fprintf( stderr, "*** Bad queue handle %04x\n", hQueue );
87 if (!GetModuleName( queue->hTask, module, sizeof(module )))
88 strcpy( module, "???" );
89 fprintf( stderr, "%04x %5d %4d %04x %s\n", hQueue, queue->msgSize,
90 queue->msgCount, queue->hTask, module );
93 fprintf( stderr, "\n" );
97 /***********************************************************************
98 * QUEUE_IsExitingQueue
100 BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue )
102 return (hExitingQueue && (hQueue == hExitingQueue));
106 /***********************************************************************
107 * QUEUE_SetExitingQueue
109 void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
111 hExitingQueue = hQueue;
115 /***********************************************************************
116 * QUEUE_CreateMsgQueue
118 * Creates a message queue. Doesn't link it into queue list!
120 static HQUEUE16 QUEUE_CreateMsgQueue( int size )
123 MESSAGEQUEUE * msgQueue;
125 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
127 TRACE(msg,"Creating message queue...\n");
129 queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
130 if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
132 msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
133 msgQueue->self = hQueue;
134 msgQueue->msgSize = sizeof(QMSG);
135 msgQueue->queueSize = size;
136 msgQueue->wakeBits = msgQueue->changeBits = QS_SMPARAMSFREE;
137 msgQueue->wWinVersion = pTask ? pTask->version : 0;
138 GlobalUnlock16( hQueue );
143 /***********************************************************************
144 * QUEUE_DeleteMsgQueue
146 * Unlinks and deletes a message queue.
148 * Note: We need to mask asynchronous events to make sure PostMessage works
149 * even in the signal handler.
151 BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
153 MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
157 TRACE(msg,"Deleting message queue %04x\n", hQueue);
159 if (!hQueue || !msgQueue)
161 WARN(msg, "invalid argument.\n");
164 if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
165 if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
167 /* flush sent messages */
168 senderQ = msgQueue->hSendingTask;
171 MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
173 sq->SendMessageReturn = 0L;
174 QUEUE_SetWakeBit( sq, QS_SMRESULT );
175 senderQ = sq->hPrevSendingTask;
178 SIGNAL_MaskAsyncEvents( TRUE );
180 pPrev = &hFirstQueue;
181 while (*pPrev && (*pPrev != hQueue))
183 MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock16(*pPrev);
186 if (*pPrev) *pPrev = msgQueue->next;
189 SIGNAL_MaskAsyncEvents( FALSE );
191 GlobalFree16( hQueue );
196 /***********************************************************************
197 * QUEUE_CreateSysMsgQueue
199 * Create the system message queue, and set the double-click speed.
200 * Must be called only once.
202 BOOL32 QUEUE_CreateSysMsgQueue( int size )
204 if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
205 else if (size <= 0) size = 1;
206 if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( size ))) return FALSE;
207 sysMsgQueue = (MESSAGEQUEUE *) GlobalLock16( hmemSysMsgQueue );
212 /***********************************************************************
215 MESSAGEQUEUE *QUEUE_GetSysQueue(void)
221 /***********************************************************************
224 * See "Windows Internals", p.449
226 void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
228 TRACE(msg,"queue = %04x (wm=%04x), bit = %04x\n",
229 queue->self, queue->wakeMask, bit );
231 if (bit & QS_MOUSE) pMouseQueue = queue;
232 if (bit & QS_KEY) pKbdQueue = queue;
233 queue->changeBits |= bit;
234 queue->wakeBits |= bit;
235 if (queue->wakeMask & bit)
238 PostEvent( queue->hTask );
243 /***********************************************************************
246 void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
248 queue->changeBits &= ~bit;
249 queue->wakeBits &= ~bit;
253 /***********************************************************************
256 * See "Windows Internals", p.447
258 void QUEUE_WaitBits( WORD bits )
262 TRACE(msg,"q %04x waiting for %04x\n", GetTaskQueue(0), bits);
266 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
268 if (queue->changeBits & bits)
270 /* One of the bits is set; we can return */
274 if (queue->wakeBits & QS_SENDMESSAGE)
276 /* Process the sent message immediately */
279 QUEUE_ReceiveMessage( queue );
280 continue; /* nested sm crux */
283 queue->wakeMask = bits | QS_SENDMESSAGE;
284 if(queue->changeBits & bits) continue;
286 TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
293 /***********************************************************************
294 * QUEUE_ReceiveMessage
296 * This routine is called when a sent message is waiting for the queue.
298 void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
300 MESSAGEQUEUE *senderQ = NULL;
301 HQUEUE16 prevSender = 0;
302 QSMCTRL* prevCtrlPtr = NULL;
305 TRACE(msg, "ReceiveMessage, queue %04x\n", queue->self );
306 if (!(queue->wakeBits & QS_SENDMESSAGE) ||
307 !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)))
308 { TRACE(msg,"\trcm: nothing to do\n"); return; }
310 if( !senderQ->hPrevSendingTask )
312 queue->wakeBits &= ~QS_SENDMESSAGE; /* no more sent messages */
313 queue->changeBits &= ~QS_SENDMESSAGE;
316 /* Save current state on stack */
317 prevSender = queue->InSendMessageHandle;
318 prevCtrlPtr = queue->smResultCurrent;
320 /* Remove sending queue from the list */
321 queue->InSendMessageHandle = queue->hSendingTask;
322 queue->smResultCurrent = senderQ->smResultInit;
323 queue->hSendingTask = senderQ->hPrevSendingTask;
325 TRACE(msg, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n",
326 (unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
327 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
329 TRACE(msg, "\trcm: calling wndproc - %04x %04x %04x%04x %08x\n",
330 senderQ->hWnd, senderQ->msg, senderQ->wParamHigh,
331 senderQ->wParam, (unsigned)senderQ->lParam );
333 if (IsWindow32( senderQ->hWnd ))
335 WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd );
336 DWORD extraInfo = queue->GetMessageExtraInfoVal;
337 queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
339 if (senderQ->flags & QUEUE_SM_WIN32)
341 WPARAM32 wParam = MAKELONG( senderQ->wParam, senderQ->wParamHigh );
342 TRACE(msg, "\trcm: msg is Win32\n" );
343 if (senderQ->flags & QUEUE_SM_UNICODE)
344 result = CallWindowProc32W( wndPtr->winproc,
345 senderQ->hWnd, senderQ->msg,
346 wParam, senderQ->lParam );
348 result = CallWindowProc32A( wndPtr->winproc,
349 senderQ->hWnd, senderQ->msg,
350 wParam, senderQ->lParam );
352 else /* Win16 message */
353 result = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
354 senderQ->hWnd, senderQ->msg,
355 senderQ->wParam, senderQ->lParam );
357 queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
358 TRACE(msg,"\trcm: result = %08x\n", (unsigned)result );
360 else WARN(msg, "\trcm: bad hWnd\n");
362 /* Return the result to the sender task */
363 ReplyMessage16( result );
365 queue->InSendMessageHandle = prevSender;
366 queue->smResultCurrent = prevCtrlPtr;
368 TRACE(msg,"done!\n");
371 /***********************************************************************
374 * Try to reply to all pending sent messages on exit.
376 void QUEUE_FlushMessages( HQUEUE16 hQueue )
378 MESSAGEQUEUE *queue = (MESSAGEQUEUE*)GlobalLock16( hQueue );
382 MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
383 QSMCTRL* CtrlPtr = queue->smResultCurrent;
387 if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
388 queue->wakeBits &= ~QS_SENDMESSAGE;
389 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
391 queue->smResultCurrent = CtrlPtr;
392 while( senderQ->wakeBits & QS_SMRESULT ) OldYield();
394 senderQ->SendMessageReturn = 0;
395 senderQ->smResult = queue->smResultCurrent;
396 QUEUE_SetWakeBit( senderQ, QS_SMRESULT);
398 if( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)) )
399 CtrlPtr = senderQ->smResultInit;
401 queue->InSendMessageHandle = 0;
405 /***********************************************************************
408 * Add a message to the queue. Return FALSE if queue is full.
410 BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG16 * msg, DWORD extraInfo )
413 MESSAGEQUEUE *msgQueue;
415 SIGNAL_MaskAsyncEvents( TRUE );
417 if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
418 pos = msgQueue->nextFreeMessage;
420 /* Check if queue is full */
421 if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
423 SIGNAL_MaskAsyncEvents( FALSE );
424 fprintf(stderr,"MSG_AddMsg // queue is full !\n");
429 msgQueue->messages[pos].msg = *msg;
430 msgQueue->messages[pos].extraInfo = extraInfo;
431 if (pos < msgQueue->queueSize-1) pos++;
433 msgQueue->nextFreeMessage = pos;
434 msgQueue->msgCount++;
436 SIGNAL_MaskAsyncEvents( FALSE );
438 QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
443 /***********************************************************************
446 * Find a message matching the given parameters. Return -1 if none available.
448 int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
450 int i, pos = msgQueue->nextMessage;
452 TRACE(msg,"hwnd=%04x pos=%d\n", hwnd, pos );
454 if (!msgQueue->msgCount) return -1;
455 if (!hwnd && !first && !last) return pos;
457 for (i = 0; i < msgQueue->msgCount; i++)
459 MSG16 * msg = &msgQueue->messages[pos].msg;
461 if (!hwnd || (msg->hwnd == hwnd))
463 if (!first && !last) return pos;
464 if ((msg->message >= first) && (msg->message <= last)) return pos;
466 if (pos < msgQueue->queueSize-1) pos++;
473 /***********************************************************************
476 * Remove a message from the queue (pos must be a valid position).
478 void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
480 SIGNAL_MaskAsyncEvents( TRUE );
482 if (pos >= msgQueue->nextMessage)
484 for ( ; pos > msgQueue->nextMessage; pos--)
485 msgQueue->messages[pos] = msgQueue->messages[pos-1];
486 msgQueue->nextMessage++;
487 if (msgQueue->nextMessage >= msgQueue->queueSize)
488 msgQueue->nextMessage = 0;
492 for ( ; pos < msgQueue->nextFreeMessage; pos++)
493 msgQueue->messages[pos] = msgQueue->messages[pos+1];
494 if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
495 else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
497 msgQueue->msgCount--;
498 if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
500 SIGNAL_MaskAsyncEvents( FALSE );
504 /***********************************************************************
507 * Wake a queue upon reception of a hardware event.
509 static void QUEUE_WakeSomeone( UINT32 message )
514 MESSAGEQUEUE *queue = pCursorQueue;
516 if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
519 if( pActiveQueue ) queue = pActiveQueue;
523 wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
524 if( (hwnd = GetCapture32()) )
525 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
526 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
529 if( (hwnd = GetSysModalWindow16()) )
530 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
531 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
535 queue = GlobalLock16( hFirstQueue );
538 if (queue->wakeMask & wakeBit) break;
539 queue = GlobalLock16( queue->next );
543 WARN(msg, "couldn't find queue\n");
548 QUEUE_SetWakeBit( queue, wakeBit );
552 /***********************************************************************
555 * Add an event to the system message queue.
556 * Note: the position is relative to the desktop window.
558 void hardware_event( WORD message, WORD wParam, LONG lParam,
559 int xPos, int yPos, DWORD time, DWORD extraInfo )
564 if (!sysMsgQueue) return;
565 pos = sysMsgQueue->nextFreeMessage;
567 /* Merge with previous event if possible */
569 if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
572 else pos = sysMsgQueue->queueSize - 1;
573 msg = &sysMsgQueue->messages[pos].msg;
574 if ((msg->message == message) && (msg->wParam == wParam))
575 sysMsgQueue->msgCount--; /* Merge events */
577 pos = sysMsgQueue->nextFreeMessage; /* Don't merge */
580 /* Check if queue is full */
582 if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
584 /* Queue is full, beep (but not on every mouse motion...) */
585 if (message != WM_MOUSEMOVE) MessageBeep32(0);
591 msg = &sysMsgQueue->messages[pos].msg;
593 msg->message = message;
594 msg->wParam = wParam;
595 msg->lParam = lParam;
597 msg->pt.x = xPos & 0xffff;
598 msg->pt.y = yPos & 0xffff;
599 sysMsgQueue->messages[pos].extraInfo = extraInfo;
600 if (pos < sysMsgQueue->queueSize - 1) pos++;
602 sysMsgQueue->nextFreeMessage = pos;
603 sysMsgQueue->msgCount++;
604 QUEUE_WakeSomeone( message );
608 /***********************************************************************
611 HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
613 MESSAGEQUEUE *queue = GlobalLock16( hQueue );
614 return (queue) ? queue->hTask : 0 ;
618 /***********************************************************************
619 * QUEUE_IncPaintCount
621 void QUEUE_IncPaintCount( HQUEUE16 hQueue )
625 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
626 queue->wPaintCount++;
627 QUEUE_SetWakeBit( queue, QS_PAINT );
631 /***********************************************************************
632 * QUEUE_DecPaintCount
634 void QUEUE_DecPaintCount( HQUEUE16 hQueue )
638 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
639 queue->wPaintCount--;
640 if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
644 /***********************************************************************
645 * QUEUE_IncTimerCount
647 void QUEUE_IncTimerCount( HQUEUE16 hQueue )
651 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
652 queue->wTimerCount++;
653 QUEUE_SetWakeBit( queue, QS_TIMER );
657 /***********************************************************************
658 * QUEUE_DecTimerCount
660 void QUEUE_DecTimerCount( HQUEUE16 hQueue )
664 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
665 queue->wTimerCount--;
666 if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
670 /***********************************************************************
671 * PostQuitMessage16 (USER.6)
673 void WINAPI PostQuitMessage16( INT16 exitCode )
675 PostQuitMessage32( exitCode );
679 /***********************************************************************
680 * PostQuitMessage32 (USER32.421)
682 void WINAPI PostQuitMessage32( INT32 exitCode )
686 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
687 queue->wPostQMsg = TRUE;
688 queue->wExitCode = (WORD)exitCode;
692 /***********************************************************************
693 * GetWindowTask16 (USER.224)
695 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
697 WND *wndPtr = WIN_FindWndPtr( hwnd );
699 if (!wndPtr) return 0;
700 return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
703 /***********************************************************************
704 * GetWindowThreadProcessId (USER32.313)
706 DWORD WINAPI GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
711 WND *wndPtr = WIN_FindWndPtr( hwnd );
713 if (!wndPtr) return 0;
714 htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
715 tdb = (TDB*)GlobalLock16(htask);
716 if (!tdb || !tdb->thdb) return 0;
717 if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
718 return THDB_TO_THREAD_ID( tdb->thdb );
722 /***********************************************************************
723 * SetMessageQueue16 (USER.266)
725 BOOL16 WINAPI SetMessageQueue16( INT16 size )
727 return SetMessageQueue32( size );
731 /***********************************************************************
732 * SetMessageQueue32 (USER32.494)
734 BOOL32 WINAPI SetMessageQueue32( INT32 size )
736 HQUEUE16 hQueue, hNewQueue;
737 MESSAGEQUEUE *queuePtr;
739 TRACE(msg,"task %04x size %i\n", GetCurrentTask(), size);
741 if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
743 if( !(hNewQueue = QUEUE_CreateMsgQueue( size )))
745 WARN(msg, "failed!\n");
748 queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
750 SIGNAL_MaskAsyncEvents( TRUE );
752 /* Copy data and free the old message queue */
753 if ((hQueue = GetTaskQueue(0)) != 0)
755 MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
756 memcpy( &queuePtr->wParamHigh, &oldQ->wParamHigh,
757 (int)oldQ->messages - (int)(&oldQ->wParamHigh) );
758 HOOK_ResetQueueHooks( hNewQueue );
759 if( WIN_GetDesktop()->hmemTaskQ == hQueue )
760 WIN_GetDesktop()->hmemTaskQ = hNewQueue;
761 WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
762 CLIPBOARD_ResetLock( hQueue, hNewQueue );
763 QUEUE_DeleteMsgQueue( hQueue );
766 /* Link new queue into list */
767 queuePtr->hTask = GetCurrentTask();
768 queuePtr->next = hFirstQueue;
769 hFirstQueue = hNewQueue;
771 if( !queuePtr->next ) pCursorQueue = queuePtr;
772 SetTaskQueue( 0, hNewQueue );
774 SIGNAL_MaskAsyncEvents( FALSE );
779 /***********************************************************************
780 * GetQueueStatus16 (USER.334)
782 DWORD WINAPI GetQueueStatus16( UINT16 flags )
787 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
788 ret = MAKELONG( queue->changeBits, queue->wakeBits );
789 queue->changeBits = 0;
790 return ret & MAKELONG( flags, flags );
793 /***********************************************************************
794 * GetQueueStatus32 (USER32.283)
796 DWORD WINAPI GetQueueStatus32( UINT32 flags )
801 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
802 ret = MAKELONG( queue->changeBits, queue->wakeBits );
803 queue->changeBits = 0;
804 return ret & MAKELONG( flags, flags );
808 /***********************************************************************
809 * GetInputState16 (USER.335)
811 BOOL16 WINAPI GetInputState16(void)
813 return GetInputState32();
816 /***********************************************************************
817 * WaitForInputIdle (USER32.577)
819 DWORD WINAPI WaitForInputIdle (HANDLE32 hProcess, DWORD dwTimeOut)
821 FIXME (msg, "(hProcess=%d, dwTimeOut=%ld): stub\n", hProcess, dwTimeOut);
827 /***********************************************************************
828 * GetInputState32 (USER32.244)
830 BOOL32 WINAPI GetInputState32(void)
834 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
836 return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
840 /***********************************************************************
841 * GetMessagePos (USER.119) (USER32.272)
843 DWORD WINAPI GetMessagePos(void)
847 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
848 return queue->GetMessagePosVal;
852 /***********************************************************************
853 * GetMessageTime (USER.120) (USER32.273)
855 LONG WINAPI GetMessageTime(void)
859 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
860 return queue->GetMessageTimeVal;
864 /***********************************************************************
865 * GetMessageExtraInfo (USER.288) (USER32.271)
867 LONG WINAPI GetMessageExtraInfo(void)
871 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
872 return queue->GetMessageExtraInfoVal;