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

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

.

File size: 32.2 KB
Line 
1/* $Id: oslibmsgtranslate.cpp,v 1.63 2001-10-23 06:00:45 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 VK_LMENU_W, 0x38, // 0x38 LAlt
105 0x20, 0x39, // 0x39 Space
106 0x14, 0x3A, // 0x3A CapsLk
107 0x70, 0x3B, // 0x3B F1
108 0x71, 0x3C, // 0x3C F2
109 0x72, 0x3D, // 0x3D F3
110 0x73, 0x3E, // 0x3E F4
111 0x74, 0x3F, // 0x3F F5
112 0x75, 0x40, // 0x40 F6
113 0x76, 0x41, // 0x41 F7
114 0x77, 0x42, // 0x42 F8
115 0x78, 0x43, // 0x43 F9
116 0x79, 0x44, // 0x44 F10 (?)
117 0x90, 0x145, // 0x45 NumLk
118 0x91, 0x46, // 0x46 ScrLk
119 0x24, 0x47, // 0x47 7 Pad
120 0x26, 0x48, // 0x48 8 Pad
121 0x21, 0x49, // 0x49 9 Pad
122 0x6D, 0x4A, // 0x4A - Pad
123 VK_LEFT_W, 0x4B, // 0x4B Left Arrow (depends on NumLock State)
124 0x0C, 0x4C, // 0x4C 5 Pad
125 0x27, 0x4D, // 0x4D 6 Pad
126 0x6B, 0x4E, // 0x4E + Pad
127 0x23, 0x4F, // 0x4F 1 Pad
128 0x28, 0x50, // 0x50 2 Pad
129 0x22, 0x51, // 0x51 3 Pad
130 0x2D, 0x52, // 0x52 0 Pad
131 0x2E, 0x53, // 0x53 . Pad
132 0, 0, // 0x54
133 0, 0, // 0x55
134 0xe2, 0x56, // 0x56 "<>|"
135 0x7A, 0x57, // 0x57 F11
136 0x7B, 0x58, // 0x58 F12
137 0, 0, // 0x59
138 0x0D, 0x11C, // 0x5A Enter Pad
139 0x11, 0x11D, // 0x5B RCtrl
140 0x6F, 0x135, // 0x5C / Pad
141 0x2D, 0x152, // 0x5D PrtSc
142 0x12, 0x5E, // 0x5E RAlt
143 0x13, 0x45, // 0x5F Pause
144 VK_HOME_W, 0x60, // 0x60
145 VK_UP_W, 0x61, // 0x61
146 VK_PRIOR_W, 0x62, // 0x62
147 VK_LEFT_W, 0x63, // 0x63
148 VK_RIGHT_W, 0x64, // 0x64
149 VK_END_W, 0x65, // 0x65
150 VK_DOWN_W, 0x66, // 0x66
151 VK_NEXT_W, 0x67, // 0x67
152 VK_INSERT_W, 0x68, // 0x68
153 VK_DELETE_W, 0x69, // 0x69
154 VK_F23_W, 0x6A, // 0x6A
155 VK_F24_W, 0x6B, // 0x6B
156 0x5D, 0x15D, // 0x6C RWin (PM scan 0x7C)
157 0, 0, // 0x6D
158 0x5B, 0x15B, // 0x6E LWin (PM scan 0x7E)
159 0x5C, 0x15C // 0x6F RMenu? (PM scan 0x7F)
160};
161
162//******************************************************************************
163//******************************************************************************
164ULONG GetMouseKeyState()
165{
166 ULONG keystate = 0;
167
168 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
169 keystate |= MK_LBUTTON_W;
170 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
171 keystate |= MK_RBUTTON_W;
172 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
173 keystate |= MK_MBUTTON_W;
174 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000)
175 keystate |= MK_SHIFT_W;
176 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
177 keystate |= MK_CONTROL_W;
178
179 return keystate;
180}
181//******************************************************************************
182//******************************************************************************
183LONG IsNCMouseMsg(Win32BaseWindow *win32wnd)
184{
185 return ((win32wnd->getLastHitTestVal() != HTCLIENT_W) && (WinQueryCapture(HWND_DESKTOP) != win32wnd->getOS2WindowHandle()));
186}
187//******************************************************************************
188//******************************************************************************
189BOOL OS2ToWinMsgTranslate(void *pTeb, QMSG *os2Msg, MSG *winMsg, BOOL isUnicode, BOOL fMsgRemoved)
190{
191 Win32BaseWindow *win32wnd = 0;
192 OSLIBPOINT point, ClientPoint;
193 POSTMSG_PACKET *packet;
194 TEB *teb = (TEB *)pTeb;
195 BOOL fWasDisabled = FALSE;
196 BOOL fIsFrame = FALSE;
197 int i;
198
199 memset(winMsg, 0, sizeof(MSG));
200 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(os2Msg->hwnd);
201 if(!win32wnd) {
202 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(os2Msg->hwnd);
203 if(win32wnd) {
204 fIsFrame = TRUE;
205 }
206 }
207
208 //PostThreadMessage posts WIN32APP_POSTMSG msg without window handle
209 //Realplayer starts a timer with hwnd 0 & proc 0; check this here
210 if(win32wnd == 0 && (os2Msg->msg != WM_CREATE && os2Msg->msg != WM_QUIT && os2Msg->msg != WM_TIMER && os2Msg->msg < WIN32APP_POSTMSG))
211 {
212 goto dummymessage; //not a win32 client window
213 }
214 winMsg->time = os2Msg->time;
215 //CB: PM bug or undocumented feature? ptl.x highword is set!
216 winMsg->pt.x = os2Msg->ptl.x & 0xFFFF;
217 winMsg->pt.y = mapScreenY(os2Msg->ptl.y);
218
219 if(win32wnd) //==0 for WM_CREATE/WM_QUIT
220 winMsg->hwnd = win32wnd->getWindowHandle();
221
222 if(os2Msg->msg >= WIN32APP_POSTMSG) {
223 packet = (POSTMSG_PACKET *)os2Msg->mp2;
224 if(packet && ((ULONG)os2Msg->mp1 == WIN32MSG_MAGICA || (ULONG)os2Msg->mp1 == WIN32MSG_MAGICW)) {
225 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
226 winMsg->wParam = packet->wParam;
227 winMsg->lParam = packet->lParam;
228 if(fMsgRemoved == MSG_REMOVE) free(packet); //free the shared memory here
229 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
230 return TRUE;
231 }
232 else {//broadcasted message (no packet present)
233 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
234 winMsg->wParam = (UINT)os2Msg->mp1;
235 winMsg->lParam = (DWORD)os2Msg->mp2;
236 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
237 return TRUE;
238 }
239 goto dummymessage;
240 }
241
242 switch(os2Msg->msg)
243 {
244 //OS/2 msgs
245 case WM_CREATE:
246 {
247 if(teb->o.odin.newWindow == 0) {
248 DebugInt3();
249 goto dummymessage;
250 }
251
252 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
253 win32wnd->addRef();
254
255 winMsg->message = WINWM_CREATE;
256 winMsg->hwnd = win32wnd->getWindowHandle();
257 winMsg->wParam = 0;
258 winMsg->lParam = (LPARAM)win32wnd->tmpcs;
259 break;
260 }
261
262 case WM_QUIT:
263 winMsg->message = WINWM_QUIT;
264 break;
265
266 case WM_CLOSE:
267 winMsg->message = WINWM_CLOSE;
268 break;
269
270 case WM_DESTROY:
271 winMsg->message = WINWM_DESTROY;
272 break;
273
274 case WM_ENABLE:
275 winMsg->message = WINWM_ENABLE;
276 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
277 break;
278
279 case WM_SHOW:
280 winMsg->message = WINWM_SHOWWINDOW;
281 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
282 break;
283
284 case WM_WINDOWPOSCHANGED:
285 {
286 PSWP pswp = (PSWP)os2Msg->mp1;
287 SWP swpOld = *(pswp + 1);
288 HWND hParent = NULLHANDLE;
289 LONG yDelta = pswp->cy - swpOld.cy;
290 LONG xDelta = pswp->cx - swpOld.cx;
291
292 if(!fIsFrame) goto dummymessage;
293
294 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto dummymessage;
295
296 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
297 if (win32wnd->isChild()) {
298 if(win32wnd->getParent()) {
299 hParent = win32wnd->getParent()->getOS2WindowHandle();
300 }
301 else goto dummymessage; //parent has just been destroyed
302 }
303 }
304 if(win32wnd->getParent()) {
305 OSLibMapSWPtoWINDOWPOS(pswp, &teb->o.odin.wp, &swpOld, win32wnd->getParent()->getClientHeight(),
306 win32wnd->getOS2WindowHandle());
307 }
308 else OSLibMapSWPtoWINDOWPOS(pswp, &teb->o.odin.wp, &swpOld, OSLibQueryScreenHeight(), win32wnd->getOS2WindowHandle());
309
310 if (!win32wnd->CanReceiveSizeMsgs()) goto dummymessage;
311
312 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
313 {
314 teb->o.odin.wp.hwnd = win32wnd->getWindowHandle();
315 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
316 {
317 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
318 if(wndAfter) {
319 teb->o.odin.wp.hwndInsertAfter = wndAfter->getWindowHandle();
320 RELEASE_WNDOBJ(wndAfter);
321 }
322 else teb->o.odin.wp.hwndInsertAfter = HWND_TOP_W;
323 }
324 }
325 winMsg->message = WINWM_WINDOWPOSCHANGED;
326 winMsg->lParam = (LPARAM)&teb->o.odin.wp;
327 break;
328 }
329
330 case WM_ACTIVATE:
331 {
332 HWND hwndActivate = (HWND)os2Msg->mp2;
333 BOOL fMinimized = FALSE;
334
335 hwndActivate = OS2ToWin32Handle(hwndActivate);
336 if(hwndActivate == 0) {
337 //another (non-win32) application's window
338 //set to desktop window handle
339 hwndActivate = windowDesktop->getWindowHandle();
340 }
341
342 if(win32wnd->getStyle() & WS_MINIMIZE_W)
343 {
344 fMinimized = TRUE;
345 }
346
347 winMsg->message = WINWM_ACTIVATE;
348 winMsg->wParam = MAKELONG((SHORT1FROMMP(os2Msg->mp1)) ? WA_ACTIVE_W : WA_INACTIVE_W, fMinimized);
349 winMsg->lParam = (LPARAM)hwndActivate;
350 break;
351 }
352
353 case WM_SETFOCUS:
354 {
355 HWND hwndFocus = (HWND)os2Msg->mp1;
356
357 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
358 //another (non-win32) application's window
359 //set to NULL (allowed according to win32 SDK) to avoid problems
360 hwndFocus = NULL;
361 }
362 else hwndFocus = OS2ToWin32Handle(hwndFocus);
363
364 if((ULONG)os2Msg->mp2 == TRUE) {
365 winMsg->message = WINWM_SETFOCUS;
366 winMsg->wParam = (WPARAM)hwndFocus;
367 }
368 else {
369 winMsg->message = WINWM_KILLFOCUS;
370 winMsg->wParam = (WPARAM)hwndFocus;
371 }
372 break;
373 }
374
375 //**************************************************************************
376 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
377 //**************************************************************************
378 case WM_BUTTON1DOWN:
379 case WM_BUTTON1UP:
380 case WM_BUTTON1DBLCLK:
381 case WM_BUTTON2DOWN:
382 case WM_BUTTON2UP:
383 case WM_BUTTON2DBLCLK:
384 case WM_BUTTON3DOWN:
385 case WM_BUTTON3UP:
386 case WM_BUTTON3DBLCLK:
387 {
388 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
389
390 HWND hwnd;
391
392 DisableLogging();
393 if(GetCapture() != winMsg->hwnd)
394 {
395 hwnd = WindowFromPoint(winMsg->pt);
396 if(win32wnd->getWindowHandle() != hwnd) {
397 RELEASE_WNDOBJ(win32wnd);
398 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
399 if(win32wnd == NULL) {
400 DebugInt3();
401 EnableLogging();
402 goto dummymessage;
403 }
404 winMsg->hwnd = hwnd;
405 }
406 }
407
408 //if a window is disabled, it's parent receives the mouse messages
409 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
410 if(win32wnd->getParent()) {
411 Win32BaseWindow *parent = win32wnd->getParent();;
412 if(parent) parent->addRef();
413 RELEASE_WNDOBJ(win32wnd);
414 win32wnd = parent;
415 }
416 fWasDisabled = TRUE;
417 }
418
419 if(IsNCMouseMsg(win32wnd)) {
420 winMsg->message = WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
421 winMsg->wParam = win32wnd->getLastHitTestVal();
422 winMsg->lParam = MAKELONG(winMsg->pt.x, winMsg->pt.y); //screen coordinates
423 }
424 else {
425 ClientPoint.x = winMsg->pt.x;
426 ClientPoint.y = winMsg->pt.y;
427 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
428 winMsg->message = WINWM_LBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
429 winMsg->wParam = GetMouseKeyState();
430 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
431 }
432 EnableLogging();
433 if((fMsgRemoved == MSG_REMOVE) && ISMOUSE_CAPTURED())
434 {
435 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
436 goto dummymessage; //dinput swallowed message
437 }
438 }
439
440 if(fWasDisabled) {
441 if(win32wnd) {
442 winMsg->hwnd = win32wnd->getWindowHandle();
443 }
444 else goto dummymessage; //don't send mouse messages to disabled windows
445 }
446 break;
447 }
448
449 case WM_BUTTON2CLICK:
450 case WM_BUTTON1CLICK:
451 case WM_BUTTON3CLICK:
452 goto dummymessage;
453
454 case WM_BUTTON2MOTIONSTART:
455 case WM_BUTTON2MOTIONEND:
456 case WM_BUTTON1MOTIONSTART:
457 case WM_BUTTON1MOTIONEND:
458 case WM_BUTTON3MOTIONSTART:
459 case WM_BUTTON3MOTIONEND:
460 //no break; translate to WM_MOUSEMOVE
461 //Some applications (e.g. Unreal) retrieve all mouse messages
462 //when a mouse button is pressed and don't expect WM_NULL
463
464 case WM_MOUSEMOVE:
465 {
466 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
467
468 HWND hwnd;
469
470 dprintf2(("WM_NCMOUSEMOVE (%d,%d)", winMsg->pt.x, winMsg->pt.y));
471 DisableLogging();
472 if(GetCapture() != winMsg->hwnd)
473 {
474 hwnd = WindowFromPoint(winMsg->pt);
475 if(win32wnd->getWindowHandle() != hwnd) {
476 RELEASE_WNDOBJ(win32wnd);
477 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
478 if(win32wnd == NULL) {
479 DebugInt3();
480 EnableLogging();
481 goto dummymessage;
482 }
483 winMsg->hwnd = hwnd;
484 }
485 }
486
487 //if a window is disabled, it's parent receives the mouse messages
488 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
489 if(win32wnd->getParent()) {
490 Win32BaseWindow *parent = win32wnd->getParent();;
491 if(parent) parent->addRef();
492 RELEASE_WNDOBJ(win32wnd);
493 win32wnd = parent;
494 }
495 fWasDisabled = TRUE;
496 }
497 if(IsNCMouseMsg(win32wnd))
498 {
499 winMsg->message = WINWM_NCMOUSEMOVE;
500 winMsg->wParam = (WPARAM)win32wnd->getLastHitTestVal();
501 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
502 }
503 else
504 {
505 ClientPoint.x = winMsg->pt.x;
506 ClientPoint.y = winMsg->pt.y;
507 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
508
509 winMsg->message = WINWM_MOUSEMOVE;
510 winMsg->wParam = GetMouseKeyState();
511 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
512 }
513 EnableLogging();
514 if((fMsgRemoved == MSG_REMOVE) && ISMOUSE_CAPTURED())
515 {
516 if(DInputMouseHandler(win32wnd->getWindowHandle(), winMsg->message, winMsg->pt.x, winMsg->pt.y)) {
517 goto dummymessage; //dinput swallowed message
518 }
519 }
520 if(fWasDisabled) {
521 if(win32wnd) {
522 winMsg->hwnd = win32wnd->getWindowHandle();
523 }
524 else {
525 goto dummymessage; //don't send mouse messages to disabled windows
526 }
527 }
528 //OS/2 Window coordinates -> Win32 Window coordinates
529 break;
530 }
531
532 case WM_CONTROL:
533 goto dummymessage;
534
535 case WM_COMMAND:
536 if(SHORT1FROMMP(os2Msg->mp2) == CMDSRC_MENU) {
537 winMsg->message = WINWM_COMMAND;
538 winMsg->wParam = (WPARAM)SHORT1FROMMP(os2Msg->mp1); //id
539 break;
540 }
541 //todo controls
542 goto dummymessage;
543
544 case WM_SYSCOMMAND:
545 {
546 ULONG x = 0, y = 0;
547 ULONG win32sc;
548
549 if(SHORT2FROMMP(os2Msg->mp2) == TRUE) {//syscommand caused by mouse action
550 POINTL pointl;
551 WinQueryPointerPos(HWND_DESKTOP, &pointl);
552 x = pointl.x;
553 y = mapScreenY(y);
554 }
555 switch(SHORT1FROMMP(os2Msg->mp1)) {
556 case SC_MOVE:
557 win32sc = SC_MOVE_W;
558 break;
559 case SC_CLOSE:
560 {
561 //FALSE -> keyboard operation = user pressed Alt-F4 -> close app
562 //TRUE -> user clicked on close button -> close window
563 if(SHORT2FROMMP(os2Msg->mp2) == FALSE)
564 {
565 HWND hwnd = win32wnd->GetTopParent();
566 if(win32wnd->getWindowHandle() != hwnd) {
567 RELEASE_WNDOBJ(win32wnd);
568 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
569 if(win32wnd == NULL) {
570 DebugInt3();
571 goto dummymessage;
572 }
573 winMsg->hwnd = hwnd;
574 }
575 }
576 win32sc = SC_CLOSE_W;
577 break;
578 }
579 case SC_MAXIMIZE:
580 win32sc = SC_MAXIMIZE_W;
581 break;
582 case SC_MINIMIZE:
583 win32sc = SC_MINIMIZE_W;
584 break;
585 case SC_NEXTFRAME:
586 case SC_NEXTWINDOW:
587 win32sc = SC_NEXTWINDOW_W;
588 break;
589 case SC_RESTORE:
590 win32sc = SC_RESTORE_W;
591 break;
592 case SC_TASKMANAGER:
593 win32sc = SC_TASKLIST_W;
594 break;
595 default:
596 dprintf(("Unknown/unsupported SC command %d", SHORT1FROMMP(os2Msg->mp1)));
597 goto dummymessage;
598 }
599 winMsg->message= WINWM_SYSCOMMAND;
600 winMsg->wParam = (WPARAM)win32sc;
601 winMsg->lParam = MAKELONG((USHORT)x, (USHORT)y);
602 break;
603 }
604
605 case WM_CHAR_SPECIAL:
606 {
607 // @@@PH
608 // special char message from the keyboard hook
609 dprintf(("PM: WM_CHAR_SPECIAL\n"));
610
611 // AltGr is a very, very strange key!
612 UCHAR ucPMScanCode = CHAR4FROMMP(os2Msg->mp1);
613 if (PMSCAN_ALTRIGHT == ucPMScanCode)
614 {
615 ULONG flags = SHORT1FROMMP(os2Msg->mp1);
616
617 // we need very special treatment here for the
618 // poor, crippled AltGr key
619
620 if (flags & KC_KEYUP)
621 {
622 // key up
623 // 1 - generate a virtual LCONTROL-keypress
624 // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-Alt!)
625 }
626 else
627 {
628 // key down:
629 // 1 - generate a virtual LCONTROL-keypress
630 // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-Alt!)
631 }
632 }
633 }
634 // NO BREAK! FALLTHRU CASE!
635
636 case WM_CHAR:
637 {
638 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
639 ULONG flags = SHORT1FROMMP(os2Msg->mp1);
640 BOOL keyWasPressed, isExtended = FALSE;
641 char c;
642
643 teb->o.odin.fTranslated = FALSE;
644 repeatCount = CHAR3FROMMP(os2Msg->mp1);
645 scanCode = CHAR4FROMMP(os2Msg->mp1);
646 keyWasPressed = ((SHORT1FROMMP (os2Msg->mp1) & KC_PREVDOWN) == KC_PREVDOWN);
647
648 dprintf(("PM: WM_CHAR: %x %x rep=%d scancode=%x", SHORT1FROMMP(os2Msg->mp2), SHORT2FROMMP(os2Msg->mp2), repeatCount, scanCode));
649 dprintf(("PM: WM_CHAR: hwnd %x flags %x mp1 %x, mp2 %x", win32wnd->getWindowHandle(), flags, os2Msg->mp1, os2Msg->mp2));
650
651 // vitali add begin
652 if ( ( SHORT1FROMMP(os2Msg->mp2) & 0x0FF ) == 0x0E0 )
653 {
654 // an extended key ( arrows, ins, del and so on )
655 // get "virtual" scancode from character code because
656 // for "regular" keys they are equal
657 if(!(flags & (KC_SHIFT|KC_ALT|KC_CTRL))) {
658 scanCode = ( SHORT1FROMMP(os2Msg->mp2) >> 8) & 0x0FF;
659 }
660 isExtended = TRUE;
661 }
662 // vitali add end
663
664 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
665 // given the OS/2 virtual key and OS/2 character
666
667 //if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
668 // ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
669 c = 0;
670 if ((SHORT1FROMMP (os2Msg->mp1) & 0xFF) != 0)
671 {
672 c = SHORT1FROMMP (os2Msg->mp2);
673 if ((c >= 'A') && (c <= 'Z')) {
674 virtualKey = c;
675 goto VirtualKeyFound;
676 }
677 if ((c >='a') && (c <= 'z')) {
678 virtualKey = c - 32; // make it uppercase
679 goto VirtualKeyFound;
680 }
681 if ((c >= '0') && (c <= '9')) {
682 virtualKey = c;
683 goto VirtualKeyFound;
684 }
685 }
686
687VirtualKeyFound:
688// dprintf (("VIRTUALKEYFOUND:(%x)", virtualKey));
689
690 // Adjust PM scancodes for Win* keys
691 if (scanCode >= 0x70)
692 scanCode -= 0x10;
693 winMsg->wParam = pmscan2winkey[scanCode][0];
694 winMsg->lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
695 winMsg->lParam |= (pmscan2winkey[scanCode][1] & 0x1FF) << 16; // bit 16-23, scancode + bit 15 extended
696
697 // Adjust VKEY value for pad digits if NumLock is on
698 if ((scanCode >= 0x47) && (scanCode <= 0x53) &&
699 (virtualKey >= 0x30) && (virtualKey >= 39))
700 winMsg->wParam = virtualKey + 0x30;
701
702 // Set the extended bit when appropriate
703 if (isExtended)
704 winMsg->lParam = winMsg->lParam | (1<<24);
705
706 if (!(flags & KC_ALT))
707 {
708 //
709 // the Alt key is not pressed
710 // or no more pressed
711 //
712 if (flags & KC_KEYUP)
713 {
714 // check for a lonesome ALT key ...
715 if ( (flags & KC_LONEKEY) &&
716 (winMsg->wParam == VK_LMENU_W) )
717 {
718 winMsg->message = WINWM_SYSKEYUP;
719
720 // held ALT-key when current key is released
721 // generates additional flag 0x2000000
722 // Note: PM seems to do this differently,
723 // KC_ALT is already reset
724 }
725 else
726 {
727 // send WM_KEYUP message
728 winMsg->message = WINWM_KEYUP;
729 }
730
731 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
732 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
733 }
734 else
735 {
736 // send WM_KEYDOWN message
737 winMsg->message = WINWM_KEYDOWN;
738 if (keyWasPressed)
739 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
740 }
741 }
742 else
743 {
744 //
745 // the Alt key is pressed
746 //
747 if (flags & KC_KEYUP)
748 {
749 // send WM_SYSKEYUP message
750 winMsg->message = WINWM_SYSKEYUP;
751 winMsg->lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
752 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
753 }
754 else
755 {
756 // send WM_SYSKEYDOWN message
757 winMsg->message = WINWM_SYSKEYDOWN;
758 if (keyWasPressed)
759 winMsg->lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
760
761 // pressed ALT-key generates additional flag 0x2000000
762 // if the current window has keyboard focus
763 winMsg->lParam |= 1 << 29;
764 }
765 }
766
767
768 if (ISKDB_CAPTURED())
769 {
770 if (DInputKeyBoardHandler(winMsg)) {
771 goto dummymessage; //dinput swallowed message
772 }
773 }
774 break;
775 }
776
777 case WM_TIMER:
778//Why was this check here????
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_RENDERFMT:
843 winMsg->message = WINWM_RENDERFORMAT;
844 winMsg->wParam = (UINT) os2Msg->mp1;
845 break;
846
847 case WM_RENDERALLFMTS:
848 winMsg->message = WINWM_RENDERALLFORMATS;
849 break;
850
851 case WM_DESTROYCLIPBOARD:
852 winMsg->message = WINWM_DESTROYCLIPBOARD;
853 break;
854
855 case WM_HSCROLL:
856 case WM_VSCROLL:
857 winMsg->message = (os2Msg->msg == WM_HSCROLL) ? WINWM_HSCROLL : WINWM_VSCROLL;
858 winMsg->lParam = 0;
859 winMsg->wParam = 0;
860 switch(SHORT2FROMMP(os2Msg->mp2)) {
861 case SB_LINERIGHT:
862 winMsg->wParam = SB_LINERIGHT_W;
863 break;
864 case SB_LINELEFT:
865 winMsg->wParam = SB_LINELEFT_W;
866 break;
867 case SB_PAGELEFT:
868 winMsg->wParam = SB_PAGELEFT_W;
869 break;
870 case SB_PAGERIGHT:
871 winMsg->wParam = SB_PAGERIGHT_W;
872 break;
873 default:
874 dprintf(("Unsupported WM_H/VSCROLL message %x!!", SHORT2FROMMP(os2Msg->mp2)));
875 goto dummymessage;
876 }
877 break;
878
879 case WM_INITMENU:
880 case WM_MENUSELECT:
881 case WM_MENUEND:
882 case WM_NEXTMENU:
883 case WM_SYSCOLORCHANGE:
884 case WM_SYSVALUECHANGED:
885 case WM_SETSELECTION:
886 case WM_PPAINT:
887 case WM_PSETFOCUS:
888 case WM_PSYSCOLORCHANGE:
889 case WM_PSIZE:
890 case WM_PACTIVATE:
891 case WM_PCONTROL:
892 case WM_HELP:
893 case WM_APPTERMINATENOTIFY:
894 case WM_PRESPARAMCHANGED:
895 case WM_DRAWITEM:
896 case WM_MEASUREITEM:
897 case WM_CONTROLPOINTER:
898 case WM_QUERYDLGCODE:
899 case WM_SUBSTITUTESTRING:
900 case WM_MATCHMNEMONIC:
901 case WM_SAVEAPPLICATION:
902 case WM_SEMANTICEVENT:
903 default:
904dummymessage:
905 dprintf2(("dummy message %x %x %x %x", os2Msg->hwnd, os2Msg->msg, os2Msg->mp1, os2Msg->mp2));
906 winMsg->message = 0;
907 winMsg->wParam = 0;
908 winMsg->lParam = 0;
909 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
910 return FALSE;
911 }
912 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
913 return TRUE;
914}
915//******************************************************************************
916//******************************************************************************
917BOOL OSLibWinTranslateMessage(MSG *msg)
918{
919 TEB *teb;
920
921 teb = GetThreadTEB();
922 if(!teb) {
923 return FALSE;
924 }
925 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
926 // the newly generated WM_CHAR message.
927 if(!teb->o.odin.fTranslated && teb->o.odin.os2msg.msg == WM_CHAR && !((SHORT1FROMMP(teb->o.odin.os2msg.mp1) & KC_KEYUP) == KC_KEYUP))
928 {//TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
929 ULONG fl = SHORT1FROMMP(teb->o.odin.os2msg.mp1);
930 MSG extramsg;
931
932 memcpy(&extramsg, msg, sizeof(MSG));
933 extramsg.wParam = SHORT1FROMMP(teb->o.odin.os2msg.mp2);
934 extramsg.lParam = 0;
935
936 if(!(fl & KC_CHAR) && msg->message < WINWM_SYSKEYDOWN) {
937 return FALSE;
938 }
939
940 if(fl & KC_VIRTUALKEY) {
941 if(msg->wParam) {
942 if ((msg->wParam >= VK_NUMPAD0_W) && (msg->wParam <= VK_NUMPAD9_W))
943 extramsg.wParam = msg->wParam - 0x30;
944 else
945 extramsg.wParam = msg->wParam;
946 }
947 else extramsg.wParam = SHORT2FROMMP(teb->o.odin.os2msg.mp2);
948 }
949
950
951 if(msg->message >= WINWM_SYSKEYDOWN) {
952 extramsg.message = WINWM_SYSCHAR;
953 }
954 else extramsg.message = WINWM_CHAR;
955
956 if(fl & KC_DEADKEY) {
957 extramsg.message++; //WM_DEADCHAR/WM_SYSDEADCHAR
958 }
959
960 extramsg.lParam = msg->lParam & 0x00FFFFFF;
961 if(fl & KC_ALT)
962 extramsg.lParam |= (1<<29);
963 if(fl & KC_PREVDOWN)
964 extramsg.lParam |= (1<<30);
965 if(fl & KC_KEYUP)
966 extramsg.lParam |= (1<<31);
967
968 teb->o.odin.fTranslated = TRUE;
969 memcpy(&teb->o.odin.msgWCHAR, &extramsg, sizeof(MSG));
970 return TRUE;
971 }
972 return FALSE;
973}
974//******************************************************************************
975//******************************************************************************
976
Note: See TracBrowser for help on using the repository browser.