blob: 7df8516d08f661397035c7031fcfaa4b0554f710 [file] [log] [blame]
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001/*
2 * Message queues related functions
3 *
Alexandre Julliardaca05781994-10-17 18:12:41 +00004 * Copyright 1993, 1994 Alexandre Julliard
Alexandre Julliard75a839a1993-07-15 11:13:45 +00005 */
6
Alexandre Julliard401710d1993-09-04 10:09:32 +00007#include <stdlib.h>
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00008#include <string.h>
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00009#include <ctype.h>
Alexandre Julliard5f721f81994-01-04 20:14:34 +000010#include <sys/time.h>
11#include <sys/types.h>
Alexandre Julliardf41aeca1993-09-14 16:47:10 +000012
Alexandre Julliard75a839a1993-07-15 11:13:45 +000013#include "message.h"
14#include "win.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000015#include "gdi.h"
Alexandre Julliardcdd09231994-01-12 11:12:51 +000016#include "sysmetrics.h"
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +000017#include "heap.h"
Alexandre Julliard58199531994-04-21 01:20:00 +000018#include "hook.h"
Alexandre Julliard01d63461997-01-20 19:43:45 +000019#include "keyboard.h"
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000020#include "spy.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000021#include "winpos.h"
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000022#include "atom.h"
23#include "dde.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000024#include "queue.h"
Alexandre Julliard3051b641996-07-05 17:14:13 +000025#include "winproc.h"
Alexandre Julliard767e6f61998-08-09 12:47:43 +000026#include "task.h"
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000027#include "process.h"
28#include "thread.h"
Alexandre Julliard84c70f51997-05-09 08:40:27 +000029#include "options.h"
Alexandre Julliard829fe321998-07-26 14:27:39 +000030#include "struct32.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000031#include "debug.h"
32
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000033#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
34#define WM_NCMOUSELAST WM_NCMBUTTONDBLCLK
35
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000036typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP,
37 SYSQ_MSG_ACCEPT, SYSQ_MSG_CONTINUE } SYSQ_STATUS;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000038
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000039extern MESSAGEQUEUE *pCursorQueue; /* queue.c */
40extern MESSAGEQUEUE *pActiveQueue;
41
Alexandre Julliard8b915631996-06-16 16:16:05 +000042DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000043
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000044static UINT32 doubleClickSpeed = 452;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000045static INT32 debugSMRL = 0; /* intertask SendMessage() recursion level */
Alexandre Julliard75a839a1993-07-15 11:13:45 +000046
47/***********************************************************************
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000048 * MSG_CheckFilter
49 */
50BOOL32 MSG_CheckFilter(WORD uMsg, DWORD filter)
51{
52 if( filter )
53 return (uMsg >= LOWORD(filter) && uMsg <= HIWORD(filter));
54 return TRUE;
55}
56
57/***********************************************************************
Alexandre Julliard77b99181997-09-14 17:17:23 +000058 * MSG_SendParentNotify
59 *
60 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
61 * the window has the WS_EX_NOPARENTNOTIFY style.
62 */
63static void MSG_SendParentNotify(WND* wndPtr, WORD event, WORD idChild, LPARAM lValue)
64{
65#define lppt ((LPPOINT16)&lValue)
66
67 /* pt has to be in the client coordinates of the parent window */
68
69 MapWindowPoints16( 0, wndPtr->hwndSelf, lppt, 1 );
70 while (wndPtr)
71 {
72 if (!(wndPtr->dwStyle & WS_CHILD) || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) break;
73 lppt->x += wndPtr->rectClient.left;
74 lppt->y += wndPtr->rectClient.top;
75 wndPtr = wndPtr->parent;
76 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
77 MAKEWPARAM( event, idChild ), lValue );
78 }
79#undef lppt
80}
81
82
83/***********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +000084 * MSG_TranslateMouseMsg
85 *
86 * Translate an mouse hardware event into a real mouse message.
Alexandre Julliarddba420a1994-02-02 06:48:31 +000087 * Return value indicates whether the translated message must be passed
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000088 * to the user, left in the queue, or skipped entirely (in this case
89 * HIWORD contains hit test code).
Alexandre Julliardcdd09231994-01-12 11:12:51 +000090 */
Alexandre Julliard84c70f51997-05-09 08:40:27 +000091static DWORD MSG_TranslateMouseMsg( HWND16 hTopWnd, DWORD filter,
92 MSG16 *msg, BOOL32 remove, WND* pWndScope )
Alexandre Julliardcdd09231994-01-12 11:12:51 +000093{
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000094 static DWORD dblclk_time_limit = 0;
95 static UINT16 clk_message = 0;
96 static HWND16 clk_hwnd = 0;
97 static POINT16 clk_pos = { 0, 0 };
Alexandre Julliardcdd09231994-01-12 11:12:51 +000098
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000099 WND *pWnd;
100 HWND16 hWnd;
101 INT16 ht, hittest, sendSC = 0;
102 UINT16 message = msg->message;
103 POINT16 screen_pt, pt;
104 HANDLE16 hQ = GetTaskQueue(0);
105 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16(hQ);
106 BOOL32 eatMsg = FALSE;
107 BOOL32 mouseClick = ((message == WM_LBUTTONDOWN) ||
108 (message == WM_RBUTTONDOWN) ||
109 (message == WM_MBUTTONDOWN))?1:0;
110 SYSQ_STATUS ret = 0;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000111
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000112 /* Find the window */
113
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000114 ht = hittest = HTCLIENT;
115 hWnd = GetCapture16();
116 if( !hWnd )
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000117 {
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000118 ht = hittest = WINPOS_WindowFromPoint( pWndScope, msg->pt, &pWnd );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000119 if( !pWnd ) pWnd = WIN_GetDesktop();
120 hWnd = pWnd->hwndSelf;
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000121 sendSC = 1;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000122 }
123 else
124 {
125 pWnd = WIN_FindWndPtr(hWnd);
126 ht = EVENT_GetCaptureInfo();
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000127 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000128
129 /* stop if not the right queue */
130
131 if (pWnd->hmemTaskQ != hQ)
Alexandre Julliard8b915631996-06-16 16:16:05 +0000132 {
133 /* Not for the current task */
Alexandre Julliard8b915631996-06-16 16:16:05 +0000134 if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
135 /* Wake up the other task */
136 queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
137 if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000138 return SYSQ_MSG_ABANDON;
Alexandre Julliard8b915631996-06-16 16:16:05 +0000139 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000140
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000141 /* check if hWnd is within hWndScope */
142
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000143 if( hTopWnd && hWnd != hTopWnd )
144 if( !IsChild16(hTopWnd, hWnd) ) return SYSQ_MSG_CONTINUE;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000145
146 if( mouseClick )
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000147 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000148 /* translate double clicks -
149 * note that ...MOUSEMOVEs can slip in between
150 * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
Alexandre Julliard329f0681996-04-14 13:21:20 +0000151
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000152 if( pWnd->class->style & CS_DBLCLKS || ht != HTCLIENT )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000153 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000154 if ((message == clk_message) && (hWnd == clk_hwnd) &&
155 (msg->time - dblclk_time_limit < doubleClickSpeed) &&
156 (abs(msg->pt.x - clk_pos.x) < SYSMETRICS_CXDOUBLECLK/2) &&
157 (abs(msg->pt.y - clk_pos.y) < SYSMETRICS_CYDOUBLECLK/2))
158 {
159 message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
160 mouseClick++; /* == 2 */
161 }
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000162 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000163 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000164 screen_pt = pt = msg->pt;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000165
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000166 if (hittest != HTCLIENT)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000167 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000168 message += ((INT16)WM_NCMOUSEMOVE - WM_MOUSEMOVE);
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000169 msg->wParam = hittest;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000170 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000171 else ScreenToClient16( hWnd, &pt );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000172
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000173 /* check message filter */
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000174
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000175 if (!MSG_CheckFilter(message, filter)) return SYSQ_MSG_CONTINUE;
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000176
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000177 pCursorQueue = queue;
178
179 /* call WH_MOUSE */
180
181 if (HOOK_IsHooked( WH_MOUSE ))
182 {
183 MOUSEHOOKSTRUCT16 *hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16);
184 if( hook )
185 {
186 hook->pt = screen_pt;
187 hook->hwnd = hWnd;
188 hook->wHitTestCode = hittest;
189 hook->dwExtraInfo = 0;
190 ret = HOOK_CallHooks16( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
191 message, (LPARAM)SEGPTR_GET(hook) );
192 SEGPTR_FREE(hook);
193 }
194 if( ret ) return MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
195 }
196
197 if ((hittest == HTERROR) || (hittest == HTNOWHERE))
198 eatMsg = sendSC = 1;
199 else if( remove && mouseClick )
200 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000201 HWND32 hwndTop = WIN_GetTopParent( hWnd );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000202
203 if( mouseClick == 1 )
204 {
205 /* set conditions */
206 dblclk_time_limit = msg->time;
207 clk_message = msg->message;
208 clk_hwnd = hWnd;
209 clk_pos = screen_pt;
210 } else
211 /* got double click - zero them out */
212 dblclk_time_limit = clk_hwnd = 0;
213
214 if( sendSC )
215 {
216 /* Send the WM_PARENTNOTIFY,
217 * note that even for double/nonclient clicks
218 * notification message is still WM_L/M/RBUTTONDOWN.
219 */
220
Alexandre Julliard77b99181997-09-14 17:17:23 +0000221 MSG_SendParentNotify( pWnd, msg->message, 0, MAKELPARAM(screen_pt.x, screen_pt.y) );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000222
223 /* Activate the window if needed */
224
Alexandre Julliard01d63461997-01-20 19:43:45 +0000225 if (hWnd != GetActiveWindow16() && hWnd != GetDesktopWindow16())
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000226 {
227 LONG ret = SendMessage16( hWnd, WM_MOUSEACTIVATE, hwndTop,
228 MAKELONG( hittest, message ) );
229
230 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
231 eatMsg = TRUE;
232
233 if (((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
Alexandre Julliard01d63461997-01-20 19:43:45 +0000234 && hwndTop != GetActiveWindow16() )
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000235 if (!WINPOS_SetActiveWindow( hwndTop, TRUE , TRUE ))
236 eatMsg = TRUE;
237 }
238 }
239 } else sendSC = (remove && sendSC);
240
241 /* Send the WM_SETCURSOR message */
242
243 if (sendSC)
244 SendMessage16( hWnd, WM_SETCURSOR, (WPARAM16)hWnd,
245 MAKELONG( hittest, message ));
246 if (eatMsg) return MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
247
248 msg->hwnd = hWnd;
249 msg->message = message;
250 msg->lParam = MAKELONG( pt.x, pt.y );
251 return SYSQ_MSG_ACCEPT;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000252}
253
254
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000255/***********************************************************************
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000256 * MSG_TranslateKbdMsg
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000257 *
258 * Translate an keyboard hardware event into a real message.
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000259 */
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000260static DWORD MSG_TranslateKbdMsg( HWND16 hTopWnd, DWORD filter,
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000261 MSG16 *msg, BOOL32 remove )
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000262{
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000263 WORD message = msg->message;
264 HWND16 hWnd = GetFocus16();
Alexandre Julliard8b915631996-06-16 16:16:05 +0000265 WND *pWnd;
266
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000267 /* Should check Ctrl-Esc and PrintScreen here */
268
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000269 if (!hWnd)
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000270 {
271 /* Send the message to the active window instead, */
272 /* translating messages to their WM_SYS equivalent */
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000273
Alexandre Julliard01d63461997-01-20 19:43:45 +0000274 hWnd = GetActiveWindow16();
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000275
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000276 if( message < WM_SYSKEYDOWN )
277 message += WM_SYSKEYDOWN - WM_KEYDOWN;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000278 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000279 pWnd = WIN_FindWndPtr( hWnd );
Alexandre Julliard8b915631996-06-16 16:16:05 +0000280 if (pWnd && (pWnd->hmemTaskQ != GetTaskQueue(0)))
281 {
282 /* Not for the current task */
283 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) );
284 if (queue) QUEUE_ClearWakeBit( queue, QS_KEY );
285 /* Wake up the other task */
286 queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
287 if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000288 return SYSQ_MSG_ABANDON;
Alexandre Julliard8b915631996-06-16 16:16:05 +0000289 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000290
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000291 if (hTopWnd && hWnd != hTopWnd)
292 if (!IsChild16(hTopWnd, hWnd)) return SYSQ_MSG_CONTINUE;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000293 if (!MSG_CheckFilter(message, filter)) return SYSQ_MSG_CONTINUE;
294
295 msg->hwnd = hWnd;
296 msg->message = message;
297
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000298 return (HOOK_CallHooks16( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
299 msg->wParam, msg->lParam )
300 ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT);
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000301}
302
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000303
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000304/***********************************************************************
305 * MSG_JournalRecordMsg
306 *
307 * Build an EVENTMSG structure and call JOURNALRECORD hook
308 */
309static void MSG_JournalRecordMsg( MSG16 *msg )
310{
311 EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
312 if (!event) return;
313 event->message = msg->message;
314 event->time = msg->time;
315 if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
316 {
317 event->paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
318 event->paramH = msg->lParam & 0x7FFF;
319 if (HIWORD(msg->lParam) & 0x0100)
320 event->paramH |= 0x8000; /* special_key - bit */
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000321 HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
322 (LPARAM)SEGPTR_GET(event) );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000323 }
324 else if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
325 {
326 event->paramL = LOWORD(msg->lParam); /* X pos */
327 event->paramH = HIWORD(msg->lParam); /* Y pos */
328 ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000329 HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
330 (LPARAM)SEGPTR_GET(event) );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000331 }
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000332 else if ((msg->message >= WM_NCMOUSEFIRST) &&
333 (msg->message <= WM_NCMOUSELAST))
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000334 {
335 event->paramL = LOWORD(msg->lParam); /* X pos */
336 event->paramH = HIWORD(msg->lParam); /* Y pos */
337 event->message += WM_MOUSEMOVE-WM_NCMOUSEMOVE;/* give no info about NC area */
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000338 HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
339 (LPARAM)SEGPTR_GET(event) );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000340 }
341 SEGPTR_FREE(event);
342}
343
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000344/***********************************************************************
345 * MSG_JournalPlayBackMsg
346 *
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000347 * Get an EVENTMSG struct via call JOURNALPLAYBACK hook function
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000348 */
349static int MSG_JournalPlayBackMsg(void)
350{
351 EVENTMSG16 *tmpMsg;
352 long wtime,lParam;
353 WORD keyDown,i,wParam,result=0;
354
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000355 if ( HOOK_IsHooked( WH_JOURNALPLAYBACK ) )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000356 {
357 tmpMsg = SEGPTR_NEW(EVENTMSG16);
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000358 wtime=HOOK_CallHooks16( WH_JOURNALPLAYBACK, HC_GETNEXT, 0,
359 (LPARAM)SEGPTR_GET(tmpMsg));
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000360 /* TRACE(msg,"Playback wait time =%ld\n",wtime); */
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000361 if (wtime<=0)
362 {
363 wtime=0;
364 if ((tmpMsg->message>= WM_KEYFIRST) && (tmpMsg->message <= WM_KEYLAST))
365 {
366 wParam=tmpMsg->paramL & 0xFF;
367 lParam=MAKELONG(tmpMsg->paramH&0x7ffff,tmpMsg->paramL>>8);
368 if (tmpMsg->message == WM_KEYDOWN || tmpMsg->message == WM_SYSKEYDOWN)
369 {
370 for (keyDown=i=0; i<256 && !keyDown; i++)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000371 if (InputKeyStateTable[i] & 0x80)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000372 keyDown++;
373 if (!keyDown)
374 lParam |= 0x40000000;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000375 AsyncKeyStateTable[wParam]=InputKeyStateTable[wParam] |= 0x80;
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000376 }
377 else /* WM_KEYUP, WM_SYSKEYUP */
378 {
379 lParam |= 0xC0000000;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000380 AsyncKeyStateTable[wParam]=InputKeyStateTable[wParam] &= ~0x80;
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000381 }
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000382 if (InputKeyStateTable[VK_MENU] & 0x80)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000383 lParam |= 0x20000000;
384 if (tmpMsg->paramH & 0x8000) /*special_key bit*/
385 lParam |= 0x01000000;
386 hardware_event( tmpMsg->message, wParam, lParam,0, 0, tmpMsg->time, 0 );
387 }
388 else
389 {
390 if ((tmpMsg->message>= WM_MOUSEFIRST) && (tmpMsg->message <= WM_MOUSELAST))
391 {
392 switch (tmpMsg->message)
393 {
Alexandre Julliard02e90081998-01-04 17:49:09 +0000394 case WM_LBUTTONDOWN:
395 MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=TRUE;break;
396 case WM_LBUTTONUP:
397 MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=FALSE;break;
398 case WM_MBUTTONDOWN:
399 MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=TRUE;break;
400 case WM_MBUTTONUP:
401 MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=FALSE;break;
402 case WM_RBUTTONDOWN:
403 MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=TRUE;break;
404 case WM_RBUTTONUP:
405 MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=FALSE;break;
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000406 }
Alexandre Julliard02e90081998-01-04 17:49:09 +0000407 AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
408 AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
409 AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000410 SetCursorPos32(tmpMsg->paramL,tmpMsg->paramH);
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000411 lParam=MAKELONG(tmpMsg->paramL,tmpMsg->paramH);
412 wParam=0;
413 if (MouseButtonsStates[0]) wParam |= MK_LBUTTON;
414 if (MouseButtonsStates[1]) wParam |= MK_MBUTTON;
415 if (MouseButtonsStates[2]) wParam |= MK_RBUTTON;
416 hardware_event( tmpMsg->message, wParam, lParam,
417 tmpMsg->paramL, tmpMsg->paramH, tmpMsg->time, 0 );
418 }
419 }
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000420 HOOK_CallHooks16( WH_JOURNALPLAYBACK, HC_SKIP, 0,
421 (LPARAM)SEGPTR_GET(tmpMsg));
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000422 }
423 else
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000424 {
425 if( tmpMsg->message == WM_QUEUESYNC )
426 if (HOOK_IsHooked( WH_CBT ))
427 HOOK_CallHooks16( WH_CBT, HCBT_QS, 0, 0L);
428
429 result= QS_MOUSE | QS_KEY; /* ? */
430 }
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000431 SEGPTR_FREE(tmpMsg);
432 }
433 return result;
434}
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000435
Alexandre Julliardaca05781994-10-17 18:12:41 +0000436/***********************************************************************
437 * MSG_PeekHardwareMsg
438 *
439 * Peek for a hardware message matching the hwnd and message filters.
440 */
Alexandre Julliard21979011997-03-05 08:22:35 +0000441static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter,
442 BOOL32 remove )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000443{
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000444 DWORD status = SYSQ_MSG_ACCEPT;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000445 MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000446 int i, kbd_msg, pos = sysMsgQueue->nextMessage;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000447
Alexandre Julliard641ee761997-08-04 16:34:36 +0000448 /* FIXME: there has to be a better way to do this */
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000449 joySendMessages();
Alexandre Julliard641ee761997-08-04 16:34:36 +0000450
Alexandre Julliardcdcdede1996-04-21 14:57:41 +0000451 /* If the queue is empty, attempt to fill it */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000452 if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() )
453 && TSXPending(display))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000454 EVENT_WaitNetEvent( FALSE, FALSE );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +0000455
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000456 for (i = kbd_msg = 0; i < sysMsgQueue->msgCount; i++, pos++)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000457 {
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000458 if (pos >= sysMsgQueue->queueSize) pos = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000459 *msg = sysMsgQueue->messages[pos].msg;
460
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000461 /* Translate message */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000462
463 if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
464 {
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000465 HWND32 hWndScope = (HWND32)sysMsgQueue->messages[pos].extraInfo;
466
467 status = MSG_TranslateMouseMsg(hwnd, filter, msg, remove,
468 (Options.managed && IsWindow32(hWndScope) )
469 ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop() );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000470 kbd_msg = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000471 }
472 else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
473 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000474 status = MSG_TranslateKbdMsg(hwnd, filter, msg, remove);
475 kbd_msg = 1;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000476 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000477 else /* Non-standard hardware event */
Alexandre Julliardade697e1995-11-26 13:59:11 +0000478 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000479 HARDWAREHOOKSTRUCT16 *hook;
480 if ((hook = SEGPTR_NEW(HARDWAREHOOKSTRUCT16)))
481 {
482 BOOL32 ret;
483 hook->hWnd = msg->hwnd;
484 hook->wMessage = msg->message;
485 hook->wParam = msg->wParam;
486 hook->lParam = msg->lParam;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000487 ret = HOOK_CallHooks16( WH_HARDWARE,
488 remove ? HC_ACTION : HC_NOREMOVE,
489 0, (LPARAM)SEGPTR_GET(hook) );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000490 SEGPTR_FREE(hook);
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000491 if (ret)
492 {
493 QUEUE_RemoveMsg( sysMsgQueue, pos );
494 continue;
495 }
496 status = SYSQ_MSG_ACCEPT;
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000497 }
Alexandre Julliardade697e1995-11-26 13:59:11 +0000498 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000499
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000500 switch (LOWORD(status))
501 {
502 case SYSQ_MSG_ACCEPT:
503 break;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000504
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000505 case SYSQ_MSG_SKIP:
506 if (HOOK_IsHooked( WH_CBT ))
Jesper Skov5c3e4571998-11-01 19:27:22 +0000507 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000508 if( kbd_msg )
509 HOOK_CallHooks16( WH_CBT, HCBT_KEYSKIPPED,
510 msg->wParam, msg->lParam );
511 else
512 {
513 MOUSEHOOKSTRUCT16 *hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16);
514 if (hook)
515 {
516 hook->pt = msg->pt;
517 hook->hwnd = msg->hwnd;
518 hook->wHitTestCode = HIWORD(status);
519 hook->dwExtraInfo = 0;
520 HOOK_CallHooks16( WH_CBT, HCBT_CLICKSKIPPED ,msg->message,
521 (LPARAM)SEGPTR_GET(hook) );
522 SEGPTR_FREE(hook);
523 }
524 }
Jesper Skov5c3e4571998-11-01 19:27:22 +0000525 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000526
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000527 if (remove)
528 QUEUE_RemoveMsg( sysMsgQueue, pos );
529 /* continue */
530
531 case SYSQ_MSG_CONTINUE:
532 continue;
533
534 case SYSQ_MSG_ABANDON:
535 return FALSE;
536 }
537
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000538 if (remove)
539 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000540 if (HOOK_IsHooked( WH_JOURNALRECORD )) MSG_JournalRecordMsg( msg );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000541 QUEUE_RemoveMsg( sysMsgQueue, pos );
542 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000543 return TRUE;
544 }
545 return FALSE;
546}
547
548
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000549/**********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000550 * SetDoubleClickTime16 (USER.20)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000551 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000552void WINAPI SetDoubleClickTime16( UINT16 interval )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000553{
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000554 SetDoubleClickTime32( interval );
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000555}
556
557
558/**********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000559 * SetDoubleClickTime32 (USER32.480)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000560 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000561BOOL32 WINAPI SetDoubleClickTime32( UINT32 interval )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000562{
563 doubleClickSpeed = interval ? interval : 500;
564 return TRUE;
565}
566
567
568/**********************************************************************
569 * GetDoubleClickTime16 (USER.21)
570 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000571UINT16 WINAPI GetDoubleClickTime16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000572{
573 return doubleClickSpeed;
574}
575
576
577/**********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000578 * GetDoubleClickTime32 (USER32.239)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000579 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000580UINT32 WINAPI GetDoubleClickTime32(void)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000581{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000582 return doubleClickSpeed;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000583}
584
585
586/***********************************************************************
Alexandre Julliardef702d81996-05-28 18:54:58 +0000587 * MSG_SendMessage
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000588 *
Alexandre Julliardef702d81996-05-28 18:54:58 +0000589 * Implementation of an inter-task SendMessage.
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000590 */
Alexandre Julliard21979011997-03-05 08:22:35 +0000591static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000592 WPARAM32 wParam, LPARAM lParam, WORD flags )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000593{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000594 INT32 prevSMRL = debugSMRL;
595 QSMCTRL qCtrl = { 0, 1};
Alexandre Julliardef702d81996-05-28 18:54:58 +0000596 MESSAGEQUEUE *queue, *destQ;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000597
Alexandre Julliardef702d81996-05-28 18:54:58 +0000598 if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return 0;
599 if (!(destQ = (MESSAGEQUEUE*)GlobalLock16( hDestQueue ))) return 0;
600
Alexandre Julliard21979011997-03-05 08:22:35 +0000601 if (IsTaskLocked() || !IsWindow32(hwnd)) return 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000602
603 debugSMRL+=4;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000604 TRACE(sendmsg,"%*sSM: %s [%04x] (%04x -> %04x)\n",
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000605 prevSMRL, "", SPY_GetMsgName(msg), msg, queue->self, hDestQueue );
606
607 if( !(queue->wakeBits & QS_SMPARAMSFREE) )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000608 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000609 TRACE(sendmsg,"\tIntertask SendMessage: sleeping since unreplied SendMessage pending\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000610 queue->changeBits &= ~QS_SMPARAMSFREE;
611 QUEUE_WaitBits( QS_SMPARAMSFREE );
Alexandre Julliardef702d81996-05-28 18:54:58 +0000612 }
613
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000614 /* resume sending */
615
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000616 queue->hWnd = hwnd;
617 queue->msg = msg;
618 queue->wParam = LOWORD(wParam);
619 queue->wParamHigh = HIWORD(wParam);
620 queue->lParam = lParam;
Alexandre Julliardef702d81996-05-28 18:54:58 +0000621 queue->hPrevSendingTask = destQ->hSendingTask;
622 destQ->hSendingTask = GetTaskQueue(0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000623
624 queue->wakeBits &= ~QS_SMPARAMSFREE;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000625 queue->flags = (queue->flags & ~(QUEUE_SM_WIN32|QUEUE_SM_UNICODE)) | flags;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000626
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000627 TRACE(sendmsg,"%*ssm: smResultInit = %08x\n", prevSMRL, "", (unsigned)&qCtrl);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000628
629 queue->smResultInit = &qCtrl;
630
Alexandre Julliardef702d81996-05-28 18:54:58 +0000631 QUEUE_SetWakeBit( destQ, QS_SENDMESSAGE );
632
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000633 /* perform task switch and wait for the result */
Alexandre Julliardef702d81996-05-28 18:54:58 +0000634
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000635 while( qCtrl.bPending )
Alexandre Julliardef702d81996-05-28 18:54:58 +0000636 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000637 if (!(queue->wakeBits & QS_SMRESULT))
638 {
639 queue->changeBits &= ~QS_SMRESULT;
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000640 if (THREAD_IsWin16( THREAD_Current() ))
641 DirectedYield( destQ->hTask );
642 else
643 QUEUE_Signal( destQ->hTask );
Alexandre Julliardef702d81996-05-28 18:54:58 +0000644 QUEUE_WaitBits( QS_SMRESULT );
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000645 TRACE(sendmsg,"\tsm: have result!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000646 }
647 /* got something */
648
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000649 TRACE(sendmsg,"%*ssm: smResult = %08x\n", prevSMRL, "", (unsigned)queue->smResult );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000650
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000651 if (queue->smResult) { /* FIXME, smResult should always be set */
652 queue->smResult->lResult = queue->SendMessageReturn;
653 queue->smResult->bPending = FALSE;
654 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000655 queue->wakeBits &= ~QS_SMRESULT;
656
657 if( queue->smResult != &qCtrl )
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000658 ERR(sendmsg, "%*ssm: weird scenes inside the goldmine!\n", prevSMRL, "");
Alexandre Julliardef702d81996-05-28 18:54:58 +0000659 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000660 queue->smResultInit = NULL;
661
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000662 TRACE(sendmsg,"%*sSM: [%04x] returning %08lx\n", prevSMRL, "", msg, qCtrl.lResult);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000663 debugSMRL-=4;
664
665 return qCtrl.lResult;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000666}
667
668
669/***********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +0000670 * ReplyMessage16 (USER.115)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000671 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000672void WINAPI ReplyMessage16( LRESULT result )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000673{
Alexandre Julliardef702d81996-05-28 18:54:58 +0000674 MESSAGEQUEUE *senderQ;
675 MESSAGEQUEUE *queue;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000676
Alexandre Julliardef702d81996-05-28 18:54:58 +0000677 if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000678
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000679 TRACE(msg,"ReplyMessage, queue %04x\n", queue->self);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000680
681 while( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
Alexandre Julliardaca05781994-10-17 18:12:41 +0000682 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000683 TRACE(msg,"\trpm: replying to %04x (%04x -> %04x)\n",
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000684 queue->msg, queue->self, senderQ->self);
685
686 if( queue->wakeBits & QS_SENDMESSAGE )
687 {
688 QUEUE_ReceiveMessage( queue );
689 continue; /* ReceiveMessage() already called us */
690 }
691
692 if(!(senderQ->wakeBits & QS_SMRESULT) ) break;
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000693 if (THREAD_IsWin16(THREAD_Current())) OldYield();
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000694 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000695 if( !senderQ ) { TRACE(msg,"\trpm: done\n"); return; }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000696
Alexandre Julliardef702d81996-05-28 18:54:58 +0000697 senderQ->SendMessageReturn = result;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000698 TRACE(msg,"\trpm: smResult = %08x, result = %08lx\n",
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000699 (unsigned)queue->smResultCurrent, result );
700
701 senderQ->smResult = queue->smResultCurrent;
Alexandre Julliardef702d81996-05-28 18:54:58 +0000702 queue->InSendMessageHandle = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000703
Alexandre Julliardef702d81996-05-28 18:54:58 +0000704 QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000705 if (THREAD_IsWin16(THREAD_Current())) DirectedYield( queue->hSendingTask );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000706}
707
708
709/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000710 * MSG_PeekMessage
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000711 */
Alexandre Julliard21979011997-03-05 08:22:35 +0000712static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
713 WORD flags, BOOL32 peek )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000714{
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000715 int pos, mask;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000716 MESSAGEQUEUE *msgQueue;
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000717 HQUEUE16 hQueue;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000718
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000719#ifdef CONFIG_IPC
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000720 DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
721 DDE_GetRemoteMessage();
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000722#endif /* CONFIG_IPC */
Alexandre Julliardef702d81996-05-28 18:54:58 +0000723
724 mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000725 if (first || last)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000726 {
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000727 if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
728 if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
729 ((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
730 if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
731 if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
732 if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000733 }
Alexandre Julliardef702d81996-05-28 18:54:58 +0000734 else mask |= QS_MOUSE | QS_KEY | QS_TIMER | QS_PAINT;
735
736 if (IsTaskLocked()) flags |= PM_NOYIELD;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000737
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000738 /* Never yield on Win32 threads */
739 if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD;
740
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000741 while(1)
742 {
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000743 hQueue = GetTaskQueue(0);
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000744 msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000745 if (!msgQueue) return FALSE;
Alexandre Julliardef702d81996-05-28 18:54:58 +0000746 msgQueue->changeBits = 0;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000747
Alexandre Julliardef702d81996-05-28 18:54:58 +0000748 /* First handle a message put by SendMessage() */
749
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000750 while (msgQueue->wakeBits & QS_SENDMESSAGE)
Alexandre Julliardef702d81996-05-28 18:54:58 +0000751 QUEUE_ReceiveMessage( msgQueue );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000752
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000753 /* Now handle a WM_QUIT message */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000754
755 if (msgQueue->wPostQMsg &&
756 (!first || WM_QUIT >= first) &&
757 (!last || WM_QUIT <= last) )
758 {
759 msg->hwnd = hwnd;
760 msg->message = WM_QUIT;
761 msg->wParam = msgQueue->wExitCode;
762 msg->lParam = 0;
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000763 if (flags & PM_REMOVE) msgQueue->wPostQMsg = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000764 break;
765 }
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000766
Alexandre Julliardef702d81996-05-28 18:54:58 +0000767 /* Now find a normal message */
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000768
Alexandre Julliardef702d81996-05-28 18:54:58 +0000769 if (((msgQueue->wakeBits & mask) & QS_POSTMESSAGE) &&
770 ((pos = QUEUE_FindMsg( msgQueue, hwnd, first, last )) != -1))
771 {
772 QMSG *qmsg = &msgQueue->messages[pos];
773 *msg = qmsg->msg;
774 msgQueue->GetMessageTimeVal = msg->time;
775 msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
776 msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000777
Alexandre Julliardef702d81996-05-28 18:54:58 +0000778 if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos );
779 break;
780 }
781
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000782 msgQueue->changeBits |= MSG_JournalPlayBackMsg();
783
Alexandre Julliardef702d81996-05-28 18:54:58 +0000784 /* Now find a hardware event */
785
786 if (((msgQueue->wakeBits & mask) & (QS_MOUSE | QS_KEY)) &&
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000787 MSG_PeekHardwareMsg( msg, hwnd, MAKELONG(first,last), flags & PM_REMOVE ))
Alexandre Julliardaca05781994-10-17 18:12:41 +0000788 {
789 /* Got one */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000790 msgQueue->GetMessageTimeVal = msg->time;
791 msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000792 msgQueue->GetMessageExtraInfoVal = 0; /* Always 0 for now */
793 break;
794 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000795
Alexandre Julliardef702d81996-05-28 18:54:58 +0000796 /* Check again for SendMessage */
797
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000798 while (msgQueue->wakeBits & QS_SENDMESSAGE)
Alexandre Julliardef702d81996-05-28 18:54:58 +0000799 QUEUE_ReceiveMessage( msgQueue );
800
801 /* Now find a WM_PAINT message */
802
803 if ((msgQueue->wakeBits & mask) & QS_PAINT)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000804 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000805 WND* wndPtr;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000806 msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000807 msg->message = WM_PAINT;
808 msg->wParam = 0;
809 msg->lParam = 0;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000810
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000811 if ((wndPtr = WIN_FindWndPtr(msg->hwnd)))
812 {
813 if( wndPtr->dwStyle & WS_MINIMIZE &&
814 wndPtr->class->hIcon )
815 {
816 msg->message = WM_PAINTICON;
817 msg->wParam = 1;
818 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000819
Alexandre Julliard01d63461997-01-20 19:43:45 +0000820 if( !hwnd || msg->hwnd == hwnd || IsChild16(hwnd,msg->hwnd) )
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000821 {
822 if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
823 {
824 wndPtr->flags &= ~WIN_INTERNAL_PAINT;
825 QUEUE_DecPaintCount( hQueue );
826 }
827 break;
828 }
829 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000830 }
831
Alexandre Julliardef702d81996-05-28 18:54:58 +0000832 /* Check for timer messages, but yield first */
833
834 if (!(flags & PM_NOYIELD))
835 {
836 UserYield();
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000837 while (msgQueue->wakeBits & QS_SENDMESSAGE)
Alexandre Julliardef702d81996-05-28 18:54:58 +0000838 QUEUE_ReceiveMessage( msgQueue );
839 }
840 if ((msgQueue->wakeBits & mask) & QS_TIMER)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000841 {
Alexandre Julliard8b915631996-06-16 16:16:05 +0000842 if (TIMER_GetTimerMsg(msg, hwnd, hQueue, flags & PM_REMOVE)) break;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000843 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000844
Alexandre Julliardaca05781994-10-17 18:12:41 +0000845 if (peek)
846 {
Alexandre Julliardef702d81996-05-28 18:54:58 +0000847 if (!(flags & PM_NOYIELD)) UserYield();
848 return FALSE;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000849 }
Alexandre Julliardef702d81996-05-28 18:54:58 +0000850 msgQueue->wakeMask = mask;
851 QUEUE_WaitBits( mask );
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000852 }
853
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000854 /* We got a message */
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000855 if (flags & PM_REMOVE)
856 {
857 WORD message = msg->message;
858
859 if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
860 {
861 BYTE *p = &QueueKeyStateTable[msg->wParam & 0xff];
862
863 if (!(*p & 0x80))
864 *p ^= 0x01;
865 *p |= 0x80;
866 }
867 else if (message == WM_KEYUP || message == WM_SYSKEYUP)
868 QueueKeyStateTable[msg->wParam & 0xff] &= ~0x80;
869 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000870 if (peek) return TRUE;
871 else return (msg->message != WM_QUIT);
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000872}
873
874
875/***********************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +0000876 * MSG_InternalGetMessage
877 *
878 * GetMessage() function for internal use. Behave like GetMessage(),
879 * but also call message filters and optionally send WM_ENTERIDLE messages.
880 * 'hwnd' must be the handle of the dialog or menu window.
881 * 'code' is the message filter value (MSGF_??? codes).
882 */
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000883BOOL32 MSG_InternalGetMessage( MSG16 *msg, HWND32 hwnd, HWND32 hwndOwner,
884 WPARAM32 code, WORD flags, BOOL32 sendIdle )
Alexandre Julliard58199531994-04-21 01:20:00 +0000885{
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000886 for (;;)
Alexandre Julliard58199531994-04-21 01:20:00 +0000887 {
888 if (sendIdle)
889 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000890 if (!MSG_PeekMessage( msg, 0, 0, 0, flags, TRUE ))
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000891 {
892 /* No message present -> send ENTERIDLE and wait */
Alexandre Julliard21979011997-03-05 08:22:35 +0000893 if (IsWindow32(hwndOwner))
Alexandre Julliardef702d81996-05-28 18:54:58 +0000894 SendMessage16( hwndOwner, WM_ENTERIDLE,
895 code, (LPARAM)hwnd );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000896 MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000897 }
Alexandre Julliard58199531994-04-21 01:20:00 +0000898 }
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000899 else /* Always wait for a message */
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000900 MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000901
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000902 /* Call message filters */
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000903
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000904 if (HOOK_IsHooked( WH_SYSMSGFILTER ) || HOOK_IsHooked( WH_MSGFILTER ))
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000905 {
906 MSG16 *pmsg = SEGPTR_NEW(MSG16);
907 if (pmsg)
908 {
909 BOOL32 ret;
910 *pmsg = *msg;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000911 ret = ((BOOL16)HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0,
912 (LPARAM)SEGPTR_GET(pmsg) ) ||
913 (BOOL16)HOOK_CallHooks16( WH_MSGFILTER, code, 0,
914 (LPARAM)SEGPTR_GET(pmsg) ));
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000915 SEGPTR_FREE(pmsg);
916 if (ret)
917 {
918 /* Message filtered -> remove it from the queue */
919 /* if it's still there. */
920 if (!(flags & PM_REMOVE))
921 MSG_PeekMessage( msg, 0, 0, 0, PM_REMOVE, TRUE );
922 continue;
923 }
924 }
925 }
926
927 return (msg->message != WM_QUIT);
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000928 }
Alexandre Julliard58199531994-04-21 01:20:00 +0000929}
930
931
932/***********************************************************************
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000933 * PeekMessage16 (USER.109)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000934 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000935BOOL16 WINAPI PeekMessage16( LPMSG16 msg, HWND16 hwnd, UINT16 first,
936 UINT16 last, UINT16 flags )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000937{
Alexandre Julliard594997c1995-04-30 10:05:20 +0000938 return MSG_PeekMessage( msg, hwnd, first, last, flags, TRUE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000939}
940
Alexandre Julliard829fe321998-07-26 14:27:39 +0000941/***********************************************************************
942 * PeekMessageA
943 */
944BOOL32 WINAPI PeekMessage32A( LPMSG32 lpmsg, HWND32 hwnd,
945 UINT32 min,UINT32 max,UINT32 wRemoveMsg)
946{
947 MSG16 msg;
948 BOOL32 ret;
949 ret=PeekMessage16(&msg,hwnd,min,max,wRemoveMsg);
950 /* FIXME: should translate the message to Win32 */
951 STRUCT32_MSG16to32(&msg,lpmsg);
952 return ret;
953}
954
955/***********************************************************************
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000956 * PeekMessageW Check queue for messages
957 *
958 * Checks for a message in the thread's queue, filtered as for
959 * GetMessage(). Returns immediately whether a message is available
960 * or not.
961 *
962 * Whether a retrieved message is removed from the queue is set by the
963 * _wRemoveMsg_ flags, which should be one of the following values:
964 *
965 * PM_NOREMOVE Do not remove the message from the queue.
966 *
967 * PM_REMOVE Remove the message from the queue.
968 *
969 * In addition, PM_NOYIELD may be combined into _wRemoveMsg_ to
970 * request that the system not yield control during PeekMessage();
971 * however applications may not rely on scheduling behavior.
972 *
973 * RETURNS
974 *
975 * Nonzero if a message is available and is retrieved, zero otherwise.
976 *
977 * CONFORMANCE
978 *
979 * ECMA-234, Win32
980 *
Alexandre Julliard829fe321998-07-26 14:27:39 +0000981 */
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000982BOOL32 WINAPI PeekMessage32W(
983 LPMSG32 lpmsg, /* buffer to receive message */
984 HWND32 hwnd, /* restrict to messages for hwnd */
985 UINT32 min, /* minimum message to receive */
986 UINT32 max, /* maximum message to receive */
987 UINT32 wRemoveMsg /* removal flags */
988) {
Alexandre Julliard829fe321998-07-26 14:27:39 +0000989 /* FIXME: Should perform Unicode translation on specific messages */
990 return PeekMessage32A(lpmsg,hwnd,min,max,wRemoveMsg);
991}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000992
993/***********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +0000994 * GetMessage16 (USER.108)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000995 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000996BOOL16 WINAPI GetMessage16( SEGPTR msg, HWND16 hwnd, UINT16 first, UINT16 last)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000997{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000998 MSG16 *lpmsg = (MSG16 *)PTR_SEG_TO_LIN(msg);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000999 MSG_PeekMessage( lpmsg,
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001000 hwnd, first, last, PM_REMOVE, FALSE );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001001
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001002 TRACE(msg,"message %04x, hwnd %04x, filter(%04x - %04x)\n", lpmsg->message,
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001003 hwnd, first, last );
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001004 HOOK_CallHooks16( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)msg );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001005 return (lpmsg->message != WM_QUIT);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001006}
1007
Alexandre Julliard829fe321998-07-26 14:27:39 +00001008/***********************************************************************
1009 * GetMessage32A (USER32.270)
1010 */
1011BOOL32 WINAPI GetMessage32A(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max)
1012{
1013 BOOL32 ret;
1014 MSG16 *msg = SEGPTR_NEW(MSG16);
1015 if (!msg) return 0;
1016 ret=GetMessage16(SEGPTR_GET(msg),(HWND16)hwnd,min,max);
1017 /* FIXME */
1018 STRUCT32_MSG16to32(msg,lpmsg);
1019 SEGPTR_FREE(msg);
1020 return ret;
1021}
1022
1023/***********************************************************************
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001024 * GetMessage32W (USER32.274) Retrieve next message
1025 *
1026 * GetMessage retrieves the next event from the calling thread's
1027 * queue and deposits it in *lpmsg.
1028 *
1029 * If _hwnd_ is not NULL, only messages for window _hwnd_ and its
1030 * children as specified by IsChild() are retrieved. If _hwnd_ is NULL
1031 * all application messages are retrieved.
1032 *
1033 * _min_ and _max_ specify the range of messages of interest. If
1034 * min==max==0, no filtering is performed. Useful examples are
1035 * WM_KEYFIRST and WM_KEYLAST to retrieve keyboard input, and
1036 * WM_MOUSEFIRST and WM_MOUSELAST to retrieve mouse input.
1037 *
1038 * WM_PAINT messages are not removed from the queue; they remain until
1039 * processed. Other messages are removed from the queue.
1040 *
1041 * RETURNS
1042 *
1043 * -1 on error, 0 if message is WM_QUIT, nonzero otherwise.
1044 *
1045 * CONFORMANCE
1046 *
1047 * ECMA-234, Win32
1048 *
Alexandre Julliard829fe321998-07-26 14:27:39 +00001049 */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001050BOOL32 WINAPI GetMessage32W(
1051 MSG32* lpmsg, /* buffer to receive message */
1052 HWND32 hwnd, /* restrict to messages for hwnd */
1053 UINT32 min, /* minimum message to receive */
1054 UINT32 max /* maximum message to receive */
1055) {
Alexandre Julliard829fe321998-07-26 14:27:39 +00001056 BOOL32 ret;
1057 MSG16 *msg = SEGPTR_NEW(MSG16);
1058 if (!msg) return 0;
1059 ret=GetMessage16(SEGPTR_GET(msg),(HWND16)hwnd,min,max);
1060 /* FIXME */
1061 STRUCT32_MSG16to32(msg,lpmsg);
1062 SEGPTR_FREE(msg);
1063 return ret;
1064}
1065
Alexandre Julliard401710d1993-09-04 10:09:32 +00001066
1067/***********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001068 * PostMessage16 (USER.110)
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001069 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001070BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 message, WPARAM16 wParam,
1071 LPARAM lParam )
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001072{
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001073 MSG16 msg;
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001074 WND *wndPtr;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001075
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001076 msg.hwnd = hwnd;
1077 msg.message = message;
1078 msg.wParam = wParam;
1079 msg.lParam = lParam;
1080 msg.time = GetTickCount();
1081 msg.pt.x = 0;
1082 msg.pt.y = 0;
1083
Alexandre Julliardb7258be1995-09-01 15:57:28 +00001084#ifdef CONFIG_IPC
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001085 if (DDE_PostMessage(&msg))
1086 return TRUE;
Alexandre Julliardb7258be1995-09-01 15:57:28 +00001087#endif /* CONFIG_IPC */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001088
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001089 if (hwnd == HWND_BROADCAST)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001090 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001091 TRACE(msg,"HWND_BROADCAST !\n");
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001092 for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
1093 {
1094 if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
1095 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001096 TRACE(msg,"BROADCAST Message to hWnd=%04x m=%04X w=%04X l=%08lX !\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001097 wndPtr->hwndSelf, message, wParam, lParam);
Alexandre Julliard21979011997-03-05 08:22:35 +00001098 PostMessage16( wndPtr->hwndSelf, message, wParam, lParam );
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001099 }
1100 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001101 TRACE(msg,"End of HWND_BROADCAST !\n");
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001102 return TRUE;
Alexandre Julliard2787be81995-05-22 18:23:01 +00001103 }
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001104
Alexandre Julliard2787be81995-05-22 18:23:01 +00001105 wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001106 if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001107
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001108 return QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001109}
1110
Alexandre Julliard21979011997-03-05 08:22:35 +00001111
1112/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001113 * PostMessage32A (USER32.419)
Alexandre Julliard21979011997-03-05 08:22:35 +00001114 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001115BOOL32 WINAPI PostMessage32A( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
1116 LPARAM lParam )
Alexandre Julliard21979011997-03-05 08:22:35 +00001117{
Kai Morich54ae4731998-10-24 12:01:36 +00001118 /* FIXME */
1119 if (message&0xffff0000)
1120 FIXME(msg,"message is truncated from %d to %d\n", message, message&0xffff);
1121 if (wParam&0xffff0000)
1122 FIXME(msg,"wParam is truncated from %d to %d\n", wParam, wParam&0xffff);
1123 return PostMessage16( hwnd, message, wParam, lParam );
Alexandre Julliard21979011997-03-05 08:22:35 +00001124}
1125
1126
1127/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001128 * PostMessage32W (USER32.420)
Alexandre Julliard21979011997-03-05 08:22:35 +00001129 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001130BOOL32 WINAPI PostMessage32W( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
1131 LPARAM lParam )
Alexandre Julliard21979011997-03-05 08:22:35 +00001132{
Kai Morich54ae4731998-10-24 12:01:36 +00001133 /* FIXME */
1134 if (message&0xffff0000)
1135 FIXME(msg,"message is truncated from %d to %d\n", message, message&0xffff);
1136 if (wParam&0xffff0000)
1137 FIXME(msg,"wParam is truncated from %d to %d\n", wParam, wParam&0xffff);
1138 return PostMessage16( hwnd, message, wParam, lParam );
Alexandre Julliard21979011997-03-05 08:22:35 +00001139}
1140
1141
Alexandre Julliard2787be81995-05-22 18:23:01 +00001142/***********************************************************************
Alexandre Julliardbf9130a1996-10-13 17:45:47 +00001143 * PostAppMessage16 (USER.116)
Alexandre Julliard2787be81995-05-22 18:23:01 +00001144 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001145BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 message, WPARAM16 wParam,
1146 LPARAM lParam )
Alexandre Julliard2787be81995-05-22 18:23:01 +00001147{
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001148 MSG16 msg;
Alexandre Julliard2787be81995-05-22 18:23:01 +00001149
1150 if (GetTaskQueue(hTask) == 0) return FALSE;
1151 msg.hwnd = 0;
1152 msg.message = message;
1153 msg.wParam = wParam;
1154 msg.lParam = lParam;
1155 msg.time = GetTickCount();
1156 msg.pt.x = 0;
1157 msg.pt.y = 0;
1158
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001159 return QUEUE_AddMsg( GetTaskQueue(hTask), &msg, 0 );
Alexandre Julliard2787be81995-05-22 18:23:01 +00001160}
1161
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001162
1163/***********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001164 * SendMessage16 (USER.111)
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001165 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001166LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
1167 LPARAM lParam)
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001168{
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001169 WND * wndPtr;
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001170 WND **list, **ppWnd;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001171 LRESULT ret;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001172
Alexandre Julliardb7258be1995-09-01 15:57:28 +00001173#ifdef CONFIG_IPC
Alexandre Julliardac9c9b01996-07-28 18:50:11 +00001174 MSG16 DDE_msg = { hwnd, msg, wParam, lParam };
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001175 if (DDE_SendMessage(&DDE_msg)) return TRUE;
Alexandre Julliardb7258be1995-09-01 15:57:28 +00001176#endif /* CONFIG_IPC */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001177
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001178 if (hwnd == HWND_BROADCAST)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001179 {
Alexandre Julliard33072e11997-06-29 18:08:02 +00001180 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1181 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001182 TRACE(msg,"HWND_BROADCAST !\n");
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001183 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001184 {
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001185 wndPtr = *ppWnd;
Alexandre Julliard21979011997-03-05 08:22:35 +00001186 if (!IsWindow32(wndPtr->hwndSelf)) continue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001187 if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
1188 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001189 TRACE(msg,"BROADCAST Message to hWnd=%04x m=%04X w=%04lX l=%08lX !\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001190 wndPtr->hwndSelf, msg, (DWORD)wParam, lParam);
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001191 SendMessage16( wndPtr->hwndSelf, msg, wParam, lParam );
Alexandre Julliard33072e11997-06-29 18:08:02 +00001192 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001193 }
Alexandre Julliard33072e11997-06-29 18:08:02 +00001194 HeapFree( SystemHeap, 0, list );
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001195 TRACE(msg,"End of HWND_BROADCAST !\n");
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001196 return TRUE;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001197 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001198
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001199 if (HOOK_IsHooked( WH_CALLWNDPROC ))
1200 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001201 LPCWPSTRUCT16 pmsg;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001202
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001203 if ((pmsg = SEGPTR_NEW(CWPSTRUCT16)))
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001204 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001205 pmsg->hwnd = hwnd;
1206 pmsg->message= msg;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001207 pmsg->wParam = wParam;
1208 pmsg->lParam = lParam;
1209 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1,
1210 (LPARAM)SEGPTR_GET(pmsg) );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001211 hwnd = pmsg->hwnd;
1212 msg = pmsg->message;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001213 wParam = pmsg->wParam;
1214 lParam = pmsg->lParam;
1215 SEGPTR_FREE( pmsg );
1216 }
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001217 }
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001218
Alexandre Julliardef702d81996-05-28 18:54:58 +00001219 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001220 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001221 WARN(msg, "invalid hwnd %04x\n", hwnd );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001222 return 0;
1223 }
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001224 if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001225 return 0; /* Don't send anything if the task is dying */
Alexandre Julliardef702d81996-05-28 18:54:58 +00001226
1227 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001228
1229 if (wndPtr->hmemTaskQ != GetTaskQueue(0))
1230 ret = MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg,
1231 wParam, lParam, 0 );
1232 else
1233 ret = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
1234 hwnd, msg, wParam, lParam );
1235
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001236 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
1237 return ret;
1238}
1239
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001240/************************************************************************
1241 * MSG_CallWndProcHook32
1242 */
1243static void MSG_CallWndProcHook32( LPMSG32 pmsg, BOOL32 bUnicode )
1244{
1245 CWPSTRUCT32 cwp;
1246
1247 cwp.lParam = pmsg->lParam;
1248 cwp.wParam = pmsg->wParam;
1249 cwp.message = pmsg->message;
1250 cwp.hwnd = pmsg->hwnd;
1251
1252 if (bUnicode) HOOK_CallHooks32W(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
1253 else HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp );
1254
1255 pmsg->lParam = cwp.lParam;
1256 pmsg->wParam = cwp.wParam;
1257 pmsg->message = cwp.message;
1258 pmsg->hwnd = cwp.hwnd;
1259}
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001260
Alexandre Julliard03468f71998-02-15 19:40:49 +00001261/**********************************************************************
1262 * PostThreadMessage32A (USER32.422)
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001263 *
1264 * BUGS
1265 *
1266 * Thread-local message queues are not supported.
1267 *
Alexandre Julliard03468f71998-02-15 19:40:49 +00001268 */
1269BOOL32 WINAPI PostThreadMessage32A(DWORD idThread , UINT32 message,
1270 WPARAM32 wParam, LPARAM lParam )
1271{
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001272 THDB *thdb = THREAD_ID_TO_THDB(idThread);
1273 if (!thdb || !thdb->process) return FALSE;
1274
1275 FIXME(sendmsg, "(...): Should use thread-local message queue!\n");
1276 return PostAppMessage16(thdb->process->task, message, wParam, lParam);
Alexandre Julliard03468f71998-02-15 19:40:49 +00001277}
1278
Marcus Meissner9cfe2d51998-11-01 14:02:57 +00001279/**********************************************************************
1280 * PostThreadMessage32W (USER32.423)
1281 *
1282 * BUGS
1283 *
1284 * Thread-local message queues are not supported.
1285 *
1286 */
1287BOOL32 WINAPI PostThreadMessage32W(DWORD idThread , UINT32 message,
1288 WPARAM32 wParam, LPARAM lParam )
1289{
1290 THDB *thdb = THREAD_ID_TO_THDB(idThread);
1291 if (!thdb || !thdb->process) return FALSE;
1292
1293 FIXME(sendmsg, "(...): Should use thread-local message queue!\n");
1294 return PostAppMessage16(thdb->process->task, message, wParam, lParam);
1295}
1296
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001297/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001298 * SendMessage32A (USER32.454)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001299 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001300LRESULT WINAPI SendMessage32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
1301 LPARAM lParam )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001302{
1303 WND * wndPtr;
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001304 WND **list, **ppWnd;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001305 LRESULT ret;
1306
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001307 if (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001308 {
Alexandre Julliard33072e11997-06-29 18:08:02 +00001309 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1310 return TRUE;
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001311 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001312 {
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001313 wndPtr = *ppWnd;
Alexandre Julliard21979011997-03-05 08:22:35 +00001314 if (!IsWindow32(wndPtr->hwndSelf)) continue;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001315 if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
1316 SendMessage32A( wndPtr->hwndSelf, msg, wParam, lParam );
1317 }
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001318 HeapFree( SystemHeap, 0, list );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001319 return TRUE;
1320 }
1321
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001322 if (HOOK_IsHooked( WH_CALLWNDPROC ))
1323 MSG_CallWndProcHook32( (LPMSG32)&hwnd, FALSE);
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001324
Alexandre Julliardef702d81996-05-28 18:54:58 +00001325 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001326 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001327 WARN(msg, "invalid hwnd %08x\n", hwnd );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001328 return 0;
1329 }
Alexandre Julliardca22b331996-07-12 19:02:39 +00001330
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001331 if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001332 return 0; /* Don't send anything if the task is dying */
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001333
Alexandre Julliardef702d81996-05-28 18:54:58 +00001334 SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001335
1336 if (wndPtr->hmemTaskQ != GetTaskQueue(0))
1337 ret = MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam,
1338 QUEUE_SM_WIN32 );
1339 else
1340 ret = CallWindowProc32A( (WNDPROC32)wndPtr->winproc,
1341 hwnd, msg, wParam, lParam );
1342
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001343 SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
1344 return ret;
1345}
1346
1347
1348/***********************************************************************
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001349 * SendMessage32W (USER32.459) Send Window Message
1350 *
1351 * Sends a message to the window procedure of the specified window.
1352 * SendMessage() will not return until the called window procedure
1353 * either returns or calls ReplyMessage().
1354 *
1355 * Use PostMessage() to send message and return immediately. A window
1356 * procedure may use InSendMessage() to detect
1357 * SendMessage()-originated messages.
1358 *
1359 * Applications which communicate via HWND_BROADCAST may use
1360 * RegisterWindowMessage() to obtain a unique message to avoid conflicts
1361 * with other applications.
1362 *
1363 * CONFORMANCE
1364 *
1365 * ECMA-234, Win32
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001366 */
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001367LRESULT WINAPI SendMessage32W(
1368 HWND32 hwnd, /* Window to send message to. If HWND_BROADCAST,
1369 the message will be sent to all top-level windows. */
1370
1371 UINT32 msg, /* message */
1372 WPARAM32 wParam, /* message parameter */
1373 LPARAM lParam /* additional message parameter */
1374) {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001375 WND * wndPtr;
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001376 WND **list, **ppWnd;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001377 LRESULT ret;
1378
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001379 if (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001380 {
Alexandre Julliard33072e11997-06-29 18:08:02 +00001381 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1382 return TRUE;
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001383 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001384 {
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001385 wndPtr = *ppWnd;
Alexandre Julliard21979011997-03-05 08:22:35 +00001386 if (!IsWindow32(wndPtr->hwndSelf)) continue;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001387 if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
1388 SendMessage32W( wndPtr->hwndSelf, msg, wParam, lParam );
1389 }
Alexandre Julliardb1bac321996-12-15 19:45:59 +00001390 HeapFree( SystemHeap, 0, list );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001391 return TRUE;
1392 }
1393
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001394 if (HOOK_IsHooked( WH_CALLWNDPROC ))
1395 MSG_CallWndProcHook32( (LPMSG32)&hwnd, TRUE);
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001396
Alexandre Julliardef702d81996-05-28 18:54:58 +00001397 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001398 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001399 WARN(msg, "invalid hwnd %08x\n", hwnd );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001400 return 0;
1401 }
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001402 if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001403 return 0; /* Don't send anything if the task is dying */
Alexandre Julliardef702d81996-05-28 18:54:58 +00001404
1405 SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001406
1407 if (wndPtr->hmemTaskQ != GetTaskQueue(0))
1408 ret = MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam,
1409 QUEUE_SM_WIN32 | QUEUE_SM_UNICODE );
1410 else
1411 ret = CallWindowProc32W( (WNDPROC32)wndPtr->winproc,
1412 hwnd, msg, wParam, lParam );
1413
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001414 SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001415 return ret;
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001416}
1417
1418
1419/***********************************************************************
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001420 * SendMessageTimeout16 (not a WINAPI)
1421 */
1422LRESULT WINAPI SendMessageTimeout16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
1423 LPARAM lParam, UINT16 flags,
1424 UINT16 timeout, LPWORD resultp)
1425{
Alexandre Julliard54c27111998-03-29 19:44:57 +00001426 FIXME(sendmsg, "(...): semistub\n");
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001427 return SendMessage16 (hwnd, msg, wParam, lParam);
1428}
1429
1430
1431/***********************************************************************
1432 * SendMessageTimeout32A (USER32.457)
1433 */
1434LRESULT WINAPI SendMessageTimeout32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
1435 LPARAM lParam, UINT32 flags,
1436 UINT32 timeout, LPDWORD resultp)
1437{
Alexandre Julliard54c27111998-03-29 19:44:57 +00001438 FIXME(sendmsg, "(...): semistub\n");
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001439 return SendMessage32A (hwnd, msg, wParam, lParam);
1440}
1441
1442
1443/***********************************************************************
1444 * SendMessageTimeout32W (USER32.458)
1445 */
1446LRESULT WINAPI SendMessageTimeout32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
1447 LPARAM lParam, UINT32 flags,
1448 UINT32 timeout, LPDWORD resultp)
1449{
Alexandre Julliard54c27111998-03-29 19:44:57 +00001450 FIXME(sendmsg, "(...): semistub\n");
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001451 return SendMessage32W (hwnd, msg, wParam, lParam);
1452}
1453
1454
1455/***********************************************************************
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001456 * WaitMessage (USER.112) (USER32.578) Suspend thread pending messages
1457 *
1458 * WaitMessage() suspends a thread until events appear in the thread's
1459 * queue.
1460 *
1461 * BUGS
1462 *
1463 * Is supposed to return BOOL under Win32.
1464 *
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001465 * Thread-local message queues are not supported.
1466 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001467 * CONFORMANCE
1468 *
1469 * ECMA-234, Win32
1470 *
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001471 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001472void WINAPI WaitMessage( void )
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001473{
Alexandre Julliard8b915631996-06-16 16:16:05 +00001474 QUEUE_WaitBits( QS_ALLINPUT );
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001475}
1476
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001477/***********************************************************************
1478 * MsgWaitForMultipleObjects (USER32.400)
1479 */
1480DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE32 *pHandles,
1481 BOOL32 fWaitAll, DWORD dwMilliseconds,
1482 DWORD dwWakeMask )
1483{
1484 DWORD retv;
1485
1486 TDB *currTask = (TDB *)GlobalLock16( GetCurrentTask() );
1487 HQUEUE16 hQueue = currTask? currTask->hQueue : 0;
1488 MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
1489 if (!msgQueue) return 0xFFFFFFFF;
1490
1491 msgQueue->changeBits = 0;
1492 msgQueue->wakeMask = dwWakeMask;
1493
1494 retv = SYNC_DoWait( nCount, pHandles, fWaitAll, dwMilliseconds, FALSE, TRUE );
1495
1496 return retv;
1497}
1498
1499
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001500
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001501struct accent_char
1502{
1503 BYTE ac_accent;
1504 BYTE ac_char;
1505 BYTE ac_result;
1506};
1507
1508static const struct accent_char accent_chars[] =
1509{
Alexandre Julliard21979011997-03-05 08:22:35 +00001510/* A good idea should be to read /usr/X11/lib/X11/locale/iso8859-x/Compose */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001511 {'`', 'A', '\300'}, {'`', 'a', '\340'},
1512 {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
1513 {'^', 'A', '\302'}, {'^', 'a', '\342'},
1514 {'~', 'A', '\303'}, {'~', 'a', '\343'},
1515 {'"', 'A', '\304'}, {'"', 'a', '\344'},
1516 {'O', 'A', '\305'}, {'o', 'a', '\345'},
1517 {'0', 'A', '\305'}, {'0', 'a', '\345'},
1518 {'A', 'A', '\305'}, {'a', 'a', '\345'},
1519 {'A', 'E', '\306'}, {'a', 'e', '\346'},
1520 {',', 'C', '\307'}, {',', 'c', '\347'},
1521 {'`', 'E', '\310'}, {'`', 'e', '\350'},
1522 {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
1523 {'^', 'E', '\312'}, {'^', 'e', '\352'},
1524 {'"', 'E', '\313'}, {'"', 'e', '\353'},
1525 {'`', 'I', '\314'}, {'`', 'i', '\354'},
1526 {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
1527 {'^', 'I', '\316'}, {'^', 'i', '\356'},
1528 {'"', 'I', '\317'}, {'"', 'i', '\357'},
1529 {'-', 'D', '\320'}, {'-', 'd', '\360'},
1530 {'~', 'N', '\321'}, {'~', 'n', '\361'},
1531 {'`', 'O', '\322'}, {'`', 'o', '\362'},
1532 {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
1533 {'^', 'O', '\324'}, {'^', 'o', '\364'},
1534 {'~', 'O', '\325'}, {'~', 'o', '\365'},
1535 {'"', 'O', '\326'}, {'"', 'o', '\366'},
1536 {'/', 'O', '\330'}, {'/', 'o', '\370'},
1537 {'`', 'U', '\331'}, {'`', 'u', '\371'},
1538 {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
1539 {'^', 'U', '\333'}, {'^', 'u', '\373'},
1540 {'"', 'U', '\334'}, {'"', 'u', '\374'},
1541 {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
1542 {'T', 'H', '\336'}, {'t', 'h', '\376'},
1543 {'s', 's', '\337'}, {'"', 'y', '\377'},
1544 {'s', 'z', '\337'}, {'i', 'j', '\377'},
Alexandre Julliard21979011997-03-05 08:22:35 +00001545 /* iso-8859-2 uses this */
1546 {'<', 'L', '\245'}, {'<', 'l', '\265'}, /* caron */
1547 {'<', 'S', '\251'}, {'<', 's', '\271'},
1548 {'<', 'T', '\253'}, {'<', 't', '\273'},
1549 {'<', 'Z', '\256'}, {'<', 'z', '\276'},
1550 {'<', 'C', '\310'}, {'<', 'c', '\350'},
1551 {'<', 'E', '\314'}, {'<', 'e', '\354'},
1552 {'<', 'D', '\317'}, {'<', 'd', '\357'},
1553 {'<', 'N', '\322'}, {'<', 'n', '\362'},
1554 {'<', 'R', '\330'}, {'<', 'r', '\370'},
1555 {';', 'A', '\241'}, {';', 'a', '\261'}, /* ogonek */
1556 {';', 'E', '\312'}, {';', 'e', '\332'},
1557 {'\'', 'Z', '\254'}, {'\'', 'z', '\274'}, /* acute */
1558 {'\'', 'R', '\300'}, {'\'', 'r', '\340'},
1559 {'\'', 'L', '\305'}, {'\'', 'l', '\345'},
1560 {'\'', 'C', '\306'}, {'\'', 'c', '\346'},
1561 {'\'', 'N', '\321'}, {'\'', 'n', '\361'},
1562/* collision whith S, from iso-8859-9 !!! */
1563 {',', 'S', '\252'}, {',', 's', '\272'}, /* cedilla */
1564 {',', 'T', '\336'}, {',', 't', '\376'},
1565 {'.', 'Z', '\257'}, {'.', 'z', '\277'}, /* dot above */
1566 {'/', 'L', '\243'}, {'/', 'l', '\263'}, /* slash */
1567 {'/', 'D', '\320'}, {'/', 'd', '\360'},
1568 {'(', 'A', '\303'}, {'(', 'a', '\343'}, /* breve */
1569 {'\275', 'O', '\325'}, {'\275', 'o', '\365'}, /* double acute */
1570 {'\275', 'U', '\334'}, {'\275', 'u', '\374'},
1571 {'0', 'U', '\332'}, {'0', 'u', '\372'}, /* ring above */
1572 /* iso-8859-3 uses this */
1573 {'/', 'H', '\241'}, {'/', 'h', '\261'}, /* slash */
1574 {'>', 'H', '\246'}, {'>', 'h', '\266'}, /* circumflex */
1575 {'>', 'J', '\254'}, {'>', 'j', '\274'},
1576 {'>', 'C', '\306'}, {'>', 'c', '\346'},
1577 {'>', 'G', '\330'}, {'>', 'g', '\370'},
1578 {'>', 'S', '\336'}, {'>', 's', '\376'},
1579/* collision whith G( from iso-8859-9 !!! */
1580 {'(', 'G', '\253'}, {'(', 'g', '\273'}, /* breve */
1581 {'(', 'U', '\335'}, {'(', 'u', '\375'},
1582/* collision whith I. from iso-8859-3 !!! */
1583 {'.', 'I', '\251'}, {'.', 'i', '\271'}, /* dot above */
1584 {'.', 'C', '\305'}, {'.', 'c', '\345'},
1585 {'.', 'G', '\325'}, {'.', 'g', '\365'},
1586 /* iso-8859-4 uses this */
1587 {',', 'R', '\243'}, {',', 'r', '\263'}, /* cedilla */
1588 {',', 'L', '\246'}, {',', 'l', '\266'},
1589 {',', 'G', '\253'}, {',', 'g', '\273'},
1590 {',', 'N', '\321'}, {',', 'n', '\361'},
1591 {',', 'K', '\323'}, {',', 'k', '\363'},
1592 {'~', 'I', '\245'}, {'~', 'i', '\265'}, /* tilde */
1593 {'-', 'E', '\252'}, {'-', 'e', '\272'}, /* macron */
1594 {'-', 'A', '\300'}, {'-', 'a', '\340'},
1595 {'-', 'I', '\317'}, {'-', 'i', '\357'},
1596 {'-', 'O', '\322'}, {'-', 'o', '\362'},
1597 {'-', 'U', '\336'}, {'-', 'u', '\376'},
1598 {'/', 'T', '\254'}, {'/', 't', '\274'}, /* slash */
1599 {'.', 'E', '\314'}, {'.', 'e', '\344'}, /* dot above */
1600 {';', 'I', '\307'}, {';', 'i', '\347'}, /* ogonek */
1601 {';', 'U', '\331'}, {';', 'u', '\371'},
1602 /* iso-8859-9 uses this */
1603 /* iso-8859-9 has really bad choosen G( S, and I. as they collide
1604 * whith the same letters on other iso-8859-x (that is they are on
1605 * different places :-( ), if you use turkish uncomment these and
1606 * comment out the lines in iso-8859-2 and iso-8859-3 sections
1607 * FIXME: should be dynamic according to chosen language
1608 * if/when Wine has turkish support.
1609 */
1610/* collision whith G( from iso-8859-3 !!! */
1611/* {'(', 'G', '\320'}, {'(', 'g', '\360'}, */ /* breve */
1612/* collision whith S, from iso-8859-2 !!! */
1613/* {',', 'S', '\336'}, {',', 's', '\376'}, */ /* cedilla */
1614/* collision whith I. from iso-8859-3 !!! */
1615/* {'.', 'I', '\335'}, {'.', 'i', '\375'}, */ /* dot above */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001616};
1617
1618
Alexandre Julliard7e50df31994-08-06 11:22:41 +00001619/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001620 * MSG_DoTranslateMessage
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001621 *
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001622 * Implementation of TranslateMessage.
1623 *
1624 * TranslateMessage translates virtual-key messages into character-messages,
Alexandre Julliardda0cfb31996-12-01 17:17:47 +00001625 * as follows :
1626 * WM_KEYDOWN/WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message.
1627 * ditto replacing WM_* with WM_SYS*
1628 * This produces WM_CHAR messages only for keys mapped to ASCII characters
1629 * by the keyboard driver.
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001630 */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001631static BOOL32 MSG_DoTranslateMessage( UINT32 message, HWND32 hwnd,
1632 WPARAM32 wParam, LPARAM lParam )
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001633{
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001634 static int dead_char;
1635 BYTE wp[2];
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001636
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001637 if (message != WM_MOUSEMOVE && message != WM_TIMER)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001638 TRACE(msg, "(%s, %04X, %08lX)\n",
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001639 SPY_GetMsgName(message), wParam, lParam );
1640 if(message >= WM_KEYFIRST && message <= WM_KEYLAST)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001641 TRACE(key, "(%s, %04X, %08lX)\n",
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001642 SPY_GetMsgName(message), wParam, lParam );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001643
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001644 if ((message != WM_KEYDOWN) && (message != WM_SYSKEYDOWN)) return FALSE;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001645
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001646 TRACE(key, "Translating key %04X, scancode %04X\n",
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001647 wParam, HIWORD(lParam) );
1648
1649 /* FIXME : should handle ToAscii yielding 2 */
1650 switch (ToAscii32(wParam, HIWORD(lParam),
1651 QueueKeyStateTable,(LPWORD)wp, 0))
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001652 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001653 case 1 :
1654 message = (message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1655 /* Should dead chars handling go in ToAscii ? */
1656 if (dead_char)
1657 {
1658 int i;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001659
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001660 if (wp[0] == ' ') wp[0] = dead_char;
Alexandre Julliard21979011997-03-05 08:22:35 +00001661 if (dead_char == 0xa2) dead_char = '(';
1662 else if (dead_char == 0xa8) dead_char = '"';
1663 else if (dead_char == 0xb2) dead_char = ';';
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001664 else if (dead_char == 0xb4) dead_char = '\'';
Alexandre Julliard21979011997-03-05 08:22:35 +00001665 else if (dead_char == 0xb7) dead_char = '<';
1666 else if (dead_char == 0xb8) dead_char = ',';
1667 else if (dead_char == 0xff) dead_char = '.';
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001668 for (i = 0; i < sizeof(accent_chars)/sizeof(accent_chars[0]); i++)
1669 if ((accent_chars[i].ac_accent == dead_char) &&
1670 (accent_chars[i].ac_char == wp[0]))
1671 {
1672 wp[0] = accent_chars[i].ac_result;
1673 break;
1674 }
1675 dead_char = 0;
1676 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001677 TRACE(key, "1 -> PostMessage(%s)\n", SPY_GetMsgName(message));
Alexandre Julliard21979011997-03-05 08:22:35 +00001678 PostMessage16( hwnd, message, wp[0], lParam );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001679 return TRUE;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001680
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001681 case -1 :
1682 message = (message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
1683 dead_char = wp[0];
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001684 TRACE(key, "-1 -> PostMessage(%s)\n",
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001685 SPY_GetMsgName(message));
Alexandre Julliard21979011997-03-05 08:22:35 +00001686 PostMessage16( hwnd, message, wp[0], lParam );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001687 return TRUE;
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001688 }
1689 return FALSE;
1690}
1691
1692
1693/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001694 * TranslateMessage16 (USER.113)
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001695 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001696BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001697{
1698 return MSG_DoTranslateMessage( msg->message, msg->hwnd,
1699 msg->wParam, msg->lParam );
1700}
1701
1702
1703/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001704 * TranslateMessage32 (USER32.556)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001705 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001706BOOL32 WINAPI TranslateMessage32( const MSG32 *msg )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001707{
1708 return MSG_DoTranslateMessage( msg->message, msg->hwnd,
1709 msg->wParam, msg->lParam );
1710}
1711
1712
1713/***********************************************************************
1714 * DispatchMessage16 (USER.114)
1715 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001716LONG WINAPI DispatchMessage16( const MSG16* msg )
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001717{
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001718 WND * wndPtr;
1719 LONG retval;
1720 int painting;
1721
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001722 /* Process timer messages */
1723 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
1724 {
1725 if (msg->lParam)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001726 {
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001727 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001728 msg->message, msg->wParam, GetTickCount() );
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001729 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001730 }
1731
1732 if (!msg->hwnd) return 0;
1733 if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001734 if (!wndPtr->winproc) return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001735 painting = (msg->message == WM_PAINT);
1736 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001737
1738 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message,
1739 msg->wParam, msg->lParam );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001740 retval = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
1741 msg->hwnd, msg->message,
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001742 msg->wParam, msg->lParam );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001743 SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );
1744
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +00001745 if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
1746 (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001747 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001748 ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
1749 msg->hwnd);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001750 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +00001751 /* Validate the update region to avoid infinite WM_PAINT loop */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001752 ValidateRect32( msg->hwnd, NULL );
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001753 }
1754 return retval;
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001755}
1756
1757
1758/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001759 * DispatchMessage32A (USER32.141)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001760 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001761LONG WINAPI DispatchMessage32A( const MSG32* msg )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001762{
1763 WND * wndPtr;
1764 LONG retval;
1765 int painting;
1766
1767 /* Process timer messages */
1768 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
1769 {
1770 if (msg->lParam)
1771 {
1772/* HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
1773 return CallWindowProc32A( (WNDPROC32)msg->lParam, msg->hwnd,
1774 msg->message, msg->wParam, GetTickCount() );
1775 }
1776 }
1777
1778 if (!msg->hwnd) return 0;
1779 if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
1780 if (!wndPtr->winproc) return 0;
1781 painting = (msg->message == WM_PAINT);
1782 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
1783/* HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
1784
1785 SPY_EnterMessage( SPY_DISPATCHMESSAGE32, msg->hwnd, msg->message,
1786 msg->wParam, msg->lParam );
1787 retval = CallWindowProc32A( (WNDPROC32)wndPtr->winproc,
1788 msg->hwnd, msg->message,
1789 msg->wParam, msg->lParam );
1790 SPY_ExitMessage( SPY_RESULT_OK32, msg->hwnd, msg->message, retval );
1791
1792 if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
1793 (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
1794 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001795 ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
1796 msg->hwnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001797 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
1798 /* Validate the update region to avoid infinite WM_PAINT loop */
1799 ValidateRect32( msg->hwnd, NULL );
1800 }
1801 return retval;
1802}
1803
1804
1805/***********************************************************************
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001806 * DispatchMessage32W (USER32.142) Process Message
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001807 *
1808 * Process the message specified in the structure *_msg_.
1809 *
1810 * If the lpMsg parameter points to a WM_TIMER message and the
1811 * parameter of the WM_TIMER message is not NULL, the lParam parameter
1812 * points to the function that is called instead of the window
1813 * procedure.
1814 *
1815 * The message must be valid.
1816 *
1817 * RETURNS
1818 *
1819 * DispatchMessage() returns the result of the window procedure invoked.
1820 *
1821 * CONFORMANCE
1822 *
1823 * ECMA-234, Win32
1824 *
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001825 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001826LONG WINAPI DispatchMessage32W( const MSG32* msg )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001827{
1828 WND * wndPtr;
1829 LONG retval;
1830 int painting;
1831
1832 /* Process timer messages */
1833 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
1834 {
1835 if (msg->lParam)
1836 {
1837/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
1838 return CallWindowProc32W( (WNDPROC32)msg->lParam, msg->hwnd,
1839 msg->message, msg->wParam, GetTickCount() );
1840 }
1841 }
1842
1843 if (!msg->hwnd) return 0;
1844 if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
1845 if (!wndPtr->winproc) return 0;
1846 painting = (msg->message == WM_PAINT);
1847 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
1848/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
1849
1850 SPY_EnterMessage( SPY_DISPATCHMESSAGE32, msg->hwnd, msg->message,
1851 msg->wParam, msg->lParam );
1852 retval = CallWindowProc32W( (WNDPROC32)wndPtr->winproc,
1853 msg->hwnd, msg->message,
1854 msg->wParam, msg->lParam );
1855 SPY_ExitMessage( SPY_RESULT_OK32, msg->hwnd, msg->message, retval );
1856
1857 if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
1858 (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
1859 {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001860 ERR(msg, "BeginPaint not called on WM_PAINT for hwnd %04x!\n",
1861 msg->hwnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001862 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
1863 /* Validate the update region to avoid infinite WM_PAINT loop */
1864 ValidateRect32( msg->hwnd, NULL );
1865 }
1866 return retval;
1867}
1868
1869
1870/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001871 * RegisterWindowMessage16 (USER.118)
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001872 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001873WORD WINAPI RegisterWindowMessage16( SEGPTR str )
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001874{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001875 TRACE(msg, "%08lx\n", (DWORD)str );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001876 return GlobalAddAtom16( str );
Alexandre Julliard75a839a1993-07-15 11:13:45 +00001877}
1878
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001879
1880/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001881 * RegisterWindowMessage32A (USER32.437)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001882 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001883WORD WINAPI RegisterWindowMessage32A( LPCSTR str )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +00001884{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001885 TRACE(msg, "%s\n", str );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001886 return GlobalAddAtom32A( str );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +00001887}
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001888
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001889
1890/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001891 * RegisterWindowMessage32W (USER32.438)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001892 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001893WORD WINAPI RegisterWindowMessage32W( LPCWSTR str )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001894{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001895 TRACE(msg, "%p\n", str );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001896 return GlobalAddAtom32W( str );
1897}
1898
1899
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001900/***********************************************************************
Douglas Ridgwayefaa5731998-10-25 09:20:30 +00001901 * GetTickCount (USER.13) (KERNEL32.299) System Time
1902 * Returns the number of milliseconds, modulo 2^32, since the start
1903 * of the current session.
1904 *
1905 * CONFORMANCE
1906 *
1907 * ECMA-234, Win32
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001908 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001909DWORD WINAPI GetTickCount(void)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001910{
1911 struct timeval t;
1912 gettimeofday( &t, NULL );
Rein Klazes43daa7a1998-10-11 14:04:10 +00001913 /* make extremely compatible: granularity is 25 msec */
1914 return ((t.tv_sec * 1000) + (t.tv_usec / 25000) * 25) - MSG_WineStartTicks;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001915}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001916
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001917
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001918/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001919 * GetCurrentTime16 (USER.15)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001920 *
1921 * (effectively identical to GetTickCount)
Alexandre Julliardade697e1995-11-26 13:59:11 +00001922 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001923DWORD WINAPI GetCurrentTime16(void)
Alexandre Julliardade697e1995-11-26 13:59:11 +00001924{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001925 return GetTickCount();
Alexandre Julliardade697e1995-11-26 13:59:11 +00001926}
1927
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00001928
Alexandre Julliardade697e1995-11-26 13:59:11 +00001929/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001930 * InSendMessage16 (USER.192)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001931 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001932BOOL16 WINAPI InSendMessage16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001933{
1934 return InSendMessage32();
1935}
1936
1937
1938/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001939 * InSendMessage32 (USER32.320)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001940 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001941BOOL32 WINAPI InSendMessage32(void)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001942{
Alexandre Julliardef702d81996-05-28 18:54:58 +00001943 MESSAGEQUEUE *queue;
1944
1945 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
1946 return 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001947 return (BOOL32)queue->InSendMessageHandle;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001948}
Alexandre Julliarde658d821997-11-30 17:45:40 +00001949
1950/***********************************************************************
1951 * BroadcastSystemMessage (USER32.12)
1952 */
1953LONG WINAPI BroadcastSystemMessage(
1954 DWORD dwFlags,LPDWORD recipients,UINT32 uMessage,WPARAM32 wParam,
1955 LPARAM lParam
1956) {
Alexandre Julliard54c27111998-03-29 19:44:57 +00001957 FIXME(sendmsg,"(%08lx,%08lx,%08x,%08x,%08lx): stub!\n",
1958 dwFlags,*recipients,uMessage,wParam,lParam
Alexandre Julliarde658d821997-11-30 17:45:40 +00001959 );
1960 return 0;
1961}
Alexandre Julliard02e90081998-01-04 17:49:09 +00001962
1963/***********************************************************************
1964 * SendNotifyMessageA (USER32.460)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001965 * FIXME
1966 * The message sended with PostMessage has to be put in the queue
1967 * with a higher priority as the other "Posted" messages.
1968 * QUEUE_AddMsg has to be modifyed.
Alexandre Julliard02e90081998-01-04 17:49:09 +00001969 */
1970LONG WINAPI SendNotifyMessage32A(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001971{ BOOL32 ret = TRUE;
1972 FIXME(msg,"(%04x,%08x,%08x,%08lx) not complete\n",
1973 hwnd, msg, wParam, lParam);
1974
1975 if ( GetCurrentThreadId() == GetWindowThreadProcessId ( hwnd, NULL))
1976 { ret=SendMessage32A ( hwnd, msg, wParam, lParam );
1977 }
1978 else
1979 { PostMessage32A ( hwnd, msg, wParam, lParam );
1980 }
1981 return ret;
Alexandre Julliard02e90081998-01-04 17:49:09 +00001982}
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001983/***********************************************************************
1984 * SendMessageCallBack32A
1985 * FIXME: It's like PostMessage. The callback gets called when the message
1986 * is processed. We have to modify the message processing for a exact
1987 * implementation...
1988 */
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001989BOOL32 WINAPI SendMessageCallBack32A(
1990 HWND32 hWnd,UINT32 Msg,WPARAM32 wParam,LPARAM lParam,
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001991 FARPROC32 lpResultCallBack,DWORD dwData)
1992{
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001993 FIXME(msg,"(0x%04x,0x%04x,0x%08x,0x%08lx,%p,0x%08lx),stub!\n",
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001994 hWnd,Msg,wParam,lParam,lpResultCallBack,dwData);
1995 if ( hWnd == HWND_BROADCAST)
1996 { PostMessage32A( hWnd, Msg, wParam, lParam);
1997 FIXME(msg,"Broadcast: Callback will not be called!\n");
1998 return TRUE;
1999 }
2000 (lpResultCallBack)( hWnd, Msg, dwData, SendMessage32A ( hWnd, Msg, wParam, lParam ));
2001 return TRUE;
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002002}