Ignore:
Timestamp:
Apr 11, 2003, 4:22:06 PM (22 years ago)
Author:
sandervl
Message:

KSO: Implemented WM_COPYDATA

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/oslibmsg.cpp

    r9950 r10012  
    1 /* $Id: oslibmsg.cpp,v 1.67 2003-03-28 11:49:01 sandervl Exp $ */
     1/* $Id: oslibmsg.cpp,v 1.68 2003-04-11 14:22:05 sandervl Exp $ */
    22/*
    33 * Window message translation functions for OS/2
     
    5353#include "user32api.h"
    5454
    55 #define DBG_LOCALLOG    DBG_oslibmsg
     55#define DBG_LOCALLOG    DBG_oslibmsg
    5656#include "dbglocal.h"
    5757
     
    210210        teb->o.odin.winmsg.time = -1;
    211211        if(msg->hwnd) {
    212                 teb->o.odin.nrOfMsgs = 1;
    213                 teb->o.odin.msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
    214                 memcpy(&teb->o.odin.msg, msg, sizeof(MSG));
     212                teb->o.odin.nrOfMsgs = 1;
     213                teb->o.odin.msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
     214                memcpy(&teb->o.odin.msg, msg, sizeof(MSG));
    215215        }
    216216        if(os2msg.hwnd || os2msg.msg == WM_QUIT) {
    217                 memset(&teb->o.odin.os2msg, 0, sizeof(teb->o.odin.os2msg));
    218                 memset(&teb->o.odin.winmsg, 0, sizeof(teb->o.odin.winmsg));
    219                 return (LONG)WinDispatchMsg(teb->o.odin.hab, &os2msg);
     217                memset(&teb->o.odin.os2msg, 0, sizeof(teb->o.odin.os2msg));
     218                memset(&teb->o.odin.winmsg, 0, sizeof(teb->o.odin.winmsg));
     219                return (LONG)WinDispatchMsg(teb->o.odin.hab, &os2msg);
    220220        }
    221221        //SvL: Don't dispatch messages sent by PostThreadMessage (correct??)
     
    241241
    242242    if(hwnd) {
    243         hwndOS2 = Win32ToOS2Handle(hwnd);
    244         if(hwndOS2 == NULL) {
    245                     memset(pMsg, 0, sizeof(MSG));
    246                     dprintf(("GetMsg: window %x NOT FOUND!", hwnd));
    247                     SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
    248                     return TRUE;
    249             }
     243        hwndOS2 = Win32ToOS2Handle(hwnd);
     244        if(hwndOS2 == NULL) {
     245                    memset(pMsg, 0, sizeof(MSG));
     246                    dprintf(("GetMsg: window %x NOT FOUND!", hwnd));
     247                    SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
     248                    return TRUE;
     249            }
    250250    }
    251251
     
    253253    if(teb == NULL) {
    254254        DebugInt3();
    255         return TRUE;
    256     }
    257    
    258     if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd)) 
     255        return TRUE;
     256    }
     257
     258    if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
    259259    {
    260260        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));
     
    277277        teb->o.odin.os2msg.msg  = 0;
    278278        teb->o.odin.os2msg.hwnd = 0;
    279    
     279
    280280        if(!IsWindow(pMsg->hwnd)) {
    281281            //could be a queued char message for a window that was just destroyed
     
    306306continuegetmsg:
    307307    if(hwnd) {
    308         filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
    309             filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
    310             if(filtermin > filtermax) {
    311                 ULONG tmp = filtermin;
    312                     filtermin = filtermax;
    313                     filtermax = filtermin;
    314             }
     308        filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
     309            filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
     310            if(filtermin > filtermax) {
     311                ULONG tmp = filtermin;
     312                    filtermin = filtermax;
     313                    filtermax = filtermin;
     314            }
    315315        do {
    316                 WinWaitMsg(teb->o.odin.hab, filtermin, filtermax);
    317                 rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
     316                WinWaitMsg(teb->o.odin.hab, filtermin, filtermax);
     317                rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
    318318        }
    319319        while(rc == FALSE);
     
    323323    else
    324324    {
    325         filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
    326             filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
    327             if(filtermin > filtermax) {
    328                 ULONG tmp = filtermin;
    329                     filtermin = filtermax;
    330                     filtermax = filtermin;
    331             }
    332         do {
    333                 eaten = FALSE;
    334                 rc = WinGetMsg(teb->o.odin.hab, &os2msg, 0, filtermin, filtermax);
    335                 if (os2msg.msg == WM_TIMER)
    336                     eaten = TIMER_HandleTimer(&os2msg);
     325        filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
     326            filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
     327            if(filtermin > filtermax) {
     328                ULONG tmp = filtermin;
     329                    filtermin = filtermax;
     330                    filtermax = filtermin;
     331            }
     332        do {
     333                eaten = FALSE;
     334                rc = WinGetMsg(teb->o.odin.hab, &os2msg, 0, filtermin, filtermax);
     335                if (os2msg.msg == WM_TIMER)
     336                    eaten = TIMER_HandleTimer(&os2msg);
    337337                if (os2msg.msg == WM_QUIT && ((ULONG)os2msg.mp2 != 0) ) {
    338338                    // Don't return FALSE when the window list sends us
     
    342342                    // in this case. When the app calls PostQuitMessage (mp2 == 0),
    343343                    // then we handle it the normal way
    344                     rc = 1; 
     344                    rc = 1;
    345345                }
    346             }
     346            }
    347347        while (eaten);
    348348    }
     
    356356    memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
    357357    memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
    358  
     358
    359359    // send keyboard messages to the registered hooks
    360360    switch (pMsg->message)
     
    375375
    376376//******************************************************************************
    377 //PeekMessage retrieves only messages associated with the window identified by the 
    378 //hwnd parameter or any of its children as specified by the IsChild function, and within 
    379 //the range of message values given by the uMsgFilterMin and uMsgFilterMax 
    380 //parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that 
    381 //belongs to the current thread making the call. (PeekMessage does not retrieve 
    382 //messages for windows that belong to other threads.) If hwnd is -1, PeekMessage only 
    383 //returns messages with a hwnd value of NULL, as posted by the PostAppMessage 
    384 //function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all 
    385 //available messages (no range filtering is performed). 
     377//PeekMessage retrieves only messages associated with the window identified by the
     378//hwnd parameter or any of its children as specified by the IsChild function, and within
     379//the range of message values given by the uMsgFilterMin and uMsgFilterMax
     380//parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that
     381//belongs to the current thread making the call. (PeekMessage does not retrieve
     382//messages for windows that belong to other threads.) If hwnd is -1, PeekMessage only
     383//returns messages with a hwnd value of NULL, as posted by the PostAppMessage
     384//function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all
     385//available messages (no range filtering is performed).
    386386//TODO: Not working as specified right now!
    387387//******************************************************************************
     
    401401    }
    402402    if(hwnd && hwnd != -1) {
    403             hwndOS2 = Win32ToOS2Handle(hwnd);
    404             if(hwndOS2 == NULL) {
    405                 dprintf(("PeekMsg: window %x NOT FOUND!", hwnd));
    406                     SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
    407                     return FALSE;
    408             }
     403            hwndOS2 = Win32ToOS2Handle(hwnd);
     404            if(hwndOS2 == NULL) {
     405                dprintf(("PeekMsg: window %x NOT FOUND!", hwnd));
     406                    SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
     407                    return FALSE;
     408            }
    409409    }
    410410
     
    415415    }
    416416
    417     if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd)) 
     417    if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
    418418    {
    419419        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));
     
    447447            goto continuepeekmsg;
    448448        }
    449    
     449
    450450        // @@@PH verify this
    451451        // if this is a keyup or keydown message, we've got to
     
    466466            }
    467467        }
    468    
     468
    469469        return TRUE;
    470470    }
    471471
    472472continuepeekmsg:
    473     if(uMsgFilterMin && uMsgFilterMax) 
     473    if(uMsgFilterMin && uMsgFilterMax)
    474474    {   //we can't use the PM message filter (since the message nrs aren't similar), so we must
    475475        //filter each message seperately
     
    485485                    eaten = FALSE;
    486486
    487                     rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, ulPMFilter, ulPMFilter, 
     487                    rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, ulPMFilter, ulPMFilter,
    488488                                    (fRemove & PM_REMOVE_W) ? PM_REMOVE : PM_NOREMOVE);
    489489                    //Sadly indeed WinPeekMsg sometimes does not filter well!
    490490                    if (rc && (os2msg.msg != ulPMFilter)) {// drop this message
    491491                       dprintf(("WARNING: WinPeekMsg returns %x even though we filter for %x", os2msg.msg, ulPMFilter));
    492                        rc = 0;   
     492                       rc = 0;
    493493                    }
    494494                    if (rc && (fRemove & PM_REMOVE_W) && os2msg.msg == WM_TIMER) {
     
    518518        return FALSE;
    519519    }
    520  
     520
    521521    // @@@PH
    522522    // warning - OS2ToWinMsgTranslate might insert additional messages
    523523    // into the queue
    524     if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, (fRemove & PM_REMOVE_W) ? MSG_REMOVE : MSG_NOREMOVE) == FALSE) 
     524    if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, (fRemove & PM_REMOVE_W) ? MSG_REMOVE : MSG_NOREMOVE) == FALSE)
    525525    {
    526526         //unused PM message; dispatch immediately and grab next one
     
    535535    //TODO: This is not safe! There's no guarantee this message will be dispatched and it might overwrite a previous message
    536536    if(fRemove & PM_REMOVE_W) {
    537         memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
    538         memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
     537        memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
     538        memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
    539539    }
    540540
     
    627627    return (BOOL)WinReplyMsg( NULLHANDLE, NULLHANDLE, HMQ_CURRENT, (MRESULT)result);
    628628}
    629 //******************************************************************************
    630 //******************************************************************************
     629
     630//******************************************************************************
     631
     632/**
     633 * Send and Post message helper for packing down interprocess and interthread messages.
     634 *
     635 * @returns Pointer to packet on success. (shared memory)
     636 * @returns NULL on failure with SendMessage return code suggestion in *pRc if pRc is set.
     637 * @param   hwndOdin    Odin window handle. (NULL allowed)
     638 * @param   hwndOS2     OS/2 window handle.
     639 * @param   msg         Message id.
     640 * @param   wParam      Message param.
     641 * @param   lParam      Message param.
     642 * @param   fUnicode    Unicode or ansi indicator.
     643 * @param   pRc         Where to store SendMessage return code. Optional.
     644 * @author  knut st. osmundsen<bird@anduin.net>
     645 */
     646void * OSLibPackMessage(HWND hwndOdin, HWND hwndOS2, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode, PULONG pRc)
     647{
     648    POSTMSG_PACKET  * pMsgPacket;
     649
     650    /*
     651     * Pack message by id.
     652     */
     653    switch (msg)
     654    {
     655        /*
     656         * lParam = PCOPYDATASTRUCT.
     657         *      Must move this to shared memory together with any
     658         *      data it's pointing at.
     659         *
     660         *      We put everything into the package that might ease cleanup...
     661         *      WARNING! Currently there are cleanup hacks which works with acrobat.
     662         */
     663        case WINWM_COPYDATA:
     664        {
     665            PCOPYDATASTRUCT_W pOrg = (PCOPYDATASTRUCT_W)lParam;
     666            dprintf(("user32::oslibmsg::OSLibPackMessage - WM_COPYDATA: lParam=%#x  dwData=%#x cbData=%d lpData=%#x",
     667                     pOrg, pOrg ? pOrg->dwData : -1, pOrg ? pOrg->cbData : -1, pOrg ? pOrg->lpData : (LPVOID)-1));
     668
     669            /*
     670             * Calc packet size.
     671             */
     672            unsigned cb = sizeof(POSTMSG_PACKET);
     673            if (pOrg)
     674            {
     675                cb += sizeof(COPYDATASTRUCT_W);
     676                if (pOrg->lpData && pOrg->cbData)
     677                    cb += 16 + pOrg->cbData; //add 16 Bytes for safty and alignment.
     678            }
     679
     680            /*
     681             * Allocate packet.
     682             */
     683            pMsgPacket = (POSTMSG_PACKET *)_smalloc(cb);
     684            if (!pMsgPacket)
     685            {
     686                dprintf(("user32::oslibmsg::OSLibPackMessage - WM_COPYDATA: failed to allocate %d shared bytes for packing", cb));
     687                DebugInt3();
     688                if (pRc)
     689                    *pRc = FALSE;
     690                //@todo figure out which error to set. This is plain guesswork!
     691                SetLastError(ERROR_NOT_ENOUGH_MEMORY_W);
     692                break;
     693            }
     694
     695            /*
     696             * Initialize packet.
     697             */
     698            PCOPYDATASTRUCT_W pNew = (PCOPYDATASTRUCT_W)(pMsgPacket + 1);
     699            pMsgPacket->wParam = wParam;
     700            pMsgPacket->lParam = (LPARAM)pNew;
     701            *pNew = *pOrg;
     702            if (pNew->cbData && pNew->lpData)
     703            {
     704                pNew->lpData = (LPVOID)(((unsigned)(pNew + 1) + 15) & ~15); //16byte align for safty.
     705                //@todo what about a safe_memcpy?
     706                memcpy(pNew->lpData, pOrg->lpData, pNew->cbData);
     707            }
     708
     709            /* done! */
     710            dprintf(("user32::oslibmsg::OSLibPackMessage - WM_COPYDATA: Packed down %d bytes at %#x (pMsgPacket)",
     711                     cb, pMsgPacket));
     712            break;
     713        }
     714
     715
     716        /*
     717         * Default packing
     718         */
     719        default:
     720        {
     721            pMsgPacket = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
     722            if (!pMsgPacket)
     723            {
     724                dprintf(("user32::oslibmsg::OSLibPackMessage - allocated packet structure is NULL"));
     725                if (pRc)
     726                {   // Can't find any better return code than 0 :/
     727                    *pRc = 0;
     728                }
     729                DebugInt3();
     730                break;
     731            }
     732            pMsgPacket->wParam = wParam;
     733            pMsgPacket->lParam = lParam;
     734        }
     735
     736    }
     737
     738    return pMsgPacket;
     739}
     740
     741
     742/**
     743 * Send an inter thread/proces message.
     744 *
     745 * @returns
     746 * @param   hwnd        OS/2 hwnd.
     747 * @param   msg         Odin message id.
     748 * @param   wParam      Message param.
     749 * @param   lParam      Message param.
     750 * @param   fUnicode    Unicode indicator.
     751 */
    631752ULONG OSLibSendMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
    632753{
    633     POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
    634  
    635     if(NULL == packet)
    636     {
    637         dprintf(("user32::oslibmsg::OSLibSendMessage - allocated packet structure is NULL"));
    638    
    639         // PH: we cannot provide a correct returncode :(
    640         DebugInt3();   
    641         return 0;
    642     }
    643  
    644     packet->wParam   = wParam;
    645     packet->lParam   = lParam;
    646 
    647     return (ULONG)WinSendMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
    648 }
     754    ULONG           rc;                 /* return code on packing failure */
     755    void *          pvMsgPacket;        /* packed message (shared memory) */
     756
     757    /*
     758     * Call message packer.
     759     */
     760    pvMsgPacket = OSLibPackMessage(NULLHANDLE, hwnd, msg, wParam, lParam, fUnicode, &rc);
     761    if (!pvMsgPacket)
     762    {
     763        dprintf(("user32::oslibmsg::OSLibSendMessage - Failed to pack message !!"));
     764        DebugInt3();
     765        return rc;
     766    }
     767
     768    return (ULONG)WinSendMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), pvMsgPacket);
     769}
     770
    649771//******************************************************************************
    650772//******************************************************************************
    651773ULONG OSLibWinBroadcastMsg(ULONG msg, ULONG wParam, ULONG lParam, BOOL fSend)
    652774{
     775    #ifdef DEBUG
     776    if (msg == WINWM_COPYDATA)
     777    {
     778        dprintf(("user32::oslibmsg::OSLibWinBroadcastMsg - WM_COPYDATA will not work outside this process !!!"));
     779        DebugInt3();
     780    }
     781    #endif
    653782    return WinBroadcastMsg(HWND_DESKTOP, WIN32APP_POSTMSG+msg, (MPARAM)wParam, (MPARAM)lParam,
    654783                           (fSend) ? BMSG_SEND : BMSG_POST);
    655784}
    656 //******************************************************************************
    657 //******************************************************************************
     785
     786
     787/**
     788 * Post a message.
     789 *
     790 * @returns Success indicator.
     791 *
     792 * @param   hwndWin32   Odin window handle.
     793 * @param   hwndOS2     OS/2 window handle
     794 * @param   msg         Odin message id.
     795 * @param   wParam      Message param.
     796 * @param   lParam      Message param.
     797 * @param   fUnicode    Unicode indicator.
     798 */
    658799BOOL OSLibPostMessage(HWND hwndWin32, HWND hwndOS2, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
    659800{
    660     POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
    661     BOOL ret;
    662 
    663     if (NULL == packet)
    664     {
    665         dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL"));
    666    
    667         // PH: we can provide a correct returncode
    668         DebugInt3();   
     801    void *          pvMsgPacket;        /* packed message (shared memory) */
     802
     803    /*
     804     * Call message packer.
     805     */
     806    pvMsgPacket = OSLibPackMessage(hwndWin32, hwndOS2, msg, wParam, lParam, fUnicode, NULL);
     807    if (!pvMsgPacket)
     808    {
     809        dprintf(("user32::oslibmsg::OSLibPostMessage - Failed to pack message !!"));
     810        DebugInt3();
    669811        return FALSE;
    670812    }
     813
     814    /*
     815     * Post the message.
     816     * Signal the receiver for if it's doing MsgWaitForMultipleObjects() at the time.
     817     */
    671818    TEB *teb = GetTEBFromThreadId(GetWindowThreadProcessId(hwndWin32, NULL));
    672 
    673     packet->wParam   = wParam;
    674     packet->lParam   = lParam;
    675     ret = WinPostMsg(hwndOS2, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
    676 
    677     if(teb && (teb->o.odin.dwWakeMask & QS_POSTMESSAGE_W)) {
     819    BOOL ret = WinPostMsg(hwndOS2,
     820                          WIN32APP_POSTMSG+msg,
     821                          (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA),
     822                          pvMsgPacket);
     823    if (teb && (teb->o.odin.dwWakeMask & QS_POSTMESSAGE_W))
     824    {
    678825        //thread is blocked in MsgWaitForMultipleObjects waiting for
    679826        //posted messages
     
    697844    POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
    698845    BOOL ret;
    699  
    700     if(NULL == packet)
     846
     847    if (NULL == packet)
    701848    {
    702849        dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL"));
    703850
    704         DebugInt3();   
     851        DebugInt3();
    705852        // PH: we can provide a correct returncode
    706853        return FALSE;
    707854    }
    708    
     855
    709856    if(teb == NULL) {
    710857        dprintf(("OSLibPostThreadMessage: thread %x not found!", threadid));
     
    715862    packet->lParam   = lParam;
    716863
    717     ret = WinPostQueueMsg((HMQ)teb->o.odin.hmq, WIN32APP_POSTMSG+msg, 
    718                           (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), 
     864    ret = WinPostQueueMsg((HMQ)teb->o.odin.hmq, WIN32APP_POSTMSG+msg,
     865                          (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA),
    719866                          (MPARAM)packet);
    720867
Note: See TracChangeset for help on using the changeset viewer.