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

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

MN: keyboard translation fixes

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