2 * Message queues related functions
4 * Copyright 1993, 1994 Alexandre Julliard
14 #include "clipboard.h"
21 #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
23 static HQUEUE16 hFirstQueue = 0;
24 static HQUEUE16 hExitingQueue = 0;
25 static HQUEUE16 hmemSysMsgQueue = 0;
26 static MESSAGEQUEUE *sysMsgQueue = NULL;
28 static MESSAGEQUEUE *pMouseQueue = NULL; /* Queue for last mouse message */
29 static MESSAGEQUEUE *pKbdQueue = NULL; /* Queue for last kbd message */
31 MESSAGEQUEUE *pCursorQueue = NULL;
32 MESSAGEQUEUE *pActiveQueue = NULL;
34 /***********************************************************************
37 void QUEUE_DumpQueue( HQUEUE16 hQueue )
41 if (!(pq = (MESSAGEQUEUE*) GlobalLock16( hQueue )) ||
42 GlobalSize16(hQueue) != sizeof(MESSAGEQUEUE))
44 WARN(msg, "%04x is not a queue handle\n", hQueue );
48 DUMP( "next: %12.4x Intertask SendMessage:\n"
49 "thread: %10p ----------------------\n"
51 "firstMsg: %8p lastMsg: %8p"
52 "msgCount: %8.4x msg: %11.8x\n"
53 "wParam: %10.8x lParam: %8.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->thdb, pq->hWnd32, pq->firstMsg, pq->lastMsg,
62 pq->msgCount, pq->msg32, pq->wParam32,(unsigned)pq->lParam,
63 (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
64 pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
65 pq->hPrevSendingTask, pq->wakeBits, pq->wakeMask, pq->hCurHook);
69 /***********************************************************************
72 void QUEUE_WalkQueues(void)
75 HQUEUE16 hQueue = hFirstQueue;
77 DUMP( "Queue Msgs Thread Task Module\n" );
80 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
83 WARN( msg, "Bad queue handle %04x\n", hQueue );
86 if (!GetModuleName( queue->thdb->process->task, module, sizeof(module )))
87 strcpy( module, "???" );
88 DUMP( "%04x %4d %p %04x %s\n", hQueue,queue->msgCount,
89 queue->thdb, queue->thdb->process->task, module );
96 /***********************************************************************
97 * QUEUE_IsExitingQueue
99 BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue )
101 return (hExitingQueue && (hQueue == hExitingQueue));
105 /***********************************************************************
106 * QUEUE_SetExitingQueue
108 void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
110 hExitingQueue = hQueue;
114 /***********************************************************************
115 * QUEUE_CreateMsgQueue
117 * Creates a message queue. Doesn't link it into queue list!
119 static HQUEUE16 QUEUE_CreateMsgQueue( )
122 MESSAGEQUEUE * msgQueue;
123 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
125 TRACE(msg,"Creating message queue...\n");
127 if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT,
128 sizeof(MESSAGEQUEUE) )))
133 msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
134 InitializeCriticalSection( &msgQueue->cSection );
135 msgQueue->self = hQueue;
136 msgQueue->wakeBits = msgQueue->changeBits = QS_SMPARAMSFREE;
137 msgQueue->wWinVersion = pTask ? pTask->version : 0;
142 /***********************************************************************
143 * QUEUE_DeleteMsgQueue
145 * Unlinks and deletes a message queue.
147 * Note: We need to mask asynchronous events to make sure PostMessage works
148 * even in the signal handler.
150 BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
152 MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
156 TRACE(msg,"Deleting message queue %04x\n", hQueue);
158 if (!hQueue || !msgQueue)
160 WARN(msg, "invalid argument.\n");
163 if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
164 if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
166 /* flush sent messages */
167 senderQ = msgQueue->hSendingTask;
170 MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
172 sq->SendMessageReturn = 0L;
173 QUEUE_SetWakeBit( sq, QS_SMRESULT );
174 senderQ = sq->hPrevSendingTask;
177 SIGNAL_MaskAsyncEvents( TRUE );
179 pPrev = &hFirstQueue;
180 while (*pPrev && (*pPrev != hQueue))
182 MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock16(*pPrev);
185 if (*pPrev) *pPrev = msgQueue->next;
188 SIGNAL_MaskAsyncEvents( FALSE );
190 GlobalFree16( hQueue );
195 /***********************************************************************
196 * QUEUE_CreateSysMsgQueue
198 * Create the system message queue, and set the double-click speed.
199 * Must be called only once.
201 BOOL32 QUEUE_CreateSysMsgQueue( int size )
203 if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( ))) return FALSE;
204 sysMsgQueue = (MESSAGEQUEUE *) GlobalLock16( hmemSysMsgQueue );
209 /***********************************************************************
212 MESSAGEQUEUE *QUEUE_GetSysQueue(void)
217 /***********************************************************************
220 void QUEUE_Signal( THDB *thdb )
222 /* Wake up thread waiting for message */
223 SetEvent( thdb->event );
225 PostEvent( thdb->process->task );
228 /***********************************************************************
231 static void QUEUE_Wait( DWORD wait_mask )
233 if ( THREAD_IsWin16( THREAD_Current() ) )
237 TRACE(msg, "current task is 32-bit, calling SYNC_DoWait\n");
238 MsgWaitForMultipleObjects( 0, NULL, FALSE, INFINITE32, wait_mask );
243 /***********************************************************************
246 * See "Windows Internals", p.449
248 void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
250 TRACE(msg,"queue = %04x (wm=%04x), bit = %04x\n",
251 queue->self, queue->wakeMask, bit );
253 if (bit & QS_MOUSE) pMouseQueue = queue;
254 if (bit & QS_KEY) pKbdQueue = queue;
255 queue->changeBits |= bit;
256 queue->wakeBits |= bit;
257 if (queue->wakeMask & bit)
260 QUEUE_Signal( queue->thdb );
265 /***********************************************************************
268 void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
270 queue->changeBits &= ~bit;
271 queue->wakeBits &= ~bit;
275 /***********************************************************************
278 * See "Windows Internals", p.447
280 void QUEUE_WaitBits( WORD bits )
284 TRACE(msg,"q %04x waiting for %04x\n", GetFastQueue(), bits);
288 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return;
290 if (queue->changeBits & bits)
292 /* One of the bits is set; we can return */
296 if (queue->wakeBits & QS_SENDMESSAGE)
298 /* Process the sent message immediately */
301 QUEUE_ReceiveMessage( queue );
302 continue; /* nested sm crux */
305 queue->wakeMask = bits | QS_SENDMESSAGE;
306 if(queue->changeBits & bits) continue;
308 TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
310 QUEUE_Wait( queue->wakeMask );
315 /***********************************************************************
316 * QUEUE_ReceiveMessage
318 * This routine is called when a sent message is waiting for the queue.
320 void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
322 MESSAGEQUEUE *senderQ = NULL;
323 HQUEUE16 prevSender = 0;
324 QSMCTRL* prevCtrlPtr = NULL;
327 TRACE(msg, "ReceiveMessage, queue %04x\n", queue->self );
328 if (!(queue->wakeBits & QS_SENDMESSAGE) ||
329 !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)))
330 { TRACE(msg,"\trcm: nothing to do\n"); return; }
332 if( !senderQ->hPrevSendingTask )
333 QUEUE_ClearWakeBit( queue, QS_SENDMESSAGE ); /* no more sent messages */
335 /* Save current state on stack */
336 prevSender = queue->InSendMessageHandle;
337 prevCtrlPtr = queue->smResultCurrent;
339 /* Remove sending queue from the list */
340 queue->InSendMessageHandle = queue->hSendingTask;
341 queue->smResultCurrent = senderQ->smResultInit;
342 queue->hSendingTask = senderQ->hPrevSendingTask;
344 TRACE(msg, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n",
345 (unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
346 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
348 TRACE(msg, "\trcm: calling wndproc - %08x %08x %08x %08x\n",
349 senderQ->hWnd32, senderQ->msg32,
350 senderQ->wParam32, (unsigned)senderQ->lParam );
352 if (IsWindow32( senderQ->hWnd32 ))
354 WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd32 );
355 DWORD extraInfo = queue->GetMessageExtraInfoVal;
356 queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
358 if (senderQ->flags & QUEUE_SM_WIN32)
360 TRACE(msg, "\trcm: msg is Win32\n" );
361 if (senderQ->flags & QUEUE_SM_UNICODE)
362 result = CallWindowProc32W( wndPtr->winproc,
363 senderQ->hWnd32, senderQ->msg32,
364 senderQ->wParam32, senderQ->lParam );
366 result = CallWindowProc32A( wndPtr->winproc,
367 senderQ->hWnd32, senderQ->msg32,
368 senderQ->wParam32, senderQ->lParam );
370 else /* Win16 message */
371 result = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
372 (HWND16) senderQ->hWnd32,
373 (UINT16) senderQ->msg32,
374 LOWORD (senderQ->wParam32),
377 queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
378 TRACE(msg,"\trcm: result = %08x\n", (unsigned)result );
380 else WARN(msg, "\trcm: bad hWnd\n");
382 /* Return the result to the sender task */
383 ReplyMessage16( result );
385 queue->InSendMessageHandle = prevSender;
386 queue->smResultCurrent = prevCtrlPtr;
388 TRACE(msg,"done!\n");
391 /***********************************************************************
394 * Try to reply to all pending sent messages on exit.
396 void QUEUE_FlushMessages( HQUEUE16 hQueue )
398 MESSAGEQUEUE *queue = (MESSAGEQUEUE*)GlobalLock16( hQueue );
402 MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
403 QSMCTRL* CtrlPtr = queue->smResultCurrent;
405 TRACE(msg,"Flushing queue %04x:\n", hQueue );
410 CtrlPtr = senderQ->smResultInit;
412 TRACE(msg,"\tfrom queue %04x, smResult %08x\n", queue->hSendingTask, (unsigned)CtrlPtr );
414 if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
415 QUEUE_ClearWakeBit( queue, QS_SENDMESSAGE );
417 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
419 queue->smResultCurrent = CtrlPtr;
420 while( senderQ->wakeBits & QS_SMRESULT ) OldYield();
422 senderQ->SendMessageReturn = 0;
423 senderQ->smResult = queue->smResultCurrent;
424 QUEUE_SetWakeBit( senderQ, QS_SMRESULT);
426 senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
429 queue->InSendMessageHandle = 0;
433 /***********************************************************************
436 * Add a message to the queue. Return FALSE if queue is full.
438 BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG32 *msg, DWORD extraInfo )
440 MESSAGEQUEUE *msgQueue;
444 if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
446 /* allocate new message in global heap for now */
447 if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
450 EnterCriticalSection( &msgQueue->cSection );
454 qmsg->extraInfo = extraInfo;
456 /* insert the message in the link list */
458 qmsg->prevMsg = msgQueue->lastMsg;
460 if (msgQueue->lastMsg)
461 msgQueue->lastMsg->nextMsg = qmsg;
463 /* update first and last anchor in message queue */
464 msgQueue->lastMsg = qmsg;
465 if (!msgQueue->firstMsg)
466 msgQueue->firstMsg = qmsg;
468 msgQueue->msgCount++;
470 LeaveCriticalSection( &msgQueue->cSection );
472 QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
478 /***********************************************************************
481 * Find a message matching the given parameters. Return -1 if none available.
483 QMSG* QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
487 EnterCriticalSection( &msgQueue->cSection );
489 if (!msgQueue->msgCount)
491 else if (!hwnd && !first && !last)
492 qmsg = msgQueue->firstMsg;
495 /* look in linked list for message matching first and last criteria */
496 for (qmsg = msgQueue->firstMsg; qmsg; qmsg = qmsg->nextMsg)
498 MSG32 *msg = &(qmsg->msg);
500 if (!hwnd || (msg->hwnd == hwnd))
503 break; /* found it */
505 if ((msg->message >= first) && (msg->message <= last))
506 break; /* found it */
511 LeaveCriticalSection( &msgQueue->cSection );
518 /***********************************************************************
521 * Remove a message from the queue (pos must be a valid position).
523 void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg )
525 EnterCriticalSection( &msgQueue->cSection );
527 /* set the linked list */
529 qmsg->prevMsg->nextMsg = qmsg->nextMsg;
532 qmsg->nextMsg->prevMsg = qmsg->prevMsg;
534 if (msgQueue->firstMsg == qmsg)
535 msgQueue->firstMsg = qmsg->nextMsg;
537 if (msgQueue->lastMsg == qmsg)
538 msgQueue->lastMsg = qmsg->prevMsg;
540 /* deallocate the memory for the message */
541 HeapFree( SystemHeap, 0, qmsg );
543 msgQueue->msgCount--;
544 if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
546 LeaveCriticalSection( &msgQueue->cSection );
550 /***********************************************************************
553 * Wake a queue upon reception of a hardware event.
555 static void QUEUE_WakeSomeone( UINT32 message )
560 MESSAGEQUEUE *queue = pCursorQueue;
562 if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
565 if( pActiveQueue ) queue = pActiveQueue;
569 wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
570 if( (hwnd = GetCapture32()) )
571 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
572 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
575 if( (hwnd = GetSysModalWindow16()) )
576 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
577 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
581 queue = GlobalLock16( hFirstQueue );
584 if (queue->wakeMask & wakeBit) break;
585 queue = GlobalLock16( queue->next );
589 WARN(msg, "couldn't find queue\n");
594 QUEUE_SetWakeBit( queue, wakeBit );
598 /***********************************************************************
601 * Add an event to the system message queue.
602 * Note: the position is relative to the desktop window.
604 void hardware_event( WORD message, WORD wParam, LONG lParam,
605 int xPos, int yPos, DWORD time, DWORD extraInfo )
608 QMSG *qmsg = sysMsgQueue->lastMsg;
611 if (!sysMsgQueue) return;
613 /* Merge with previous event if possible */
615 if ((message == WM_MOUSEMOVE) && sysMsgQueue->lastMsg)
617 msg = &(sysMsgQueue->lastMsg->msg);
619 if ((msg->message == message) && (msg->wParam == wParam))
622 qmsg = sysMsgQueue->lastMsg;
629 /* Should I limit the number of message in
630 the system message queue??? */
632 /* Don't merge allocate a new msg in the global heap */
634 if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
637 /* put message at the end of the linked list */
639 qmsg->prevMsg = sysMsgQueue->lastMsg;
641 if (sysMsgQueue->lastMsg)
642 sysMsgQueue->lastMsg->nextMsg = qmsg;
644 /* set last and first anchor index in system message queue */
645 sysMsgQueue->lastMsg = qmsg;
646 if (!sysMsgQueue->firstMsg)
647 sysMsgQueue->firstMsg = qmsg;
649 sysMsgQueue->msgCount++;
655 msg->message = message;
656 msg->wParam = wParam;
657 msg->lParam = lParam;
661 qmsg->extraInfo = extraInfo;
663 QUEUE_WakeSomeone( message );
667 /***********************************************************************
670 HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
672 MESSAGEQUEUE *queue = GlobalLock16( hQueue );
673 return (queue) ? queue->thdb->process->task : 0 ;
677 /***********************************************************************
678 * QUEUE_IncPaintCount
680 void QUEUE_IncPaintCount( HQUEUE16 hQueue )
684 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
685 queue->wPaintCount++;
686 QUEUE_SetWakeBit( queue, QS_PAINT );
690 /***********************************************************************
691 * QUEUE_DecPaintCount
693 void QUEUE_DecPaintCount( HQUEUE16 hQueue )
697 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
698 queue->wPaintCount--;
699 if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
703 /***********************************************************************
704 * QUEUE_IncTimerCount
706 void QUEUE_IncTimerCount( HQUEUE16 hQueue )
710 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
711 queue->wTimerCount++;
712 QUEUE_SetWakeBit( queue, QS_TIMER );
716 /***********************************************************************
717 * QUEUE_DecTimerCount
719 void QUEUE_DecTimerCount( HQUEUE16 hQueue )
723 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
724 queue->wTimerCount--;
725 if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
729 /***********************************************************************
730 * PostQuitMessage16 (USER.6)
732 void WINAPI PostQuitMessage16( INT16 exitCode )
734 PostQuitMessage32( exitCode );
738 /***********************************************************************
739 * PostQuitMessage32 (USER32.421)
741 * PostQuitMessage() posts a message to the system requesting an
742 * application to terminate execution. As a result of this function,
743 * the WM_QUIT message is posted to the application, and
744 * PostQuitMessage() returns immediately. The exitCode parameter
745 * specifies an application-defined exit code, which appears in the
746 * _wParam_ parameter of the WM_QUIT message posted to the application.
752 void WINAPI PostQuitMessage32( INT32 exitCode )
756 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return;
757 queue->wPostQMsg = TRUE;
758 queue->wExitCode = (WORD)exitCode;
762 /***********************************************************************
763 * GetWindowTask16 (USER.224)
765 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
767 WND *wndPtr = WIN_FindWndPtr( hwnd );
769 if (!wndPtr) return 0;
770 return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
773 /***********************************************************************
774 * GetWindowThreadProcessId (USER32.313)
776 DWORD WINAPI GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
781 WND *wndPtr = WIN_FindWndPtr( hwnd );
783 if (!wndPtr) return 0;
784 htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
785 tdb = (TDB*)GlobalLock16(htask);
786 if (!tdb || !tdb->thdb) return 0;
787 if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
788 return THDB_TO_THREAD_ID( tdb->thdb );
792 /***********************************************************************
793 * SetMessageQueue16 (USER.266)
795 BOOL16 WINAPI SetMessageQueue16( INT16 size )
797 return SetMessageQueue32( size );
801 /***********************************************************************
802 * SetMessageQueue32 (USER32.494)
804 BOOL32 WINAPI SetMessageQueue32( INT32 size )
806 /* now obsolete the message queue will be expanded dynamically
809 /* access the queue to create it if it's not existing */
815 /***********************************************************************
816 * InitThreadInput (USER.409)
818 HQUEUE16 WINAPI InitThreadInput( WORD unknown, WORD flags )
821 MESSAGEQUEUE *queuePtr;
823 THDB *thdb = THREAD_Current();
828 hQueue = thdb->teb.queue;
832 /* Create thread message queue */
833 if( !(hQueue = QUEUE_CreateMsgQueue( 0 )))
835 WARN(msg, "failed!\n");
839 /* Link new queue into list */
840 queuePtr = (MESSAGEQUEUE *)GlobalLock16( hQueue );
841 queuePtr->thdb = THREAD_Current();
843 SIGNAL_MaskAsyncEvents( TRUE );
844 SetThreadQueue( 0, hQueue );
845 thdb->teb.queue = hQueue;
847 queuePtr->next = hFirstQueue;
848 hFirstQueue = hQueue;
849 SIGNAL_MaskAsyncEvents( FALSE );
855 /***********************************************************************
856 * GetQueueStatus16 (USER.334)
858 DWORD WINAPI GetQueueStatus16( UINT16 flags )
863 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
864 ret = MAKELONG( queue->changeBits, queue->wakeBits );
865 queue->changeBits = 0;
866 return ret & MAKELONG( flags, flags );
869 /***********************************************************************
870 * GetQueueStatus32 (USER32.283)
872 DWORD WINAPI GetQueueStatus32( UINT32 flags )
877 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
878 ret = MAKELONG( queue->changeBits, queue->wakeBits );
879 queue->changeBits = 0;
880 return ret & MAKELONG( flags, flags );
884 /***********************************************************************
885 * GetInputState16 (USER.335)
887 BOOL16 WINAPI GetInputState16(void)
889 return GetInputState32();
892 /***********************************************************************
893 * WaitForInputIdle (USER32.577)
895 DWORD WINAPI WaitForInputIdle (HANDLE32 hProcess, DWORD dwTimeOut)
897 FIXME (msg, "(hProcess=%d, dwTimeOut=%ld): stub\n", hProcess, dwTimeOut);
903 /***********************************************************************
904 * GetInputState32 (USER32.244)
906 BOOL32 WINAPI GetInputState32(void)
910 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() )))
912 return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
915 /***********************************************************************
916 * UserYield (USER.332)
918 void WINAPI UserYield(void)
920 TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
921 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
923 if ( !THREAD_IsWin16( THREAD_Current() ) )
925 FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
929 /* Handle sent messages */
930 while (queue && (queue->wakeBits & QS_SENDMESSAGE))
931 QUEUE_ReceiveMessage( queue );
935 queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
936 while (queue && (queue->wakeBits & QS_SENDMESSAGE))
937 QUEUE_ReceiveMessage( queue );
940 /***********************************************************************
941 * GetMessagePos (USER.119) (USER32.272)
943 * The GetMessagePos() function returns a long value representing a
944 * cursor position, in screen coordinates, when the last message
945 * retrieved by the GetMessage() function occurs. The x-coordinate is
946 * in the low-order word of the return value, the y-coordinate is in
947 * the high-order word. The application can use the MAKEPOINT()
948 * macro to obtain a POINT structure from the return value.
950 * For the current cursor position, use GetCursorPos().
954 * Cursor position of last message on success, zero on failure.
961 DWORD WINAPI GetMessagePos(void)
965 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
966 return queue->GetMessagePosVal;
970 /***********************************************************************
971 * GetMessageTime (USER.120) (USER32.273)
973 * GetMessageTime() returns the message time for the last message
974 * retrieved by the function. The time is measured in milliseconds with
975 * the same offset as GetTickCount().
977 * Since the tick count wraps, this is only useful for moderately short
978 * relative time comparisons.
982 * Time of last message on success, zero on failure.
989 LONG WINAPI GetMessageTime(void)
993 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
994 return queue->GetMessageTimeVal;
998 /***********************************************************************
999 * GetMessageExtraInfo (USER.288) (USER32.271)
1001 LONG WINAPI GetMessageExtraInfo(void)
1003 MESSAGEQUEUE *queue;
1005 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetFastQueue() ))) return 0;
1006 return queue->GetMessageExtraInfoVal;