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

Last change on this file since 10488 was 10451, checked in by sandervl, 22 years ago

removed obsolete comments

File size: 43.4 KB
Line 
1/* $Id: oslibmsgtranslate.cpp,v 1.119 2004-02-11 15:38: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#include <pmkbdhk.h>
36#include <pmscan.h>
37#include <winscan.h>
38#include <winkeyboard.h>
39#include <winnls.h>
40#include <heapstring.h>
41#include "hook.h"
42#include "user32api.h"
43
44
45#define DBG_LOCALLOG DBG_oslibmsgtranslate
46#include "dbglocal.h"
47
48static BOOL fGenerateDoubleClick = FALSE;
49static MSG doubleClickMsg = {0};
50
51//For wheel mouse translation
52#define WHEEL_DELTA 120
53#define OS2_WHEEL_CORRECTION 1
54//PF Correction is different for different mouse drivers. For now no correction
55//is ok because lots of Odin controls rely on minimum delta. However in future
56//we will possibly detect mouse driver and use correction if speed will be
57//too high or too low.
58
59//******************************************************************************
60//
61// setThreadQueueExtraCharMessage: queues WM_CHAR message so it is retrieved
62// by GetMessage & PeekMessage
63//
64// NOTE: WM_CHAR message always in ascii format
65//
66//******************************************************************************
67BOOL setThreadQueueExtraCharMessage(TEB* teb, MSG* pExtraMsg)
68{
69 if ( teb->o.odin.tidAttachedInputThread
70 && OSLibForwardMessageToAttachedThread(teb, pExtraMsg, NULL))
71 return TRUE;
72
73 // check if the single slot is occupied already
74 if (teb->o.odin.fTranslated == TRUE) {
75 // there's still an already translated message to be processed
76 dprintf(("WARNING: translated message already pending!"));
77 return FALSE;
78 }
79
80 teb->o.odin.fTranslated = TRUE;
81 memcpy(&teb->o.odin.msgWCHAR, pExtraMsg, sizeof(MSG));
82 return TRUE;
83}
84
85//******************************************************************************
86//******************************************************************************
87ULONG ConvertNumPadKey(ULONG pmScan)
88{
89 ULONG ret;
90 BYTE winKey;
91
92 switch (pmScan)
93 {
94 case PMSCAN_PAD7: ret = PMSCAN_HOME; break;
95 case PMSCAN_PAD8: ret = PMSCAN_UP; break;
96 case PMSCAN_PAD9: ret = PMSCAN_PAGEUP; break;
97 case PMSCAN_PAD4: ret = PMSCAN_LEFT; break;
98 case PMSCAN_PAD6: ret = PMSCAN_RIGHT; break;
99 case PMSCAN_PAD1: ret = PMSCAN_END; break;
100 case PMSCAN_PAD2: ret = PMSCAN_DOWN; break;
101 case PMSCAN_PAD3: ret = PMSCAN_PAGEDOWN; break;
102 case PMSCAN_PAD0: ret = PMSCAN_INSERT; break;
103 case PMSCAN_PADPERIOD: ret = PMSCAN_DELETE; break;
104 default:
105 ret = pmScan;
106 }
107
108 KeyTranslatePMScanToWinVKey(ret, FALSE, (PBYTE)&winKey, NULL, NULL);
109 return winKey;
110
111}
112//******************************************************************************
113//******************************************************************************
114LONG IsNCMouseMsg(Win32BaseWindow *win32wnd)
115{
116 return ((win32wnd->getLastHitTestVal() != HTCLIENT_W) && (WinQueryCapture(HWND_DESKTOP) != win32wnd->getOS2WindowHandle()));
117}
118//******************************************************************************
119//******************************************************************************
120void OSLibSetMenuDoubleClick(BOOL fSet)
121{
122 fGenerateDoubleClick = fSet;
123}
124//******************************************************************************
125
126
127/**
128 * Inter process/thread packet cleanup.
129 * See OSLibPackMessage() for details on the packing.
130 *
131 * @param pTeb Pointer to the thread environment block for the current thread.
132 * @param pPacket Pointer to the packet in question.
133 * @param pWinMsg Pointer to the window message corresponding to the packet.
134 */
135inline void OSLibCleanupPacket(TEB *pTeb, POSTMSG_PACKET *pPacket, MSG *pWinMsg)
136{
137 switch (pWinMsg->message)
138 {
139 /*
140 * Place this in the TEB freeing any previous WM_COPYDATA packet.
141 * Note! Nested WM_COPYDATA isn't working.
142 */
143 case WINWM_COPYDATA:
144 {
145 dprintf(("OSLibCleanupPacket: WM_COPYDATA: old %#p new %#p", pTeb->o.odin.pWM_COPYDATA, pPacket));
146 if (pTeb->o.odin.pWM_COPYDATA)
147 _sfree(pTeb->o.odin.pWM_COPYDATA);
148 pTeb->o.odin.pWM_COPYDATA = pPacket;
149 break;
150 }
151
152 /*
153 * Default packing - free the shared memory here.
154 */
155 default:
156 _sfree(pPacket);
157 break;
158 }
159}
160
161//******************************************************************************
162BOOL OS2ToWinMsgTranslate(void *pTeb, QMSG *os2Msg, MSG *winMsg, BOOL isUnicode, BOOL fMsgRemoved)
163{
164 Win32BaseWindow *win32wnd = 0;
165 OSLIBPOINT point, ClientPoint;
166 POSTMSG_PACKET *packet;
167 TEB *teb = (TEB *)pTeb;
168 BOOL fWasDisabled = FALSE;
169 BOOL fIsFrame = FALSE;
170 int i;
171
172 /*
173 * Forwarded input (AttachThreadInput()).
174 */
175 if ( os2Msg->hwnd == NULLHANDLE
176 && os2Msg->msg == WIN32APP_FORWARDEDPOSTMSG
177 && os2Msg->mp2 == (MPARAM)WIN32APP_FORWARDEDPOSTMSG_MAGIC
178 && os2Msg->mp1 != NULL)
179 {
180 *winMsg = *(MSG*)os2Msg->mp1;
181 if (fMsgRemoved)
182 _sfree(os2Msg->mp1);
183 dprintf(("OS2ToWinMsgTranslate: Received forwarded messaged %x\n", os2Msg->msg));
184 return TRUE;
185 }
186
187 memset(winMsg, 0, sizeof(MSG));
188 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(os2Msg->hwnd);
189 if(!win32wnd) {
190 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(os2Msg->hwnd);
191 if(win32wnd) {
192 fIsFrame = TRUE;
193 }
194 }
195
196 //PostThreadMessage posts WIN32APP_POSTMSG msg without window handle
197 //Realplayer starts a timer with hwnd 0 & proc 0; check this here
198 if(win32wnd == 0 && (os2Msg->msg != WM_CREATE && os2Msg->msg != WM_QUIT && os2Msg->msg != WM_TIMER && os2Msg->msg < WIN32APP_POSTMSG))
199 {
200 goto dummymessage; //not a win32 client window
201 }
202 winMsg->time = os2Msg->time;
203 //CB: PM bug or undocumented feature? ptl.x highword is set!
204 winMsg->pt.x = os2Msg->ptl.x & 0xFFFF;
205 winMsg->pt.y = mapScreenY(os2Msg->ptl.y);
206
207 if(win32wnd) //==0 for WM_CREATE/WM_QUIT
208 winMsg->hwnd = win32wnd->getWindowHandle();
209
210 if(os2Msg->msg >= WIN32APP_POSTMSG) {
211 packet = (POSTMSG_PACKET *)os2Msg->mp2;
212 if(packet && ((ULONG)os2Msg->mp1 == WIN32MSG_MAGICA || (ULONG)os2Msg->mp1 == WIN32MSG_MAGICW)) {
213 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
214 winMsg->wParam = packet->wParam;
215 winMsg->lParam = packet->lParam;
216 if (fMsgRemoved == MSG_REMOVE)
217 OSLibCleanupPacket(teb, packet, winMsg);
218 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
219 return TRUE;
220 }
221 else {//broadcasted message (no packet present)
222 winMsg->message = os2Msg->msg - WIN32APP_POSTMSG;
223 winMsg->wParam = (UINT)os2Msg->mp1;
224 winMsg->lParam = (DWORD)os2Msg->mp2;
225 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
226 return TRUE;
227 }
228 goto dummymessage;
229 }
230
231 switch(os2Msg->msg)
232 {
233 //OS/2 msgs
234 case WM_CREATE:
235 {
236 if(teb->o.odin.newWindow == 0) {
237 DebugInt3();
238 goto dummymessage;
239 }
240
241 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
242 win32wnd->addRef();
243
244 winMsg->message = WINWM_CREATE;
245 winMsg->hwnd = win32wnd->getWindowHandle();
246 winMsg->wParam = 0;
247 winMsg->lParam = (LPARAM)win32wnd->tmpcs;
248 break;
249 }
250
251 case WM_QUIT:
252 winMsg->message = WINWM_QUIT;
253 if (fMsgRemoved && win32wnd && (ULONG)os2Msg->mp2 != 0) {
254 // mp2 != 0 -> sent by window list; be nice and close
255 // the window first
256 win32wnd->MsgClose();
257 }
258 break;
259
260 case WM_CLOSE:
261 winMsg->message = WINWM_CLOSE;
262 break;
263
264 case WM_DESTROY:
265 winMsg->message = WINWM_DESTROY;
266 break;
267
268 case WM_ENABLE:
269 winMsg->message = WINWM_ENABLE;
270 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
271 break;
272
273 case WM_SHOW:
274 winMsg->message = WINWM_SHOWWINDOW;
275 winMsg->wParam = SHORT1FROMMP(os2Msg->mp1);
276 break;
277
278 case WM_REALIZEPALETTE:
279 winMsg->message = WINWM_PALETTECHANGED;
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 //If SetFocus(0) was called, then the window has already received
368 //a WM_KILLFOCUS; don't send another one
369 if(!fIgnoreKeystrokes) {
370 winMsg->message = WINWM_KILLFOCUS;
371 winMsg->wParam = (WPARAM)hwndFocus;
372 }
373 else {
374 dprintf(("Window has already received a WM_KILLFOCUS (SetFocus(0)); ignore"));
375 goto dummymessage;
376 }
377 }
378 break;
379 }
380
381 //**************************************************************************
382 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
383 //**************************************************************************
384 case WM_BUTTON1DOWN:
385 case WM_BUTTON1UP:
386 case WM_BUTTON1DBLCLK:
387 case WM_BUTTON2DOWN:
388 case WM_BUTTON2UP:
389 case WM_BUTTON2DBLCLK:
390 case WM_BUTTON3DOWN:
391 case WM_BUTTON3UP:
392 case WM_BUTTON3DBLCLK:
393 {
394 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
395
396 dprintf(("MsgButton %x (%x) %d at (%d,%d) time %x", winMsg->hwnd, os2Msg->hwnd, WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN), winMsg->pt.x, winMsg->pt.y, winMsg->time));
397
398 HWND hwnd;
399
400 DisableLogging();
401 if(GetCapture() != winMsg->hwnd)
402 {
403 hwnd = WindowFromPoint(winMsg->pt);
404 if(win32wnd->getWindowHandle() != hwnd) {
405 RELEASE_WNDOBJ(win32wnd);
406 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
407 if(win32wnd == NULL) {
408 DebugInt3();
409 EnableLogging();
410 goto dummymessage;
411 }
412 winMsg->hwnd = hwnd;
413 }
414 }
415
416 //if a window is disabled, its parent receives the mouse messages
417 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
418 if(win32wnd->getParent()) {
419 Win32BaseWindow *parent = win32wnd->getParent();;
420 if(parent) parent->addRef();
421 RELEASE_WNDOBJ(win32wnd);
422 win32wnd = parent;
423 }
424 fWasDisabled = TRUE;
425 }
426
427 if(IsNCMouseMsg(win32wnd)) {
428 winMsg->message = WINWM_NCLBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
429 winMsg->wParam = win32wnd->getLastHitTestVal();
430 winMsg->lParam = MAKELONG(winMsg->pt.x, winMsg->pt.y); //screen coordinates
431 }
432 else {
433 ClientPoint.x = winMsg->pt.x;
434 ClientPoint.y = winMsg->pt.y;
435 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
436 winMsg->message = WINWM_LBUTTONDOWN + (os2Msg->msg - WM_BUTTON1DOWN);
437 winMsg->wParam = GetMouseKeyState();
438 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
439 }
440 EnableLogging();
441
442 if(fWasDisabled) {
443 if(win32wnd) {
444 winMsg->hwnd = win32wnd->getWindowHandle();
445 }
446 else goto dummymessage; //don't send mouse messages to disabled windows
447 }
448
449 DisableLogging();
450 if ((winMsg->message == WINWM_LBUTTONDOWN) ||
451 (winMsg->message == WINWM_RBUTTONDOWN) ||
452 (winMsg->message == WINWM_MBUTTONDOWN) ||
453 (winMsg->message == WINWM_NCLBUTTONDOWN) ||
454 (winMsg->message == WINWM_NCRBUTTONDOWN) ||
455 (winMsg->message == WINWM_NCMBUTTONDOWN))
456 {
457 if(fGenerateDoubleClick && doubleClickMsg.message == winMsg->message &&
458 winMsg->time - doubleClickMsg.time < GetDoubleClickTime() &&
459 (abs(winMsg->pt.x - doubleClickMsg.pt.x) < GetSystemMetrics(SM_CXDOUBLECLK_W)/2) &&
460 (abs(winMsg->pt.y - doubleClickMsg.pt.y) < GetSystemMetrics(SM_CYDOUBLECLK_W)/2))
461 {
462 dprintf(("single -> double click"));
463 if(winMsg->message >= WINWM_LBUTTONDOWN) {
464 winMsg->message += (WINWM_LBUTTONDBLCLK - WINWM_LBUTTONDOWN);
465 }
466 else winMsg->message += (WINWM_LBUTTONDBLCLK - WINWM_NCLBUTTONDOWN);
467 if(fMsgRemoved) doubleClickMsg.message = 0;
468 }
469 else {
470 dprintf(("save for double click"));
471 if(fMsgRemoved) {
472 doubleClickMsg = *winMsg;
473 if(doubleClickMsg.message >= WINWM_NCLBUTTONDOWN && doubleClickMsg.message <= WINWM_NCMBUTTONDOWN) {
474 doubleClickMsg.message += (WINWM_LBUTTONDOWN - WINWM_NCLBUTTONDOWN);
475 }
476 }
477 }
478 }
479 EnableLogging();
480
481 if(fMsgRemoved == MSG_REMOVE)
482 {
483 MSLLHOOKSTRUCT hook;
484 ULONG msg;
485
486 if(winMsg->message >= WINWM_NCLBUTTONDOWN && winMsg->message <= WINWM_NCMBUTTONDBLCLK) {
487 msg = winMsg->message - WINWM_NCLBUTTONDOWN + WINWM_LBUTTONDOWN;
488 }
489 else msg = winMsg->message;
490
491 if(msg == WINWM_LBUTTONDBLCLK) {
492 msg = WINWM_LBUTTONDOWN;
493 }
494 else
495 if(msg == WINWM_RBUTTONDBLCLK) {
496 msg = WINWM_RBUTTONDOWN;
497 }
498 else
499 if(msg == WINWM_MBUTTONDBLCLK) {
500 msg = WINWM_MBUTTONDOWN;
501 }
502
503 hook.pt.x = os2Msg->ptl.x & 0xFFFF;
504 hook.pt.y = mapScreenY(os2Msg->ptl.y);
505 hook.mouseData = 0; //todo: XBUTTON1/2 (XP feature) or wheel data
506 hook.flags = 0; //todo: injected (LLMHF_INJECTED)
507 hook.time = winMsg->time;
508 hook.dwExtraInfo = 0;
509
510 if(HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, msg, (LPARAM)&hook)) {
511 goto dummymessage; //hook swallowed message
512 }
513 }
514 break;
515 }
516
517 case WM_BUTTON2CLICK:
518 case WM_BUTTON1CLICK:
519 case WM_BUTTON3CLICK:
520 goto dummymessage;
521
522 case WM_BUTTON2MOTIONSTART:
523 case WM_BUTTON2MOTIONEND:
524 case WM_BUTTON1MOTIONSTART:
525 case WM_BUTTON1MOTIONEND:
526 case WM_BUTTON3MOTIONSTART:
527 case WM_BUTTON3MOTIONEND:
528 //no break; translate to WM_MOUSEMOVE
529 //Some applications (e.g. Unreal) retrieve all mouse messages
530 //when a mouse button is pressed and don't expect WM_NULL
531
532 case WM_MOUSEMOVE:
533 {
534 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
535
536 HWND hwnd;
537
538 dprintf2(("WM_MOUSEMOVE (%d,%d)", winMsg->pt.x, winMsg->pt.y));
539 DisableLogging();
540 if(GetCapture() != winMsg->hwnd)
541 {
542 hwnd = WindowFromPoint(winMsg->pt);
543 if(win32wnd->getWindowHandle() != hwnd) {
544 RELEASE_WNDOBJ(win32wnd);
545 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
546 if(win32wnd == NULL) {
547 DebugInt3();
548 EnableLogging();
549 goto dummymessage;
550 }
551 winMsg->hwnd = hwnd;
552 }
553 }
554
555 //if a window is disabled, its parent receives the mouse messages
556 if(!IsWindowEnabled(win32wnd->getWindowHandle())) {
557 if(win32wnd->getParent()) {
558 Win32BaseWindow *parent = win32wnd->getParent();;
559 if(parent) parent->addRef();
560 RELEASE_WNDOBJ(win32wnd);
561 win32wnd = parent;
562 }
563 fWasDisabled = TRUE;
564 }
565 if(IsNCMouseMsg(win32wnd))
566 {
567 winMsg->message = WINWM_NCMOUSEMOVE;
568 winMsg->wParam = (WPARAM)win32wnd->getLastHitTestVal();
569 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
570 }
571 else
572 {
573 ClientPoint.x = winMsg->pt.x;
574 ClientPoint.y = winMsg->pt.y;
575 MapWindowPoints(0, win32wnd->getWindowHandle(), (LPPOINT)&ClientPoint, 1);
576
577 winMsg->message = WINWM_MOUSEMOVE;
578 winMsg->wParam = GetMouseKeyState();
579 winMsg->lParam = MAKELONG(ClientPoint.x, ClientPoint.y); //client coordinates
580 }
581 EnableLogging();
582 if(fWasDisabled) {
583 if(win32wnd) {
584 winMsg->hwnd = win32wnd->getWindowHandle();
585 }
586 else {
587 goto dummymessage; //don't send mouse messages to disabled windows
588 }
589 }
590 if(fMsgRemoved == MSG_REMOVE)
591 {
592 MSLLHOOKSTRUCT hook;
593
594 hook.pt.x = os2Msg->ptl.x & 0xFFFF;
595 hook.pt.y = mapScreenY(os2Msg->ptl.y);
596 hook.mouseData = 0;
597 hook.flags = 0; //todo: injected (LLMHF_INJECTED)
598 hook.time = winMsg->time;
599 hook.dwExtraInfo = 0;
600
601 if(HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, winMsg->message, (LPARAM)&hook)) {
602 goto dummymessage; //hook swallowed message
603 }
604 }
605 break;
606 }
607
608 case WM_CONTROL:
609 goto dummymessage;
610
611 case WM_COMMAND:
612 if(SHORT1FROMMP(os2Msg->mp2) == CMDSRC_MENU) {
613 winMsg->message = WINWM_COMMAND;
614 winMsg->wParam = (WPARAM)SHORT1FROMMP(os2Msg->mp1); //id
615 break;
616 }
617 //todo controls
618 goto dummymessage;
619
620 case WM_SYSCOMMAND:
621 {
622 ULONG x = 0, y = 0;
623 ULONG win32sc;
624
625 if(SHORT2FROMMP(os2Msg->mp2) == TRUE) {//syscommand caused by mouse action
626 POINTL pointl;
627 WinQueryPointerPos(HWND_DESKTOP, &pointl);
628 x = pointl.x;
629 y = mapScreenY(y);
630 }
631 switch(SHORT1FROMMP(os2Msg->mp1)) {
632 case SC_MOVE:
633 win32sc = SC_MOVE_W;
634 break;
635 case SC_CLOSE:
636 {
637 //FALSE -> keyboard operation = user pressed Alt-F4 -> close app
638 //TRUE -> user clicked on close button -> close window
639 if(SHORT2FROMMP(os2Msg->mp2) == FALSE)
640 {
641 HWND hwnd = win32wnd->GetTopParent();
642 if(win32wnd->getWindowHandle() != hwnd) {
643 RELEASE_WNDOBJ(win32wnd);
644 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
645 if(win32wnd == NULL) {
646 DebugInt3();
647 goto dummymessage;
648 }
649 winMsg->hwnd = hwnd;
650 }
651 }
652 win32sc = SC_CLOSE_W;
653 break;
654 }
655 case SC_MAXIMIZE:
656 win32sc = SC_MAXIMIZE_W;
657 break;
658 case SC_MINIMIZE:
659 win32sc = SC_MINIMIZE_W;
660 break;
661 case SC_NEXTFRAME:
662 case SC_NEXTWINDOW:
663 win32sc = SC_NEXTWINDOW_W;
664 break;
665 case SC_RESTORE:
666 win32sc = SC_RESTORE_W;
667 break;
668 case SC_TASKMANAGER:
669 win32sc = SC_TASKLIST_W;
670 break;
671 case SC_SYSMENU:
672 win32sc = SC_KEYMENU_W; //??
673 break;
674 default:
675 dprintf(("Unknown/unsupported SC command %d", SHORT1FROMMP(os2Msg->mp1)));
676 goto dummymessage;
677 }
678 winMsg->message= WINWM_SYSCOMMAND;
679 winMsg->wParam = (WPARAM)win32sc;
680 winMsg->lParam = MAKELONG((USHORT)x, (USHORT)y);
681 break;
682 }
683
684 case WM_CHAR_SPECIAL_ALTGRCONTROL:
685 {
686 // special char message from the keyboard hook
687 dprintf(("PM: WM_CHAR_SPECIAL_ALTGRCONTROL"));
688 // NO BREAK! FALLTHRU CASE!
689 }
690
691 case WM_CHAR_SPECIAL:
692 {
693 // @@@PH
694 // special char message from the keyboard hook
695 if(os2Msg->msg == WM_CHAR_SPECIAL) {
696 dprintf(("PM: WM_CHAR_SPECIAL"));
697 }
698 // NO BREAK! FALLTHRU CASE!
699 }
700
701 case WM_CHAR:
702 {
703 ULONG repeatCount=0;
704 ULONG virtualKey=0;
705 ULONG keyFlags=0;
706 USHORT scanCode=0;
707 ULONG flags = SHORT1FROMMP(os2Msg->mp1);
708 BOOL keyWasPressed;
709 BOOL numPressed = (BOOL)(WinGetKeyState(HWND_DESKTOP,VK_NUMLOCK) & 1);
710 char c;
711 USHORT usPMScanCode = CHAR4FROMMP(os2Msg->mp1);
712
713 teb->o.odin.fTranslated = FALSE;
714 repeatCount = CHAR3FROMMP(os2Msg->mp1);
715 scanCode = CHAR4FROMMP(os2Msg->mp1);
716 keyWasPressed = ((SHORT1FROMMP (os2Msg->mp1) & KC_PREVDOWN) == KC_PREVDOWN);
717
718 dprintf(("PM: WM_CHAR: %x %x rep=%d scancode=%x num=%d", SHORT1FROMMP(os2Msg->mp2), SHORT2FROMMP(os2Msg->mp2), repeatCount, scanCode, numPressed));
719 dprintf(("PM: WM_CHAR: hwnd %x flags %x mp1 %x, mp2 %x, time=%08xh", win32wnd->getWindowHandle(), flags, os2Msg->mp1, os2Msg->mp2, os2Msg->time));
720
721 BOOL fWinExtended;
722 BYTE bWinVKey;
723 WORD wWinScan;
724
725 if ( (!IsDBCSEnv() && scanCode == 0) ||
726 (scanCode==0 ) && !( flags & KC_CHAR ) )
727 {
728 goto dummymessage;
729 }
730
731 if( scanCode != 0 )
732 {
733 KeyTranslatePMScanToWinVKey(usPMScanCode,
734 FALSE,
735 &bWinVKey,
736 &wWinScan,
737 &fWinExtended);
738 winMsg->wParam = bWinVKey;
739 }
740 else
741 {
742 dprintf(("PM: WM_CHAR: DBCS processing "));
743
744 winMsg->wParam = CHAR1FROMMP( os2Msg->mp2 );
745
746 wWinScan = 0;
747 fWinExtended = 0;
748
749 if( CHAR2FROMMP( os2Msg->mp2 )) // DBCS character
750 {
751 CHAR dbcsCh[ 2 ] = { CHAR1FROMMP( os2Msg->mp2 ), CHAR2FROMMP( os2Msg->mp2 )};
752
753 if( isUnicode )
754 {
755 WCHAR uniChar;
756
757 MultiByteToWideChar( CP_ACP, 0, dbcsCh, 2, &uniChar, 1 );
758 winMsg->wParam = ( WPARAM )uniChar;
759 }
760 else
761 winMsg->wParam = ( dbcsCh[ 0 ] << 8 ) | dbcsCh[ 1 ];
762 }
763 }
764 winMsg->lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
765 winMsg->lParam |= (wWinScan & 0x1FF) << 16; // bit 16-23, scancode + bit 15 extended
766
767 // Set the extended bit when appropriate
768 if (fWinExtended)
769 winMsg->lParam = winMsg->lParam | WIN_KEY_EXTENDED;
770
771 //PF When we press shift we enable non-numeric functions of Numpad
772 if ((!numPressed || (flags & KC_SHIFT)) && (scanCode >= PMSCAN_PAD7) && (scanCode <= PMSCAN_PADPERIOD))
773 winMsg->wParam = ConvertNumPadKey(scanCode);
774
775 //@PF This looks ugly but this is just what we have in win32 both in win98/win2k
776 //what happens is that lParam is tweaked in win32 to contain some illegal codes
777 //I simply reproduce here all situation. Absolute values can be kept because
778 //Break scancode can be acheived only by pressing Ctrl-Break combination
779 if ((usPMScanCode == PMSCAN_BREAK) && !(flags & KC_KEYUP) && (flags & KC_CTRL)
780 && (fMsgRemoved && !(teb->o.odin.fTranslated)))
781 {
782 MSG extramsg;
783 memcpy(&extramsg, winMsg, sizeof(MSG));
784 // adjust our WM_CHAR code
785 extramsg.lParam = 0x01460001;
786
787 //After SetFocus(0), all keystrokes are converted in WM_SYS*
788 extramsg.message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR;
789
790 setThreadQueueExtraCharMessage(teb, &extramsg);
791 // and finally adjust our WM_KEYDOWN code
792 winMsg->lParam = 0x01460001;
793 }
794
795 if (!(flags & KC_ALT))
796 {
797 //
798 // the Alt key is not pressed
799 // or no more pressed
800 //
801 if (flags & KC_KEYUP)
802 {
803 // check for a lonesome ALT key ...
804 // SvL: Only Left Alt; AltGr generates a WM_KEYUP when released
805 if ( (flags & KC_LONEKEY) &&
806 (winMsg->wParam == VK_LMENU_W) )
807 {
808 winMsg->message = WINWM_SYSKEYUP;
809 // held ALT-key when current key is released
810 // generates additional flag 0x2000000
811 // Note: PM seems to do this differently,
812 // KC_ALT is already reset
813 }
814 else
815 {
816 // send WM_KEYUP message
817 winMsg->message = WINWM_KEYUP;
818 }
819 winMsg->lParam |= WIN_KEY_PREVSTATE; // bit 30, previous state, always 1 for a WM_KEYUP message
820 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
821 }
822 else if( scanCode == 0 )
823 {
824 if( CHAR2FROMMP( os2Msg->mp2 ))
825 winMsg->message = WINWM_IME_CHAR;
826 else
827 {
828 //After SetFocus(0), all keystrokes are converted in WM_SYS*
829 winMsg->message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR;
830 }
831 }
832 else
833 { // send WM_KEYDOWN message
834 winMsg->message = WINWM_KEYDOWN;
835
836 if (keyWasPressed)
837 winMsg->lParam |= WIN_KEY_PREVSTATE; // bit 30, previous state, 1 means key was pressed
838
839 //Shift-Enter and possibly others need to have special handling
840 if (flags & KC_SHIFT)
841 {
842 if(fMsgRemoved && !(teb->o.odin.fTranslated))
843 {
844 dprintf(("PM: KC_SHIFT: %x",winMsg->wParam));
845 if (winMsg->wParam == VK_RETURN_W)
846 {
847 MSG extramsg;
848 memcpy(&extramsg, winMsg, sizeof(MSG));
849
850 //After SetFocus(0), all keystrokes are converted in WM_SYS*
851 extramsg.message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR;
852
853 // insert message into the queue
854 setThreadQueueExtraCharMessage(teb, &extramsg);
855 winMsg->lParam &= 0x3FFFFFFF;
856 }
857 } // else ???
858 } // KC_SHIFT
859 else
860 {
861 // in case we handle Enter directly through PMKBDHOOK
862 if ((os2Msg->msg == WM_CHAR_SPECIAL) && (winMsg->wParam == VK_RETURN_W)
863 && (fMsgRemoved && !(teb->o.odin.fTranslated)))
864 {
865 MSG extramsg;
866 memcpy(&extramsg, winMsg, sizeof(MSG));
867
868 //After SetFocus(0), all keystrokes are converted in WM_SYS*
869 extramsg.message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR;
870
871 // insert message into the queue
872 setThreadQueueExtraCharMessage(teb, &extramsg);
873 }
874 }
875 }
876 // if right alt is down, then we need to set the alt down bit too
877 // except for the fake Ctrl WM_CHAR sent for AltGr emulation
878 if (os2Msg->msg != WM_CHAR_SPECIAL_ALTGRCONTROL &&
879 (WinGetKeyState(HWND_DESKTOP, VK_ALTGRAF) & 0x8000))
880 {
881 winMsg->lParam |= WIN_KEY_ALTHELD;
882 }
883 }
884 else
885 {
886 //
887 // the Alt key is pressed
888 //
889 if (flags & KC_KEYUP)
890 {
891 //@@PF Note that without pmkbdhook there will not be correct message for Alt-Enter
892 winMsg->message = WINWM_SYSKEYUP;
893 winMsg->lParam |= WIN_KEY_PREVSTATE;
894 // No ALTHELD for Alt itself ;)
895 winMsg->lParam |= WIN_KEY_ALTHELD;
896 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
897 }
898 else
899 {
900 // send WM_SYSKEYDOWN message
901 winMsg->message = WINWM_SYSKEYDOWN;
902 if (keyWasPressed)
903 winMsg->lParam |= WIN_KEY_PREVSTATE; // bit 30, previous state, 1 means key was pressed
904
905 // pressed ALT-key generates additional flag 0x2000000
906 // if the current window has keyboard focus
907 winMsg->lParam |= WIN_KEY_ALTHELD;
908 }
909 }
910
911 //After SetFocus(0), all keystrokes are converted in WM_SYS*
912 if(fIgnoreKeystrokes) {
913 if(winMsg->message == WINWM_KEYDOWN) {
914 winMsg->message = WINWM_SYSKEYDOWN;
915 }
916 else
917 if(winMsg->message == WINWM_KEYUP) {
918 winMsg->message = WINWM_SYSKEYUP;
919 }
920 }
921 break;
922 }
923
924 case WM_TIMER:
925//Why was this check here????
926// if (os2Msg->mp2)
927// {
928 BOOL sys;
929 ULONG id, proc;
930
931 if (TIMER_GetTimerInfo(os2Msg->hwnd,(ULONG)os2Msg->mp1,&sys,&id, &proc))
932 {
933 winMsg->wParam = (WPARAM)id;
934 winMsg->lParam = (LPARAM)proc;
935 winMsg->message= (sys) ? WINWM_SYSTIMER : WINWM_TIMER;
936 break;
937 }
938// }
939 goto dummymessage; //for caret blinking
940
941 case WM_SETWINDOWPARAMS:
942 {
943 WNDPARAMS *wndParams = (WNDPARAMS *)os2Msg->mp1;
944
945 if(wndParams->fsStatus & WPM_TEXT) {
946 winMsg->message = WINWM_SETTEXT;
947 winMsg->lParam = (LPARAM)wndParams->pszText;
948 break;
949 }
950 goto dummymessage;
951 }
952
953#if 0
954 case WM_QUERYWINDOWPARAMS:
955 {
956 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
957 ULONG textlen;
958 PSZ wintext;
959
960 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
961 {
962 if(wndpars->fsStatus & WPM_CCHTEXT)
963 wndpars->cchText = win32wnd->MsgGetTextLength();
964 if(wndpars->fsStatus & WPM_TEXT)
965 wndpars->pszText = win32wnd->MsgGetText();
966
967 wndpars->fsStatus = 0;
968 wndpars->cbCtlData = 0;
969 wndpars->cbPresParams = 0;
970 goto dummymessage;
971 }
972 }
973#endif
974
975 case WM_PAINT:
976 {
977 if(win32wnd->IsWindowIconic()) {
978 winMsg->message = WINWM_PAINTICON;
979 }
980 else winMsg->message = WINWM_PAINT;
981 break;
982 }
983
984 case WM_CONTEXTMENU:
985 winMsg->message = WINWM_CONTEXTMENU;
986 winMsg->wParam = win32wnd->getWindowHandle();
987 winMsg->lParam = MAKELONG(winMsg->pt.x,winMsg->pt.y);
988 break;
989
990 case WM_RENDERFMT:
991 winMsg->message = WINWM_RENDERFORMAT;
992 winMsg->wParam = (UINT) os2Msg->mp1;
993 break;
994
995 case WM_RENDERALLFMTS:
996 winMsg->message = WINWM_RENDERALLFORMATS;
997 break;
998
999 case WM_DESTROYCLIPBOARD:
1000 winMsg->message = WINWM_DESTROYCLIPBOARD;
1001 break;
1002
1003 case WM_DRAWCLIPBOARD:
1004 winMsg->message = WINWM_DRAWCLIPBOARD;
1005 break;
1006
1007 case WM_HSCROLL:
1008 case WM_VSCROLL:
1009 //PF For win32 we support only vertical scrolling for WM_MOUSEWHEEL
1010 if (os2Msg->msg == WM_VSCROLL)
1011 {
1012 POINT CursorPoint;
1013 winMsg->message = WINWM_MOUSEWHEEL;
1014 if (OSLibWinQueryPointerPos(&CursorPoint))
1015 mapScreenPoint((OSLIBPOINT*)&CursorPoint);
1016
1017 if (SHORT2FROMMP(os2Msg->mp2) == SB_LINEDOWN)
1018 winMsg->wParam = MAKELONG(GetMouseKeyState(), -WHEEL_DELTA/OS2_WHEEL_CORRECTION);
1019 else
1020 if (SHORT2FROMMP(os2Msg->mp2) == SB_LINEUP)
1021 winMsg->wParam = MAKELONG(GetMouseKeyState(), WHEEL_DELTA/OS2_WHEEL_CORRECTION);
1022 else
1023 winMsg->wParam = MAKELONG(GetMouseKeyState(), 0);
1024
1025 winMsg->lParam = MAKELONG(CursorPoint.x, CursorPoint.y);
1026
1027 dprintf(("WM_MOUSEWHEEL message delta %d at (%d,%d)",HIWORD(winMsg->wParam),CursorPoint.x, CursorPoint.y));
1028 if (fMsgRemoved == MSG_REMOVE)
1029 {
1030 MSLLHOOKSTRUCT hook;
1031
1032 hook.pt.x = os2Msg->ptl.x & 0xFFFF;
1033 hook.pt.y = mapScreenY(os2Msg->ptl.y);
1034 if (SHORT2FROMMP(os2Msg->mp2) == SB_LINEDOWN)
1035 hook.mouseData = MAKELONG(GetMouseKeyState(), -WHEEL_DELTA/OS2_WHEEL_CORRECTION);
1036 else
1037 if (SHORT2FROMMP(os2Msg->mp2) == SB_LINEUP)
1038 hook.mouseData = MAKELONG(GetMouseKeyState(), WHEEL_DELTA/OS2_WHEEL_CORRECTION);
1039 else goto dummymessage; // IBM driver produces other messages as well sometimes
1040
1041 hook.flags = LLMHF_INJECTED;
1042 hook.time = winMsg->time;
1043 hook.dwExtraInfo = 0;
1044 if(HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, WINWM_MOUSEWHEEL, (LPARAM)&hook))
1045 goto dummymessage; //hook swallowed message
1046 }
1047 break;
1048 }
1049 goto dummymessage; //eat this message
1050 break;
1051
1052 case WM_INITMENU:
1053 case WM_MENUSELECT:
1054 case WM_MENUEND:
1055 case WM_NEXTMENU:
1056 case WM_SYSCOLORCHANGE:
1057 case WM_SYSVALUECHANGED:
1058 case WM_SETSELECTION:
1059 case WM_PPAINT:
1060 case WM_PSETFOCUS:
1061 case WM_PSYSCOLORCHANGE:
1062 case WM_PSIZE:
1063 case WM_PACTIVATE:
1064 case WM_PCONTROL:
1065 case WM_HELP:
1066 case WM_APPTERMINATENOTIFY:
1067 case WM_PRESPARAMCHANGED:
1068 case WM_DRAWITEM:
1069 case WM_MEASUREITEM:
1070 case WM_CONTROLPOINTER:
1071 case WM_QUERYDLGCODE:
1072 case WM_SUBSTITUTESTRING:
1073 case WM_MATCHMNEMONIC:
1074 case WM_SAVEAPPLICATION:
1075 case WM_SEMANTICEVENT:
1076 default:
1077dummymessage:
1078 dprintf2(("dummy message %x %x %x %x", os2Msg->hwnd, os2Msg->msg, os2Msg->mp1, os2Msg->mp2));
1079 winMsg->message = 0;
1080 winMsg->wParam = 0;
1081 winMsg->lParam = 0;
1082 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1083 return FALSE;
1084 }
1085msgdone:
1086 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1087 return TRUE;
1088}
1089//******************************************************************************
1090//******************************************************************************
1091BOOL OSLibWinTranslateMessage(MSG *msg)
1092{
1093 TEB *teb;
1094 MSG extramsg;
1095 BOOL numPressed = (BOOL)(WinGetKeyState(HWND_DESKTOP,VK_NUMLOCK) & 1);
1096 teb = GetThreadTEB();
1097 if(!teb)
1098 return FALSE;
1099
1100 UCHAR ucPMScanCode = CHAR4FROMMP(teb->o.odin.os2msg.mp1);
1101 ULONG fl = SHORT1FROMMP(teb->o.odin.os2msg.mp1);
1102
1103
1104 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
1105 // the newly generated WM_CHAR message.
1106 if(!teb->o.odin.fTranslated &&
1107 teb->o.odin.os2msg.msg == WM_CHAR &&
1108 !((SHORT1FROMMP(teb->o.odin.os2msg.mp1) & KC_KEYUP) == KC_KEYUP))
1109 {
1110 //TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
1111 memcpy(&extramsg, msg, sizeof(MSG));
1112 extramsg.wParam = SHORT1FROMMP(teb->o.odin.os2msg.mp2);
1113 extramsg.lParam = 0;
1114
1115 // ESCAPE generates a WM_CHAR under windows, so take
1116 // special care for this here.
1117 switch (ucPMScanCode)
1118 {
1119 case PMSCAN_ESC:
1120 extramsg.wParam = VK_ESCAPE_W;
1121 fl |= KC_CHAR;
1122 break;
1123 }
1124
1125 // PF With NumLock off do not generate any WM_CHAR messages at all
1126 // PADMINUS,PADPLUS fall in range of PAD7..PADPERIOD but they should generate WM_CHAR
1127 // other PAD(X) buttons miss that range at all and thus generate WM_CHAR
1128 if (!numPressed && (ucPMScanCode != PMSCAN_PADMINUS) && (ucPMScanCode != PMSCAN_PADPLUS) &&
1129 (ucPMScanCode >= PMSCAN_PAD7) && (ucPMScanCode <= PMSCAN_PADPERIOD))
1130 return FALSE;
1131
1132 if(!(fl & KC_CHAR) && msg->message < WINWM_SYSKEYDOWN)
1133 {
1134 return FALSE;
1135 }
1136
1137 //the KC_COMPOSITE flag might be set; in that case this key will
1138 //be combined with the previous dead key, so we must use the scancode
1139 //(e.g. ^ on german keyboards)
1140 if((fl & (KC_VIRTUALKEY|KC_COMPOSITE)) == KC_VIRTUALKEY)
1141 {
1142 if(msg->wParam)
1143 {
1144 if ((msg->wParam >= VK_NUMPAD0_W) &&
1145 (msg->wParam <= VK_NUMPAD9_W))
1146 extramsg.wParam = msg->wParam - 0x30;
1147 else
1148 if (msg->wParam == VK_DECIMAL_W)
1149 extramsg.wParam = VK_DELETE_W;
1150 else
1151 /* PM Sends Bogus Things when pressing Shift+NUMAsterisk */
1152 if (msg->wParam != VK_MULTIPLY_W)
1153 extramsg.wParam = msg->wParam;
1154 }
1155 else
1156 extramsg.wParam = SHORT2FROMMP(teb->o.odin.os2msg.mp2);
1157 }
1158
1159
1160 //After SetFocus(0), all keystrokes are converted in WM_SYS*
1161 if(msg->message >= WINWM_SYSKEYDOWN || fIgnoreKeystrokes)
1162 extramsg.message = WINWM_SYSCHAR;
1163 else
1164 extramsg.message = WINWM_CHAR;
1165
1166 if(fl & KC_DEADKEY)
1167 extramsg.message++; //WM_DEADCHAR/WM_SYSDEADCHAR
1168
1169
1170 extramsg.lParam = msg->lParam & 0x00FFFFFF;
1171 if ((fl & KC_ALT) || (msg->lParam & WIN_KEY_ALTHELD))
1172 extramsg.lParam |= WIN_KEY_ALTHELD;
1173 if(fl & KC_PREVDOWN)
1174 extramsg.lParam |= WIN_KEY_PREVSTATE;
1175 if(fl & KC_KEYUP)
1176 extramsg.lParam |= (1<<31);
1177
1178 // insert message into the queue
1179 setThreadQueueExtraCharMessage(teb, &extramsg);
1180
1181 return TRUE;
1182 }
1183 return FALSE;
1184}
1185//******************************************************************************
1186//******************************************************************************
1187
1188/**
1189 * Checks if the message is one that should be forwarded.
1190 *
1191 * @returns True if the message should be forwarded.
1192 * @returns False if the message doesn't fall in to that group.
1193 * @param pMsg Message to examin.
1194 * @remark Are there more messages???
1195 */
1196BOOL OSLibForwardableMessage(const MSG *pMsg)
1197{
1198 return ( (pMsg->message >= WINWM_KEYFIRST && pMsg->message <= WINWM_KEYLAST)
1199 || (pMsg->message >= WINWM_MOUSEFIRST && pMsg->message <= WINWM_MOUSELAST) );
1200}
1201
1202/**
1203 * Forwards this message to the attached thread if it's in the group of messages
1204 * which is supposed to be forwarded.
1205 *
1206 * @returns True if forwarded.
1207 * @returns False if not forwarded.
1208 * @param pTeb Pointer to the TEB of the current thread.
1209 * @param pMsg Message to forward.
1210 * @author knut st. osmundsen <bird-srcspam@anduin.net>
1211 */
1212BOOL OSLibForwardMessageToAttachedThread(void *pvTeb, MSG *pMsg, void *hmm)
1213{
1214 TEB *pTeb = (TEB *)pvTeb;
1215 dprintf(("OSLibForwardMessageToAttachedThread: %p %p (msg=%x)\n", pvTeb, pMsg, pMsg->message));
1216 if (!OSLibForwardableMessage(pMsg))
1217 return FALSE;
1218
1219 /*
1220 * Find the actual receiver thread.
1221 */
1222 int c = 100;
1223 TEB *pTebTo = pTeb;
1224 do
1225 {
1226 pTebTo = GetTEBFromThreadId(pTebTo->o.odin.tidAttachedInputThread);
1227 } while (c-- > 0 && !pTebTo && pTebTo->o.odin.tidAttachedInputThread);
1228 if (!c || !pTebTo)
1229 {
1230 if (c) dprintf(("OSLibForwardMessageToAttachedThread: The receiver thread is dead or non existing.\n"));
1231 else dprintf(("OSLibForwardMessageToAttachedThread: threads are attached in looooop.\n"));
1232 return FALSE; /* hmm.... */
1233 }
1234 dprintf(("OSLibForwardMessageToAttachedThread: Forwarding message %#x to %#x\n",
1235 pMsg->message, pTeb->o.odin.tidAttachedInputThread));
1236
1237 /*
1238 * Pack down the message into shared memory.
1239 */
1240 MSG *pMsgCopy = (MSG *)_smalloc(sizeof(MSG));
1241 if (!pMsgCopy)
1242 return FALSE;
1243 *pMsgCopy = *pMsg;
1244
1245 /*
1246 * Figure out how we should send the message.
1247 */
1248 if (WinInSendMsg(pTebTo->o.odin.hab))
1249 {
1250#if 0
1251 /*
1252 * Hmm what do we do here....
1253 */
1254 MRESULT rc = WinSendQueueMsg(pTebTo->o.odin.hmq, /*special! */, pMsgCopy, /*magic*/ );
1255 /* if (hmmSendMsgResult)
1256 *hmmSendMsgResult = (???)rc; */
1257#else
1258 dprintf(("OSLibForwardMessage: ERROR! %x in sendmsg!!!\n", pMsg->message));
1259 DebugInt3();
1260
1261 _sfree(pMsgCopy);
1262 return FALSE;
1263#endif
1264 }
1265 else
1266 {
1267 if (!WinPostQueueMsg(pTebTo->o.odin.hmq, WIN32APP_FORWARDEDPOSTMSG, pMsgCopy, (MPARAM)WIN32APP_FORWARDEDPOSTMSG_MAGIC))
1268 {
1269 dprintf(("OSLibForwardMessage: Failed to post queue message to hmq=%#x\n", pTebTo->o.odin.hmq));
1270 _sfree(pMsgCopy);
1271 }
1272 }
1273
1274 return TRUE;
1275}
Note: See TracBrowser for help on using the repository browser.