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

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

.

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