2 * Message queues related functions
4 * Copyright 1993 Alexandre Julliard
8 * This code assumes that there is only one Windows task (hence
12 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
16 #include <sys/types.h>
21 #include "sysmetrics.h"
23 #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
25 extern BOOL
TIMER_CheckTimer( LONG
*next
, MSG
*msg
,
26 HWND hwnd
, BOOL remove
); /* timer.c */
27 extern void EVENT_ProcessEvent( XEvent
*event
); /* event.c */
28 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
29 extern void WIN_SendParentNotify( HWND hwnd
, WORD event
,
30 LONG lParam
); /* win.c */
32 extern Display
* display
;
34 /* System message queue (for hardware events) */
35 static HANDLE hmemSysMsgQueue
= 0;
36 static MESSAGEQUEUE
* sysMsgQueue
= NULL
;
38 /* Application message queue (should be a list, one queue per task) */
39 static HANDLE hmemAppMsgQueue
= 0;
40 static MESSAGEQUEUE
* appMsgQueue
= NULL
;
42 /* Double-click time */
43 static int doubleClickSpeed
= 452;
46 /***********************************************************************
49 * Create a message queue.
51 static HANDLE
MSG_CreateMsgQueue( int size
)
54 MESSAGEQUEUE
* msgQueue
;
57 queueSize
= sizeof(MESSAGEQUEUE
) + size
* sizeof(QMSG
);
58 if (!(hQueue
= GlobalAlloc( GMEM_FIXED
, queueSize
))) return 0;
59 msgQueue
= (MESSAGEQUEUE
*) GlobalLock( hQueue
);
62 msgQueue
->msgSize
= sizeof(QMSG
);
63 msgQueue
->msgCount
= 0;
64 msgQueue
->nextMessage
= 0;
65 msgQueue
->nextFreeMessage
= 0;
66 msgQueue
->queueSize
= size
;
67 msgQueue
->GetMessageTimeVal
= 0;
68 msgQueue
->GetMessagePosVal
= 0;
69 msgQueue
->GetMessageExtraInfoVal
= 0;
74 msgQueue
->wPostQMsg
= 0;
75 msgQueue
->wExitCode
= 0;
76 msgQueue
->InSendMessageHandle
= 0;
77 msgQueue
->wPaintCount
= 0;
78 msgQueue
->wTimerCount
= 0;
79 msgQueue
->tempStatus
= 0;
81 GlobalUnlock( hQueue
);
86 /***********************************************************************
87 * MSG_CreateSysMsgQueue
89 * Create the system message queue, and set the double-click speed.
90 * Must be called only once.
92 BOOL
MSG_CreateSysMsgQueue( int size
)
94 if (size
> MAX_QUEUE_SIZE
) size
= MAX_QUEUE_SIZE
;
95 else if (size
<= 0) size
= 1;
96 if (!(hmemSysMsgQueue
= MSG_CreateMsgQueue( size
))) return FALSE
;
97 sysMsgQueue
= (MESSAGEQUEUE
*) GlobalLock( hmemSysMsgQueue
);
98 doubleClickSpeed
= GetProfileInt( "windows", "DoubleClickSpeed", 452 );
103 /***********************************************************************
106 * Add a message to the queue. Return FALSE if queue is full.
108 static int MSG_AddMsg( MESSAGEQUEUE
* msgQueue
, MSG
* msg
, DWORD extraInfo
)
112 SpyMessage(msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
114 if (!msgQueue
) return FALSE
;
115 pos
= msgQueue
->nextFreeMessage
;
117 /* Check if queue is full */
118 if ((pos
== msgQueue
->nextMessage
) && (msgQueue
->msgCount
> 0))
122 msgQueue
->messages
[pos
].msg
= *msg
;
123 msgQueue
->messages
[pos
].extraInfo
= extraInfo
;
124 if (pos
< msgQueue
->queueSize
-1) pos
++;
126 msgQueue
->nextFreeMessage
= pos
;
127 msgQueue
->msgCount
++;
128 msgQueue
->status
|= QS_POSTMESSAGE
;
129 msgQueue
->tempStatus
|= QS_POSTMESSAGE
;
134 /***********************************************************************
137 * Find a message matching the given parameters. Return -1 if none available.
139 static int MSG_FindMsg(MESSAGEQUEUE
* msgQueue
, HWND hwnd
, int first
, int last
)
141 int i
, pos
= msgQueue
->nextMessage
;
143 if (!msgQueue
->msgCount
) return -1;
144 if (!hwnd
&& !first
&& !last
) return pos
;
146 for (i
= 0; i
< msgQueue
->msgCount
; i
++)
148 MSG
* msg
= &msgQueue
->messages
[pos
].msg
;
150 if (!hwnd
|| (msg
->hwnd
== hwnd
))
152 if (!first
&& !last
) return pos
;
153 if ((msg
->message
>= first
) && (msg
->message
<= last
)) return pos
;
155 if (pos
< msgQueue
->queueSize
-1) pos
++;
162 /***********************************************************************
165 * Remove a message from the queue (pos must be a valid position).
167 static void MSG_RemoveMsg( MESSAGEQUEUE
* msgQueue
, int pos
)
169 if (pos
>= msgQueue
->nextMessage
)
171 for ( ; pos
> msgQueue
->nextMessage
; pos
--)
172 msgQueue
->messages
[pos
] = msgQueue
->messages
[pos
-1];
173 msgQueue
->nextMessage
++;
174 if (msgQueue
->nextMessage
>= msgQueue
->queueSize
)
175 msgQueue
->nextMessage
= 0;
179 for ( ; pos
< msgQueue
->nextFreeMessage
; pos
++)
180 msgQueue
->messages
[pos
] = msgQueue
->messages
[pos
+1];
181 if (msgQueue
->nextFreeMessage
) msgQueue
->nextFreeMessage
--;
182 else msgQueue
->nextFreeMessage
= msgQueue
->queueSize
-1;
184 msgQueue
->msgCount
--;
185 if (!msgQueue
->msgCount
) msgQueue
->status
&= ~QS_POSTMESSAGE
;
186 msgQueue
->tempStatus
= 0;
190 /***********************************************************************
191 * MSG_TranslateMouseMsg
193 * Translate an mouse hardware event into a real mouse message.
194 * Return value indicates whether the translated message must be passed
197 * - Translate button-down messages in double-clicks.
198 * - Send the WM_NCHITTEST message to find where the cursor is.
199 * - Activate the window if needed.
200 * - Translate the message into a non-client message, or translate
201 * the coordinates to client coordinates.
202 * - Send the WM_SETCURSOR message.
204 static BOOL
MSG_TranslateMouseMsg( MSG
*msg
)
207 static DWORD lastClickTime
= 0;
208 static WORD lastClickMsg
= 0;
209 static POINT lastClickPos
= { 0, 0 };
211 BOOL mouseClick
= ((msg
->message
== WM_LBUTTONDOWN
) ||
212 (msg
->message
== WM_RBUTTONDOWN
) ||
213 (msg
->message
== WM_MBUTTONDOWN
));
215 /* Send the WM_NCHITTEST message */
217 LONG hittest_result
= SendMessage( msg
->hwnd
, WM_NCHITTEST
, 0,
218 MAKELONG( msg
->pt
.x
, msg
->pt
.y
) );
220 /* Send the WM_PARENTNOTIFY message */
222 if (mouseClick
) WIN_SendParentNotify( msg
->hwnd
, msg
->message
,
223 MAKELONG( msg
->pt
.x
, msg
->pt
.y
) );
225 /* Activate the window if needed */
229 HWND parent
, hwndTop
= msg
->hwnd
;
230 while ((parent
= GetParent(hwndTop
)) != 0) hwndTop
= parent
;
231 if (hwndTop
!= GetActiveWindow())
233 LONG ret
= SendMessage( msg
->hwnd
, WM_MOUSEACTIVATE
, hwndTop
,
234 MAKELONG( hittest_result
, msg
->message
) );
235 if ((ret
== MA_ACTIVATEANDEAT
) || (ret
== MA_NOACTIVATEANDEAT
))
237 if ((ret
== MA_ACTIVATE
) || (ret
== MA_ACTIVATEANDEAT
))
239 SetWindowPos( hwndTop
, HWND_TOP
, 0, 0, 0, 0,
240 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
241 WINPOS_ChangeActiveWindow( hwndTop
, TRUE
);
246 /* Send the WM_SETCURSOR message */
248 SendMessage( msg
->hwnd
, WM_SETCURSOR
, msg
->hwnd
,
249 MAKELONG( hittest_result
, msg
->message
));
250 if (eatMsg
) return FALSE
;
252 /* Check for double-click */
256 BOOL dbl_click
= FALSE
;
258 if ((msg
->message
== lastClickMsg
) &&
259 (msg
->time
- lastClickTime
< doubleClickSpeed
) &&
260 (abs(msg
->pt
.x
- lastClickPos
.x
) < SYSMETRICS_CXDOUBLECLK
/2) &&
261 (abs(msg
->pt
.y
- lastClickPos
.y
) < SYSMETRICS_CYDOUBLECLK
/2))
264 if (dbl_click
&& (hittest_result
== HTCLIENT
))
266 /* Check whether window wants the double click message. */
267 WND
* wndPtr
= WIN_FindWndPtr( msg
->hwnd
);
268 if (!wndPtr
|| !(wndPtr
->flags
& WIN_DOUBLE_CLICKS
))
272 if (dbl_click
) switch(msg
->message
)
274 case WM_LBUTTONDOWN
: msg
->message
= WM_LBUTTONDBLCLK
; break;
275 case WM_RBUTTONDOWN
: msg
->message
= WM_RBUTTONDBLCLK
; break;
276 case WM_MBUTTONDOWN
: msg
->message
= WM_MBUTTONDBLCLK
; break;
279 lastClickTime
= msg
->time
;
280 lastClickMsg
= msg
->message
;
281 lastClickPos
= msg
->pt
;
284 /* Build the translated message */
286 msg
->lParam
= MAKELONG( msg
->pt
.x
, msg
->pt
.y
);
287 if (hittest_result
== HTCLIENT
)
289 ScreenToClient( msg
->hwnd
, (LPPOINT
)&msg
->lParam
);
293 msg
->wParam
= hittest_result
;
294 msg
->message
+= WM_NCLBUTTONDOWN
- WM_LBUTTONDOWN
;
300 /**********************************************************************
301 * SetDoubleClickTime (USER.20)
303 void SetDoubleClickTime( WORD interval
)
306 doubleClickSpeed
= 500;
308 doubleClickSpeed
= interval
;
312 /**********************************************************************
313 * GetDoubleClickTime (USER.21)
315 WORD
GetDoubleClickTime()
317 return (WORD
)doubleClickSpeed
;
321 /***********************************************************************
324 void MSG_IncPaintCount( HANDLE hQueue
)
326 if (hQueue
!= hmemAppMsgQueue
) return;
327 appMsgQueue
->wPaintCount
++;
328 appMsgQueue
->status
|= QS_PAINT
;
329 appMsgQueue
->tempStatus
|= QS_PAINT
;
333 /***********************************************************************
336 void MSG_DecPaintCount( HANDLE hQueue
)
338 if (hQueue
!= hmemAppMsgQueue
) return;
339 appMsgQueue
->wPaintCount
--;
340 if (!appMsgQueue
->wPaintCount
) appMsgQueue
->status
&= ~QS_PAINT
;
344 /***********************************************************************
347 void MSG_IncTimerCount( HANDLE hQueue
)
349 if (hQueue
!= hmemAppMsgQueue
) return;
350 appMsgQueue
->wTimerCount
++;
351 appMsgQueue
->status
|= QS_TIMER
;
352 appMsgQueue
->tempStatus
|= QS_TIMER
;
356 /***********************************************************************
359 void MSG_DecTimerCount( HANDLE hQueue
)
361 if (hQueue
!= hmemAppMsgQueue
) return;
362 appMsgQueue
->wTimerCount
--;
363 if (!appMsgQueue
->wTimerCount
) appMsgQueue
->status
&= ~QS_TIMER
;
367 /***********************************************************************
370 * Add an event to the system message queue.
371 * Note: the position is relative to the desktop window.
373 void hardware_event( WORD message
, WORD wParam
, LONG lParam
,
374 int xPos
, int yPos
, DWORD time
, DWORD extraInfo
)
379 msg
.message
= message
;
383 msg
.pt
.x
= xPos
& 0xffff;
384 msg
.pt
.y
= yPos
& 0xffff;
386 /* Determine the hwnd for this message */
387 /* Maybe this should be done in GetMessage() */
389 if ((message
>= WM_MOUSEFIRST
) && (message
<= WM_MOUSELAST
))
392 if (GetCapture()) msg
.hwnd
= GetCapture();
393 else msg
.hwnd
= WindowFromPoint( msg
.pt
);
395 else if ((message
>= WM_KEYFIRST
) && (message
<= WM_KEYLAST
))
398 msg
.hwnd
= GetFocus();
399 if (!msg
.hwnd
&& ((message
==WM_KEYDOWN
) || (message
==WM_SYSKEYDOWN
)))
400 MessageBeep(0); /* Beep on key press if no focus */
402 if (!msg
.hwnd
) return; /* No window for this message */
404 /* Merge with previous event if possible */
406 if (sysMsgQueue
->msgCount
&& (message
== WM_MOUSEMOVE
))
408 MSG
*prevMsg
= &sysMsgQueue
->messages
[sysMsgQueue
->nextMessage
].msg
;
409 if ((prevMsg
->message
== message
) && (prevMsg
->wParam
== wParam
))
411 *prevMsg
= msg
; /* Overwrite previous message */
416 if (!MSG_AddMsg( sysMsgQueue
, &msg
, extraInfo
))
417 printf( "hardware_event: Queue is full\n" );
421 /***********************************************************************
422 * MSG_GetHardwareMessage
424 * Like GetMessage(), but only return mouse and keyboard events.
425 * Used internally for window moving and resizing. Mouse messages
426 * are not translated.
428 BOOL
MSG_GetHardwareMessage( LPMSG msg
)
435 if ((pos
= MSG_FindMsg( sysMsgQueue
, 0, 0, 0 )) != -1)
437 *msg
= sysMsgQueue
->messages
[pos
].msg
;
438 MSG_RemoveMsg( sysMsgQueue
, pos
);
441 XNextEvent( display
, &event
);
442 EVENT_ProcessEvent( &event
);
448 /***********************************************************************
449 * SetTaskQueue (KERNEL.34)
451 WORD
SetTaskQueue( HANDLE hTask
, HANDLE hQueue
)
453 HANDLE prev
= hmemAppMsgQueue
;
454 hmemAppMsgQueue
= hQueue
;
459 /***********************************************************************
460 * GetTaskQueue (KERNEL.35)
462 WORD
GetTaskQueue( HANDLE hTask
)
464 return hmemAppMsgQueue
;
468 /***********************************************************************
469 * SetMessageQueue (USER.266)
471 BOOL
SetMessageQueue( int size
)
475 if ((size
> MAX_QUEUE_SIZE
) || (size
<= 0)) return TRUE
;
477 /* Free the old message queue */
478 if ((hQueue
= GetTaskQueue(0)) != 0)
480 GlobalUnlock( hQueue
);
481 GlobalFree( hQueue
);
484 if (!(hQueue
= MSG_CreateMsgQueue( size
))) return FALSE
;
485 SetTaskQueue( 0, hQueue
);
486 appMsgQueue
= (MESSAGEQUEUE
*)GlobalLock( hQueue
);
491 /***********************************************************************
492 * PostQuitMessage (USER.6)
494 void PostQuitMessage( int exitCode
)
496 if (!appMsgQueue
) return;
497 appMsgQueue
->wPostQMsg
= TRUE
;
498 appMsgQueue
->wExitCode
= exitCode
;
502 /***********************************************************************
503 * GetQueueStatus (USER.334)
505 DWORD
GetQueueStatus( int flags
)
507 unsigned long ret
= (appMsgQueue
->status
<< 16) | appMsgQueue
->tempStatus
;
508 appMsgQueue
->tempStatus
= 0;
509 return ret
& ((flags
<< 16) | flags
);
513 /***********************************************************************
514 * GetInputState (USER.335)
518 return appMsgQueue
->status
& (QS_KEY
| QS_MOUSEBUTTON
);
522 /***********************************************************************
525 * Synchronize with the X server. Should not be used too often.
527 void MSG_Synchronize()
531 XSync( display
, False
);
532 while (XPending( display
))
534 XNextEvent( display
, &event
);
535 EVENT_ProcessEvent( &event
);
540 /***********************************************************************
543 static BOOL
MSG_PeekMessage( MESSAGEQUEUE
* msgQueue
, LPMSG msg
, HWND hwnd
,
544 WORD first
, WORD last
, WORD flags
, BOOL peek
)
547 LONG nextExp
; /* Next timer expiration time */
552 mask
= QS_POSTMESSAGE
; /* Always selectioned */
553 if ((first
<= WM_KEYLAST
) && (last
>= WM_KEYFIRST
)) mask
|= QS_KEY
;
554 if ((first
<= WM_MOUSELAST
) && (last
>= WM_MOUSEFIRST
)) mask
|= QS_MOUSE
;
555 if ((first
<= WM_TIMER
) && (last
>= WM_TIMER
)) mask
|= WM_TIMER
;
556 if ((first
<= WM_SYSTIMER
) && (last
>= WM_SYSTIMER
)) mask
|= WM_TIMER
;
557 if ((first
<= WM_PAINT
) && (last
>= WM_PAINT
)) mask
|= WM_PAINT
;
559 else mask
= QS_MOUSE
| QS_KEY
| QS_POSTMESSAGE
| QS_TIMER
| QS_PAINT
;
561 while (XPending( display
))
563 XNextEvent( display
, &event
);
564 EVENT_ProcessEvent( &event
);
569 /* First handle a WM_QUIT message */
570 if (msgQueue
->wPostQMsg
)
573 msg
->message
= WM_QUIT
;
574 msg
->wParam
= msgQueue
->wExitCode
;
579 /* Then handle a message put by SendMessage() */
580 if (msgQueue
->status
& QS_SENDMESSAGE
)
582 if (!hwnd
|| (msgQueue
->hWnd
== hwnd
))
584 if ((!first
&& !last
) ||
585 ((msgQueue
->msg
>= first
) && (msgQueue
->msg
<= last
)))
587 msg
->hwnd
= msgQueue
->hWnd
;
588 msg
->message
= msgQueue
->msg
;
589 msg
->wParam
= msgQueue
->wParam
;
590 msg
->lParam
= msgQueue
->lParam
;
591 if (flags
& PM_REMOVE
) msgQueue
->status
&= ~QS_SENDMESSAGE
;
597 /* Now find a normal message */
598 pos
= MSG_FindMsg( msgQueue
, hwnd
, first
, last
);
601 QMSG
*qmsg
= &msgQueue
->messages
[pos
];
603 msgQueue
->GetMessageTimeVal
= msg
->time
;
604 msgQueue
->GetMessagePosVal
= *(DWORD
*)&msg
->pt
;
605 msgQueue
->GetMessageExtraInfoVal
= qmsg
->extraInfo
;
607 if (flags
& PM_REMOVE
) MSG_RemoveMsg( msgQueue
, pos
);
611 /* Now find a hardware event */
612 pos
= MSG_FindMsg( sysMsgQueue
, hwnd
, first
, last
);
615 QMSG
*qmsg
= &sysMsgQueue
->messages
[pos
];
617 msgQueue
->GetMessageTimeVal
= msg
->time
;
618 msgQueue
->GetMessagePosVal
= *(DWORD
*)&msg
->pt
;
619 msgQueue
->GetMessageExtraInfoVal
= qmsg
->extraInfo
;
621 if ((msg
->message
>= WM_MOUSEFIRST
) &&
622 (msg
->message
<= WM_MOUSELAST
))
623 if (!MSG_TranslateMouseMsg( msg
))
625 MSG_RemoveMsg( sysMsgQueue
, pos
);
628 if (flags
& PM_REMOVE
) MSG_RemoveMsg( sysMsgQueue
, pos
);
632 /* Now find a WM_PAINT message */
633 if ((msgQueue
->status
& QS_PAINT
) && (mask
& QS_PAINT
))
635 msg
->hwnd
= WIN_FindWinToRepaint( hwnd
);
636 msg
->message
= WM_PAINT
;
639 if (msg
->hwnd
!= 0) break;
642 /* Finally handle WM_TIMER messages */
643 if ((msgQueue
->status
& QS_TIMER
) && (mask
& QS_TIMER
))
645 if (TIMER_CheckTimer( &nextExp
, msg
, hwnd
, flags
& PM_REMOVE
))
646 break; /* Got a timer msg */
648 else nextExp
= -1; /* No timeout needed */
650 /* Wait until something happens */
651 if (peek
) return FALSE
;
652 if (!XPending( display
) && (nextExp
!= -1))
655 struct timeval timeout
;
656 int fd
= ConnectionNumber(display
);
657 FD_ZERO( &read_set
);
658 FD_SET( fd
, &read_set
);
659 timeout
.tv_sec
= nextExp
/ 1000;
660 timeout
.tv_usec
= (nextExp
% 1000) * 1000;
661 if (select( fd
+1, &read_set
, NULL
, NULL
, &timeout
) != 1)
662 continue; /* On timeout or error, restart from the start */
664 XNextEvent( display
, &event
);
665 EVENT_ProcessEvent( &event
);
668 /* We got a message */
669 if (peek
) return TRUE
;
670 else return (msg
->message
!= WM_QUIT
);
674 /***********************************************************************
675 * PeekMessage (USER.109)
677 BOOL
PeekMessage( LPMSG msg
, HWND hwnd
, WORD first
, WORD last
, WORD flags
)
679 return MSG_PeekMessage( appMsgQueue
, msg
, hwnd
, first
, last
, flags
, TRUE
);
683 /***********************************************************************
684 * GetMessage (USER.108)
686 BOOL
GetMessage( LPMSG msg
, HWND hwnd
, WORD first
, WORD last
)
688 return MSG_PeekMessage( appMsgQueue
, msg
, hwnd
, first
, last
, PM_REMOVE
, FALSE
);
692 /***********************************************************************
693 * PostMessage (USER.110)
695 BOOL
PostMessage( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
698 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
700 if (!wndPtr
|| !wndPtr
->hmemTaskQ
) return FALSE
;
703 msg
.message
= message
;
706 msg
.time
= GetTickCount();
710 return MSG_AddMsg( appMsgQueue
, &msg
, 0 );
714 /***********************************************************************
715 * SendMessage (USER.111)
717 LONG
SendMessage( HWND hwnd
, WORD msg
, WORD wParam
, LONG lParam
)
721 SpyMessage(hwnd
, msg
, wParam
, lParam
);
723 wndPtr
= WIN_FindWndPtr( hwnd
);
724 if (!wndPtr
) return 0;
725 return CallWindowProc( wndPtr
->lpfnWndProc
, hwnd
, msg
, wParam
, lParam
);
729 /***********************************************************************
730 * TranslateMessage (USER.113)
732 BOOL
TranslateMessage( LPMSG msg
)
734 int message
= msg
->message
;
736 if ((message
== WM_KEYDOWN
) || (message
== WM_KEYUP
) ||
737 (message
== WM_SYSKEYDOWN
) || (message
== WM_SYSKEYUP
))
740 printf( "Translating key message\n" );
748 /***********************************************************************
749 * DispatchMessage (USER.114)
751 LONG
DispatchMessage( LPMSG msg
)
758 printf( "Dispatch message hwnd=%08x msg=0x%x w=%d l=%d time=%u pt=%d,%d\n",
759 msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
,
760 msg
->time
, msg
->pt
.x
, msg
->pt
.y
);
763 /* Process timer messages */
764 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
767 return CallWindowProc( (FARPROC
)msg
->lParam
, msg
->hwnd
,
768 msg
->message
, msg
->wParam
, GetTickCount() );
771 if (!msg
->hwnd
) return 0;
772 if (!(wndPtr
= WIN_FindWndPtr( msg
->hwnd
))) return 0;
773 if (!wndPtr
->lpfnWndProc
) return 0;
774 painting
= (msg
->message
== WM_PAINT
);
775 if (painting
) wndPtr
->flags
|= WIN_NEEDS_BEGINPAINT
;
776 retval
= CallWindowProc( wndPtr
->lpfnWndProc
, msg
->hwnd
, msg
->message
,
777 msg
->wParam
, msg
->lParam
);
778 if (painting
&& (wndPtr
->flags
& WIN_NEEDS_BEGINPAINT
))
781 printf( "BeginPaint not called on WM_PAINT for hwnd %d!\n", msg
->hwnd
);
783 wndPtr
->flags
&= ~WIN_NEEDS_BEGINPAINT
;
789 /***********************************************************************
790 * GetMessagePos (USER.119)
792 DWORD
GetMessagePos(void)
794 return appMsgQueue
->GetMessagePosVal
;
798 /***********************************************************************
799 * GetMessageTime (USER.120)
801 LONG
GetMessageTime(void)
803 return appMsgQueue
->GetMessageTimeVal
;
807 /***********************************************************************
808 * GetMessageExtraInfo (USER.288)
810 LONG
GetMessageExtraInfo(void)
812 return appMsgQueue
->GetMessageExtraInfoVal
;
816 /***********************************************************************
817 * RegisterWindowMessage (USER.118)
819 WORD
RegisterWindowMessage( LPCSTR str
)
822 printf( "RegisterWindowMessage: '%s'\n", str
);
824 return GlobalAddAtom( str
);
828 /***********************************************************************
829 * GetTickCount (USER.13)
834 gettimeofday( &t
, NULL
);
835 return (t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000);