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

Last change on this file since 7155 was 7155, checked in by phaller, 24 years ago

added PM hook

File size: 30.9 KB
Line 
1/* $Id: oslibmsgtranslate.cpp,v 1.61 2001-10-22 23:14:32 phaller 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 <win32api.h>
25#include "oslibmsg.h"
26#include <winuser32.h>
27#include "win32wdesktop.h"
28#include "oslibutil.h"
29#include "timer.h"
30#include <thread.h>
31#include <wprocess.h>
32#include "pmwindow.h"
33#include "oslibwin.h"
34#include "winmouse.h"
35#include <pmkbdhk.h>
36
37#define DBG_LOCALLOG DBG_oslibmsgtranslate
38#include "dbglocal.h"
39
40// Formerly used method of translation based on OS/2 VKEY value didn't work
41// right. We need to take a look at the scan code we get from PM and derive
42// the Win32 VKEY and scancode from that because sometimes even the scancode
43// used in Win32 is different from the PM scancode!
44// The format is:
45// Win VKEY, Win scancode, (PM scancode) (key description)
46USHORT pmscan2winkey [][2] = {
47 0, 0, // 0x00
48 0x1B, 0x01, // 0x01 Esc
49 0x31, 0x02, // 0x02 1
50 0x32, 0x03, // 0x03 2
51 0x33, 0x04, // 0x04 3
52 0x34, 0x05, // 0x05 4
53 0x35, 0x06, // 0x06 5
54 0x36, 0x07, // 0x07 6
55 0x37, 0x08, // 0x08 7
56 0x38, 0x09, // 0x09 8
57 0x39, 0x0A, // 0x0A 9
58 0x30, 0x0B, // 0x0B 0
59 0xBD, 0x0C, // 0x0C -
60 0xBB, 0x0D, // 0x0D =
61 0x08, 0x0E, // 0x0E Bksp
62 0x09, 0x0F, // 0x0F Tab
63 0x51, 0x10, // 0x10 q
64 0x57, 0x11, // 0x11 w
65 0x45, 0x12, // 0x12 e
66 0x52, 0x13, // 0x13 r
67 0x54, 0x14, // 0x14 t
68 0x59, 0x15, // 0x15 y
69 0x55, 0x16, // 0x16 u
70 0x49, 0x17, // 0x17 i
71 0x4F, 0x18, // 0x18 o
72 0x50, 0x19, // 0x19 p
73 0xDB, 0x1A, // 0x1A [
74 0xDD, 0x1B, // 0x1B ]
75 0x0D, 0x1C, // 0x1C Enter
76 0x11, 0x1D, // 0x1D LCtrl
77 0x41, 0x1E, // 0x1E a
78 0x53, 0x1F, // 0x1F s
79 0x44, 0x20, // 0x20 d
80 0x46, 0x21, // 0x21 f
81 0x47, 0x22, // 0x22 g
82 0x48, 0x23, // 0x23 h
83 0x4A, 0x24, // 0x24 j
84 0x4B, 0x25, // 0x25 k
85 0x4C, 0x26, // 0x26 l
86 0xBA, 0x27, // 0x27 ;
87 0xDE, 0x28, // 0x28 '
88 0xC0, 0x29, // 0x29 `
89 0x10, 0x2A, // 0x2A LShift
90 0xDC, 0x2B, // 0x2B Bkslsh
91 0x5A, 0x2C, // 0x2C z
92 0x58, 0x2D, // 0x2D x
93 0x43, 0x2E, // 0x2E c
94 0x56, 0x2F, // 0x2F v
95 0x42, 0x30, // 0x30 b
96 0x4E, 0x31, // 0x31 n
97 0x4D, 0x32, // 0x32 m
98 0xBC, 0x33, // 0x33 ,
99 0xBE, 0x34, // 0x34 .
100 0xBF, 0x35, // 0x35 /
101 0x10, 0x36, // 0x36 RShift
102 0x6A, 0x37, // 0x37 * Pad
103 0x12, 0x38, // 0x38 LAlt
104 0x20, 0x39, // 0x39 Space
105 0x14, 0x3A, // 0x3A CapsLk
106 0x70, 0x3B, // 0x3B F1
107 0x71, 0x3C, // 0x3C F2
108 0x72, 0x3D, // 0x3D F3
109 0x73, 0x3E, // 0x3E F4
110 0x74, 0x3F, // 0x3F F5
111 0x75, 0x40, // 0x40 F6
112 0x76, 0x41, // 0x41 F7
113 0x77, 0x42, // 0x42 F8
114 0x78, 0x43, // 0x43 F9
115 0x79, 0x44, // 0x44 F10 (?)
116 0x90, 0x145, // 0x45 NumLk
117 0x91, 0x46, // 0x46 ScrLk
118 0x24, 0x47, // 0x47 7 Pad
119 0x26, 0x48, // 0x48 8 Pad
120 0x21, 0x49, // 0x49 9 Pad
121 0x6D, 0x4A, // 0x4A - Pad
122 0x25, 0x4B, // 0x4B 4 Pad
123 0x0C, 0x4C, // 0x4C 5 Pad
124 0x27, 0x4D, // 0x4D 6 Pad
125 0x6B, 0x4E, // 0x4E + Pad
126 0x23, 0x4F, // 0x4F 1 Pad
127 0x28, 0x50, // 0x50 2 Pad
128 0x22, 0x51, // 0x51 3 Pad
129 0x2D, 0x52, // 0x52 0 Pad
130 0x2E, 0x53, // 0x53 . Pad
131 0, 0, // 0x54
132 0, 0, // 0x55
133 0, 0, // 0x56
134 0x7A, 0x57, // 0x57 F11
135 0x7B, 0x58, // 0x58 F12
136 0, 0, // 0x59
137 0x0D, 0x11C, // 0x5A Enter Pad
138 0x11, 0x11D, // 0x5B RCtrl
139 0x6F, 0x135, // 0x5C / Pad
140 0x2D, 0x152, // 0x5D PrtSc
141 0x12, 0x5E, // 0x5E RAlt
142 0x13, 0x45, // 0x5F Pause
143 VK_HOME_W, 0x60, // 0x60
144 VK_UP_W, 0x61, // 0x61
145 VK_PRIOR_W, 0x62, // 0x62
146 VK_LEFT_W, 0x63, // 0x63
147 VK_RIGHT_W, 0x64, // 0x64
148 VK_END_W, 0x65, // 0x65
149 VK_DOWN_W, 0x66, // 0x66
150 VK_NEXT_W, 0x67, // 0x67
151 VK_INSERT_W, 0x68, // 0x68
152 VK_DELETE_W, 0x69, // 0x69
153 VK_F23_W, 0x6A, // 0x6A
154 VK_F24_W, 0x6B, // 0x6B
155 0x5D, 0x15D, // 0x6C RWin (PM scan 0x7C)
156 0, 0, // 0x6D
157 0x5B, 0x15B, // 0x6E LWin (PM scan 0x7E)
158 0x5C, 0x15C // 0x6F RMenu? (PM scan 0x7F)
159};
160
161//******************************************************************************
162//******************************************************************************
163ULONG GetMouseKeyState()
164{
165 ULONG keystate = 0;
166
167 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
168 keystate |= MK_LBUTTON_W;
169 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
170 keystate |= MK_RBUTTON_W;
171 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
172 keystate |= MK_MBUTTON_W;
173 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000)
174 keystate |= MK_SHIFT_W;
175 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
176 keystate |= MK_CONTROL_W;
177
178 return keystate;
179}
180//******************************************************************************
181//******************************************************************************
182LONG IsNCMouseMsg(Win32BaseWindow *win32wnd)
183{
184 return ((win32wnd->getLastHitTestVal() != HTCLIENT_W) && (WinQueryCapture(HWND_DESKTOP) != win32wnd->getOS2WindowHandle()));
185}
186//******************************************************************************
187//******************************************************************************
188BOOL OS2ToWinMsgTranslate(void *pTeb, QMSG *os2Msg, MSG *winMsg, BOOL isUnicode, BOOL fMsgRemoved)
189{
190 Win32BaseWindow *win32wnd = 0;
191 OSLIBPOINT point, ClientPoint;
192 POSTMSG_PACKET *packet;
193 TEB *teb = (TEB *)pTeb;
194 BOOL fWasDisabled = FALSE;
195 BOOL fIsFrame = FALSE;
196 int i;
197
198 memset(winMsg, 0, sizeof(MSG));
199 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(os2Msg->hwnd);
200 if(!win32wnd) {
201 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(os2Msg->hwnd);
202 if(win32wnd) {
203 fIsFrame = TRUE;
204 }
205 }
206
207 //PostThreadMessage posts WIN32APP_POSTMSG msg without window handle
208 //Realplayer starts a timer with hwnd 0 & proc 0; check this here
209 if(win32wnd == 0 && (os2Msg->msg != WM_CREATE && os2Msg->msg != WM_QUIT && os2Msg->msg != WM_TIMER && os2Msg->msg < WIN32APP_POSTMSG))
210 {
211 goto dummymessage; //not a win32 client window
212 }
213 winMsg->time = os2Msg->time;
214 //CB: PM bug or undocumented feature? ptl.x highword is set!
215 winMsg->pt.x = os2Msg->ptl.x & 0xFFFF;
216 winMsg->pt.y = mapScreenY(os2Msg->ptl.y);
217
218 if(win32wnd) //==0 for WM_CREATE/WM_QUIT
219 winMsg->hwnd = win32wnd->getWindowHandle();
220
221 if(os2Msg->msg >= WIN32APP_POSTMSG) {
222 packet = (POSTMSG_PACKET *)os2Msg->mp2;
223 if(packet && ((ULONG)os2Msg->mp1 == WIN32MSG_MAGICA || (ULONG)os2Msg->mp1 == WIN32MSG_MAGICW)) {
224 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
225 winMsg->wParam = packet->wParam;
226 winMsg->lParam = packet->lParam;
227 if(fMsgRemoved == MSG_REMOVE) free(packet); //free the shared memory here
228 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
229 return TRUE;
230 }
231 else {//broadcasted message (no packet present)
232 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
233 winMsg->wParam = (UINT)os2Msg->mp1;
234 winMsg->lParam = (DWORD)os2Msg->mp2;
235 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
236 return TRUE;
237 }
238 goto dummymessage;
239 }
240
241 switch(os2Msg->msg)
242 {
243 //OS/2 msgs
244 case WM_CREATE:
245 {
246 if(teb->o.odin.newWindow == 0) {
247 DebugInt3();
248 goto dummymessage;
249 }
250
251 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
252 win32wnd->addRef();
253
254 winMsg->message = WINWM_CREATE;
255 winMsg->hwnd = win32wnd->getWindowHandle();
256 winMsg->wParam = 0;
257 winMsg->lParam = (LPARAM)win32wnd->tmpcs;
258 break;
259 }
260
261 case WM_QUIT:
262 winMsg->message = WINWM_QUIT;
263 break;
264
265 case WM_CLOSE:
266 winMsg->message = WINWM_CLOSE;
267 break;
268
269 case WM_DESTROY:
270 winMsg->message = WINWM_DESTROY;
271 break;
272
273 case WM_ENABLE:
274 winMsg->message = WINWM_ENABLE;
275 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
276 break;
277
278 case WM_SHOW:
279 winMsg->message = WINWM_SHOWWINDOW;
280 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
281 break;
282
283 case WM_WINDOWPOSCHANGED:
284 {
285 PSWP pswp = (PSWP)os2Msg->mp1;
286 SWP swpOld = *(pswp + 1);
287 HWND hParent = NULLHANDLE;
288 LONG yDelta = pswp->cy - swpOld.cy;
289 LONG xDelta = pswp->cx - swpOld.cx;
290
291 if(!fIsFrame) goto dummymessage;
292
293 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto dummymessage;
294
295 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
296 if (win32wnd->isChild()) {
297 if(win32wnd->getParent()) {
298 hParent = win32wnd->getParent()->getOS2WindowHandle();
299 }
300 else goto dummymessage; //parent has just been destroyed
301 }
302 }
303 if(win32wnd->getParent()) {
304 OSLibMapSWPtoWINDOWPOS(pswp, &teb->o.odin.wp, &swpOld, win32wnd->getParent()->getClientHeight(),
305 win32wnd->getOS2WindowHandle());
306 }
307 else OSLibMapSWPtoWINDOWPOS(pswp, &teb->o.odin.wp, &swpOld, OSLibQueryScreenHeight(), win32wnd->getOS2WindowHandle());
308
309 if (!win32wnd->CanReceiveSizeMsgs()) goto dummymessage;
310
311 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
312 {
313 teb->o.odin.wp.hwnd = win32wnd->getWindowHandle();
314 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
315 {
316 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
317 if(wndAfter) {
318 teb->o.odin.wp.hwndInsertAfter = wndAfter->getWindowHandle();
319 RELEASE_WNDOBJ(wndAfter);
320 }
321 else teb->o.odin.wp.hwndInsertAfter = HWND_TOP_W;
322 }
323 }
324 winMsg->message = WINWM_WINDOWPOSCHANGED;
325 winMsg->lParam = (LPARAM)&teb->o.odin.wp;
326 break;
327 }
328
329 case WM_ACTIVATE:
330 {
331 HWND hwndActivate = (HWND)os2Msg->mp2;
332 BOOL fMinimized = FALSE;
333
334 hwndActivate = OS2ToWin32Handle(hwndActivate);
335 if(hwndActivate == 0) {
336 //another (non-win32) application's window
337 //set to desktop window handle
338 hwndActivate = windowDesktop->getWindowHandle();
339 }
340
341 if(win32wnd->getStyle() & WS_MINIMIZE_W)
342 {
343 fMinimized = TRUE;
344 }
345
346 winMsg->message = WINWM_ACTIVATE;
347 winMsg->wParam = MAKELONG((SHORT1FROMMP(os2Msg->mp1)) ? WA_ACTIVE_W : WA_INACTIVE_W, fMinimized);
348 winMsg->lParam = (LPARAM)hwndActivate;
349 break;
350 }
351
352 case WM_SETFOCUS:
353 {
354 HWND hwndFocus = (HWND)os2Msg->mp1;
355
356 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
357 //another (non-win32) application's window
358 //set to NULL (allowed according to win32 SDK) to avoid problems
359 hwndFocus = NULL;
360 }
361 else hwndFocus = OS2ToWin32Handle(hwndFocus);
362
363 if((ULONG)os2Msg->mp2 == TRUE) {
364 winMsg->message = WINWM_SETFOCUS;
365 winMsg->wParam = (WPARAM)hwndFocus;
366 }
367 else {
368 winMsg->message = WINWM_KILLFOCUS;
369 winMsg->wParam = (WPARAM)hwndFocus;
370 }
371 break;
372 }
373
374 //**************************************************************************
375 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
376 //**************************************************************************
377 case WM_BUTTON1DOWN:
378 case WM_BUTTON1UP:
379 case WM_BUTTON1DBLCLK:
380 case WM_BUTTON2DOWN:
381 case WM_BUTTON2UP:
382 case WM_BUTTON2DBLCLK:
383 case WM_BUTTON3DOWN:
384 case WM_BUTTON3UP:
385 case WM_BUTTON3DBLCLK:
386 {
387 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
388
389 HWND hwnd;
390
391 DisableLogging();
392 if(GetCapture() != winMsg->hwnd)
393 {
394 hwnd = WindowFromPoint(winMsg->pt);
395 if(win32wnd->getWindowHandle() != hwnd) {
396 RELEASE_WNDOBJ(win32wnd);
397 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
398 if(win32wnd == NULL) {
399 DebugInt3();
400 EnableLogging();
401 goto dummymessage;
402 }
403 winMsg->hwnd = hwnd;
404 }
405 }
406
407 //if a window is disabled, it's parent receives the mouse messages
408 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
409 if(win32wnd->getParent()) {
410 Win32BaseWindow *parent = win32wnd->getParent();;
411 if(parent) parent->addRef();
412 RELEASE_WNDOBJ(win32wnd);
413 win32wnd = parent;
414 }
415 fWasDisabled = TRUE;
416 }
417
418 if(IsNCMouseMsg(win32wnd)) {
419 winMsg->message = WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
420 winMsg->wParam = win32wnd->getLastHitTestVal();
421 winMsg->lParam = MAKELONG(winMsg->pt.x, winMsg->pt.y); //screen coordinates
422 }
423 else {
424 ClientPoint.x = winMsg->pt.x;
425 ClientPoint.y = winMsg->pt.y;
426 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
427 winMsg->message = WINWM_LBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
428 winMsg->wParam = GetMouseKeyState();
429 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
430 }
431 EnableLogging();
432 if((fMsgRemoved == MSG_REMOVE) && ISMOUSE_CAPTURED())
433 {
434 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
435 goto dummymessage; //dinput swallowed message
436 }
437 }
438
439 if(fWasDisabled) {
440 if(win32wnd) {
441 winMsg->hwnd = win32wnd->getWindowHandle();
442 }
443 else goto dummymessage; //don't send mouse messages to disabled windows
444 }
445 break;
446 }
447
448 case WM_BUTTON2CLICK:
449 case WM_BUTTON1CLICK:
450 case WM_BUTTON3CLICK:
451 goto dummymessage;
452
453 case WM_BUTTON2MOTIONSTART:
454 case WM_BUTTON2MOTIONEND:
455 case WM_BUTTON1MOTIONSTART:
456 case WM_BUTTON1MOTIONEND:
457 case WM_BUTTON3MOTIONSTART:
458 case WM_BUTTON3MOTIONEND:
459 //no break; translate to WM_MOUSEMOVE
460 //Some applications (e.g. Unreal) retrieve all mouse messages
461 //when a mouse button is pressed and don't expect WM_NULL
462
463 case WM_MOUSEMOVE:
464 {
465 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
466
467 HWND hwnd;
468
469 dprintf2(("WM_NCMOUSEMOVE (%d,%d)", winMsg->pt.x, winMsg->pt.y));
470 DisableLogging();
471 if(GetCapture() != winMsg->hwnd)
472 {
473 hwnd = WindowFromPoint(winMsg->pt);
474 if(win32wnd->getWindowHandle() != hwnd) {
475 RELEASE_WNDOBJ(win32wnd);
476 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
477 if(win32wnd == NULL) {
478 DebugInt3();
479 EnableLogging();
480 goto dummymessage;
481 }
482 winMsg->hwnd = hwnd;
483 }
484 }
485
486 //if a window is disabled, it's parent receives the mouse messages
487 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
488 if(win32wnd->getParent()) {
489 Win32BaseWindow *parent = win32wnd->getParent();;
490 if(parent) parent->addRef();
491 RELEASE_WNDOBJ(win32wnd);
492 win32wnd = parent;
493 }
494 fWasDisabled = TRUE;
495 }
496 if(IsNCMouseMsg(win32wnd))
497 {
498 winMsg->message = WINWM_NCMOUSEMOVE;
499 winMsg->wParam = (WPARAM)win32wnd->getLastHitTestVal();
500 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
501 }
502 else
503 {
504 ClientPoint.x = winMsg->pt.x;
505 ClientPoint.y = winMsg->pt.y;
506 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
507
508 winMsg->message = WINWM_MOUSEMOVE;
509 winMsg->wParam = GetMouseKeyState();
510 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
511 }
512 EnableLogging();
513 if((fMsgRemoved == MSG_REMOVE) && ISMOUSE_CAPTURED())
514 {
515 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
516 goto dummymessage; //dinput swallowed message
517 }
518 }
519 if(fWasDisabled) {
520 if(win32wnd) {
521 winMsg->hwnd = win32wnd->getWindowHandle();
522 }
523 else {
524 goto dummymessage; //don't send mouse messages to disabled windows
525 }
526 }
527 //OS/2 Window coordinates -> Win32 Window coordinates
528 break;
529 }
530
531 case WM_CONTROL:
532 goto dummymessage;
533
534 case WM_COMMAND:
535 if(SHORT1FROMMP(os2Msg->mp2) == CMDSRC_MENU) {
536 winMsg->message = WINWM_COMMAND;
537 winMsg->wParam = (WPARAM)SHORT1FROMMP(os2Msg->mp1); //id
538 break;
539 }
540 //todo controls
541 goto dummymessage;
542
543 case WM_SYSCOMMAND:
544 {
545 ULONG x = 0, y = 0;
546 ULONG win32sc;
547
548 if(SHORT2FROMMP(os2Msg->mp2) == TRUE) {//syscommand caused by mouse action
549 POINTL pointl;
550 WinQueryPointerPos(HWND_DESKTOP, &pointl);
551 x = pointl.x;
552 y = mapScreenY(y);
553 }
554 switch(SHORT1FROMMP(os2Msg->mp1)) {
555 case SC_MOVE:
556 win32sc = SC_MOVE_W;
557 break;
558 case SC_CLOSE:
559 {
560 //FALSE -> keyboard operation = user pressed Alt-F4 -> close app
561 //TRUE -> user clicked on close button -> close window
562 if(SHORT2FROMMP(os2Msg->mp2) == FALSE)
563 {
564 HWND hwnd = win32wnd->GetTopParent();
565 if(win32wnd->getWindowHandle() != hwnd) {
566 RELEASE_WNDOBJ(win32wnd);
567 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
568 if(win32wnd == NULL) {
569 DebugInt3();
570 goto dummymessage;
571 }
572 winMsg->hwnd = hwnd;
573 }
574 }
575 win32sc = SC_CLOSE_W;
576 break;
577 }
578 case SC_MAXIMIZE:
579 win32sc = SC_MAXIMIZE_W;
580 break;
581 case SC_MINIMIZE:
582 win32sc = SC_MINIMIZE_W;
583 break;
584 case SC_NEXTFRAME:
585 case SC_NEXTWINDOW:
586 win32sc = SC_NEXTWINDOW_W;
587 break;
588 case SC_RESTORE:
589 win32sc = SC_RESTORE_W;
590 break;
591 case SC_TASKMANAGER:
592 win32sc = SC_TASKLIST_W;
593 break;
594 default:
595 dprintf(("Unknown/unsupported SC command %d", SHORT1FROMMP(os2Msg->mp1)));
596 goto dummymessage;
597 }
598 winMsg->message= WINWM_SYSCOMMAND;
599 winMsg->wParam = (WPARAM)win32sc;
600 winMsg->lParam = MAKELONG((USHORT)x, (USHORT)y);
601 break;
602 }
603
604 case WM_CHAR_SPECIAL:
605 // @@@PH
606 // special char message from the keyboard hook
607 dprintf(("PM: WM_CHAR_SPECIAL\n"));
608 // NO BREAK! FALLTHRU CASE!
609
610 case WM_CHAR:
611 {
612 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
613 ULONG flags = SHORT1FROMMP(os2Msg->mp1);
614 BOOL keyWasPressed, isExtended = FALSE;
615 char c;
616
617 teb->o.odin.fTranslated = FALSE;
618 repeatCount = CHAR3FROMMP(os2Msg->mp1);
619 scanCode = CHAR4FROMMP(os2Msg->mp1);
620 keyWasPressed = ((SHORT1FROMMP (os2Msg->mp1) & KC_PREVDOWN) == KC_PREVDOWN);
621
622 dprintf(("PM: WM_CHAR: %x %x %d %x", SHORT1FROMMP(os2Msg->mp2), SHORT2FROMMP(os2Msg->mp2), repeatCount, scanCode));
623 dprintf(("PM: WM_CHAR: hwnd %x flags %x mp1 %x, mp2 %x", win32wnd->getWindowHandle(), flags, os2Msg->mp1, os2Msg->mp2));
624
625 // vitali add begin
626 if ( ( SHORT1FROMMP(os2Msg->mp2) & 0x0FF ) == 0x0E0 )
627 {
628 // an extended key ( arrows, ins, del and so on )
629 // get "virtual" scancode from character code because
630 // for "regular" keys they are equal
631 if(!(flags & (KC_SHIFT|KC_ALT|KC_CTRL))) {
632 scanCode = ( SHORT1FROMMP(os2Msg->mp2) >> 8) & 0x0FF;
633 }
634 isExtended = TRUE;
635 }
636 // vitali add end
637
638 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
639 // given the OS/2 virtual key and OS/2 character
640
641 //if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
642 // ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
643 c = 0;
644 if ((SHORT1FROMMP (os2Msg->mp1) & 0xFF) != 0)
645 {
646 c = SHORT1FROMMP (os2Msg->mp2);
647 if ((c >= 'A') && (c <= 'Z')) {
648 virtualKey = c;
649 goto VirtualKeyFound;
650 }
651 if ((c >='a') && (c <= 'z')) {
652 virtualKey = c - 32; // make it uppercase
653 goto VirtualKeyFound;
654 }
655 if ((c >= '0') && (c <= '9')) {
656 virtualKey = c;
657 goto VirtualKeyFound;
658 }
659 }
660
661VirtualKeyFound:
662// dprintf (("VIRTUALKEYFOUND:(%x)", virtualKey));
663
664 // Adjust PM scancodes for Win* keys
665 if (scanCode >= 0x70)
666 scanCode -= 0x10;
667 winMsg->wParam = pmscan2winkey[scanCode][0];
668 winMsg->lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
669 winMsg->lParam |= (pmscan2winkey[scanCode][1] & 0x1FF) << 16; // bit 16-23, scancode + bit 15 extended
670
671 // Adjust VKEY value for pad digits if NumLock is on
672 if ((scanCode >= 0x47) && (scanCode <= 0x53) &&
673 (virtualKey >= 0x30) && (virtualKey >= 39))
674 winMsg->wParam = virtualKey + 0x30;
675
676 // Set the extended bit when appropriate
677 if (isExtended)
678 winMsg->lParam = winMsg->lParam | (1<<24);
679
680 if (!(flags & KC_ALT))
681 {
682 //
683 // the Alt key is not pressed
684 //
685 if ((flags & KC_KEYUP) == KC_KEYUP) {
686 // send WM_KEYUP message
687
688 winMsg->message = WINWM_KEYUP;
689 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
690 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
691 }
692 else {
693 // send WM_KEYDOWN message
694 winMsg->message = WINWM_KEYDOWN;
695 if (keyWasPressed)
696 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
697 }
698 }
699 else {
700 //
701 // the Alt key is pressed
702 //
703 if ((flags & KC_KEYUP) == KC_KEYUP) {
704 // send WM_SYSKEYUP message
705
706 winMsg->message = WINWM_SYSKEYUP;
707 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
708 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
709 }
710 else {
711 // send WM_SYSKEYDOWN message
712 winMsg->message = WINWM_SYSKEYDOWN;
713 if (keyWasPressed)
714 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
715 }
716//NT sends WM_SYSKEYDOWN for single Alt key
717#if 0
718 if(winMsg->wParam == VK_MENU_W) {
719 winMsg->message = 0; //WM_SYS* already implies Alt
720 }
721#endif
722 }
723 if (ISKDB_CAPTURED())
724 {
725 if (DInputKeyBoardHandler(winMsg)) {
726 goto dummymessage; //dinput swallowed message
727 }
728 }
729 break;
730 }
731
732 case WM_TIMER:
733//Why was this check here????
734// if (os2Msg->mp2)
735// {
736 BOOL sys;
737 ULONG id;
738
739 if (TIMER_GetTimerInfo(os2Msg->hwnd,(ULONG)os2Msg->mp1,&sys,&id))
740 {
741 winMsg->wParam = (WPARAM)id;
742 winMsg->message= (sys) ? WINWM_SYSTIMER : WINWM_TIMER;
743 break;
744 }
745// }
746 goto dummymessage; //for caret blinking
747
748 case WM_SETWINDOWPARAMS:
749 {
750 WNDPARAMS *wndParams = (WNDPARAMS *)os2Msg->mp1;
751
752 if(wndParams->fsStatus & WPM_TEXT) {
753 winMsg->message = WINWM_SETTEXT;
754 winMsg->lParam = (LPARAM)wndParams->pszText;
755 break;
756 }
757 goto dummymessage;
758 }
759
760#if 0
761 case WM_QUERYWINDOWPARAMS:
762 {
763 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
764 ULONG textlen;
765 PSZ wintext;
766
767 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
768 {
769 if(wndpars->fsStatus & WPM_CCHTEXT)
770 wndpars->cchText = win32wnd->MsgGetTextLength();
771 if(wndpars->fsStatus & WPM_TEXT)
772 wndpars->pszText = win32wnd->MsgGetText();
773
774 wndpars->fsStatus = 0;
775 wndpars->cbCtlData = 0;
776 wndpars->cbPresParams = 0;
777 goto dummymessage;
778 }
779 }
780#endif
781
782 case WM_PAINT:
783 {
784 if(win32wnd->IsWindowIconic()) {
785 winMsg->message = WINWM_PAINTICON;
786 }
787 else winMsg->message = WINWM_PAINT;
788 break;
789 }
790
791 case WM_CONTEXTMENU:
792 winMsg->message = WINWM_CONTEXTMENU;
793 winMsg->wParam = win32wnd->getWindowHandle();
794 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
795 break;
796
797 case WM_RENDERFMT:
798 winMsg->message = WINWM_RENDERFORMAT;
799 winMsg->wParam = (UINT) os2Msg->mp1;
800 break;
801
802 case WM_RENDERALLFMTS:
803 winMsg->message = WINWM_RENDERALLFORMATS;
804 break;
805
806 case WM_DESTROYCLIPBOARD:
807 winMsg->message = WINWM_DESTROYCLIPBOARD;
808 break;
809
810 case WM_HSCROLL:
811 case WM_VSCROLL:
812 winMsg->message = (os2Msg->msg == WM_HSCROLL) ? WINWM_HSCROLL : WINWM_VSCROLL;
813 winMsg->lParam = 0;
814 winMsg->wParam = 0;
815 switch(SHORT2FROMMP(os2Msg->mp2)) {
816 case SB_LINERIGHT:
817 winMsg->wParam = SB_LINERIGHT_W;
818 break;
819 case SB_LINELEFT:
820 winMsg->wParam = SB_LINELEFT_W;
821 break;
822 case SB_PAGELEFT:
823 winMsg->wParam = SB_PAGELEFT_W;
824 break;
825 case SB_PAGERIGHT:
826 winMsg->wParam = SB_PAGERIGHT_W;
827 break;
828 default:
829 dprintf(("Unsupported WM_H/VSCROLL message %x!!", SHORT2FROMMP(os2Msg->mp2)));
830 goto dummymessage;
831 }
832 break;
833
834 case WM_INITMENU:
835 case WM_MENUSELECT:
836 case WM_MENUEND:
837 case WM_NEXTMENU:
838 case WM_SYSCOLORCHANGE:
839 case WM_SYSVALUECHANGED:
840 case WM_SETSELECTION:
841 case WM_PPAINT:
842 case WM_PSETFOCUS:
843 case WM_PSYSCOLORCHANGE:
844 case WM_PSIZE:
845 case WM_PACTIVATE:
846 case WM_PCONTROL:
847 case WM_HELP:
848 case WM_APPTERMINATENOTIFY:
849 case WM_PRESPARAMCHANGED:
850 case WM_DRAWITEM:
851 case WM_MEASUREITEM:
852 case WM_CONTROLPOINTER:
853 case WM_QUERYDLGCODE:
854 case WM_SUBSTITUTESTRING:
855 case WM_MATCHMNEMONIC:
856 case WM_SAVEAPPLICATION:
857 case WM_SEMANTICEVENT:
858 default:
859dummymessage:
860 dprintf2(("dummy message %x %x %x %x", os2Msg->hwnd, os2Msg->msg, os2Msg->mp1, os2Msg->mp2));
861 winMsg->message = 0;
862 winMsg->wParam = 0;
863 winMsg->lParam = 0;
864 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
865 return FALSE;
866 }
867 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
868 return TRUE;
869}
870//******************************************************************************
871//******************************************************************************
872BOOL OSLibWinTranslateMessage(MSG *msg)
873{
874 TEB *teb;
875
876 teb = GetThreadTEB();
877 if(!teb) {
878 return FALSE;
879 }
880 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
881 // the newly generated WM_CHAR message.
882 if(!teb->o.odin.fTranslated && teb->o.odin.os2msg.msg == WM_CHAR && !((SHORT1FROMMP(teb->o.odin.os2msg.mp1) & KC_KEYUP) == KC_KEYUP))
883 {//TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
884 ULONG fl = SHORT1FROMMP(teb->o.odin.os2msg.mp1);
885 MSG extramsg;
886
887 memcpy(&extramsg, msg, sizeof(MSG));
888 extramsg.wParam = SHORT1FROMMP(teb->o.odin.os2msg.mp2);
889 extramsg.lParam = 0;
890
891 if(!(fl & KC_CHAR) && msg->message < WINWM_SYSKEYDOWN) {
892 return FALSE;
893 }
894
895 if(fl & KC_VIRTUALKEY) {
896 if(msg->wParam) {
897 if ((msg->wParam >= VK_NUMPAD0_W) && (msg->wParam <= VK_NUMPAD9_W))
898 extramsg.wParam = msg->wParam - 0x30;
899 else
900 extramsg.wParam = msg->wParam;
901 }
902 else extramsg.wParam = SHORT2FROMMP(teb->o.odin.os2msg.mp2);
903 }
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 teb->o.odin.fTranslated = TRUE;
924 memcpy(&teb->o.odin.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.