Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

oslibmsg.cpp

Go to the documentation of this file.
00001 /* $Id: oslibmsg.cpp,v 1.52 2001/12/12 16:40:43 sandervl Exp $ */
00002 /*
00003  * Window message translation functions for OS/2
00004  *
00005  *
00006  * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
00007  *
00008  *
00009  * Project Odin Software License can be found in LICENSE.TXT
00010  *
00011  * TODO: Some messages that are sent to the frame window are directly passed on to the client
00012  *       -> Get/PeekMessage never gets them as we return a dummy message for non-client windows
00013  *       (i.e. menu WM_COMMAND messages)
00014  *
00015  * TODO: Filter translation isn't correct! (for posted messages or messages that don't have
00016  *       a PM version.
00017  *
00018  */
00019 #define  INCL_WIN
00020 #define  INCL_PM
00021 #define  INCL_DOSPROCESS
00022 #include <os2wrap.h>
00023 #include <odinwrap.h>
00024 #include <string.h>
00025 #include <misc.h>
00026 #include "oslibmsg.h"
00027 #include <winconst.h>
00028 #include <win32api.h>
00029 #include <winuser32.h>
00030 #include "oslibutil.h"
00031 #include "timer.h"
00032 #include <thread.h>
00033 #include <wprocess.h>
00034 #include "pmwindow.h"
00035 #include "oslibwin.h"
00036 #include <win\hook.h>
00037 #include <winscan.h>
00038 #include <winkeyboard.h>
00039 
00040 #define DBG_LOCALLOG    DBG_oslibmsg
00041 #include "dbglocal.h"
00042 
00043 
00044 ODINDEBUGCHANNEL(USER32-OSLIBMSG)
00045 
00046 
00047 
00048 typedef BOOL (EXPENTRY FNTRANS)(MSG *, QMSG *);
00049 typedef FNTRANS *PFNTRANS;
00050 
00051 typedef struct
00052 {
00053    ULONG   msgOS2;
00054    ULONG   msgWin32;
00055 // PFNTRANS toOS2;
00056 // PFNTRANS toWIN32;
00057 } MSGTRANSTAB, *PMSGTRANSTAB;
00058 
00059 //NOTE: Must be ordered by win32 message id!!
00060 MSGTRANSTAB MsgTransTab[] = {
00061    WM_NULL,          WINWM_NULL,
00062    WM_CREATE,        WINWM_CREATE,
00063    WM_DESTROY,       WINWM_DESTROY,
00064    WM_MOVE,          WINWM_MOVE,            //TODO: Sent directly
00065    WM_SIZE,          WINWM_SIZE,            //TODO: Sent directly
00066    WM_ACTIVATE,      WINWM_ACTIVATE,
00067    WM_SETFOCUS,      WINWM_SETFOCUS,
00068    WM_SETFOCUS,      WINWM_KILLFOCUS,
00069    WM_ENABLE,        WINWM_ENABLE,
00070    WM_PAINT,         WINWM_PAINT,
00071    WM_CLOSE,         WINWM_CLOSE,
00072    WM_QUIT,          WINWM_QUIT,
00073    WM_SHOW,          WINWM_SHOWWINDOW,
00074 
00075    WM_HITTEST,       WINWM_NCHITTEST,
00076 
00077    //todo: not always right if mouse msg turns out to be for the client window
00078    WM_MOUSEMOVE,     WINWM_NCMOUSEMOVE,
00079    WM_BUTTON1DOWN,   WINWM_NCLBUTTONDOWN,
00080    WM_BUTTON1UP,     WINWM_NCLBUTTONUP,
00081    WM_BUTTON1DBLCLK, WINWM_NCLBUTTONDBLCLK,
00082    WM_BUTTON2DOWN,   WINWM_NCRBUTTONDOWN,
00083    WM_BUTTON2UP,     WINWM_NCRBUTTONUP,
00084    WM_BUTTON2DBLCLK, WINWM_NCRBUTTONDBLCLK,
00085    WM_BUTTON3DOWN,   WINWM_NCMBUTTONDOWN,
00086    WM_BUTTON3UP,     WINWM_NCMBUTTONUP,
00087    WM_BUTTON3DBLCLK, WINWM_NCMBUTTONDBLCLK,
00088 
00089    //TODO: Needs better translation!
00090    WM_CHAR,          WINWM_KEYDOWN,   //WM_KEYFIRST
00091    WM_CHAR,          WINWM_KEYUP,
00092    WM_CHAR,          WINWM_CHAR,
00093    WM_CHAR,          WINWM_DEADCHAR,
00094    WM_CHAR,          WINWM_SYSKEYDOWN,
00095    WM_CHAR,          WINWM_SYSKEYUP,
00096    WM_CHAR,          WINWM_SYSCHAR,
00097    WM_CHAR,          WINWM_SYSDEADCHAR,
00098    WM_CHAR,          WINWM_KEYLAST,
00099 
00100    //
00101    WM_TIMER,         WINWM_TIMER,
00102 
00103    //
00104    //todo: not always right if mouse msg turns out to be for the nonclient window
00105    WM_MOUSEMOVE,     WINWM_MOUSEMOVE,    //WM_MOUSEFIRST
00106    WM_BUTTON1DOWN,   WINWM_LBUTTONDOWN,
00107    WM_BUTTON1UP,     WINWM_LBUTTONUP,
00108    WM_BUTTON1DBLCLK, WINWM_LBUTTONDBLCLK,
00109    WM_BUTTON2DOWN,   WINWM_RBUTTONDOWN,
00110    WM_BUTTON2UP,     WINWM_RBUTTONUP,
00111    WM_BUTTON2DBLCLK, WINWM_RBUTTONDBLCLK,
00112    WM_BUTTON3DOWN,   WINWM_MBUTTONDOWN,
00113    WM_BUTTON3UP,     WINWM_MBUTTONUP,
00114    WM_BUTTON3DBLCLK, WINWM_MBUTTONDBLCLK,
00115    WM_BUTTON3DBLCLK, WINWM_MOUSEWHEEL,    //WM_MOUSELAST
00116    999999999,        999999999,
00117 };
00118 #define MAX_MSGTRANSTAB (sizeof(MsgTransTab)/sizeof(MsgTransTab[0]))
00119 
00120 //******************************************************************************
00121 //******************************************************************************
00122 void WinToOS2MsgTranslate(MSG *winMsg, QMSG *os2Msg, BOOL isUnicode)
00123 {
00124   dprintf(("WinToOS2MsgTranslate not implemented"));
00125 //  memcpy(os2Msg, winMsg, sizeof(MSG));
00126 //  os2Msg->hwnd = Win32ToOS2Handle(winMsg->hwnd);
00127 //  os2Msg->reserved = 0;
00128 }
00129 //******************************************************************************
00130 //TODO: NOT COMPLETE nor 100% CORRECT!!!
00131 //If both the minimum & maximum message are unknown, the result can be wrong (max > min)!
00132 //******************************************************************************
00133 ULONG TranslateWinMsg(ULONG msg, BOOL fMinFilter)
00134 {
00135     if(msg == 0)
00136         return 0;
00137 
00138     if(msg >= WINWM_USER)
00139         return msg + WIN32APP_POSTMSG;
00140 
00141     for(int i=0;i<MAX_MSGTRANSTAB;i++)
00142     {
00143         if(fMinFilter && MsgTransTab[i].msgWin32 >= msg) {
00144             return MsgTransTab[i].msgOS2;
00145         }
00146         else
00147         if(!fMinFilter && MsgTransTab[i].msgWin32 >= msg) {
00148             if(MsgTransTab[i].msgWin32 == msg)
00149                     return MsgTransTab[i].msgOS2;
00150             else    return MsgTransTab[i-1].msgOS2;
00151         }
00152     }
00153 
00154     //not found, get everything
00155     dprintf(("WARNING: TranslateWinMsg: message %x not found", msg));
00156     return 0;
00157 }
00158 //******************************************************************************
00159 //******************************************************************************
00160 void OSLibWinPostQuitMessage(ULONG nExitCode)
00161 {
00162  APIRET rc;
00163 
00164   rc = WinPostQueueMsg(NULLHANDLE, WM_QUIT, MPFROMLONG(nExitCode), 0);
00165   dprintf(("WinPostQueueMsg %d returned %d", nExitCode, rc));
00166 }
00167 //******************************************************************************
00168 //******************************************************************************
00169 LONG OSLibWinDispatchMsg(MSG *msg, BOOL isUnicode)
00170 {
00171  TEB  *teb;
00172  QMSG  os2msg;
00173  LONG  rc;
00174 
00175   teb = GetThreadTEB();
00176   if(teb == NULL) {
00177         DebugInt3();
00178         return FALSE;
00179   }
00180 
00181   //TODO: What to do if app changed msg? (translate)
00182   //  WinToOS2MsgTranslate(msg, &qmsg, isUnicode);
00183 
00184   if(!memcmp(msg, &teb->o.odin.winmsg, sizeof(MSG)) || msg->hwnd == 0) {
00185         memcpy(&os2msg, &teb->o.odin.os2msg, sizeof(QMSG));
00186         teb->o.odin.os2msg.time = -1;
00187         teb->o.odin.winmsg.time = -1;
00188         if(msg->hwnd) {
00189                 teb->o.odin.nrOfMsgs = 1;
00190                 teb->o.odin.msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
00191                 memcpy(&teb->o.odin.msg, msg, sizeof(MSG));
00192         }
00193         if(os2msg.hwnd || os2msg.msg == WM_QUIT) {
00194                 memset(&teb->o.odin.os2msg, 0, sizeof(teb->o.odin.os2msg));
00195                 memset(&teb->o.odin.winmsg, 0, sizeof(teb->o.odin.winmsg));
00196                 return (LONG)WinDispatchMsg(teb->o.odin.hab, &os2msg);
00197         }
00198         //SvL: Don't dispatch messages sent by PostThreadMessage (correct??)
00199         //     Or WM_TIMER msgs with no window handle or timer proc
00200         return 0;
00201 
00202   }
00203   else {//is this allowed?
00204 //        dprintf(("WARNING: OSLibWinDispatchMsg: called with own message!"));
00205         return SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam);
00206   }
00207 }
00208 //******************************************************************************
00209 //******************************************************************************
00210 
00211 #ifdef ALTGR_HACK
00212 static void i_MostUglyAltGrHack(LPMSG pMsg)
00213 {
00214   switch (pMsg->message)
00215   {
00216     case WINWM_KEYUP:
00217     case WINWM_SYSKEYUP:
00218       USHORT wWinScan = (pMsg->lParam & 0x00ff0000) >> 16;
00219       if (wWinScan == WINSCAN_ALTRIGHT)
00220       {
00221         KeySetOverlayKeyState(VK_RMENU_W, KEYOVERLAYSTATE_DONTCARE);
00222         KeySetOverlayKeyState(VK_MENU_W, KEYOVERLAYSTATE_DONTCARE);
00223       }
00224       break;
00225   }
00226 }
00227 #else
00228 #define i_MostUglyAltGrHack(a)
00229 #endif
00230 
00231 BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
00232                     BOOL isUnicode)
00233 {
00234  BOOL rc, eaten;
00235  TEB  *teb;
00236  QMSG  os2msg;
00237  HWND  hwndOS2 = 0;
00238  ULONG filtermin, filtermax;
00239 
00240   if(hwnd) {
00241         hwndOS2 = Win32ToOS2Handle(hwnd);
00242         if(hwndOS2 == NULL) {
00243                 memset(pMsg, 0, sizeof(MSG));
00244                 dprintf(("GetMsg: window %x NOT FOUND!", hwnd));
00245                 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
00246                 return TRUE;
00247         }
00248   }
00249 
00250   teb = GetThreadTEB();
00251   if(teb == NULL) {
00252         DebugInt3();
00253         return TRUE;
00254   }
00255 
00256   if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd)) 
00257   {
00258         dprintf(("Return queued WM_CHAR message hwnd=%x msg=%d wParam=%x lParam=%x", teb->o.odin.msgWCHAR.hwnd, teb->o.odin.msgWCHAR.message, teb->o.odin.msgWCHAR.wParam, teb->o.odin.msgWCHAR.lParam));
00259         if(uMsgFilterMin) {
00260             if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
00261                 goto continuegetmsg;
00262         }
00263         if(uMsgFilterMax) {
00264             if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
00265                 goto continuegetmsg;
00266         }
00267         teb->o.odin.fTranslated = FALSE;
00268         memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
00269         teb->o.odin.os2msg.msg  = 0;
00270         teb->o.odin.os2msg.hwnd = 0;
00271     
00272         // @@@PH verify this
00273         // if this is a keyup or keydown message, we've got to
00274         // call the keyboard hook here
00275         // send keyboard messages to the registered hooks
00276         switch (pMsg->message)
00277         {
00278           case WINWM_KEYDOWN:
00279           case WINWM_KEYUP:
00280           case WINWM_SYSKEYDOWN:
00281           case WINWM_SYSKEYUP:
00282             // only supposed to be called upon WM_KEYDOWN
00283             // and WM_KEYUP according to docs.
00284             if(ProcessKbdHook(pMsg, TRUE))
00285               goto continuegetmsg;
00286             break;
00287         }
00288 
00289         i_MostUglyAltGrHack(pMsg);
00290 
00291         return (pMsg->message != WINWM_QUIT);
00292   }
00293 
00294 continuegetmsg:
00295   if(hwnd) {
00296         filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
00297         filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
00298         if(filtermin > filtermax) {
00299                 ULONG tmp = filtermin;
00300                 filtermin = filtermax;
00301                 filtermax = filtermin;
00302         }
00303         do {
00304                 WinWaitMsg(teb->o.odin.hab, filtermin, filtermax);
00305                 rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
00306         }
00307         while(rc == FALSE);
00308 
00309         return (pMsg->message != WINWM_QUIT);
00310   }
00311   else
00312   {
00313         filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
00314         filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
00315         if(filtermin > filtermax) {
00316                 ULONG tmp = filtermin;
00317                 filtermin = filtermax;
00318                 filtermax = filtermin;
00319         }
00320         do {
00321                 eaten = FALSE;
00322                 rc = WinGetMsg(teb->o.odin.hab, &os2msg, 0, filtermin, filtermax);
00323                 if (os2msg.msg == WM_TIMER)
00324                     eaten = TIMER_HandleTimer(&os2msg);
00325         } while (eaten);
00326   }
00327   if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, MSG_REMOVE) == FALSE) {
00328       //dispatch untranslated message immediately
00329       WinDispatchMsg(teb->o.odin.hab, &os2msg);
00330       //and get the next one
00331       return OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, isUnicode);
00332   }
00333 
00334   memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
00335   memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
00336   
00337   // send keyboard messages to the registered hooks
00338   switch (pMsg->message)
00339   {
00340     case WINWM_KEYDOWN:
00341     case WINWM_KEYUP:
00342     case WINWM_SYSKEYDOWN:
00343     case WINWM_SYSKEYUP:
00344       // only supposed to be called upon WM_KEYDOWN
00345       // and WM_KEYUP according to docs.
00346       if(ProcessKbdHook(pMsg, TRUE))
00347         goto continuegetmsg;
00348       break;
00349   }
00350   
00351   i_MostUglyAltGrHack(pMsg);
00352   
00353   return rc;
00354 }
00355 
00356 
00357 //******************************************************************************
00358 //PeekMessage retrieves only messages associated with the window identified by the 
00359 //hwnd parameter or any of its children as specified by the IsChild function, and within 
00360 //the range of message values given by the uMsgFilterMin and uMsgFilterMax 
00361 //parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that 
00362 //belongs to the current thread making the call. (PeekMessage does not retrieve 
00363 //messages for windows that belong to other threads.) If hwnd is -1, PeekMessage only 
00364 //returns messages with a hwnd value of NULL, as posted by the PostAppMessage 
00365 //function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all 
00366 //available messages (no range filtering is performed). 
00367 //TODO: Not working as specified right now!
00368 //******************************************************************************
00369 BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
00370                      DWORD fRemove, BOOL isUnicode)
00371 {
00372  BOOL  rc, eaten;
00373  TEB  *teb;
00374  QMSG  os2msg;
00375  HWND  hwndOS2 = 0;
00376 
00377   if(hwnd && hwnd != -1) {
00378         hwndOS2 = Win32ToOS2Handle(hwnd);
00379         if(hwndOS2 == NULL) {
00380                 dprintf(("PeekMsg: window %x NOT FOUND!", hwnd));
00381                 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
00382                 return FALSE;
00383         }
00384   }
00385 
00386   teb = GetThreadTEB();
00387   if(teb == NULL) {
00388         DebugInt3();
00389         return FALSE;
00390   }
00391 
00392   if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd)) 
00393   {
00394         dprintf(("Return queued WM_CHAR message hwnd=%x msg=%d wParam=%x lParam=%x", teb->o.odin.msgWCHAR.hwnd, teb->o.odin.msgWCHAR.message, teb->o.odin.msgWCHAR.wParam, teb->o.odin.msgWCHAR.lParam));
00395         if(uMsgFilterMin) {
00396             if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
00397                 goto continuepeekmsg;
00398         }
00399         if(uMsgFilterMax) {
00400             if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
00401                 goto continuepeekmsg;
00402         }
00403 
00404         if(fRemove & PM_REMOVE_W) {
00405             teb->o.odin.fTranslated = FALSE;
00406             teb->o.odin.os2msg.msg  = 0;
00407             teb->o.odin.os2msg.hwnd = 0;
00408         }
00409         memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
00410     
00411         // @@@PH verify this
00412         // if this is a keyup or keydown message, we've got to
00413         // call the keyboard hook here
00414         // send keyboard messages to the registered hooks
00415         switch (pMsg->message)
00416         {
00417           case WINWM_KEYDOWN:
00418           case WINWM_KEYUP:
00419           case WINWM_SYSKEYDOWN:
00420           case WINWM_SYSKEYUP:
00421             // only supposed to be called upon WM_KEYDOWN
00422             // and WM_KEYUP according to docs.
00423             if(ProcessKbdHook(pMsg, fRemove))
00424               goto continuepeekmsg;
00425             break;
00426         }
00427     
00428         return TRUE;
00429   }
00430 
00431 continuepeekmsg:
00432   do {
00433         eaten = FALSE;
00434         rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
00435                         TranslateWinMsg(uMsgFilterMax, FALSE), (fRemove & PM_REMOVE_W) ? PM_REMOVE : PM_NOREMOVE);
00436 
00437         if (rc && (fRemove & PM_REMOVE_W) && os2msg.msg == WM_TIMER) {
00438             eaten = TIMER_HandleTimer(&os2msg);
00439         }
00440   }
00441   while (eaten && rc);
00442 
00443   if(rc == FALSE) {
00444       return FALSE;
00445   }
00446   
00447   // @@@PH
00448   // warning - OS2ToWinMsgTranslate might insert additional messages
00449   // into the queue
00450   if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, (fRemove & PM_REMOVE_W) ? MSG_REMOVE : MSG_NOREMOVE) == FALSE) 
00451   {
00452      //unused PM message; dispatch immediately and grab next one
00453      dprintf2(("OSLibWinPeekMsg: Untranslated message; dispatched immediately"));
00454      if(!(fRemove & PM_REMOVE_W)) {
00455          rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
00456                          TranslateWinMsg(uMsgFilterMax, FALSE), PM_REMOVE);
00457      }
00458      WinDispatchMsg(teb->o.odin.hab, &os2msg);
00459      return OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax,
00460                             fRemove, isUnicode);
00461   }
00462   //TODO: This is not safe! There's no guarantee this message will be dispatched and it might overwrite a previous message
00463   if(fRemove & PM_REMOVE_W) {
00464         memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
00465         memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
00466   }
00467 
00468   // send keyboard messages to the registered hooks
00469   switch (pMsg->message)
00470   {
00471     case WINWM_KEYDOWN:
00472     case WINWM_KEYUP:
00473     case WINWM_SYSKEYDOWN:
00474     case WINWM_SYSKEYUP:
00475       // only supposed to be called upon WM_KEYDOWN
00476       // and WM_KEYUP according to docs.
00477       if(ProcessKbdHook(pMsg, fRemove))
00478         goto continuepeekmsg;
00479       break;
00480   }
00481 
00482   return rc;
00483 }
00484 //******************************************************************************
00485 //******************************************************************************
00486 ULONG OSLibWinQueryMsgTime()
00487 {
00488   return WinQueryMsgTime(GetThreadHAB());
00489 }
00490 //******************************************************************************
00491 //******************************************************************************
00492 BOOL OSLibWinWaitMessage()
00493 {
00494   return WinWaitMsg(GetThreadHAB(), 0, 0);
00495 }
00496 //******************************************************************************
00497 //TODO: QS_HOTKEY
00498 //******************************************************************************
00499 ULONG OSLibWinQueryQueueStatus()
00500 {
00501  ULONG statusOS2, statusWin32 = 0;
00502 
00503    statusOS2 = WinQueryQueueStatus(HWND_DESKTOP);
00504 
00505    if(statusOS2 & QS_KEY)
00506     statusWin32 |= QS_KEY_W;
00507    if(statusOS2 & QS_MOUSEBUTTON)
00508     statusWin32 |= QS_MOUSEBUTTON_W;
00509    if(statusOS2 & QS_MOUSEMOVE)
00510     statusWin32 |= QS_MOUSEMOVE_W;
00511    if(statusOS2 & QS_TIMER)
00512     statusWin32 |= QS_TIMER_W;
00513    if(statusOS2 & QS_PAINT)
00514     statusWin32 |= QS_PAINT_W;
00515    if(statusOS2 & QS_POSTMSG)
00516     statusWin32 |= QS_POSTMESSAGE_W;
00517    if(statusOS2 & QS_SENDMSG)
00518     statusWin32 |= QS_SENDMESSAGE_W;
00519 
00520    return statusWin32;
00521 }
00522 //******************************************************************************
00523 //******************************************************************************
00524 BOOL OSLibWinInSendMessage()
00525 {
00526    return WinInSendMsg(GetThreadHAB());
00527 }
00528 //******************************************************************************
00529 //******************************************************************************
00530 DWORD OSLibWinGetMessagePos()
00531 {
00532  APIRET rc;
00533  POINTL ptl;
00534 
00535    rc = WinQueryMsgPos(GetThreadHAB(), &ptl);
00536    if(!rc) {
00537       return 0;
00538    }
00539    //convert to windows coordinates
00540    return MAKEULONG(ptl.x,mapScreenY(ptl.y));
00541 }
00542 //******************************************************************************
00543 //******************************************************************************
00544 LONG OSLibWinGetMessageTime()
00545 {
00546    return (LONG)WinQueryMsgTime(GetThreadHAB());
00547 }
00548 //******************************************************************************
00549 //******************************************************************************
00550 BOOL OSLibWinReplyMessage(ULONG result)
00551 {
00552    return (BOOL)WinReplyMsg( NULLHANDLE, NULLHANDLE, HMQ_CURRENT, (MRESULT)result);
00553 }
00554 //******************************************************************************
00555 //******************************************************************************
00556 ULONG OSLibSendMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
00557 {
00558  POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
00559   
00560     if(NULL == packet)
00561     {
00562         dprintf(("user32::oslibmsg::OSLibSendMessage - allocated packet structure is NULL, heapmin=%d\n",
00563                  _sheapmin() ));
00564     
00565         // PH: we cannot provide a correct returncode :(
00566         DebugInt3();    
00567         return 0;
00568     }
00569   
00570     packet->wParam   = wParam;
00571     packet->lParam   = lParam;
00572 
00573     return (ULONG)WinSendMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
00574 }
00575 //******************************************************************************
00576 //******************************************************************************
00577 ULONG OSLibWinBroadcastMsg(ULONG msg, ULONG wParam, ULONG lParam, BOOL fSend)
00578 {
00579     return WinBroadcastMsg(HWND_DESKTOP, WIN32APP_POSTMSG+msg, (MPARAM)wParam, (MPARAM)lParam,
00580                            (fSend) ? BMSG_SEND : BMSG_POST);
00581 }
00582 //******************************************************************************
00583 //******************************************************************************
00584 BOOL OSLibPostMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
00585 {
00586  POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
00587   
00588     if (NULL == packet)
00589     {
00590         dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
00591                  _sheapmin() ));
00592     
00593         // PH: we can provide a correct returncode
00594         DebugInt3();    
00595         return FALSE;
00596     }
00597     packet->wParam   = wParam;
00598     packet->lParam   = lParam;
00599     return WinPostMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
00600 }
00601 //******************************************************************************
00602 //Direct posting of messages that must remain invisible to the win32 app
00603 //******************************************************************************
00604 BOOL OSLibPostMessageDirect(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam)
00605 {
00606     return WinPostMsg(hwnd, msg, (MPARAM)wParam, (MPARAM)lParam);
00607 }
00608 //******************************************************************************
00609 BOOL    _System _O32_PostThreadMessage( DWORD, UINT, WPARAM, LPARAM );
00610 
00611 inline BOOL O32_PostThreadMessage(DWORD a, UINT b, WPARAM c, LPARAM d)
00612 {
00613  BOOL yyrc;
00614  USHORT sel = RestoreOS2FS();
00615 
00616     yyrc = _O32_PostThreadMessage(a, b, c, d);
00617     SetFS(sel);
00618 
00619     return yyrc;
00620 }
00621 //******************************************************************************
00622 BOOL OSLibPostThreadMessage(ULONG threadid, UINT msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
00623 {
00624  TEB *teb = GetTEBFromThreadId(threadid);
00625  POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
00626  BOOL ret;
00627   
00628     if(NULL == packet)
00629     {
00630         dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
00631                  _sheapmin() ));
00632 
00633         DebugInt3();    
00634         // PH: we can provide a correct returncode
00635         return FALSE;
00636     }
00637     
00638     if(teb == NULL) {
00639         dprintf(("OSLibPostThreadMessage: thread %x not found!", threadid));
00640         return FALSE;
00641     }
00642     dprintf(("PostThreadMessageA %x %x %x %x -> hmq %x", threadid, msg, wParam, lParam, teb->o.odin.hmq));
00643     packet->wParam   = wParam;
00644     packet->lParam   = lParam;
00645 
00646     ret = WinPostQueueMsg((HMQ)teb->o.odin.hmq, WIN32APP_POSTMSG+msg, 
00647                           (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), 
00648                           (MPARAM)packet);
00649 
00650     if(ret == FALSE)
00651     {
00652        SetLastError(ERROR_INVALID_PARAMETER_W);
00653        return FALSE;
00654     }
00655     SetLastError(ERROR_SUCCESS_W);
00656     return TRUE;
00657 }
00658 //******************************************************************************
00659 //******************************************************************************
00660 DWORD GetThreadMessageExtraInfo()
00661 {
00662  TEB *teb;
00663 
00664   teb = GetThreadTEB();
00665   if(teb)
00666   {
00667       return teb->o.odin.dwMsgExtraInfo;
00668   }
00669   dprintf(("GetThreadMessageExtraInfo: teb == NULL!!"));
00670   return 0;
00671 }
00672 //******************************************************************************
00673 //******************************************************************************
00674 DWORD SetThreadMessageExtraInfo(DWORD lParam)
00675 {
00676  TEB *teb;
00677 
00678   teb = GetThreadTEB();
00679   if(teb)
00680   {
00681         teb->o.odin.dwMsgExtraInfo = lParam;
00682   }
00683   else  dprintf(("SetThreadMessageExtraInfo: teb == NULL!!"));
00684   return 0;
00685 }
00686 //******************************************************************************
00687 //******************************************************************************

Generated on Wed Jan 23 23:17:38 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001