source: trunk/src/user32/pmwindow.cpp@ 1799

Last change on this file since 1799 was 1762, checked in by cbratschi, 26 years ago

cursor handling fixed

File size: 33.2 KB
Line 
1/* $Id: pmwindow.cpp,v 1.54 1999-11-17 17:04:53 cbratschi Exp $ */
2/*
3 * Win32 Window Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_WIN
13#define INCL_GPI
14
15#include <os2wrap.h>
16#include <stdlib.h>
17#include "win32type.h"
18#include <winconst.h>
19#include <wprocess.h>
20#include <misc.h>
21#include <win32wbase.h>
22#include <win32dlg.h>
23#include "win32wdesktop.h"
24#include "pmwindow.h"
25#include "oslibwin.h"
26#include "oslibutil.h"
27#include "oslibgdi.h"
28#include "oslibmsg.h"
29#include "dc.h"
30#include <thread.h>
31#include <wprocess.h>
32#include "caret.h"
33#include "timer.h"
34
35HMQ hmq = 0; /* Message queue handle */
36HAB hab = 0;
37
38RECTL desktopRectl = {0};
39ULONG ScreenWidth = 0;
40ULONG ScreenHeight = 0;
41
42//Used for key translation while processing WM_CHAR message
43USHORT virtualKeyTable [66] = {
44 0x00, // OS/2 VK Win32 VK, Entry 0 is not used
45 0x01, // VK_BUTTON1 VK_LBUTTON
46 0x02, // VK_BUTTON2 VK_RBUTTON
47 0x04, // VK_BUTTON3 VK_MBUTTON
48 0x03, // VK_BREAK VK_CANCEL
49 0x08, // VK_BACKSPACE VK_BACK
50 0x09, // VK_TAB VK_TAB
51 0x00, // VK_BACKTAB No equivalent!
52 0x0A, // VK_NEWLINE 0x0A (no VK_* def)
53 0x10, // VK_SHIFT VK_SHIFT
54 0x11, // VK_CTRL VK_CONTROL
55 0x12, // VK_ALT VK_MENU, best match I guess
56 0x12, // VK_ALTGRAF VK_MENU, best match I guess
57 0x13, // VK_PAUSE VK_PAUSE
58 0x14, // VK_CAPSLOCK VK_CAPITAL
59 0x1B, // VK_ESC VK_ESCAPE
60 0x20, // VK_SPACE VK_SPACE
61 0x21, // VK_PAGEUP VK_PRIOR
62 0x22, // VK_PAGEDOWN VK_NEXT
63 0x23, // VK_END VK_END
64 0x24, // VK_HOME VK_HOME
65 0x25, // VK_LEFT VK_LEFT
66 0x26, // VK_UP VK_UP
67 0x27, // VK_RIGHT VK_RIGHT
68 0x28, // VK_DOWN VK_DOWN
69 0x2C, // VK_PRINTSCRN VK_SNAPSHOT
70 0x2D, // VK_INSERT VK_INSERT
71 0x2E, // VK_DELETE VK_DELETE
72 0x91, // VK_SCRLLOCK VK_SCROLL
73 0x90, // VK_NUMLOCK VK_NUMLOCK
74 0x0D, // VK_ENTER VK_RETURN
75 0x00, // VK_SYSRQ No equivalent!
76 0x70, // VK_F1 VK_F1
77 0x71, // VK_F2 VK_F2
78 0x72, // VK_F3 VK_F3
79 0x73, // VK_F4 VK_F4
80 0x74, // VK_F5 VK_F5
81 0x75, // VK_F6 VK_F6
82 0x76, // VK_F7 VK_F7
83 0x77, // VK_F8 VK_F8
84 0x78, // VK_F9 VK_F9
85 0x79, // VK_F10 VK_F10
86 0x7A, // VK_F11 VK_F11
87 0x7B, // VK_F12 VK_F12
88 0x7C, // VK_F13 VK_F13
89 0x7D, // VK_F14 VK_F14
90 0x7E, // VK_F15 VK_F15
91 0x7F, // VK_F16 VK_F16
92 0x80, // VK_F17 VK_F17
93 0x81, // VK_F18 VK_F18
94 0x82, // VK_F19 VK_F19
95 0x83, // VK_F20 VK_F20
96 0x84, // VK_F21 VK_F21
97 0x85, // VK_F22 VK_F22
98 0x86, // VK_F23 VK_F23
99 0x87, // VK_F24 VK_F24
100 0x00, // VK_ENDDRAG No equivalent!
101 0x0C, // VK_CLEAR VK_CLEAR
102 0xF9, // VK_EREOF VK_EREOF
103 0xFD, // VK_PA1 VK_PA1
104 0xF6, // VK_ATTN VK_ATTN
105 0xF7, // VK_CRSEL VK_CRSEL
106 0xF8, // VK_EXSEL VK_EXSEL
107 0x00, // VK_COPY No equivalent!
108 0x00, // VK_BLK1 No equivalent!
109 0x00}; // VK_BLK2 No equivalent!
110
111MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
112
113//******************************************************************************
114//Initialize PM; create hab, message queue and register special Win32 window classes
115//******************************************************************************
116BOOL InitPM()
117{
118 CLASSINFO FrameClassInfo;
119
120 hab = WinInitialize(0);
121 dprintf(("Winitialize returned %x", hab));
122 hmq = WinCreateMsgQueue(hab, 0);
123
124 if(!hab || !hmq)
125 {
126 UINT error;
127 //CB: only fail on real error
128 error = WinGetLastError(hab) & 0xFFFF; //error code
129 if (!hab || error != PMERR_MSG_QUEUE_ALREADY_EXISTS)
130 {
131 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
132 dprintf((" Error = %x",error));
133 return(FALSE);
134 }
135 else
136 {
137 if(!hab) {
138 hab = WinQueryAnchorBlock(HWND_DESKTOP);
139 dprintf(("WinQueryAnchorBlock returned %x", hab));
140 }
141 if(!hmq) {
142 hmq = HMQ_CURRENT;
143 }
144 }
145 }
146 SetThreadHAB(hab);
147 dprintf(("InitPM: hmq = %x", hmq));
148 SetThreadMessageQueue(hmq);
149
150 if(!WinRegisterClass( /* Register window class */
151 hab, /* Anchor block handle */
152 (PSZ)WIN32_STDCLASS, /* Window class name */
153 (PFNWP)Win32WindowProc, /* Address of window procedure */
154// CS_SIZEREDRAW | CS_HITTEST | CS_MOVENOTIFY,
155 CS_SIZEREDRAW | CS_HITTEST,
156 NROF_WIN32WNDBYTES)) {
157 dprintf(("WinRegisterClass Win32BaseWindow failed"));
158 return(FALSE);
159 }
160 if (!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
161 dprintf (("WinQueryClassInfo WC_FRAME failed"));
162 return (FALSE);
163 }
164 FrameClassInfo.flClassStyle &= ~(CS_PUBLIC | CS_CLIPSIBLINGS);
165 if (!WinRegisterClass (hab,
166 WIN32_INNERFRAME,
167 FrameClassInfo.pfnWindowProc,
168 FrameClassInfo.flClassStyle,
169 FrameClassInfo.cbWindowData)) {
170 dprintf (("WinRegisterClass Win32InnerFrame failed"));
171 return (FALSE);
172 }
173
174 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
175 ScreenWidth = desktopRectl.xRight;
176 ScreenHeight = desktopRectl.yTop;
177
178 dprintf(("InitPM: Desktop (%d,%d)", ScreenWidth, ScreenHeight));
179 return OSLibInitMsgQueue();
180} /* End of main */
181//******************************************************************************
182//Win32 window message handler
183//******************************************************************************
184MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
185{
186 POSTMSG_PACKET *postmsg;
187 OSLIBPOINT point, ClientPoint;
188 Win32BaseWindow *win32wnd;
189 APIRET rc;
190
191 //Restore our FS selector
192 SetWin32TIB();
193
194 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
195
196 if(msg != WM_CREATE && win32wnd == NULL) {
197 dprintf(("Invalid win32wnd pointer for window %x!!", hwnd));
198 goto RunDefWndProc;
199 }
200 if(msg > WIN32APP_USERMSGBASE) {
201 //win32 app user message
202 return (MRESULT)win32wnd->SendMessageA((ULONG)msg-WIN32APP_USERMSGBASE, (ULONG)mp1, (ULONG)mp2);
203 }
204 switch( msg )
205 {
206 //OS/2 msgs
207 case WM_CREATE:
208 {
209 THDB *thdb = GetThreadTHDB();
210
211 if(thdb == NULL || thdb->newWindow == 0)
212 goto createfail;
213
214 //Processing is done in after WinCreateWindow returns
215 dprintf(("OS2: WM_CREATE %x", hwnd));
216 win32wnd = (Win32BaseWindow *)thdb->newWindow;
217
218 if(win32wnd->MsgCreate(WinQueryWindow(hwnd, QW_PARENT), hwnd) == FALSE)
219 {
220 RestoreOS2TIB();
221 return (MRESULT)TRUE; //discontinue window creation
222 }
223 createfail:
224 RestoreOS2TIB();
225 return (MRESULT)FALSE;
226 }
227
228 case WM_QUIT:
229 dprintf(("OS2: WM_QUIT %x", hwnd));
230 if(win32wnd->MsgQuit()) {
231 goto RunDefWndProc;
232 }
233 break;
234
235 case WM_CLOSE:
236 dprintf(("OS2: WM_CLOSE %x", hwnd));
237// win32wnd->RemoveFakeOpen32();
238 if(win32wnd->MsgClose()) {
239 goto RunDefWndProc;
240 }
241 break;
242
243 case WM_DESTROY:
244 dprintf(("OS2: WM_DESTROY %x", hwnd));
245 if(win32wnd->MsgDestroy()) {
246 goto RunDefWndProc;
247 }
248 break;
249
250 case WM_ENABLE:
251 dprintf(("OS2: WM_ENABLE %x", hwnd));
252 if(win32wnd->MsgEnable(SHORT1FROMMP(mp1))) {
253 goto RunDefWndProc;
254 }
255 break;
256
257 case WM_SHOW:
258 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
259 if(win32wnd->MsgShow((ULONG)mp1)) {
260 goto RunDefWndProc;
261 }
262 break;
263
264#if 0
265 case WM_ADJUSTWINDOWPOS:
266 {
267 PSWP pswp = (PSWP)mp1;
268 SWP swpOld, swpNew;
269 WINDOWPOS wp;
270 ULONG parentHeight = 0;
271 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE, hwndAfter;
272
273 dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", hwnd, pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
274
275 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto RunDefWndProc;;
276
277 //SvL: TODO: Workaround. Why is this happening?
278 // When this flag is set the coordinates are 0, even though SWP_SIZE & SWP_MOVE are set.
279// if ((pswp->fl & SWP_NOADJUST)) goto RunDefWndProc;
280
281 if(!win32wnd->CanReceiveSizeMsgs()) goto RunDefWndProc;;
282
283 WinQueryWindowPos(hwnd, &swpOld);
284
285 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
286 if (win32wnd->isChild()) {
287 if(win32wnd->getParent()) {
288 hParent = win32wnd->getParent()->getOS2WindowHandle();
289 }
290 else goto RunDefWndProc;;
291 }
292 }
293 hwndAfter = pswp->hwndInsertBehind;
294 hFrame = win32wnd->getOS2FrameWindowHandle();
295 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hFrame);
296
297 wp.hwnd = win32wnd->getWindowHandle();
298 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
299 {
300 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
301 if(wndAfter) wp.hwndInsertAfter = wndAfter->getWindowHandle();
302 }
303 if(win32wnd->MsgPosChanging((LPARAM)&wp) == 0)
304 {//app or default window handler changed wp
305 dprintf(("OS2: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
306 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
307 OSLibMapWINDOWPOStoSWP(&wp, &swpNew, &swpOld, hParent, hFrame);
308 dprintf(("%x (%d,%d), (%d,%d)", swpNew.fl, swpNew.x, swpNew.y, swpNew.cx, swpNew.cy));
309 swpNew.fl |= SWP_NOADJUST;
310 swpNew.hwndInsertBehind = hwndAfter;
311 swpNew.hwnd = hFrame;
312
313 WinSetMultWindowPos(GetThreadHAB(), &swpNew, 1);
314 return (MRESULT)0;
315 }
316 break;
317 }
318
319 case WM_WINDOWPOSCHANGED:
320 {
321 PSWP pswp = (PSWP)mp1;
322 SWP swpOld = *(pswp + 1);
323 WINDOWPOS wp;
324 HWND hParent = NULLHANDLE;
325 LONG yDelta = pswp->cy - swpOld.cy;
326 LONG xDelta = pswp->cx - swpOld.cx;
327
328 dprintf(("OS2: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
329
330 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
331
332 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
333 if (win32wnd->isChild()) {
334 if(win32wnd->getParent()) {
335 hParent = win32wnd->getParent()->getOS2WindowHandle();
336 }
337 else goto RunDefWndProc; //parent has just been destroyed
338 }
339 }
340 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, win32wnd->getOS2FrameWindowHandle());
341
342 if (!win32wnd->CanReceiveSizeMsgs()) break;
343
344 win32wnd->setWindowRect(wp.x, wp.y, wp.x+wp.cx, wp.y+wp.cy);
345 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
346
347 wp.hwnd = win32wnd->getWindowHandle();
348 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
349 {
350 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
351 wp.hwndInsertAfter = wndAfter->getWindowHandle();
352 }
353
354 if (yDelta != 0 || xDelta != 0)
355 {
356 HENUM henum = WinBeginEnumWindows(pswp->hwnd);
357 SWP swp[10];
358 int i = 0;
359 HWND hwnd;
360
361 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
362 {
363#if 0
364 if (mdiClient )
365 {
366 continue;
367 }
368#endif
369 WinQueryWindowPos(hwnd, &(swp[i]));
370
371#ifdef DEBUG
372 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
373 dprintf(("ENUMERATE %x delta %d (%d,%d) (%d,%d) %x", (window) ? window->getWindowHandle() : hwnd,
374 yDelta, swp[i].x, swp[i].y, swp[i].cx, swp[i].cy, swp[i].fl));
375#endif
376
377 if(swp[i].y != 0) {
378 //child window at offset <> 0 from client area -> offset now changes
379 swp[i].y += yDelta;
380 swp[i].fl &= ~(SWP_NOREDRAW);
381 }
382 //else child window with the same start coorindates as the client area
383 //The app should resize it.
384
385 if (i == 9)
386 {
387 WinSetMultWindowPos(GetThreadHAB(), swp, 10);
388 i = 0;
389 }
390 else
391 {
392 i++;
393 }
394 }
395
396 WinEndEnumWindows(henum);
397
398 if (i)
399 WinSetMultWindowPos(GetThreadHAB(), swp, i);
400 }
401 if (yDelta != 0)
402 {
403 POINT pt;
404 if(GetCaretPos (&pt) == TRUE)
405 {
406 pt.y -= yDelta;
407 SetCaretPos (pt.x, pt.y);
408 }
409 }
410 win32wnd->MsgPosChanged((LPARAM)&wp);
411
412 goto RunDefWndProc;
413 }
414#endif
415
416 case WM_ACTIVATE:
417 {
418 HWND hwndActivate = (HWND)mp2;
419 BOOL fMinimized = FALSE;
420
421 dprintf(("OS2: WM_ACTIVATE %x %x", hwnd, hwndActivate));
422 if(WinQueryWindowULong(hwndActivate, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
423 //another (non-win32) application's window
424 //set to NULL (allowed according to win32 SDK) to avoid problems
425 hwndActivate = NULL;
426 }
427 if(WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)
428 {
429 fMinimized = TRUE;
430 }
431
432 if(win32wnd->MsgActivate(SHORT1FROMMP(mp1), fMinimized, Win32BaseWindow::OS2ToWin32Handle(hwndActivate))) {
433 goto RunDefWndProc;
434 }
435 break;
436 }
437
438 case WM_SIZE:
439 {
440 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
441 break;
442 }
443
444 case WM_OWNERPOSCHANGE:
445 {
446 dprintf(("OS2: WM_OWNERPOSCHANGE"));
447 goto RunDefWndProc;
448 }
449
450 case WM_CALCVALIDRECTS:
451 {
452 dprintf(("OS2: WM_CALCVALIDRECTS"));
453 goto RunDefWndProc;
454 }
455
456 case WM_FOCUSCHANGE:
457 dprintf(("OS2: WM_FOCUSCHANGE %x", win32wnd->getWindowHandle()));
458 goto RunDefWndProc;
459
460 case WM_SETFOCUS:
461 {
462 HWND hwndFocus = (HWND)mp1;
463
464 dprintf(("OS2: WM_SETFOCUS %x %x %d", win32wnd->getWindowHandle(), mp1, mp2));
465 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
466 //another (non-win32) application's window
467 //set to NULL (allowed according to win32 SDK) to avoid problems
468 hwndFocus = NULL;
469 }
470 if((ULONG)mp2 == TRUE) {
471 HWND hwndFocusWin32 = Win32BaseWindow::OS2ToWin32Handle(hwndFocus);
472 recreateCaret (hwndFocusWin32);
473 rc = win32wnd->MsgSetFocus(hwndFocusWin32);
474 }
475 else rc = win32wnd->MsgKillFocus(Win32BaseWindow::OS2ToWin32Handle(hwndFocus));
476 if(rc) {
477 goto RunDefWndProc;
478 }
479 break;
480 }
481
482 //**************************************************************************
483 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
484 //**************************************************************************
485 case WM_BUTTON1DOWN:
486 dprintf(("OS2: WM_BUTTON1DOWN %x", hwnd));
487 point.x = (*(POINTS *)&mp1).x;
488 point.y = (*(POINTS *)&mp1).y;
489 ClientPoint.x = point.x;
490 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
491 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
492 if(win32wnd->MsgButton(BUTTON_LEFTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
493 goto RunDefWndProc;
494 }
495 break;
496
497 case WM_BUTTON1UP:
498 dprintf(("OS2: WM_BUTTON1UP %x", hwnd));
499 point.x = (*(POINTS *)&mp1).x;
500 point.y = (*(POINTS *)&mp1).y;
501 ClientPoint.x = point.x;
502 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
503 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
504 if(win32wnd->MsgButton(BUTTON_LEFTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
505 goto RunDefWndProc;
506 }
507 break;
508 case WM_BUTTON1DBLCLK:
509 point.x = (*(POINTS *)&mp1).x;
510 point.y = (*(POINTS *)&mp1).y;
511 ClientPoint.x = point.x;
512 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
513 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
514 if(win32wnd->MsgButton(BUTTON_LEFTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
515 goto RunDefWndProc;
516 }
517 break;
518 case WM_BUTTON2DOWN:
519 point.x = (*(POINTS *)&mp1).x;
520 point.y = (*(POINTS *)&mp1).y;
521 ClientPoint.x = point.x;
522 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
523 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
524 if(win32wnd->MsgButton(BUTTON_RIGHTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
525 goto RunDefWndProc;
526 }
527 break;
528 case WM_BUTTON2UP:
529 point.x = (*(POINTS *)&mp1).x;
530 point.y = (*(POINTS *)&mp1).y;
531 ClientPoint.x = point.x;
532 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
533 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
534 if(win32wnd->MsgButton(BUTTON_RIGHTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
535 goto RunDefWndProc;
536 }
537 break;
538 case WM_BUTTON2DBLCLK:
539 point.x = (*(POINTS *)&mp1).x;
540 point.y = (*(POINTS *)&mp1).y;
541 ClientPoint.x = point.x;
542 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
543 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
544 if(win32wnd->MsgButton(BUTTON_RIGHTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
545 goto RunDefWndProc;
546 }
547 break;
548 case WM_BUTTON3DOWN:
549 point.x = (*(POINTS *)&mp1).x;
550 point.y = (*(POINTS *)&mp1).y;
551 ClientPoint.x = point.x;
552 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
553 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
554 if(win32wnd->MsgButton(BUTTON_MIDDLEDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
555 goto RunDefWndProc;
556 }
557 break;
558 case WM_BUTTON3UP:
559 point.x = (*(POINTS *)&mp1).x;
560 point.y = (*(POINTS *)&mp1).y;
561 ClientPoint.x = point.x;
562 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
563 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
564 if(win32wnd->MsgButton(BUTTON_MIDDLEUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
565 goto RunDefWndProc;
566 }
567 break;
568 case WM_BUTTON3DBLCLK:
569 point.x = (*(POINTS *)&mp1).x;
570 point.y = (*(POINTS *)&mp1).y;
571 ClientPoint.x = point.x;
572 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
573 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
574 if(win32wnd->MsgButton(BUTTON_MIDDLEDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
575 goto RunDefWndProc;
576 }
577 break;
578
579 case WM_BUTTON2MOTIONSTART:
580 case WM_BUTTON2MOTIONEND:
581 case WM_BUTTON2CLICK:
582 case WM_BUTTON1MOTIONSTART:
583 case WM_BUTTON1MOTIONEND:
584 case WM_BUTTON1CLICK:
585 case WM_BUTTON3MOTIONSTART:
586 case WM_BUTTON3MOTIONEND:
587 case WM_BUTTON3CLICK:
588 goto RunDefWndProc;
589
590 case WM_MOUSEMOVE:
591 {
592 ULONG keystate = 0;
593 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1))
594 keystate |= WMMOVE_LBUTTON;
595 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2))
596 keystate |= WMMOVE_MBUTTON;
597 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3))
598 keystate |= WMMOVE_RBUTTON;
599 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT))
600 keystate |= WMMOVE_SHIFT;
601 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL))
602 keystate |= WMMOVE_CTRL;
603
604 //OS/2 Window coordinates -> Win32 Window coordinates
605 win32wnd->MsgMouseMove(keystate, SHORT1FROMMP(mp1), MapOS2ToWin32Y(win32wnd, SHORT2FROMMP(mp1)));
606 break;
607 }
608
609 case WM_CONTROL:
610
611 case WM_COMMAND:
612 if(SHORT1FROMMP(mp2) == CMDSRC_MENU) {
613 win32wnd->MsgCommand(CMD_MENU, SHORT1FROMMP(mp1), 0);
614 }
615 if(SHORT1FROMMP(mp2) == CMDSRC_ACCELERATOR) {
616 win32wnd->MsgCommand(CMD_ACCELERATOR, SHORT1FROMMP(mp1), 0);
617 }
618 //todo controls + accelerators
619 break;
620
621 case WM_SYSCOMMAND:
622 {
623 ULONG x = 0, y = 0;
624 ULONG win32sc;
625
626 if(SHORT2FROMMP(mp2) == TRUE) {//syscommand caused by mouse action
627 POINTL pointl;
628 WinQueryPointerPos(HWND_DESKTOP, &pointl);
629 x = pointl.x;
630 y = ScreenHeight - y;
631 }
632 switch(SHORT1FROMMP(mp1)) {
633 case SC_MOVE:
634 win32sc = SC_MOVE_W;
635 break;
636 case SC_CLOSE:
637 win32sc = SC_CLOSE_W;
638 break;
639 case SC_MAXIMIZE:
640 win32sc = SC_MAXIMIZE_W;
641 break;
642 case SC_MINIMIZE:
643 win32sc = SC_MINIMIZE_W;
644 break;
645 case SC_NEXTFRAME:
646 case SC_NEXTWINDOW:
647 win32sc = SC_NEXTWINDOW_W;
648 break;
649 case SC_RESTORE:
650 win32sc = SC_RESTORE_W;
651 break;
652 case SC_TASKMANAGER:
653 win32sc = SC_TASKLIST_W;
654 break;
655 default:
656 goto RunDefWndProc;
657 }
658 dprintf(("WM_SYSCOMMAND %x %x (%d,%d)", hwnd, win32sc, x, y));
659 if(win32wnd->MsgSysCommand(win32sc, x, y)) {
660 goto RunDefWndProc;
661 }
662 break;
663 }
664 case WM_CHAR:
665 {
666 THDB *thdb;
667 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
668 ULONG flags = SHORT1FROMMP(mp1);
669 BOOL keyWasPressed, fTranslated = FALSE, fRunDefWndProc = FALSE;
670
671 char c;
672
673 repeatCount = CHAR3FROMMP(mp1);
674 scanCode = CHAR4FROMMP(mp1);
675 keyWasPressed = ((SHORT1FROMMP (mp1) & KC_PREVDOWN) == KC_PREVDOWN);
676
677 dprintf(("PM: WM_CHAR: %x %x %d %x", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), repeatCount, scanCode));
678 dprintf(("PM: WM_CHAR: %x", flags));
679 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
680 // given the OS/2 virtual key and OS/2 character
681
682 //if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
683 // ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
684 c = 0;
685 if ((SHORT1FROMMP (mp1) & 0xFF) != 0)
686 {
687 c = SHORT1FROMMP (mp2);
688 if ((c >= 'A') && (c <= 'Z')) {
689 virtualKey = c;
690 goto VirtualKeyFound;
691 }
692 if ((c >='a') && (c <= 'z')) {
693 virtualKey = c - 32; // make it uppercase
694 goto VirtualKeyFound;
695 }
696 if ((c >= '0') && (c <= '9')) {
697 virtualKey = c;
698 goto VirtualKeyFound;
699 }
700 }
701
702 // convert OS/2 virtual keys to Win32 virtual key
703 if (SHORT2FROMMP (mp2) <= VK_BLK2)
704 virtualKey = virtualKeyTable [SHORT2FROMMP (mp2)];
705
706VirtualKeyFound:
707 dprintf (("VIRTUALKEYFOUND:(%x)", virtualKey));
708
709 if(!(SHORT1FROMMP(mp1) & KC_ALT))
710 {
711 //
712 // the Alt key is not pressed
713 //
714 if ((flags & KC_KEYUP) == KC_KEYUP) {
715 // send WM_KEYUP message
716
717 if(win32wnd->MsgKeyUp (repeatCount, scanCode, virtualKey)) {
718 fRunDefWndProc = TRUE;
719 }
720 }
721 else {
722 // send WM_KEYDOWN message
723 if (win32wnd->MsgKeyDown (repeatCount, scanCode,
724 virtualKey, keyWasPressed))
725 fRunDefWndProc = TRUE;
726 }
727 }
728 else {
729 //
730 // the Alt key is pressed
731 //
732 if ((flags & KC_KEYUP) == KC_KEYUP) {
733 // send WM_SYSKEYUP message
734
735 dprintf(("PMWINDOW_WM_SYSKEYUP: vkey:(%x)", virtualKey));
736 if(win32wnd->MsgSysKeyUp (repeatCount, scanCode, virtualKey)) {
737 fRunDefWndProc = TRUE;
738 }
739 }
740 else {
741 // send WM_SYSKEYDOWN message
742 dprintf(("PMWINDOW_WM_SYSKEYDOWN: vkey:(%x)", virtualKey));
743 if (win32wnd->MsgSysKeyDown (repeatCount, scanCode, virtualKey, keyWasPressed))
744 fRunDefWndProc = TRUE;
745 }
746 }
747
748 thdb = GetThreadTHDB();
749 if(thdb) {
750 fTranslated = thdb->fMsgTranslated;
751 thdb->fMsgTranslated = FALSE; //reset flag
752 }
753 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
754 // the newly generated WM_CHAR message.
755 if(fTranslated && !((flags & KC_KEYUP) == KC_KEYUP))
756 {//TranslatedMessage was called before DispatchMessage, so send WM_CHAR messages
757 ULONG keyflags = 0, vkey = 0;
758 ULONG fl = SHORT1FROMMP(mp1);
759 ULONG chCode = SHORT1FROMMP(mp2);
760
761 if(!(fl & KC_CHAR)) {
762//SvL: Test
763 break;
764// goto RunDefWndProc;
765 }
766 if(fl & KC_VIRTUALKEY) {
767 if(virtualKey)
768 vkey = virtualKey;
769 else vkey = SHORT2FROMMP(mp2);
770 chCode = vkey;
771 }
772 if(fl & KC_KEYUP) {
773 keyflags |= KEY_UP;
774 }
775 if(fl & KC_ALT) {
776 keyflags |= KEY_ALTDOWN;
777 }
778 if(fl & KC_PREVDOWN) {
779 keyflags |= KEY_PREVDOWN;
780 }
781 if(fl & KC_DEADKEY) {
782 keyflags |= KEY_DEADKEY;
783 }
784 if(win32wnd->MsgChar(chCode, CHAR3FROMMP(mp1), CHAR4FROMMP(mp1), virtualKey, keyflags)) {
785//SvL: Test
786// goto RunDefWndProc;
787
788 }
789 }
790//SvL: Test
791// if(fRunDefWndProc) goto RunDefWndProc;
792 break;
793 }
794
795 case WM_INITMENU:
796 case WM_MENUSELECT:
797 case WM_MENUEND:
798 case WM_NEXTMENU:
799 goto RunDefWndProc;
800
801 case WM_TIMER:
802 if (mp2)
803 {
804 BOOL sys;
805 ULONG id;
806
807 dprintf(("OS2: WM_TIMER %x %d", hwnd, mp1));
808 if (TIMER_GetTimerInfo(hwnd,(ULONG)mp1,&sys,&id))
809 {
810 if (sys)
811 win32wnd->MsgSysTimer(id);
812 else
813 win32wnd->MsgTimer(id);
814 }
815 }
816 goto RunDefWndProc;
817
818 case WM_SETWINDOWPARAMS:
819 {
820 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
821
822 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
823 if(wndParams->fsStatus & WPM_TEXT) {
824 if(win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText)) {
825 goto RunDefWndProc;
826 }
827 }
828 goto RunDefWndProc;
829 }
830
831 case WM_QUERYWINDOWPARAMS:
832 {
833 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
834 ULONG textlen;
835 PSZ wintext;
836
837 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
838 {
839 if(wndpars->fsStatus & WPM_CCHTEXT)
840 wndpars->cchText = win32wnd->MsgGetTextLength();
841 if(wndpars->fsStatus & WPM_TEXT)
842 wndpars->pszText = win32wnd->MsgGetText();
843
844 wndpars->fsStatus = 0;
845 wndpars->cbCtlData = 0;
846 wndpars->cbPresParams = 0;
847 RestoreOS2TIB();
848 return (MRESULT)TRUE;
849 }
850 goto RunDefWndProc;
851 }
852
853 case WM_ERASEBACKGROUND:
854 {
855 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
856 if (WinQueryUpdateRect (hwnd, NULL) && !win32wnd->isSupressErase()) {
857 BOOL erased = sendEraseBkgnd (win32wnd);
858 win32wnd->setEraseBkgnd (!erased, !erased);
859 }
860 break;
861 }
862
863 case WM_PAINT:
864 dprintf(("OS2: WM_PAINT %x", hwnd));
865
866 if (WinQueryUpdateRect (hwnd, NULL)) {
867 if (!win32wnd->isSupressErase()) {
868 BOOL erased = sendEraseBkgnd (win32wnd);
869 win32wnd->setEraseBkgnd (!erased, !erased);
870 }
871 }
872 win32wnd->setSupressErase (FALSE);
873
874 if(win32wnd->MsgPaint(0, 0)) {
875 goto RunDefWndProc;
876 }
877 //Apparently there are apps that return 0, but don't do anything during WM_PAINT
878 goto RunDefWndProc;
879
880 case WM_HITTEST:
881 // Only send this message if the window is enabled
882 if (WinIsWindowEnabled(hwnd))
883 {
884 if(win32wnd->MsgHitTest((*(POINTS *)&mp1).x, MapOS2ToWin32Y(OSLIB_HWND_DESKTOP, hwnd, (*(POINTS *)&mp1).y))) {
885 goto RunDefWndProc;
886 }
887 }
888 else goto RunDefWndProc;
889 break;
890
891 case WM_CONTEXTMENU:
892 {
893 POINTL pt;
894
895 dprintf(("OS2: WM_CONTEXTMENU %x", hwnd));
896 pt.x = (*(POINTS *)&mp1).x;
897 pt.y = (*(POINTS *)&mp1).y;
898 WinMapWindowPoints(hwnd,HWND_DESKTOP,&pt,1);
899 pt.y = WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN)-pt.y-1;
900 win32wnd->MsgContextMenu(pt.x,pt.y);
901
902 RestoreOS2TIB();
903 return (MRESULT)TRUE;
904 }
905
906 case WM_SYSCOLORCHANGE:
907 case WM_SYSVALUECHANGED:
908 case WM_SETSELECTION:
909 case WM_PPAINT:
910 case WM_PSETFOCUS:
911 case WM_PSYSCOLORCHANGE:
912 case WM_PSIZE:
913 case WM_PACTIVATE:
914 case WM_PCONTROL:
915 case WM_HELP:
916 case WM_APPTERMINATENOTIFY:
917 case WM_PRESPARAMCHANGED:
918 case WM_DRAWITEM:
919 case WM_MEASUREITEM:
920 case WM_CONTROLPOINTER:
921 case WM_QUERYDLGCODE:
922 case WM_SUBSTITUTESTRING:
923 case WM_MATCHMNEMONIC:
924 case WM_SAVEAPPLICATION:
925 case WM_SEMANTICEVENT:
926 default:
927// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
928 RestoreOS2TIB();
929 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
930 }
931 RestoreOS2TIB();
932 return (MRESULT)FALSE;
933
934RunDefWndProc:
935// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
936 RestoreOS2TIB();
937 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
938} /* End of Win32WindowProc */
939//******************************************************************************
940//******************************************************************************
941MRESULT EXPENTRY Win32SubclassWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
942{
943 Win32BaseWindow* win32wnd;
944
945 //Restore our FS selector
946 SetWin32TIB();
947
948 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
949
950 if (!win32wnd)
951 {
952 dprintf(("Invalid win32wnd pointer for subclassed window %x!!", hwnd));
953 goto RunDefWndProc;
954 }
955
956 switch (msg)
957 {
958 case WM_WINDOWPOSCHANGED:
959 {
960 PSWP pswp = (PSWP)mp1;
961 SWP swpOld = *(pswp + 1);
962 WINDOWPOS wp;
963 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE;
964
965 dprintf(("OS2Subclass: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
966 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
967
968 hParent = hFrame = WinQueryWindow(hwnd, QW_PARENT);
969
970 OSLibMapSWPtoWINDOWPOS(pswp,&wp, &swpOld,hParent,hFrame);
971
972 win32wnd->setWindowRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
973 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
974 wp.x = swpOld.x;
975 wp.y = swpOld.y;
976 wp.cx = swpOld.cx;
977 wp.cy = swpOld.cy;
978
979 wp.hwnd = win32wnd->getWindowHandle();
980
981 win32wnd->MsgPosChanged((LPARAM)&wp);
982
983 goto RunOldWndProc;
984 }
985
986 default:
987 goto RunDefHandler;
988 }
989
990RunDefWndProc:
991 RestoreOS2TIB();
992 return WinDefWindowProc(hwnd,msg,mp1,mp2);
993
994RunOldWndProc:
995 RestoreOS2TIB();
996 return ((PFNWP)win32wnd->getOldWndProc())(hwnd,msg,mp1,mp2);
997
998RunDefHandler:
999 RestoreOS2TIB();
1000 return Win32WindowProc(hwnd,msg,mp1,mp2);
1001}
1002
1003PVOID SubclassWithDefHandler(HWND hwnd)
1004{
1005 return WinSubclassWindow(hwnd,Win32SubclassWindowProc);
1006}
Note: See TracBrowser for help on using the repository browser.