Release 980809
[wine.git] / windows / queue.c
blob712dea1ef1848a6ae9574666932c56536cb0373b
1 /*
2 * Message queues related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <signal.h>
9 #include "miscemu.h"
10 #include "module.h"
11 #include "queue.h"
12 #include "task.h"
13 #include "win.h"
14 #include "clipboard.h"
15 #include "hook.h"
16 #include "heap.h"
17 #include "thread.h"
18 #include "process.h"
19 #include "debug.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 /***********************************************************************
35 * QUEUE_DumpQueue
37 void QUEUE_DumpQueue( HQUEUE16 hQueue )
39 MESSAGEQUEUE *pq;
41 if (!(pq = (MESSAGEQUEUE*) GlobalLock16( hQueue )) ||
42 GlobalSize16(hQueue) < sizeof(MESSAGEQUEUE)+pq->queueSize*sizeof(QMSG))
44 WARN(msg, "%04x is not a queue handle\n", hQueue );
45 return;
48 DUMP( "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"
58 "wakeBits: %8.4x\n"
59 "wakeMask: %8.4x\n"
60 "hCurHook: %8.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 /***********************************************************************
71 * QUEUE_WalkQueues
73 void QUEUE_WalkQueues(void)
75 char module[10];
76 HQUEUE16 hQueue = hFirstQueue;
78 DUMP( "Queue Size Msgs Task\n" );
79 while (hQueue)
81 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
82 if (!queue)
84 WARN( msg, "Bad queue handle %04x\n", hQueue );
85 return;
87 if (!GetModuleName( queue->hTask, module, sizeof(module )))
88 strcpy( module, "???" );
89 DUMP( "%04x %5d %4d %04x %s\n", hQueue, queue->msgSize,
90 queue->msgCount, queue->hTask, module );
91 hQueue = queue->next;
93 DUMP( "\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 )
122 HQUEUE16 hQueue;
123 MESSAGEQUEUE * msgQueue;
124 int queueSize;
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 )))
131 return 0;
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 );
139 return 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);
154 HQUEUE16 senderQ;
155 HQUEUE16 *pPrev;
157 TRACE(msg,"Deleting message queue %04x\n", hQueue);
159 if (!hQueue || !msgQueue)
161 WARN(msg, "invalid argument.\n");
162 return 0;
164 if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
165 if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
167 /* flush sent messages */
168 senderQ = msgQueue->hSendingTask;
169 while( senderQ )
171 MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
172 if( !sq ) break;
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);
184 pPrev = &msgQ->next;
186 if (*pPrev) *pPrev = msgQueue->next;
187 msgQueue->self = 0;
189 SIGNAL_MaskAsyncEvents( FALSE );
191 GlobalFree16( hQueue );
192 return 1;
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 );
208 return TRUE;
212 /***********************************************************************
213 * QUEUE_GetSysQueue
215 MESSAGEQUEUE *QUEUE_GetSysQueue(void)
217 return sysMsgQueue;
221 /***********************************************************************
222 * QUEUE_SetWakeBit
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)
237 queue->wakeMask = 0;
238 PostEvent( queue->hTask );
240 /* Wake up thread waiting for message */
241 /* NOTE: This should really wake up *the* thread that owns
242 the queue. Since we dont't have thread-local message
243 queues yet, we wake up all waiting threads ... */
244 SYSTEM_LOCK();
246 TDB *pTask = (TDB *)GlobalLock16( queue->hTask );
247 PDB32 *pdb = pTask? pTask->thdb->process : NULL;
248 THREAD_ENTRY *entry = pdb? pdb->thread_list->next : NULL;
250 if (entry)
251 for (;;)
253 if (entry->thread->wait_struct.wait_msg)
254 SYNC_MsgWakeUp( entry->thread );
255 if (entry == pdb->thread_list) break;
256 entry = entry->next;
259 SYSTEM_UNLOCK();
264 /***********************************************************************
265 * QUEUE_ClearWakeBit
267 void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
269 queue->changeBits &= ~bit;
270 queue->wakeBits &= ~bit;
274 /***********************************************************************
275 * QUEUE_WaitBits
277 * See "Windows Internals", p.447
279 void QUEUE_WaitBits( WORD bits )
281 MESSAGEQUEUE *queue;
283 TRACE(msg,"q %04x waiting for %04x\n", GetTaskQueue(0), bits);
285 for (;;)
287 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
289 if (queue->changeBits & bits)
291 /* One of the bits is set; we can return */
292 queue->wakeMask = 0;
293 return;
295 if (queue->wakeBits & QS_SENDMESSAGE)
297 /* Process the sent message immediately */
299 queue->wakeMask = 0;
300 QUEUE_ReceiveMessage( queue );
301 continue; /* nested sm crux */
304 queue->wakeMask = bits | QS_SENDMESSAGE;
305 if(queue->changeBits & bits) continue;
307 TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
309 WaitEvent( 0 );
314 /***********************************************************************
315 * QUEUE_ReceiveMessage
317 * This routine is called when a sent message is waiting for the queue.
319 void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
321 MESSAGEQUEUE *senderQ = NULL;
322 HQUEUE16 prevSender = 0;
323 QSMCTRL* prevCtrlPtr = NULL;
324 LRESULT result = 0;
326 TRACE(msg, "ReceiveMessage, queue %04x\n", queue->self );
327 if (!(queue->wakeBits & QS_SENDMESSAGE) ||
328 !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)))
329 { TRACE(msg,"\trcm: nothing to do\n"); return; }
331 if( !senderQ->hPrevSendingTask )
333 queue->wakeBits &= ~QS_SENDMESSAGE; /* no more sent messages */
334 queue->changeBits &= ~QS_SENDMESSAGE;
337 /* Save current state on stack */
338 prevSender = queue->InSendMessageHandle;
339 prevCtrlPtr = queue->smResultCurrent;
341 /* Remove sending queue from the list */
342 queue->InSendMessageHandle = queue->hSendingTask;
343 queue->smResultCurrent = senderQ->smResultInit;
344 queue->hSendingTask = senderQ->hPrevSendingTask;
346 TRACE(msg, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n",
347 (unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
348 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
350 TRACE(msg, "\trcm: calling wndproc - %04x %04x %04x%04x %08x\n",
351 senderQ->hWnd, senderQ->msg, senderQ->wParamHigh,
352 senderQ->wParam, (unsigned)senderQ->lParam );
354 if (IsWindow32( senderQ->hWnd ))
356 WND *wndPtr = WIN_FindWndPtr( senderQ->hWnd );
357 DWORD extraInfo = queue->GetMessageExtraInfoVal;
358 queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
360 if (senderQ->flags & QUEUE_SM_WIN32)
362 WPARAM32 wParam = MAKELONG( senderQ->wParam, senderQ->wParamHigh );
363 TRACE(msg, "\trcm: msg is Win32\n" );
364 if (senderQ->flags & QUEUE_SM_UNICODE)
365 result = CallWindowProc32W( wndPtr->winproc,
366 senderQ->hWnd, senderQ->msg,
367 wParam, senderQ->lParam );
368 else
369 result = CallWindowProc32A( wndPtr->winproc,
370 senderQ->hWnd, senderQ->msg,
371 wParam, senderQ->lParam );
373 else /* Win16 message */
374 result = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
375 senderQ->hWnd, senderQ->msg,
376 senderQ->wParam, senderQ->lParam );
378 queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
379 TRACE(msg,"\trcm: result = %08x\n", (unsigned)result );
381 else WARN(msg, "\trcm: bad hWnd\n");
383 /* Return the result to the sender task */
384 ReplyMessage16( result );
386 queue->InSendMessageHandle = prevSender;
387 queue->smResultCurrent = prevCtrlPtr;
389 TRACE(msg,"done!\n");
392 /***********************************************************************
393 * QUEUE_FlushMessage
395 * Try to reply to all pending sent messages on exit.
397 void QUEUE_FlushMessages( HQUEUE16 hQueue )
399 MESSAGEQUEUE *queue = (MESSAGEQUEUE*)GlobalLock16( hQueue );
401 if( queue )
403 MESSAGEQUEUE *senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask);
404 QSMCTRL* CtrlPtr = queue->smResultCurrent;
406 while( senderQ )
408 if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
409 queue->wakeBits &= ~QS_SENDMESSAGE;
410 QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
412 queue->smResultCurrent = CtrlPtr;
413 while( senderQ->wakeBits & QS_SMRESULT ) OldYield();
415 senderQ->SendMessageReturn = 0;
416 senderQ->smResult = queue->smResultCurrent;
417 QUEUE_SetWakeBit( senderQ, QS_SMRESULT);
419 if( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)) )
420 CtrlPtr = senderQ->smResultInit;
422 queue->InSendMessageHandle = 0;
426 /***********************************************************************
427 * QUEUE_AddMsg
429 * Add a message to the queue. Return FALSE if queue is full.
431 BOOL32 QUEUE_AddMsg( HQUEUE16 hQueue, MSG16 * msg, DWORD extraInfo )
433 int pos;
434 MESSAGEQUEUE *msgQueue;
436 SIGNAL_MaskAsyncEvents( TRUE );
438 if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return FALSE;
439 pos = msgQueue->nextFreeMessage;
441 /* Check if queue is full */
442 if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
444 SIGNAL_MaskAsyncEvents( FALSE );
445 WARN( msg,"Queue is full!\n" );
446 return FALSE;
449 /* Store message */
450 msgQueue->messages[pos].msg = *msg;
451 msgQueue->messages[pos].extraInfo = extraInfo;
452 if (pos < msgQueue->queueSize-1) pos++;
453 else pos = 0;
454 msgQueue->nextFreeMessage = pos;
455 msgQueue->msgCount++;
457 SIGNAL_MaskAsyncEvents( FALSE );
459 QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
460 return TRUE;
464 /***********************************************************************
465 * QUEUE_FindMsg
467 * Find a message matching the given parameters. Return -1 if none available.
469 int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd, int first, int last )
471 int i, pos = msgQueue->nextMessage;
473 TRACE(msg,"hwnd=%04x pos=%d\n", hwnd, pos );
475 if (!msgQueue->msgCount) return -1;
476 if (!hwnd && !first && !last) return pos;
478 for (i = 0; i < msgQueue->msgCount; i++)
480 MSG16 * msg = &msgQueue->messages[pos].msg;
482 if (!hwnd || (msg->hwnd == hwnd))
484 if (!first && !last) return pos;
485 if ((msg->message >= first) && (msg->message <= last)) return pos;
487 if (pos < msgQueue->queueSize-1) pos++;
488 else pos = 0;
490 return -1;
494 /***********************************************************************
495 * QUEUE_RemoveMsg
497 * Remove a message from the queue (pos must be a valid position).
499 void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
501 SIGNAL_MaskAsyncEvents( TRUE );
503 if (pos >= msgQueue->nextMessage)
505 for ( ; pos > msgQueue->nextMessage; pos--)
506 msgQueue->messages[pos] = msgQueue->messages[pos-1];
507 msgQueue->nextMessage++;
508 if (msgQueue->nextMessage >= msgQueue->queueSize)
509 msgQueue->nextMessage = 0;
511 else
513 for ( ; pos < msgQueue->nextFreeMessage; pos++)
514 msgQueue->messages[pos] = msgQueue->messages[pos+1];
515 if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
516 else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
518 msgQueue->msgCount--;
519 if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
521 SIGNAL_MaskAsyncEvents( FALSE );
525 /***********************************************************************
526 * QUEUE_WakeSomeone
528 * Wake a queue upon reception of a hardware event.
530 static void QUEUE_WakeSomeone( UINT32 message )
532 WND* wndPtr = NULL;
533 WORD wakeBit;
534 HWND32 hwnd;
535 MESSAGEQUEUE *queue = pCursorQueue;
537 if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
539 wakeBit = QS_KEY;
540 if( pActiveQueue ) queue = pActiveQueue;
542 else
544 wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
545 if( (hwnd = GetCapture32()) )
546 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
547 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
550 if( (hwnd = GetSysModalWindow16()) )
551 if( (wndPtr = WIN_FindWndPtr( hwnd )) )
552 queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
554 if( !queue )
556 queue = GlobalLock16( hFirstQueue );
557 while( queue )
559 if (queue->wakeMask & wakeBit) break;
560 queue = GlobalLock16( queue->next );
562 if( !queue )
564 WARN(msg, "couldn't find queue\n");
565 return;
569 QUEUE_SetWakeBit( queue, wakeBit );
573 /***********************************************************************
574 * hardware_event
576 * Add an event to the system message queue.
577 * Note: the position is relative to the desktop window.
579 void hardware_event( WORD message, WORD wParam, LONG lParam,
580 int xPos, int yPos, DWORD time, DWORD extraInfo )
582 MSG16 *msg;
583 int pos;
585 if (!sysMsgQueue) return;
586 pos = sysMsgQueue->nextFreeMessage;
588 /* Merge with previous event if possible */
590 if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
592 if (pos > 0) pos--;
593 else pos = sysMsgQueue->queueSize - 1;
594 msg = &sysMsgQueue->messages[pos].msg;
595 if ((msg->message == message) && (msg->wParam == wParam))
596 sysMsgQueue->msgCount--; /* Merge events */
597 else
598 pos = sysMsgQueue->nextFreeMessage; /* Don't merge */
601 /* Check if queue is full */
603 if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
605 /* Queue is full, beep (but not on every mouse motion...) */
606 if (message != WM_MOUSEMOVE) MessageBeep32(0);
607 return;
610 /* Store message */
612 msg = &sysMsgQueue->messages[pos].msg;
613 msg->hwnd = 0;
614 msg->message = message;
615 msg->wParam = wParam;
616 msg->lParam = lParam;
617 msg->time = time;
618 msg->pt.x = xPos & 0xffff;
619 msg->pt.y = yPos & 0xffff;
620 sysMsgQueue->messages[pos].extraInfo = extraInfo;
621 if (pos < sysMsgQueue->queueSize - 1) pos++;
622 else pos = 0;
623 sysMsgQueue->nextFreeMessage = pos;
624 sysMsgQueue->msgCount++;
625 QUEUE_WakeSomeone( message );
629 /***********************************************************************
630 * QUEUE_GetQueueTask
632 HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
634 MESSAGEQUEUE *queue = GlobalLock16( hQueue );
635 return (queue) ? queue->hTask : 0 ;
639 /***********************************************************************
640 * QUEUE_IncPaintCount
642 void QUEUE_IncPaintCount( HQUEUE16 hQueue )
644 MESSAGEQUEUE *queue;
646 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
647 queue->wPaintCount++;
648 QUEUE_SetWakeBit( queue, QS_PAINT );
652 /***********************************************************************
653 * QUEUE_DecPaintCount
655 void QUEUE_DecPaintCount( HQUEUE16 hQueue )
657 MESSAGEQUEUE *queue;
659 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
660 queue->wPaintCount--;
661 if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
665 /***********************************************************************
666 * QUEUE_IncTimerCount
668 void QUEUE_IncTimerCount( HQUEUE16 hQueue )
670 MESSAGEQUEUE *queue;
672 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
673 queue->wTimerCount++;
674 QUEUE_SetWakeBit( queue, QS_TIMER );
678 /***********************************************************************
679 * QUEUE_DecTimerCount
681 void QUEUE_DecTimerCount( HQUEUE16 hQueue )
683 MESSAGEQUEUE *queue;
685 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
686 queue->wTimerCount--;
687 if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
691 /***********************************************************************
692 * PostQuitMessage16 (USER.6)
694 void WINAPI PostQuitMessage16( INT16 exitCode )
696 PostQuitMessage32( exitCode );
700 /***********************************************************************
701 * PostQuitMessage32 (USER32.421)
703 void WINAPI PostQuitMessage32( INT32 exitCode )
705 MESSAGEQUEUE *queue;
707 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
708 queue->wPostQMsg = TRUE;
709 queue->wExitCode = (WORD)exitCode;
713 /***********************************************************************
714 * GetWindowTask16 (USER.224)
716 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
718 WND *wndPtr = WIN_FindWndPtr( hwnd );
720 if (!wndPtr) return 0;
721 return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
724 /***********************************************************************
725 * GetWindowThreadProcessId (USER32.313)
727 DWORD WINAPI GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
729 HTASK16 htask;
730 TDB *tdb;
732 WND *wndPtr = WIN_FindWndPtr( hwnd );
734 if (!wndPtr) return 0;
735 htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
736 tdb = (TDB*)GlobalLock16(htask);
737 if (!tdb || !tdb->thdb) return 0;
738 if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
739 return THDB_TO_THREAD_ID( tdb->thdb );
743 /***********************************************************************
744 * SetMessageQueue16 (USER.266)
746 BOOL16 WINAPI SetMessageQueue16( INT16 size )
748 return SetMessageQueue32( size );
752 /***********************************************************************
753 * SetMessageQueue32 (USER32.494)
755 BOOL32 WINAPI SetMessageQueue32( INT32 size )
757 HQUEUE16 hQueue, hNewQueue;
758 MESSAGEQUEUE *queuePtr;
760 TRACE(msg,"task %04x size %i\n", GetCurrentTask(), size);
762 if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
764 if( !(hNewQueue = QUEUE_CreateMsgQueue( size )))
766 WARN(msg, "failed!\n");
767 return FALSE;
769 queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
771 SIGNAL_MaskAsyncEvents( TRUE );
773 /* Copy data and free the old message queue */
774 if ((hQueue = GetTaskQueue(0)) != 0)
776 MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
777 memcpy( &queuePtr->wParamHigh, &oldQ->wParamHigh,
778 (int)oldQ->messages - (int)(&oldQ->wParamHigh) );
779 HOOK_ResetQueueHooks( hNewQueue );
780 if( WIN_GetDesktop()->hmemTaskQ == hQueue )
781 WIN_GetDesktop()->hmemTaskQ = hNewQueue;
782 WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
783 CLIPBOARD_ResetLock( hQueue, hNewQueue );
784 QUEUE_DeleteMsgQueue( hQueue );
787 /* Link new queue into list */
788 queuePtr->hTask = GetCurrentTask();
789 queuePtr->next = hFirstQueue;
790 hFirstQueue = hNewQueue;
792 if( !queuePtr->next ) pCursorQueue = queuePtr;
793 SetTaskQueue( 0, hNewQueue );
795 SIGNAL_MaskAsyncEvents( FALSE );
796 return TRUE;
800 /***********************************************************************
801 * GetQueueStatus16 (USER.334)
803 DWORD WINAPI GetQueueStatus16( UINT16 flags )
805 MESSAGEQUEUE *queue;
806 DWORD ret;
808 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
809 ret = MAKELONG( queue->changeBits, queue->wakeBits );
810 queue->changeBits = 0;
811 return ret & MAKELONG( flags, flags );
814 /***********************************************************************
815 * GetQueueStatus32 (USER32.283)
817 DWORD WINAPI GetQueueStatus32( UINT32 flags )
819 MESSAGEQUEUE *queue;
820 DWORD ret;
822 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
823 ret = MAKELONG( queue->changeBits, queue->wakeBits );
824 queue->changeBits = 0;
825 return ret & MAKELONG( flags, flags );
829 /***********************************************************************
830 * GetInputState16 (USER.335)
832 BOOL16 WINAPI GetInputState16(void)
834 return GetInputState32();
837 /***********************************************************************
838 * WaitForInputIdle (USER32.577)
840 DWORD WINAPI WaitForInputIdle (HANDLE32 hProcess, DWORD dwTimeOut)
842 FIXME (msg, "(hProcess=%d, dwTimeOut=%ld): stub\n", hProcess, dwTimeOut);
844 return WAIT_TIMEOUT;
848 /***********************************************************************
849 * GetInputState32 (USER32.244)
851 BOOL32 WINAPI GetInputState32(void)
853 MESSAGEQUEUE *queue;
855 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
856 return FALSE;
857 return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
861 /***********************************************************************
862 * GetMessagePos (USER.119) (USER32.272)
864 DWORD WINAPI GetMessagePos(void)
866 MESSAGEQUEUE *queue;
868 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
869 return queue->GetMessagePosVal;
873 /***********************************************************************
874 * GetMessageTime (USER.120) (USER32.273)
876 LONG WINAPI GetMessageTime(void)
878 MESSAGEQUEUE *queue;
880 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
881 return queue->GetMessageTimeVal;
885 /***********************************************************************
886 * GetMessageExtraInfo (USER.288) (USER32.271)
888 LONG WINAPI GetMessageExtraInfo(void)
890 MESSAGEQUEUE *queue;
892 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
893 return queue->GetMessageExtraInfoVal;