source: trunk/src/user32/oslibmsgtranslate.cpp@ 3603

Last change on this file since 3603 was 3603, checked in by sandervl, 25 years ago

experimental WM_NCHITTEST generation (disabled) + MDI fixes

File size: 31.6 KB
Line 
1/* $Id: oslibmsgtranslate.cpp,v 1.31 2000-05-24 19:30:05 sandervl Exp $ */
2/*
3 * Window message translation functions for OS/2
4 *
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1999 Daniela Engert (dani@ngrt.de)
8 * Copyright 1999 Rene Pronk (R.Pronk@twi.tudelft.nl)
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 * TODO: Extra msgs: which messages must be put into the queue and which can be sent directly?
13 * (According to the docs TranslateMessage really inserts a msg in the queue)
14 * TODO: Filter translation isn't correct for posted messages
15 *
16 */
17#define INCL_WIN
18#define INCL_PM
19#define INCL_DOSPROCESS
20#include <os2wrap.h>
21#include <string.h>
22#include <misc.h>
23#include <winconst.h>
24#include "oslibmsg.h"
25#include "win32wnd.h"
26#include "win32wdesktop.h"
27#include "oslibutil.h"
28#include "timer.h"
29#include <thread.h>
30#include <wprocess.h>
31#include "pmwindow.h"
32#include "oslibwin.h"
33#include "winmouse.h"
34
35#define DBG_LOCALLOG DBG_oslibmsgtranslate
36#include "dbglocal.h"
37
38//Used for key translation while processing WM_CHAR message
39USHORT virtualKeyTable [66] = {
40 0x00, // OS/2 VK Win32 VK, Entry 0 is not used
41 0x01, // VK_BUTTON1 VK_LBUTTON
42 0x02, // VK_BUTTON2 VK_RBUTTON
43 0x04, // VK_BUTTON3 VK_MBUTTON
44 0x03, // VK_BREAK VK_CANCEL
45 0x08, // VK_BACKSPACE VK_BACK
46 0x09, // VK_TAB VK_TAB
47 0x00, // VK_BACKTAB No equivalent!
48 0x0D, // VK_NEWLINE VK_RETURN
49 0x10, // VK_SHIFT VK_SHIFT
50 0x11, // VK_CTRL VK_CONTROL
51 0x12, // VK_ALT VK_MENU, best match I guess
52 0x12, // VK_ALTGRAF VK_MENU, best match I guess
53 0x13, // VK_PAUSE VK_PAUSE
54 0x14, // VK_CAPSLOCK VK_CAPITAL
55 0x1B, // VK_ESC VK_ESCAPE
56 0x20, // VK_SPACE VK_SPACE
57 0x21, // VK_PAGEUP VK_PRIOR
58 0x22, // VK_PAGEDOWN VK_NEXT
59 0x23, // VK_END VK_END
60 0x24, // VK_HOME VK_HOME
61 0x25, // VK_LEFT VK_LEFT
62 0x26, // VK_UP VK_UP
63 0x27, // VK_RIGHT VK_RIGHT
64 0x28, // VK_DOWN VK_DOWN
65 0x2C, // VK_PRINTSCRN VK_SNAPSHOT
66 0x2D, // VK_INSERT VK_INSERT
67 0x2E, // VK_DELETE VK_DELETE
68 0x91, // VK_SCRLLOCK VK_SCROLL
69 0x90, // VK_NUMLOCK VK_NUMLOCK
70 0x0D, // VK_ENTER VK_RETURN
71 0x00, // VK_SYSRQ No equivalent!
72 0x70, // VK_F1 VK_F1
73 0x71, // VK_F2 VK_F2
74 0x72, // VK_F3 VK_F3
75 0x73, // VK_F4 VK_F4
76 0x74, // VK_F5 VK_F5
77 0x75, // VK_F6 VK_F6
78 0x76, // VK_F7 VK_F7
79 0x77, // VK_F8 VK_F8
80 0x78, // VK_F9 VK_F9
81 0x79, // VK_F10 VK_F10
82 0x7A, // VK_F11 VK_F11
83 0x7B, // VK_F12 VK_F12
84 0x7C, // VK_F13 VK_F13
85 0x7D, // VK_F14 VK_F14
86 0x7E, // VK_F15 VK_F15
87 0x7F, // VK_F16 VK_F16
88 0x80, // VK_F17 VK_F17
89 0x81, // VK_F18 VK_F18
90 0x82, // VK_F19 VK_F19
91 0x83, // VK_F20 VK_F20
92 0x84, // VK_F21 VK_F21
93 0x85, // VK_F22 VK_F22
94 0x86, // VK_F23 VK_F23
95 0x87, // VK_F24 VK_F24
96 0x00, // VK_ENDDRAG No equivalent!
97 0x0C, // VK_CLEAR VK_CLEAR
98 0xF9, // VK_EREOF VK_EREOF
99 0xFD, // VK_PA1 VK_PA1
100 0xF6, // VK_ATTN VK_ATTN
101 0xF7, // VK_CRSEL VK_CRSEL
102 0xF8, // VK_EXSEL VK_EXSEL
103 0x00, // VK_COPY No equivalent!
104 0x00, // VK_BLK1 No equivalent!
105 0x00}; // VK_BLK2 No equivalent!
106
107//******************************************************************************
108//******************************************************************************
109ULONG GetMouseKeyState()
110{
111 ULONG keystate = 0;
112
113 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
114 keystate |= MK_LBUTTON_W;
115 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
116 keystate |= MK_RBUTTON_W;
117 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
118 keystate |= MK_MBUTTON_W;
119 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000)
120 keystate |= MK_SHIFT_W;
121 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
122 keystate |= MK_CONTROL_W;
123
124 return keystate;
125}
126//******************************************************************************
127//******************************************************************************
128LONG IsNCMouseMsg(Win32BaseWindow *win32wnd)
129{
130 return ((win32wnd->getLastHitTestVal() != HTCLIENT_W) && (WinQueryCapture(HWND_DESKTOP) != win32wnd->getOS2WindowHandle()));
131}
132//******************************************************************************
133//******************************************************************************
134BOOL OS2ToWinMsgTranslate(void *pThdb, QMSG *os2Msg, MSG *winMsg, BOOL isUnicode, BOOL fMsgRemoved)
135{
136 Win32BaseWindow *win32wnd = 0;
137 OSLIBPOINT point, ClientPoint;
138 POSTMSG_PACKET *packet;
139 THDB *thdb = (THDB *)pThdb;
140 BOOL fWasDisabled = FALSE;
141 int i;
142
143 memset(winMsg, 0, sizeof(MSG));
144 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(os2Msg->hwnd);
145 if (!win32wnd) win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(os2Msg->hwnd);
146
147 //PostThreadMessage posts WIN32APP_POSTMSG msg without window handle
148 //Realplayer starts a timer with hwnd 0 & proc 0; check this here
149 if(win32wnd == 0 && (os2Msg->msg != WM_CREATE && os2Msg->msg != WM_QUIT && os2Msg->msg != WM_TIMER && os2Msg->msg != WIN32APP_POSTMSG))
150 {
151 goto dummymessage; //not a win32 client window
152 }
153 winMsg->time = os2Msg->time;
154 //CB: PM bug or undocumented feature? ptl.x highword is set!
155 winMsg->pt.x = os2Msg->ptl.x & 0xFFFF;
156 winMsg->pt.y = mapScreenY(os2Msg->ptl.y);
157
158 if(win32wnd) //==0 for WM_CREATE/WM_QUIT
159 winMsg->hwnd = win32wnd->getWindowHandle();
160
161 if (win32wnd && (os2Msg->hwnd == win32wnd->getOS2FrameWindowHandle()))
162 {
163 //special frame messages
164
165 switch (os2Msg->msg)
166 {
167 case WM_HITTEST:
168 winMsg->message = WINWM_NCHITTEST;
169 winMsg->wParam = 0;
170 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
171
172 if(!win32wnd->IsWindowEnabled()) {
173 if(win32wnd->getParent()) {
174 winMsg->hwnd = win32wnd->getParent()->getWindowHandle();
175 }
176 else goto dummymessage; //don't send mouse messages to disabled windows
177 }
178 return TRUE;
179
180 case WM_BUTTON1DOWN:
181 case WM_BUTTON1UP:
182 case WM_BUTTON1DBLCLK:
183 case WM_BUTTON2DOWN:
184 case WM_BUTTON2UP:
185 case WM_BUTTON2DBLCLK:
186 case WM_BUTTON3DOWN:
187 case WM_BUTTON3UP:
188 case WM_BUTTON3DBLCLK:
189 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
190
191#ifdef ODIN_HITTEST
192 //Send WM_HITTEST message
193 win32wnd->sendHitTest(MAKELONG(winMsg->pt.x,winMsg->pt.y));
194#endif
195
196 //if a window is disabled, it's parent receives the mouse messages
197 if(!win32wnd->IsWindowEnabled()) {
198 if(win32wnd->getParent()) {
199 win32wnd = win32wnd->getParent();
200 }
201 dprintf(("Rerouting mouse messages to parent %x of disabled window %x", win32wnd->getWindowHandle(), winMsg->hwnd));
202 fWasDisabled = TRUE;
203 }
204
205 if (IsNCMouseMsg(win32wnd)) {
206 winMsg->message = WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
207 winMsg->wParam = win32wnd->getLastHitTestVal();
208 winMsg->lParam = MAKELONG(winMsg->pt.x, winMsg->pt.y); //screen coordinates
209 }
210 else {
211 point.x = (*(POINTS *)&os2Msg->mp1).x;
212 point.y = (*(POINTS *)&os2Msg->mp1).y;
213 ClientPoint.x = point.x;
214 ClientPoint.y = mapOS2ToWin32Y(os2Msg->hwnd,win32wnd->getOS2WindowHandle(),point.y);
215
216 winMsg->message = WINWM_LBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
217 winMsg->wParam = GetMouseKeyState();
218 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
219 }
220 if(ISMOUSE_CAPTURED())
221 {
222 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
223 goto dummymessage; //dinput swallowed message
224 }
225 }
226 if(fWasDisabled) {
227 if(win32wnd) {
228 winMsg->hwnd = win32wnd->getWindowHandle();
229 }
230 else goto dummymessage; //don't send mouse messages to disabled windows
231 }
232 return TRUE;
233
234 case WM_BUTTON2MOTIONSTART:
235 case WM_BUTTON2MOTIONEND:
236 case WM_BUTTON2CLICK:
237 case WM_BUTTON1MOTIONSTART:
238 case WM_BUTTON1MOTIONEND:
239 case WM_BUTTON1CLICK:
240 case WM_BUTTON3MOTIONSTART:
241 case WM_BUTTON3MOTIONEND:
242 case WM_BUTTON3CLICK:
243 goto dummymessage;
244
245 case WM_MOUSEMOVE:
246 {
247 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
248
249#ifdef ODIN_HITTEST
250 //Send WM_HITTEST message
251 win32wnd->sendHitTest(MAKELONG(winMsg->pt.x,winMsg->pt.y));
252#endif
253 //if a window is disabled, it's parent receives the mouse messages
254 if(!win32wnd->IsWindowEnabled()) {
255 if(win32wnd->getParent()) {
256 win32wnd = win32wnd->getParent();
257 }
258 dprintf(("Rerouting mouse messages to parent %x of disabled window %x", win32wnd->getWindowHandle(), winMsg->hwnd));
259 fWasDisabled = TRUE;
260 }
261 if (IsNCMouseMsg(win32wnd))
262 {
263 winMsg->message = WINWM_NCMOUSEMOVE;
264 winMsg->wParam = (WPARAM)win32wnd->getLastHitTestVal();
265 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
266 }
267 else
268 {
269 winMsg->message = WINWM_MOUSEMOVE;
270 winMsg->wParam = GetMouseKeyState();
271 winMsg->lParam = MAKELONG(SHORT1FROMMP(os2Msg->mp1),mapOS2ToWin32Y(win32wnd->getOS2FrameWindowHandle(),win32wnd->getOS2WindowHandle(),SHORT2FROMMP(os2Msg->mp1)));
272 }
273 if(ISMOUSE_CAPTURED())
274 {
275 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
276 goto dummymessage; //dinput swallowed message
277 }
278 }
279 if(fWasDisabled) {
280 if(win32wnd) {
281 winMsg->hwnd = win32wnd->getWindowHandle();
282 }
283 else goto dummymessage; //don't send mouse messages to disabled windows
284 }
285 //OS/2 Window coordinates -> Win32 Window coordinates
286 return TRUE;
287 }
288
289 case WM_PAINT:
290 {
291 winMsg->message = WINWM_NCPAINT;
292 return TRUE;
293 }
294
295 case WM_ACTIVATE:
296 {
297 winMsg->message = WINWM_NCACTIVATE;
298 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
299
300 return TRUE;
301 }
302 case WM_WINDOWPOSCHANGED:
303 {
304 //todo: proper translation
305 return FALSE;
306 }
307 }
308 //do normal translation for all other messages
309 }
310
311 switch(os2Msg->msg)
312 {
313 case WIN32APP_POSTMSG:
314 {
315 packet = (POSTMSG_PACKET *)os2Msg->mp2;
316 if(packet && ((ULONG)os2Msg->mp1 == WIN32MSG_MAGICA || (ULONG)os2Msg->mp1 == WIN32MSG_MAGICW)) {
317 winMsg->message = packet->Msg;
318 winMsg->wParam = packet->wParam;
319 winMsg->lParam = packet->lParam;
320 if(fMsgRemoved == MSG_REMOVE) free(packet); //free the shared memory here
321 break;
322 }
323 goto dummymessage;
324 }
325
326 //OS/2 msgs
327 case WM_CREATE:
328 {
329 if(thdb->newWindow == 0) {
330 DebugInt3();
331 goto dummymessage;
332 }
333
334 win32wnd = (Win32BaseWindow *)thdb->newWindow;
335
336 winMsg->message = WINWM_CREATE;
337 winMsg->hwnd = win32wnd->getWindowHandle();
338 winMsg->wParam = 0;
339 winMsg->lParam = (LPARAM)win32wnd->tmpcs;
340 break;
341 }
342
343 case WM_QUIT:
344 winMsg->message = WINWM_QUIT;
345 break;
346
347 case WM_CLOSE:
348 winMsg->message = WINWM_CLOSE;
349 break;
350
351 case WM_DESTROY:
352 winMsg->message = WINWM_DESTROY;
353 break;
354
355 case WM_ENABLE:
356 winMsg->message = WINWM_ENABLE;
357 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
358 break;
359
360 case WM_SHOW:
361 winMsg->message = WINWM_SHOWWINDOW;
362 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
363 break;
364
365 case WM_WINDOWPOSCHANGED:
366 {
367 PSWP pswp = (PSWP)os2Msg->mp1;
368 SWP swpOld = *(pswp + 1);
369 HWND hParent = NULLHANDLE;
370 LONG yDelta = pswp->cy - swpOld.cy;
371 LONG xDelta = pswp->cx - swpOld.cx;
372
373 dprintf(("OS2: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
374
375 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto dummymessage;
376
377 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
378 if (win32wnd->isChild()) {
379 if(win32wnd->getParent()) {
380 hParent = win32wnd->getParent()->getOS2WindowHandle();
381 }
382 else goto dummymessage; //parent has just been destroyed
383 }
384 }
385 OSLibMapSWPtoWINDOWPOS(pswp, &thdb->wp, &swpOld, hParent, win32wnd->getOS2FrameWindowHandle());
386
387 if (!win32wnd->CanReceiveSizeMsgs()) goto dummymessage;
388
389 ULONG windowStyle = WinQueryWindowULong(os2Msg->hwnd, QWL_STYLE);
390 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MAXIMIZE_W|WS_MINIMIZE_W));
391 if (windowStyle & WS_MINIMIZED) {
392 win32wnd->setStyle(win32wnd->getStyle() | WS_MINIMIZE_W);
393 }
394 else
395 if (windowStyle & WS_MAXIMIZED) {
396 win32wnd->setStyle(win32wnd->getStyle() | WS_MAXIMIZE_W);
397 }
398
399 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
400 dprintf(("Set client rectangle to (%d,%d)(%d,%d)", swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy));
401 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
402
403 thdb->wp.hwnd = win32wnd->getWindowHandle();
404 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
405 {
406 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
407 if(wndAfter)
408 thdb->wp.hwndInsertAfter = wndAfter->getWindowHandle();
409 }
410
411 PRECT lpRect = win32wnd->getWindowRect();
412 //SvL: Only send it when the client has changed & the frame hasn't
413 // If the frame size/position has changed, pmframe.cpp will send
414 // this message
415 if(lpRect->right == thdb->wp.x+thdb->wp.cx && lpRect->bottom == thdb->wp.y+thdb->wp.cy) {
416 winMsg->message = WINWM_WINDOWPOSCHANGED;
417 winMsg->lParam = (LPARAM)&thdb->wp;
418 break;
419 }
420 }
421 goto dummymessage;
422 }
423
424 case WM_ACTIVATE:
425 {
426 HWND hwndActivate = (HWND)os2Msg->mp2;
427 BOOL fMinimized = FALSE;
428
429 hwndActivate = Win32BaseWindow::OS2ToWin32Handle(hwndActivate);
430 if(hwndActivate == 0) {
431 //another (non-win32) application's window
432 //set to desktop window handle
433 hwndActivate = windowDesktop->getWindowHandle();
434 }
435
436 if(WinQueryWindowULong(os2Msg->hwnd, QWL_STYLE) & WS_MINIMIZED)
437 {
438 fMinimized = TRUE;
439 }
440
441 winMsg->message = WINWM_ACTIVATE;
442 winMsg->wParam = MAKELONG((SHORT1FROMMP(os2Msg->mp1)) ? WA_ACTIVE_W : WA_INACTIVE_W, fMinimized);
443 winMsg->lParam = (LPARAM)hwndActivate;
444 break;
445 }
446
447 case WM_SETFOCUS:
448 {
449 HWND hwndFocus = (HWND)os2Msg->mp1;
450
451 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
452 //another (non-win32) application's window
453 //set to NULL (allowed according to win32 SDK) to avoid problems
454 hwndFocus = NULL;
455 }
456 else hwndFocus = Win32BaseWindow::OS2ToWin32Handle(hwndFocus);
457
458 if((ULONG)os2Msg->mp2 == TRUE) {
459 winMsg->message = WINWM_SETFOCUS;
460 winMsg->wParam = (WPARAM)hwndFocus;
461 }
462 else {
463 winMsg->message = WINWM_KILLFOCUS;
464 winMsg->wParam = (WPARAM)hwndFocus;
465 }
466 break;
467 }
468
469 //**************************************************************************
470 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
471 //**************************************************************************
472 case WM_HITTEST:
473 winMsg->message = WINWM_NCHITTEST;
474 winMsg->wParam = 0;
475 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
476 if(!win32wnd->IsWindowEnabled()) {
477 if(win32wnd->getParent()) {
478 winMsg->hwnd = win32wnd->getParent()->getWindowHandle();
479 }
480 else goto dummymessage; //don't send mouse messages to disabled windows
481 }
482 break;
483
484 case WM_BUTTON1DOWN:
485 case WM_BUTTON1UP:
486 case WM_BUTTON1DBLCLK:
487 case WM_BUTTON2DOWN:
488 case WM_BUTTON2UP:
489 case WM_BUTTON2DBLCLK:
490 case WM_BUTTON3DOWN:
491 case WM_BUTTON3UP:
492 case WM_BUTTON3DBLCLK:
493 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
494
495#ifdef ODIN_HITTEST
496 //Send WM_HITTEST message
497 win32wnd->sendHitTest(MAKELONG(winMsg->pt.x,winMsg->pt.y));
498#endif
499
500 //if a window is disabled, it's parent receives the mouse messages
501 if(!win32wnd->IsWindowEnabled()) {
502 if(win32wnd->getParent()) {
503 win32wnd = win32wnd->getParent();
504 }
505 fWasDisabled = TRUE;
506 }
507
508 if(IsNCMouseMsg(win32wnd)) {
509 winMsg->message = WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
510 winMsg->wParam = win32wnd->getLastHitTestVal();
511 winMsg->lParam = MAKELONG(winMsg->pt.x, winMsg->pt.y); //screen coordinates
512 }
513 else {
514 point.x = (*(POINTS *)&os2Msg->mp1).x;
515 point.y = (*(POINTS *)&os2Msg->mp1).y;
516 ClientPoint.x = point.x;
517 ClientPoint.y = mapY(os2Msg->hwnd,point.y);
518
519 winMsg->message = WINWM_LBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
520 winMsg->wParam = GetMouseKeyState();
521 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
522 }
523 if(ISMOUSE_CAPTURED())
524 {
525 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
526 goto dummymessage; //dinput swallowed message
527 }
528 }
529
530 if(fWasDisabled) {
531 if(win32wnd) {
532 winMsg->hwnd = win32wnd->getWindowHandle();
533 }
534 else goto dummymessage; //don't send mouse messages to disabled windows
535 }
536 break;
537
538 case WM_BUTTON2MOTIONSTART:
539 case WM_BUTTON2MOTIONEND:
540 case WM_BUTTON2CLICK:
541 case WM_BUTTON1MOTIONSTART:
542 case WM_BUTTON1MOTIONEND:
543 case WM_BUTTON1CLICK:
544 case WM_BUTTON3MOTIONSTART:
545 case WM_BUTTON3MOTIONEND:
546 case WM_BUTTON3CLICK:
547 goto dummymessage;
548
549 case WM_MOUSEMOVE:
550 {
551 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
552
553#ifdef ODIN_HITTEST
554 //Send WM_HITTEST message
555 win32wnd->sendHitTest(MAKELONG(winMsg->pt.x,winMsg->pt.y));
556#endif
557
558 //if a window is disabled, it's parent receives the mouse messages
559 if(!win32wnd->IsWindowEnabled()) {
560 if(win32wnd->getParent()) {
561 win32wnd = win32wnd->getParent();
562 }
563 fWasDisabled = TRUE;
564 }
565 if(IsNCMouseMsg(win32wnd))
566 {
567 winMsg->message = WINWM_NCMOUSEMOVE;
568 winMsg->wParam = (WPARAM)win32wnd->getLastHitTestVal();
569 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
570 }
571 else
572 {
573 winMsg->message = WINWM_MOUSEMOVE;
574 winMsg->wParam = GetMouseKeyState();
575 winMsg->lParam = MAKELONG(SHORT1FROMMP(os2Msg->mp1),mapY(win32wnd,SHORT2FROMMP(os2Msg->mp1)));
576 }
577 if(ISMOUSE_CAPTURED())
578 {
579 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
580 goto dummymessage; //dinput swallowed message
581 }
582 }
583 if(fWasDisabled) {
584 if(win32wnd) {
585 winMsg->hwnd = win32wnd->getWindowHandle();
586 }
587 else goto dummymessage; //don't send mouse messages to disabled windows
588 }
589 //OS/2 Window coordinates -> Win32 Window coordinates
590 break;
591 }
592
593 case WM_CONTROL:
594 goto dummymessage;
595
596 case WM_COMMAND:
597 if(SHORT1FROMMP(os2Msg->mp2) == CMDSRC_MENU) {
598 winMsg->message = WINWM_COMMAND;
599 winMsg->wParam = (WPARAM)SHORT1FROMMP(os2Msg->mp1); //id
600 break;
601 }
602 //todo controls
603 goto dummymessage;
604
605 case WM_SYSCOMMAND:
606 {
607 ULONG x = 0, y = 0;
608 ULONG win32sc;
609
610 if(SHORT2FROMMP(os2Msg->mp2) == TRUE) {//syscommand caused by mouse action
611 POINTL pointl;
612 WinQueryPointerPos(HWND_DESKTOP, &pointl);
613 x = pointl.x;
614 y = mapScreenY(y);
615 }
616 switch(SHORT1FROMMP(os2Msg->mp1)) {
617 case SC_MOVE:
618 win32sc = SC_MOVE_W;
619 break;
620 case SC_CLOSE:
621 win32sc = SC_CLOSE_W;
622 break;
623 case SC_MAXIMIZE:
624 win32sc = SC_MAXIMIZE_W;
625 break;
626 case SC_MINIMIZE:
627 win32sc = SC_MINIMIZE_W;
628 break;
629 case SC_NEXTFRAME:
630 case SC_NEXTWINDOW:
631 win32sc = SC_NEXTWINDOW_W;
632 break;
633 case SC_RESTORE:
634 win32sc = SC_RESTORE_W;
635 break;
636 case SC_TASKMANAGER:
637 win32sc = SC_TASKLIST_W;
638 break;
639 default:
640 goto dummymessage;
641 }
642 winMsg->message = WINWM_SYSCOMMAND;
643 winMsg->wParam = (WPARAM)win32sc;
644 winMsg->lParam = MAKELONG((USHORT)x, (USHORT)y);
645 break;
646 }
647 case WM_CHAR:
648 {
649 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
650 ULONG flags = SHORT1FROMMP(os2Msg->mp1);
651 BOOL keyWasPressed;
652 char c;
653
654 thdb->fTranslated = FALSE;
655 repeatCount = CHAR3FROMMP(os2Msg->mp1);
656 scanCode = CHAR4FROMMP(os2Msg->mp1);
657 keyWasPressed = ((SHORT1FROMMP (os2Msg->mp1) & KC_PREVDOWN) == KC_PREVDOWN);
658
659 dprintf(("PM: WM_CHAR: %x %x %d %x", SHORT1FROMMP(os2Msg->mp2), SHORT2FROMMP(os2Msg->mp2), repeatCount, scanCode));
660 dprintf(("PM: WM_CHAR: hwnd %x flags %x", win32wnd->getWindowHandle(), flags));
661
662 // vitali add begin
663 if ( ( SHORT1FROMMP(os2Msg->mp2) & 0x0FF ) == 0x0E0 )
664 {
665 // an extended key ( arrows, ins, del and so on )
666 // get "virtual" scancode from character code cause
667 // for "regular" keys they are equal
668 scanCode = ( SHORT1FROMMP(os2Msg->mp2) >> 8) & 0x0FF;
669 }
670 // vitali add end
671
672 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
673 // given the OS/2 virtual key and OS/2 character
674
675 //if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
676 // ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
677 c = 0;
678 if ((SHORT1FROMMP (os2Msg->mp1) & 0xFF) != 0)
679 {
680 c = SHORT1FROMMP (os2Msg->mp2);
681 if ((c >= 'A') && (c <= 'Z')) {
682 virtualKey = c;
683 goto VirtualKeyFound;
684 }
685 if ((c >='a') && (c <= 'z')) {
686 virtualKey = c - 32; // make it uppercase
687 goto VirtualKeyFound;
688 }
689 if ((c >= '0') && (c <= '9')) {
690 virtualKey = c;
691 goto VirtualKeyFound;
692 }
693 }
694
695 // convert OS/2 virtual keys to Win32 virtual key
696 if (SHORT2FROMMP (os2Msg->mp2) <= VK_BLK2)
697 virtualKey = virtualKeyTable [SHORT2FROMMP (os2Msg->mp2)];
698
699VirtualKeyFound:
700 dprintf (("VIRTUALKEYFOUND:(%x)", virtualKey));
701
702 winMsg->wParam = virtualKey;
703 winMsg->lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
704 winMsg->lParam |= (scanCode & 0x0FF) << 16; // bit 16-23, scancode
705
706 //TODO: Is this correct and complete? (how does PM differentiate between
707 // i.e numeric pad pgdn & 'normal' pgdn??)
708 //Check if it's an extended key
709 switch(virtualKey) {
710 case VK_RETURN_W:
711 //The enter key on the numeric keypad is an extended key
712 if(SHORT2FROMMP(os2Msg->mp2) != VK_NEWLINE)
713 break;
714 //no break
715 case VK_LEFT_W:
716 case VK_RIGHT_W:
717 case VK_DOWN_W:
718 case VK_UP_W:
719 case VK_PRIOR_W:
720 case VK_NEXT_W:
721 case VK_END_W:
722 case VK_DIVIDE_W:
723 case VK_DELETE_W:
724 case VK_HOME_W:
725 case VK_INSERT_W:
726 case VK_RCONTROL_W:
727 case VK_RMENU_W: //is this the right alt???
728 winMsg->lParam = winMsg->lParam | (1<<24);
729 break;
730 }
731
732 if(!(SHORT1FROMMP(os2Msg->mp1) & KC_ALT))
733 {
734 //
735 // the Alt key is not pressed
736 //
737 if ((flags & KC_KEYUP) == KC_KEYUP) {
738 // send WM_KEYUP message
739
740 winMsg->message = WINWM_KEYUP;
741 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
742 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
743 }
744 else {
745 // send WM_KEYDOWN message
746 winMsg->message = WINWM_KEYDOWN;
747 if (keyWasPressed)
748 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
749 }
750 }
751 else {
752 //
753 // the Alt key is pressed
754 //
755 if ((flags & KC_KEYUP) == KC_KEYUP) {
756 // send WM_SYSKEYUP message
757
758 winMsg->message = WINWM_SYSKEYUP;
759 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
760 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
761 }
762 else {
763 // send WM_SYSKEYDOWN message
764 winMsg->message = WINWM_SYSKEYDOWN;
765 if (keyWasPressed)
766 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
767 }
768 }
769 if(ISKDB_CAPTURED())
770 {
771 if(DInputKeyBoardHandler(winMsg)) {
772 goto dummymessage; //dinput swallowed message
773 }
774 }
775 break;
776 }
777
778 case WM_TIMER:
779 if (os2Msg->mp2)
780 {
781 BOOL sys;
782 ULONG id;
783
784 if (TIMER_GetTimerInfo(os2Msg->hwnd,(ULONG)os2Msg->mp1,&sys,&id))
785 {
786 winMsg->wParam = (WPARAM)id;
787 winMsg->message= (sys) ? WINWM_SYSTIMER : WINWM_TIMER;
788 break;
789 }
790 }
791 goto dummymessage; //for caret blinking
792
793 case WM_SETWINDOWPARAMS:
794 {
795 WNDPARAMS *wndParams = (WNDPARAMS *)os2Msg->mp1;
796
797 if(wndParams->fsStatus & WPM_TEXT) {
798 winMsg->message = WINWM_SETTEXT;
799 winMsg->lParam = (LPARAM)wndParams->pszText;
800 break;
801 }
802 goto dummymessage;
803 }
804
805#if 0
806 case WM_QUERYWINDOWPARAMS:
807 {
808 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
809 ULONG textlen;
810 PSZ wintext;
811
812 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
813 {
814 if(wndpars->fsStatus & WPM_CCHTEXT)
815 wndpars->cchText = win32wnd->MsgGetTextLength();
816 if(wndpars->fsStatus & WPM_TEXT)
817 wndpars->pszText = win32wnd->MsgGetText();
818
819 wndpars->fsStatus = 0;
820 wndpars->cbCtlData = 0;
821 wndpars->cbPresParams = 0;
822 goto dummymessage;
823 }
824 }
825#endif
826
827 case WM_PAINT:
828 {
829 if(win32wnd->IsWindowIconic()) {
830 winMsg->message = WINWM_PAINTICON;
831 }
832 else winMsg->message = WINWM_PAINT;
833 break;
834 }
835
836 case WM_CONTEXTMENU:
837 winMsg->message = WINWM_CONTEXTMENU;
838 winMsg->wParam = win32wnd->getWindowHandle();
839 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
840 break;
841
842 case WM_INITMENU:
843 case WM_MENUSELECT:
844 case WM_MENUEND:
845 case WM_NEXTMENU:
846 case WM_SYSCOLORCHANGE:
847 case WM_SYSVALUECHANGED:
848 case WM_SETSELECTION:
849 case WM_PPAINT:
850 case WM_PSETFOCUS:
851 case WM_PSYSCOLORCHANGE:
852 case WM_PSIZE:
853 case WM_PACTIVATE:
854 case WM_PCONTROL:
855 case WM_HELP:
856 case WM_APPTERMINATENOTIFY:
857 case WM_PRESPARAMCHANGED:
858 case WM_DRAWITEM:
859 case WM_MEASUREITEM:
860 case WM_CONTROLPOINTER:
861 case WM_QUERYDLGCODE:
862 case WM_SUBSTITUTESTRING:
863 case WM_MATCHMNEMONIC:
864 case WM_SAVEAPPLICATION:
865 case WM_SEMANTICEVENT:
866 default:
867dummymessage:
868 winMsg->message = 0;
869 winMsg->wParam = 0;
870 winMsg->lParam = 0;
871 return FALSE;
872 }
873 return TRUE;
874}
875//******************************************************************************
876//******************************************************************************
877BOOL OSLibWinTranslateMessage(MSG *msg)
878{
879 THDB *thdb;
880
881 thdb = GetThreadTHDB();
882 if(!thdb) {
883 return FALSE;
884 }
885 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
886 // the newly generated WM_CHAR message.
887 if(!thdb->fTranslated && thdb->os2msg.msg == WM_CHAR && !((SHORT1FROMMP(thdb->os2msg.mp1) & KC_KEYUP) == KC_KEYUP))
888 {//TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
889 ULONG fl = SHORT1FROMMP(thdb->os2msg.mp1);
890 MSG extramsg;
891
892 memcpy(&extramsg, msg, sizeof(MSG));
893 extramsg.wParam = SHORT1FROMMP(thdb->os2msg.mp2);
894 extramsg.lParam = 0;
895
896 if(!(fl & KC_CHAR)) {
897 return FALSE;
898 }
899
900 if(fl & KC_VIRTUALKEY) {
901 if(msg->wParam)
902 extramsg.wParam = msg->wParam;
903 else extramsg.wParam = SHORT2FROMMP(thdb->os2msg.mp2);
904 }
905
906 if(msg->message >= WINWM_SYSKEYDOWN) {
907 extramsg.message = WINWM_SYSCHAR;
908 }
909 else extramsg.message = WINWM_CHAR;
910
911 if(fl & KC_DEADKEY) {
912 extramsg.message++; //WM_DEADCHAR/WM_SYSDEADCHAR
913 }
914
915 extramsg.lParam = msg->lParam & 0x00FFFFFF;
916 if(fl & KC_ALT)
917 extramsg.lParam |= (1<<29);
918 if(fl & KC_PREVDOWN)
919 extramsg.lParam |= (1<<30);
920 if(fl & KC_KEYUP)
921 extramsg.lParam |= (1<<31);
922
923 thdb->fTranslated = TRUE;
924 memcpy(&thdb->msgWCHAR, &extramsg, sizeof(MSG));
925 return TRUE;
926 }
927 return FALSE;
928}
929//******************************************************************************
930//******************************************************************************
931
Note: See TracBrowser for help on using the repository browser.