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)
75 HQUEUE16 hQueue = hFirstQueue;
77 fprintf( stderr, "Queue Size Msgs Task\n" );
80 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
83 fprintf( stderr, "*** Bad queue handle %04x\n", hQueue );
86 fprintf( stderr, "%04x %5d %4d %04x %s\n",
87 hQueue, queue->msgSize, queue->msgCount, queue->hTask,
88 MODULE_GetModuleName( queue->hTask ) );
91 fprintf( stderr, "\n" );
95 /***********************************************************************
96 * QUEUE_IsExitingQueue
98 BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue )
100 return (hExitingQueue && (hQueue == hExitingQueue));
104 /***********************************************************************
105 * QUEUE_SetExitingQueue
107 void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
109 hExitingQueue = hQueue;
113 /***********************************************************************
114 * QUEUE_CreateMsgQueue
116 * Creates a message queue. Doesn't link it into queue list!
118 static HQUEUE16 QUEUE_CreateMsgQueue( int size )
121 MESSAGEQUEUE * msgQueue;
123 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
125 TRACE(msg,"Creating message queue...\n");
127 queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
128 if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
130 msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
131 msgQueue->self = hQueue;
132 msgQueue->msgSize = sizeof(QMSG);
133 msgQueue->queueSize = size;
134 msgQueue->wakeBits = msgQueue->changeBits = QS_SMPARAMSFREE;
135 msgQueue->wWinVersion = pTask ? pTask->version : 0;
136 GlobalUnlock16( hQueue );
141 /***********************************************************************
142 * QUEUE_DeleteMsgQueue
144 * Unlinks and deletes a message queue.
146 * Note: We need to mask asynchronous events to make sure PostMessage works
147 * even in the signal handler.
149 BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
151 MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
155 TRACE(msg,"Deleting message queue %04x\n", hQueue);
157 if (!hQueue || !msgQueue)
159 WARN(msg, "invalid argument.\n");
162 if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
163 if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
165 /* flush sent messages */
166 senderQ = msgQueue->hSendingTask;
169 MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
171 sq->SendMessageReturn = 0L;
172 QUEUE_SetWakeBit( sq, QS_SMRESULT );
173 senderQ = sq->hPrevSendingTask;
176 SIGNAL_MaskAsyncEvents( TRUE );
178 pPrev = &hFirstQueue;
179 while (*pPrev && (*pPrev != hQueue))
181 MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock16(*pPrev);
184 if (*pPrev) *pPrev = msgQueue->next;
187 SIGNAL_MaskAsyncEvents( FALSE );
189 GlobalFree16( hQueue );
194 /***********************************************************************
195 * QUEUE_CreateSysMsgQueue
197 * Create the system message queue, and set the double-click speed.
198 * Must be called only once.
200 BOOL32 QUEUE_CreateSysMsgQueue( int size )
202 if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
203 else if (size <= 0) size = 1;
204 if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( size ))) return FALSE;
205 sysMsgQueue = (MESSAGEQUEUE *) GlobalLock16( hmemSysMsgQueue );
210 /***********************************************************************
213 MESSAGEQUEUE *QUEUE_GetSysQueue(void)
219 /***********************************************************************
222 * See "Windows Internals", p.449
224 void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
226 TRACE(msg,"queue = %04x (wm=%04x), bit = %04x\n",
227 queue->self, queue->wakeMask, bit );
229 if (bit & QS_MOUSE) pMouseQueue = queue;
230 if (bit & QS_KEY) pKbdQueue = queue;
231 queue->changeBits |= bit;
232 queue->wakeBits |= bit;
233 if (queue->wakeMask & bit)
236 PostEvent( queue->hTask );
241 /***********************************************************************
244 void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
246 queue->changeBits &= ~bit;
247 queue->wakeBits &= ~bit;
251 /***********************************************************************
254 * See "Windows Internals", p.447
256 void QUEUE_WaitBits( WORD bits )
260 TRACE(msg,"q %04x waiting for %04x\n", GetTaskQueue(0), bits);
264 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
266 if (queue->changeBits & bits)
268 /* One of the bits is set; we can return */
272 if (queue->wakeBits & QS_SENDMESSAGE)
274 /* Process the sent message immediately */
277 QUEUE_ReceiveMessage( queue );
278 continue; /* nested sm crux */
281 queue->wakeMask = bits | QS_SENDMESSAGE;
282 if(queue->changeBits & bits) continue;
284 TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
291 /***********************************************************************
292 * QUEUE_ReceiveMessage
294 * This routine is called when a sent message is waiting for the queue.
296 void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
298 MESSAGEQUEUE *senderQ = NULL;
299 HQUEUE16 prevSender = 0;
300 QSMCTRL* prevCtrlPtr = NULL;
303 TRACE(msg, "ReceiveMessage, queue %04x\n", queue->self );
304 if (!(queue->wakeBits & QS_SENDMESSAGE) ||
305 !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)))
306 { TRACE(msg,"\trcm: nothing to do\n"); return; }
308 if( !senderQ->hPrevSendingTask )
310 queue->wakeBits &= ~QS_SENDMESSAGE; /* no more sent messages */
311 queue->changeBits &= ~QS_SENDMESSAGE;
314 /* Save current state on stack */
315 prevSender = queue->InSendMessageHandle;
316 prevCtrlPtr = queue->smResultCurrent;
318 /* Remove sending queue from the list */
319 queue->InSendMessageHandle = queue->hSendingTask;
320 queue->smResultCurrent = senderQ->smResultInit;
321 queue->hSendingTask = senderQ->hPrevSendingTask;
323 TRACE(msg, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n",
324 (unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
325 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
327 TRACE(msg, "\trcm: calling wndproc - %04x %04x %04x%04x %08x\n",
328 senderQ->hWnd, senderQ->msg, senderQ->wParamHigh,
329 senderQ->wParam, (unsigned)senderQ->lParam );
331 if (IsWindow32( senderQ->hWnd ))
333 WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd );
334 DWORD extraInfo = queue->GetMessageExtraInfoVal;
335 queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
337 if (senderQ->flags & QUEUE_SM_WIN32)
339 WPARAM32 wParam = MAKELONG( senderQ->wParam, senderQ->wParamHigh );
340 TRACE(msg, "\trcm: msg is Win32\n" );
341 if (senderQ->flags & QUEUE_SM_UNICODE)
342 result = CallWindowProc32W( wndPtr->winproc,
343 senderQ->hWnd, senderQ->msg,
344 wParam, senderQ->lParam );
346 result = CallWindowProc32A( wndPtr->winproc,
347 senderQ->hWnd, senderQ->msg,
348 wParam, senderQ->lParam );
350 else /* Win16 message */
351 result = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
352 senderQ->hWnd, senderQ->msg,
353 senderQ->wParam, senderQ->lParam );
355 queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
356 TRACE(msg,"\trcm: result = %08x\n", (unsigned)result );
358 else WARN(msg, "\trcm: bad hWnd\n");
360 /* Return the result to the sender task */
361 ReplyMessage16( result );
363 queue->InSendMessageHandle = prevSender;
364 queue->smResultCurrent = prevCtrlPtr;
366 TRACE(msg,"done!\n");
369 /***********************************************************************
372 * Try to reply to all pending sent messages on exit.
374 void QUEUE_FlushMessages( HQUEUE16 hQueue )
376 MESSAGEQUEUE *queue = (MESSAGEQUEUE*)GlobalLock16( hQueue );
380 MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
381 QSMCTRL* CtrlPtr = queue->smResultCurrent;
385 if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
386 queue->wakeBits &= ~QS_SENDMESSAGE;
387 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
389 queue->smResultCurrent = CtrlPtr;
390 while( senderQ->wakeBits & QS_SMRESULT ) OldYield();
392 senderQ->SendMessageReturn = 0;
393 senderQ->smResult = queue->smResultCurrent;
394 QUEUE_SetWakeBit( senderQ, QS_SMRESULT);
396 if( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)) )
397 CtrlPtr = senderQ->smResultInit;
399 queue->InSendMessageHandle = 0;
403 /***********************************************************************
406 * Add a message to the queue. Return FALSE if queue is full.
408 BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG16 * msg, DWORD extraInfo )
411 MESSAGEQUEUE *msgQueue;
413 SIGNAL_MaskAsyncEvents( TRUE );
415 if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
416 pos = msgQueue->nextFreeMessage;
418 /* Check if queue is full */
419 if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
421 SIGNAL_MaskAsyncEvents( FALSE );
422 fprintf(stderr,"MSG_AddMsg // queue is full !\n");
427 msgQueue->messages[pos].msg = *msg;
428 msgQueue->messages[pos].extraInfo = extraInfo;
429 if (pos < msgQueue->queueSize-1) pos++;
431 msgQueue->nextFreeMessage = pos;
432 msgQueue->msgCount++;
434 SIGNAL_MaskAsyncEvents( FALSE );
436 QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
441 /***********************************************************************
444 * Find a message matching the given parameters. Return -1 if none available.
446 int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
448 int i, pos = msgQueue->nextMessage;
450 TRACE(msg,"hwnd=%04x pos=%d\n", hwnd, pos );
452 if (!msgQueue->msgCount) return -1;
453 if (!hwnd && !first && !last) return pos;
455 for (i = 0; i < msgQueue->msgCount; i++)
457 MSG16 * msg = &msgQueue->messages[pos].msg;
459 if (!hwnd || (msg->hwnd == hwnd))
461 if (!first && !last) return pos;
462 if ((msg->message >= first) && (msg->message <= last)) return pos;
464 if (pos < msgQueue->queueSize-1) pos++;
471 /***********************************************************************
474 * Remove a message from the queue (pos must be a valid position).
476 void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
478 SIGNAL_MaskAsyncEvents( TRUE );
480 if (pos >= msgQueue->nextMessage)
482 for ( ; pos > msgQueue->nextMessage; pos--)
483 msgQueue->messages[pos] = msgQueue->messages[pos-1];
484 msgQueue->nextMessage++;
485 if (msgQueue->nextMessage >= msgQueue->queueSize)
486 msgQueue->nextMessage = 0;
490 for ( ; pos < msgQueue->nextFreeMessage; pos++)
491 msgQueue->messages[pos] = msgQueue->messages[pos+1];
492 if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
493 else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
495 msgQueue->msgCount--;
496 if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
498 SIGNAL_MaskAsyncEvents( FALSE );
502 /***********************************************************************
505 * Wake a queue upon reception of a hardware event.
507 static void QUEUE_WakeSomeone( UINT32 message )
512 MESSAGEQUEUE *queue = pCursorQueue;
514 if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
517 if( pActiveQueue ) queue = pActiveQueue;
521 wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
522 if( (hwnd = GetCapture32()) )
523 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
524 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
527 if( (hwnd = GetSysModalWindow16()) )
528 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
529 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
533 queue = GlobalLock16( hFirstQueue );
536 if (queue->wakeMask & wakeBit) break;
537 queue = GlobalLock16( queue->next );
541 WARN(msg, "couldn't find queue\n");
546 QUEUE_SetWakeBit( queue, wakeBit );
550 /***********************************************************************
553 * Add an event to the system message queue.
554 * Note: the position is relative to the desktop window.
556 void hardware_event( WORD message, WORD wParam, LONG lParam,
557 int xPos, int yPos, DWORD time, DWORD extraInfo )
562 if (!sysMsgQueue) return;
563 pos = sysMsgQueue->nextFreeMessage;
565 /* Merge with previous event if possible */
567 if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
570 else pos = sysMsgQueue->queueSize - 1;
571 msg = &sysMsgQueue->messages[pos].msg;
572 if ((msg->message == message) && (msg->wParam == wParam))
573 sysMsgQueue->msgCount--; /* Merge events */
575 pos = sysMsgQueue->nextFreeMessage; /* Don't merge */
578 /* Check if queue is full */
580 if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
582 /* Queue is full, beep (but not on every mouse motion...) */
583 if (message != WM_MOUSEMOVE) MessageBeep32(0);
589 msg = &sysMsgQueue->messages[pos].msg;
591 msg->message = message;
592 msg->wParam = wParam;
593 msg->lParam = lParam;
595 msg->pt.x = xPos & 0xffff;
596 msg->pt.y = yPos & 0xffff;
597 sysMsgQueue->messages[pos].extraInfo = extraInfo;
598 if (pos < sysMsgQueue->queueSize - 1) pos++;
600 sysMsgQueue->nextFreeMessage = pos;
601 sysMsgQueue->msgCount++;
602 QUEUE_WakeSomeone( message );
606 /***********************************************************************
609 HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
611 MESSAGEQUEUE *queue = GlobalLock16( hQueue );
612 return (queue) ? queue->hTask : 0 ;
616 /***********************************************************************
617 * QUEUE_IncPaintCount
619 void QUEUE_IncPaintCount( HQUEUE16 hQueue )
623 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
624 queue->wPaintCount++;
625 QUEUE_SetWakeBit( queue, QS_PAINT );
629 /***********************************************************************
630 * QUEUE_DecPaintCount
632 void QUEUE_DecPaintCount( HQUEUE16 hQueue )
636 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
637 queue->wPaintCount--;
638 if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
642 /***********************************************************************
643 * QUEUE_IncTimerCount
645 void QUEUE_IncTimerCount( HQUEUE16 hQueue )
649 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
650 queue->wTimerCount++;
651 QUEUE_SetWakeBit( queue, QS_TIMER );
655 /***********************************************************************
656 * QUEUE_DecTimerCount
658 void QUEUE_DecTimerCount( HQUEUE16 hQueue )
662 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
663 queue->wTimerCount--;
664 if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
668 /***********************************************************************
669 * PostQuitMessage16 (USER.6)
671 void WINAPI PostQuitMessage16( INT16 exitCode )
673 PostQuitMessage32( exitCode );
677 /***********************************************************************
678 * PostQuitMessage32 (USER32.420)
680 void WINAPI PostQuitMessage32( INT32 exitCode )
684 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
685 queue->wPostQMsg = TRUE;
686 queue->wExitCode = (WORD)exitCode;
690 /***********************************************************************
691 * GetWindowTask16 (USER.224)
693 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
695 WND *wndPtr = WIN_FindWndPtr( hwnd );
697 if (!wndPtr) return 0;
698 return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
701 /***********************************************************************
702 * GetWindowThreadProcessId (USER32.312)
704 DWORD WINAPI GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
709 WND *wndPtr = WIN_FindWndPtr( hwnd );
711 if (!wndPtr) return 0;
712 htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
713 tdb = (TDB*)GlobalLock16(htask);
714 if (!tdb || !tdb->thdb) return 0;
715 if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
716 return THDB_TO_THREAD_ID( tdb->thdb );
720 /***********************************************************************
721 * SetMessageQueue16 (USER.266)
723 BOOL16 WINAPI SetMessageQueue16( INT16 size )
725 return SetMessageQueue32( size );
729 /***********************************************************************
730 * SetMessageQueue32 (USER32.493)
732 BOOL32 WINAPI SetMessageQueue32( INT32 size )
734 HQUEUE16 hQueue, hNewQueue;
735 MESSAGEQUEUE *queuePtr;
737 TRACE(msg,"task %04x size %i\n", GetCurrentTask(), size);
739 if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
741 if( !(hNewQueue = QUEUE_CreateMsgQueue( size )))
743 WARN(msg, "failed!\n");
746 queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
748 SIGNAL_MaskAsyncEvents( TRUE );
750 /* Copy data and free the old message queue */
751 if ((hQueue = GetTaskQueue(0)) != 0)
753 MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
754 memcpy( &queuePtr->wParamHigh, &oldQ->wParamHigh,
755 (int)oldQ->messages - (int)(&oldQ->wParamHigh) );
756 HOOK_ResetQueueHooks( hNewQueue );
757 if( WIN_GetDesktop()->hmemTaskQ == hQueue )
758 WIN_GetDesktop()->hmemTaskQ = hNewQueue;
759 WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
760 CLIPBOARD_ResetLock( hQueue, hNewQueue );
761 QUEUE_DeleteMsgQueue( hQueue );
764 /* Link new queue into list */
765 queuePtr->hTask = GetCurrentTask();
766 queuePtr->next = hFirstQueue;
767 hFirstQueue = hNewQueue;
769 if( !queuePtr->next ) pCursorQueue = queuePtr;
770 SetTaskQueue( 0, hNewQueue );
772 SIGNAL_MaskAsyncEvents( FALSE );
777 /***********************************************************************
778 * GetQueueStatus16 (USER.334)
780 DWORD WINAPI GetQueueStatus16( UINT16 flags )
785 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
786 ret = MAKELONG( queue->changeBits, queue->wakeBits );
787 queue->changeBits = 0;
788 return ret & MAKELONG( flags, flags );
791 /***********************************************************************
792 * GetQueueStatus32 (USER32.283)
794 DWORD WINAPI GetQueueStatus32( UINT32 flags )
799 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
800 ret = MAKELONG( queue->changeBits, queue->wakeBits );
801 queue->changeBits = 0;
802 return ret & MAKELONG( flags, flags );
806 /***********************************************************************
807 * GetInputState16 (USER.335)
809 BOOL16 WINAPI GetInputState16(void)
811 return GetInputState32();
815 /***********************************************************************
816 * GetInputState32 (USER32.243)
818 BOOL32 WINAPI GetInputState32(void)
822 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
824 return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
828 /***********************************************************************
829 * GetMessagePos (USER.119) (USER32.271)
831 DWORD WINAPI GetMessagePos(void)
835 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
836 return queue->GetMessagePosVal;
840 /***********************************************************************
841 * GetMessageTime (USER.120) (USER32.272)
843 LONG WINAPI GetMessageTime(void)
847 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
848 return queue->GetMessageTimeVal;
852 /***********************************************************************
853 * GetMessageExtraInfo (USER.288) (USER32.270)
855 LONG WINAPI GetMessageExtraInfo(void)
859 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
860 return queue->GetMessageExtraInfoVal;