Added mappings for a few messages.
[wine] / dlls / user / msg16.c
1 /*
2  * 16-bit messaging support
3  *
4  * Copyright 2001 Alexandre Julliard
5  */
6
7 #include "wine/winuser16.h"
8 #include "heap.h"
9 #include "hook.h"
10 #include "message.h"
11 #include "spy.h"
12 #include "task.h"
13 #include "thread.h"
14 #include "win.h"
15 #include "debugtools.h"
16
17 DEFAULT_DEBUG_CHANNEL(msg);
18
19
20 /***********************************************************************
21  *              SendMessage  (USER.111)
22  */
23 LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
24 {
25     LRESULT result;
26
27     if (hwnd != HWND_BROADCAST &&
28         GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
29     {
30         /* call 16-bit window proc directly */
31         WND *wndPtr;
32         WNDPROC16 winproc;
33
34         /* first the WH_CALLWNDPROC hook */
35         if (HOOK_IsHooked( WH_CALLWNDPROC ))
36         {
37             CWPSTRUCT16 *cwp;
38
39             if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
40             {
41                 cwp->hwnd    = hwnd;
42                 cwp->message = msg;
43                 cwp->wParam  = wparam;
44                 cwp->lParam  = lparam;
45                 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
46                 hwnd   = cwp->hwnd;
47                 msg    = cwp->message;
48                 wparam = cwp->wParam;
49                 lparam = cwp->lParam;
50                 SEGPTR_FREE( cwp );
51             }
52         }
53
54         if (!(wndPtr = WIN_FindWndPtr( hwnd )))
55         {
56             WARN("invalid hwnd %04x\n", hwnd );
57             return 0;
58         }
59         winproc = (WNDPROC16)wndPtr->winproc;
60         WIN_ReleaseWndPtr( wndPtr );
61
62         SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
63         result = CallWindowProc16( (WNDPROC16)winproc, hwnd, msg, wparam, lparam );
64         SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
65     }
66     else  /* map to 32-bit unicode for inter-thread/process message */
67     {
68         UINT msg32;
69         WPARAM wparam32;
70
71         if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
72             return 0;
73         result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
74                                           SendMessageW( hwnd, msg32, wparam32, lparam ) );
75     }
76     return result;
77 }
78
79
80 /***********************************************************************
81  *              PostMessage  (USER.110)
82  */
83 BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
84 {
85     WPARAM wparam32;
86     UINT msg32;
87
88     switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
89     {
90     case 0:
91         return PostMessageW( hwnd, msg32, wparam32, lparam );
92     case 1:
93         ERR( "16-bit message %x contains pointer, cannot post\n", msg );
94         return FALSE;
95     default:
96         return FALSE;
97     }
98 }
99
100
101 /***********************************************************************
102  *              PostAppMessage (USER.116)
103  *              PostAppMessage16 (USER32.@)
104  */
105 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
106 {
107     WPARAM wparam32;
108     UINT msg32;
109     TDB *pTask = TASK_GetPtr( hTask );
110     if (!pTask) return FALSE;
111
112     switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
113     {
114     case 0:
115         return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
116     case 1:
117         ERR( "16-bit message %x contains pointer, cannot post\n", msg );
118         return FALSE;
119     default:
120         return FALSE;
121     }
122 }
123
124
125 /***********************************************************************
126  *              InSendMessage  (USER.192)
127  */
128 BOOL16 WINAPI InSendMessage16(void)
129 {
130     return InSendMessage();
131 }
132
133
134 /***********************************************************************
135  *              ReplyMessage  (USER.115)
136  */
137 void WINAPI ReplyMessage16( LRESULT result )
138 {
139     ReplyMessage( result );
140 }
141
142
143 /***********************************************************************
144  *              PeekMessage32 (USER.819)
145  */
146 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd,
147                                 UINT16 first, UINT16 last, UINT16 flags,
148                                 BOOL16 wHaveParamHigh )
149 {
150     MSG msg;
151
152     if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
153
154     msg16->msg.hwnd    = msg.hwnd;
155     msg16->msg.lParam  = msg.lParam;
156     msg16->msg.time    = msg.time;
157     msg16->msg.pt.x    = (INT16)msg.pt.x;
158     msg16->msg.pt.y    = (INT16)msg.pt.y;
159     if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
160
161     return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
162                                    &msg16->msg.message, &msg16->msg.wParam,
163                                    &msg16->msg.lParam ) != -1);
164 }
165
166
167 /***********************************************************************
168  *              PeekMessage  (USER.109)
169  */
170 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
171                              UINT16 first, UINT16 last, UINT16 flags )
172 {
173     return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
174 }
175
176
177 /***********************************************************************
178  *              GetMessage32  (USER.820)
179  */
180 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd, UINT16 first,
181                                UINT16 last, BOOL16 wHaveParamHigh )
182 {
183     MSG msg;
184
185     do
186     {
187         GetMessageW( &msg, hwnd, first, last );
188         msg16->msg.hwnd    = msg.hwnd;
189         msg16->msg.lParam  = msg.lParam;
190         msg16->msg.time    = msg.time;
191         msg16->msg.pt.x    = (INT16)msg.pt.x;
192         msg16->msg.pt.y    = (INT16)msg.pt.y;
193         if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
194     }
195     while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
196                                   &msg16->msg.message, &msg16->msg.wParam,
197                                   &msg16->msg.lParam ) == -1);
198
199     TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
200            msg16->msg.message, hwnd, first, last );
201
202     return msg16->msg.message != WM_QUIT;
203 }
204
205
206 /***********************************************************************
207  *              GetMessage  (USER.108)
208  */
209 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
210 {
211     return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
212 }
213
214
215 /***********************************************************************
216  *              TranslateMessage32 (USER.821)
217  */
218 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
219 {
220     MSG msg32;
221
222     msg32.hwnd    = msg->msg.hwnd;
223     msg32.message = msg->msg.message;
224     msg32.wParam  = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
225     msg32.lParam  = msg->msg.lParam;
226     return TranslateMessage( &msg32 );
227 }
228
229
230 /***********************************************************************
231  *              TranslateMessage (USER.113)
232  */
233 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
234 {
235     return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
236 }
237
238
239 /***********************************************************************
240  *              DispatchMessage (USER.114)
241  */
242 LONG WINAPI DispatchMessage16( const MSG16* msg )
243 {
244     WND * wndPtr;
245     WNDPROC16 winproc;
246     LONG retval;
247     int painting;
248
249       /* Process timer messages */
250     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
251     {
252         if (msg->lParam)
253         {
254             /* before calling window proc, verify whether timer is still valid;
255                there's a slim chance that the application kills the timer
256                between GetMessage and DispatchMessage API calls */
257             if (!TIMER_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
258                 return 0; /* invalid winproc */
259
260             return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
261                                      msg->message, msg->wParam, GetTickCount() );
262         }
263     }
264
265     if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
266     if (!wndPtr->winproc)
267     {
268         WIN_ReleaseWndPtr( wndPtr );
269         return 0;
270     }
271     winproc = (WNDPROC16)wndPtr->winproc;
272     painting = (msg->message == WM_PAINT);
273     if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
274     WIN_ReleaseWndPtr( wndPtr );
275
276     SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message, msg->wParam, msg->lParam );
277     retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
278     SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam );
279
280     if (!painting) return retval;
281
282     if ((wndPtr = WIN_FindWndPtr( msg->hwnd )))
283     {
284         if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
285         {
286             ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
287             wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
288             /* Validate the update region to avoid infinite WM_PAINT loop */
289             RedrawWindow( wndPtr->hwndSelf, NULL, 0,
290                           RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
291         }
292         WIN_ReleaseWndPtr( wndPtr );
293     }
294     return retval;
295 }
296
297
298 /***********************************************************************
299  *              DispatchMessage32 (USER.822)
300  */
301 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
302 {
303     if (wHaveParamHigh == FALSE)
304         return DispatchMessage16( &msg16->msg );
305     else
306     {
307         MSG msg;
308
309         msg.hwnd    = msg16->msg.hwnd;
310         msg.message = msg16->msg.message;
311         msg.wParam  = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
312         msg.lParam  = msg16->msg.lParam;
313         msg.time    = msg16->msg.time;
314         msg.pt.x    = msg16->msg.pt.x;
315         msg.pt.y    = msg16->msg.pt.y;
316         return DispatchMessageA( &msg );
317     }
318 }
319
320
321 /***********************************************************************
322  *              MsgWaitForMultipleObjects  (USER.640)
323  */
324 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
325                                           BOOL wait_all, DWORD timeout, DWORD mask )
326 {
327     return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
328                                         wait_all ? MWMO_WAITALL : 0 );
329 }
330
331
332 /**********************************************************************
333  *              SetDoubleClickTime (USER.20)
334  */
335 void WINAPI SetDoubleClickTime16( UINT16 interval )
336 {
337     SetDoubleClickTime( interval );
338 }
339
340
341 /**********************************************************************
342  *              GetDoubleClickTime (USER.21)
343  */
344 UINT16 WINAPI GetDoubleClickTime16(void)
345 {
346     return GetDoubleClickTime();
347 }
348
349
350 /***********************************************************************
351  *              PostQuitMessage (USER.6)
352  */
353 void WINAPI PostQuitMessage16( INT16 exitCode )
354 {
355     PostQuitMessage( exitCode );
356 }
357
358
359 /***********************************************************************
360  *              SetMessageQueue (USER.266)
361  */
362 BOOL16 WINAPI SetMessageQueue16( INT16 size )
363 {
364     return SetMessageQueue( size );
365 }
366
367
368 /***********************************************************************
369  *              GetQueueStatus (USER.334)
370  */
371 DWORD WINAPI GetQueueStatus16( UINT16 flags )
372 {
373     return GetQueueStatus( flags );
374 }
375
376
377 /***********************************************************************
378  *              GetInputState (USER.335)
379  */
380 BOOL16 WINAPI GetInputState16(void)
381 {
382     return GetInputState();
383 }