source: trunk/src/user32/oslibmsg.cpp@ 2200

Last change on this file since 2200 was 2200, checked in by sandervl, 26 years ago

Message handling rewrite

File size: 10.6 KB
Line 
1/* $Id: oslibmsg.cpp,v 1.15 1999-12-24 18:39:10 sandervl Exp $ */
2/*
3 * Window message translation functions for OS/2
4 *
5 *
6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 * TODO: Some messages that are sent to the frame window are directly passed on to the client
12 * -> Get/PeekMessage never gets them as we return a dummy message for non-client windows
13 * (i.e. menu WM_COMMAND messages)
14 *
15 * TODO: Filter translation isn't correct for posted messages
16 *
17 */
18#define INCL_WIN
19#define INCL_PM
20#define INCL_DOSPROCESS
21#include <os2.h>
22#include <os2wrap.h>
23#include <string.h>
24#include <misc.h>
25#include "oslibmsg.h"
26#include <win32wnd.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
34typedef BOOL (EXPENTRY FNTRANS)(MSG *, QMSG *);
35typedef FNTRANS *PFNTRANS;
36
37typedef struct
38{
39 ULONG msgOS2;
40 ULONG msgWin32;
41// PFNTRANS toOS2;
42// PFNTRANS toWIN32;
43} MSGTRANSTAB, *PMSGTRANSTAB;
44
45MSGTRANSTAB MsgTransTab[] = {
46 WM_NULL, WINWM_NULL,
47 WM_CREATE, WINWM_CREATE,
48 WM_DESTROY, WINWM_DESTROY,
49 WM_TIMER, WINWM_TIMER,
50 WM_CLOSE, WINWM_CLOSE,
51 WM_QUIT, WINWM_QUIT,
52
53 WM_ENABLE, WINWM_ENABLE,
54 WM_SHOW, WINWM_SHOWWINDOW,
55 WM_MOVE, WINWM_MOVE,
56 WM_SIZE, WINWM_SIZE,
57 //
58 WM_HITTEST, WINWM_NCHITTEST,
59 //
60 WM_ACTIVATE, WINWM_ACTIVATE,
61 WM_SETFOCUS, WINWM_SETFOCUS,
62 //
63 WM_COMMAND, WINWM_COMMAND,
64 WM_SYSCOMMAND, WINWM_SYSCOMMAND,
65 //
66 WM_PAINT, WINWM_PAINT,
67 WM_TIMER, WINWM_TIMER,
68 //
69 WM_CLOSE, WINWM_CLOSE,
70 WM_QUIT, WINWM_QUIT,
71 //
72 WM_CONTROL, WINWM_COMMAND,
73 //
74 WM_MOUSEMOVE, WINWM_MOUSEMOVE,
75 WM_BUTTON1DOWN, WINWM_LBUTTONDOWN,
76 WM_BUTTON1UP, WINWM_LBUTTONUP,
77 WM_BUTTON1DBLCLK, WINWM_LBUTTONDBLCLK,
78 WM_BUTTON2DOWN, WINWM_RBUTTONDOWN,
79 WM_BUTTON2UP, WINWM_RBUTTONUP,
80 WM_BUTTON2DBLCLK, WINWM_RBUTTONDBLCLK,
81 WM_BUTTON3DOWN, WINWM_MBUTTONDOWN,
82 WM_BUTTON3UP, WINWM_MBUTTONUP,
83 WM_BUTTON3DBLCLK, WINWM_MBUTTONDBLCLK,
84 0x020a, 0x020a, // WM_???, WM_???
85 WM_CHAR, WINWM_CHAR,
86
87 //TODO: Needs better translation!
88 WM_CHAR, WINWM_KEYDOWN,
89 WM_CHAR, WINWM_KEYUP,
90 WM_CHAR, WINWM_SYSKEYDOWN,
91 WM_CHAR, WINWM_SYSKEYUP,
92 WM_CHAR, WINWM_KEYLAST
93};
94#define MAX_MSGTRANSTAB (sizeof(MsgTransTab)/sizeof(MsgTransTab[0]))
95
96QMSG *MsgThreadPtr = 0;
97
98LRESULT WIN32API SendMessageA(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
99
100//******************************************************************************
101//******************************************************************************
102BOOL OSLibInitMsgQueue()
103{
104 if(DosAllocThreadLocalMemory(sizeof(QMSG)/sizeof(ULONG), (PULONG *)&MsgThreadPtr) != 0)
105 {
106 dprintf(("OSLibInitMsgQueue: local thread memory alloc failed!!"));
107 DebugInt3();
108 return FALSE;
109 }
110 return TRUE;
111}
112//******************************************************************************
113//******************************************************************************
114void WinToOS2MsgTranslate(MSG *winMsg, QMSG *os2Msg, BOOL isUnicode)
115{
116// memcpy(os2Msg, winMsg, sizeof(MSG));
117// os2Msg->hwnd = Win32Window::Win32ToOS2Handle(winMsg->hwnd);
118// os2Msg->reserved = 0;
119}
120//******************************************************************************
121//TODO!!!
122//Signal that the incoming messages in pmwindow need to be translated
123//(i.e. PM WM_CHAR when translated generates WM_CHAR messages, otherwise
124// WM_KEYUP/DOWN (etc))
125//******************************************************************************
126ULONG TranslateWinMsg(ULONG msg)
127{
128 POSTMSG_PACKET *packet;
129
130 if(msg >= WINWM_USER)
131 return WIN32APP_POSTMSG;
132
133 for(int i=0;i<MAX_MSGTRANSTAB;i++)
134 {
135 if(MsgTransTab[i].msgWin32 == msg)
136 {
137 return MsgTransTab[i].msgOS2;
138 }
139 }
140
141 return 0;
142}
143//******************************************************************************
144//******************************************************************************
145void OSLibWinPostQuitMessage(ULONG nExitCode)
146{
147 APIRET rc;
148
149 rc = WinPostQueueMsg(NULLHANDLE, WM_QUIT, (MPARAM)nExitCode, 0);
150 dprintf(("WinPostQueueMsg %d returned %d", nExitCode, rc));
151}
152//******************************************************************************
153//******************************************************************************
154LONG OSLibWinDispatchMsg(MSG *msg, BOOL isUnicode)
155{
156 THDB *thdb;
157 QMSG os2msg;
158 LONG rc;
159
160 thdb = GetThreadTHDB();
161 if(thdb == NULL) {
162 DebugInt3();
163 return FALSE;
164 }
165
166 //TODO: What to do if app changed msg? (translate)
167 // WinToOS2MsgTranslate(msg, &qmsg, isUnicode);
168
169 if(msg->time == MsgThreadPtr->time || msg->hwnd == 0) {
170 memcpy(&os2msg, MsgThreadPtr, sizeof(QMSG));
171 MsgThreadPtr->time = -1;
172 if(msg->hwnd) {
173 thdb->nrOfMsgs = 1;
174 thdb->msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
175 memcpy(&thdb->msg, msg, sizeof(MSG));
176 }
177 return (LONG)WinDispatchMsg(thdb->hab, &os2msg);
178 }
179 else {//is this allowed?
180// dprintf(("WARNING: OSLibWinDispatchMsg: called with own message!"));
181 return SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam);
182 }
183}
184//******************************************************************************
185//******************************************************************************
186BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
187 BOOL isUnicode)
188{
189 BOOL rc, eaten;
190 THDB *thdb;
191
192 thdb = GetThreadTHDB();
193 if(thdb == NULL) {
194 DebugInt3();
195 return FALSE;
196 }
197
198 if(thdb->fTranslated && (!hwnd || hwnd == thdb->msgWCHAR.hwnd)) {
199 thdb->fTranslated = FALSE;
200 memcpy(pMsg, &thdb->msgWCHAR, sizeof(MSG));
201 MsgThreadPtr->msg = 0;
202 MsgThreadPtr->hwnd = 0;
203 return TRUE;
204 }
205 if(hwnd) {
206 do {
207 WinWaitMsg(thdb->hab, TranslateWinMsg(uMsgFilterMin), TranslateWinMsg(uMsgFilterMax));
208 rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
209 }
210 while(rc == FALSE);
211 }
212 else
213 {
214 do {
215 eaten = FALSE;
216 rc = WinGetMsg(thdb->hab, MsgThreadPtr, TranslateWinMsg(uMsgFilterMin), TranslateWinMsg(uMsgFilterMax), 0);
217 if (MsgThreadPtr->msg == WM_TIMER)
218 eaten = TIMER_HandleTimer (MsgThreadPtr);
219 } while (eaten);
220 }
221 OS2ToWinMsgTranslate((PVOID)thdb, MsgThreadPtr, pMsg, isUnicode);
222 return rc;
223}
224//******************************************************************************
225//******************************************************************************
226BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
227 DWORD fRemove, BOOL isUnicode)
228{
229 BOOL rc, eaten;
230 THDB *thdb;
231 QMSG os2msg;
232
233 thdb = GetThreadTHDB();
234 if(thdb == NULL) {
235 DebugInt3();
236 return FALSE;
237 }
238
239 if(thdb->fTranslated && (!hwnd || hwnd == thdb->msgWCHAR.hwnd)) {
240 if(fRemove == PM_REMOVE_W) {
241 thdb->fTranslated = FALSE;
242 MsgThreadPtr->msg = 0;
243 MsgThreadPtr->hwnd = 0;
244 }
245 memcpy(pMsg, &thdb->msgWCHAR, sizeof(MSG));
246 return TRUE;
247 }
248
249 do {
250 eaten = FALSE;
251 rc = WinPeekMsg(thdb->hab, &os2msg, Win32BaseWindow::OS2ToWin32Handle(hwnd), TranslateWinMsg(uMsgFilterMin),
252 TranslateWinMsg(uMsgFilterMax), (fRemove == PM_REMOVE_W) ? PM_REMOVE : PM_NOREMOVE);
253
254 if (rc && fRemove == PM_REMOVE_W && os2msg.msg == WM_TIMER)
255 eaten = TIMER_HandleTimer(&os2msg);
256 }
257 while (eaten && rc);
258
259 OS2ToWinMsgTranslate((PVOID)thdb, &os2msg, pMsg, isUnicode);
260 //TODO: This is not safe! There's no guarantee this message will be dispatched and it might overwrite a previous message
261 if(fRemove == PM_REMOVE_W) {
262 memcpy(MsgThreadPtr, &os2msg, sizeof(QMSG));
263 }
264 return rc;
265}
266//******************************************************************************
267//******************************************************************************
268ULONG OSLibWinQueryMsgTime()
269{
270 return WinQueryMsgTime(GetThreadHAB());
271}
272//******************************************************************************
273//******************************************************************************
274BOOL OSLibWinWaitMessage()
275{
276 return WinWaitMsg(GetThreadHAB(), 0, 0);
277}
278//******************************************************************************
279//TODO: QS_HOTKEY
280//******************************************************************************
281ULONG OSLibWinQueryQueueStatus()
282{
283 ULONG statusOS2, statusWin32 = 0;
284
285 statusOS2 = WinQueryQueueStatus(HWND_DESKTOP);
286
287 if(statusOS2 & QS_KEY)
288 statusWin32 |= QS_KEY_W;
289 if(statusOS2 & QS_MOUSEBUTTON)
290 statusWin32 |= QS_MOUSEBUTTON_W;
291 if(statusOS2 & QS_MOUSEMOVE)
292 statusWin32 |= QS_MOUSEMOVE_W;
293 if(statusOS2 & QS_TIMER)
294 statusWin32 |= QS_TIMER_W;
295 if(statusOS2 & QS_PAINT)
296 statusWin32 |= QS_PAINT_W;
297 if(statusOS2 & QS_POSTMSG)
298 statusWin32 |= QS_POSTMESSAGE_W;
299 if(statusOS2 & QS_SENDMSG)
300 statusWin32 |= QS_SENDMESSAGE_W;
301
302 return statusWin32;
303}
304//******************************************************************************
305//******************************************************************************
306BOOL OSLibWinInSendMessage()
307{
308 return WinInSendMsg(GetThreadHAB());
309}
310//******************************************************************************
311//******************************************************************************
312DWORD OSLibWinGetMessagePos()
313{
314 APIRET rc;
315 POINTL ptl;
316
317 rc = WinQueryMsgPos(GetThreadHAB(), &ptl);
318 if(!rc) {
319 return 0;
320 }
321 //convert to windows coordinates
322 return MAKEULONG(ptl.x, ScreenHeight - ptl.y - 1);
323}
324//******************************************************************************
325//******************************************************************************
326LONG OSLibWinGetMessageTime()
327{
328 return (LONG)WinQueryMsgTime(GetThreadHAB());
329}
330//******************************************************************************
331//******************************************************************************
332BOOL OSLibWinReplyMessage(ULONG result)
333{
334 return (BOOL)WinReplyMsg( NULLHANDLE, NULLHANDLE, HMQ_CURRENT, (MRESULT)result);
335}
336//******************************************************************************
337//******************************************************************************
Note: See TracBrowser for help on using the repository browser.