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

Last change on this file since 6718 was 6718, checked in by sandervl, 24 years ago

SC_CLOSE translation fix + activation changes

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