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();
814 /***********************************************************************
815 * WaitForInputIdle (USER32.577)
817 DWORD WINAPI
WaitForInputIdle (HANDLE32 hProcess
, DWORD dwTimeOut
)
819 FIXME (msg
, "WaitForInputIdle: stub\n");
824 /***********************************************************************
825 * GetInputState32 (USER32.243)
827 BOOL32 WINAPI
GetInputState32(void)
831 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) )))
833 return queue
->wakeBits
& (QS_KEY
| QS_MOUSEBUTTON
);
837 /***********************************************************************
838 * GetMessagePos (USER.119) (USER32.271)
840 DWORD WINAPI
GetMessagePos(void)
844 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
845 return queue
->GetMessagePosVal
;
849 /***********************************************************************
850 * GetMessageTime (USER.120) (USER32.272)
852 LONG WINAPI
GetMessageTime(void)
856 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
857 return queue
->GetMessageTimeVal
;
861 /***********************************************************************
862 * GetMessageExtraInfo (USER.288) (USER32.270)
864 LONG WINAPI
GetMessageExtraInfo(void)
868 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
869 return queue
->GetMessageExtraInfoVal
;