VirtualBox

Changeset 97734 in vbox


Ignore:
Timestamp:
Dec 2, 2022 7:58:41 PM (2 years ago)
Author:
vboxsync
Message:

DnD/VBoxClient: Now uses similar debug / verbose messages via system notifications when the users starts it in verbose mode (like VBoxTray). Also added easier to read (verbose release) logging to see what's going on with release builds.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp

    r96407 r97734  
    5050#include <VBox/log.h>
    5151#include <VBox/VBoxGuestLib.h>
     52#include <VBox/version.h>
    5253
    5354#include "VBox/HostServices/DragAndDropSvc.h"
    5455#include "VBoxClient.h"
    5556
    56 /* Enable this define to see the proxy window(s) when debugging
    57  * their behavior. Don't have this enabled in release builds! */
    58 #ifdef DEBUG
    59 //# define VBOX_DND_DEBUG_WND
    60 #endif
    6157
    6258/* Enable this to handle drag'n drop "promises".
     
    131127/** How many X properties our proxy window can hold. */
    132128#define VBOX_MAX_XPROPERTIES (LONG_MAX-1)
     129
     130/** The notification header text for VBClShowNotify(). */
     131#define VBOX_DND_SHOWNOTIFY_HEADER              VBOX_PRODUCT " Drag'n Drop"
    133132
    134133/**
     
    199198
    200199/**
    201  * Xdnd message value indexes, sorted by message type.
     200 * Xdnd message value indices, sorted by message type.
    202201 */
    203202typedef enum XdndMsg
     
    251250    /** XdndFinished. */
    252251    XdndFinishedWindow = 0,         /* Target window (sender). */
    253     XdndFinishedFlags,              /* Version 5: Bit 0 is set if the current target accepted the drop. */
    254     XdndFinishedAction              /* Version 5: Contains the action performed by the target. */
     252    XdndFinishedFlags,              /* Since version 5: Bit 0 is set if the current target accepted the drop. */
     253    XdndFinishedAction              /* Since version 5: Contains the action performed by the target. */
    255254
    256255} XdndMsg;
     
    628627    /** Current source/target window handle. */
    629628    Window                      m_wndCur;
    630     /** The XDnD protocol version the current
    631      *  source/target window is using. */
     629    /** The XDnD protocol version the current source/target window is using. */
    632630    long                        m_curVer;
    633     /** List of (Atom) formats the source window supports. */
     631    /** List of (Atom) formats the current source/target window supports. */
    634632    VBoxDnDAtomList             m_lstAtomFormats;
    635     /** List of (Atom) actions the source window supports. */
     633    /** List of (Atom) actions the current source/target window supports. */
    636634    VBoxDnDAtomList             m_lstAtomActions;
    637635    /** Buffer for answering the target window's selection request. */
     
    645643    /** The instance's own X event queue. */
    646644    RTCMTList<WrappedXEvent>    m_eventQueueList;
    647     /** Critical section for providing serialized access to list
    648      *  event queue's contents. */
     645    /** Critical section for providing serialized access to list event queue's contents. */
    649646    RTCRITSECT                  m_eventQueueCS;
    650     /** Event for notifying this instance in case of a new
    651      *  event. */
     647    /** Event for notifying this instance in case of a new event. */
    652648    RTSEMEVENT                  m_eventQueueEvent;
    653649    /** Critical section for data access. */
     
    824820        RTCritSectLeave(&m_dataCS);
    825821    }
     822
     823    LogFlowFuncLeave();
    826824}
    827825
     
    838836    if (rc != VINF_SUCCESS)
    839837        return rc;
     838
     839    if (g_cVerbosity)
     840    {
     841        RTCString strBody = RTCStringFmt("Connected (screen %RU32, verbosity %u)", uScreenID, g_cVerbosity);
     842        VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, strBody.c_str());
     843    }
    840844
    841845    do
     
    891895        attr.override_redirect     = True;
    892896        attr.do_not_propagate_mask = NoEventMask;
    893 #ifdef VBOX_DND_DEBUG_WND
    894         attr.background_pixel      = XWhitePixel(m_pDisplay, m_screenID);
    895         attr.border_pixel          = XBlackPixel(m_pDisplay, m_screenID);
    896         m_wndProxy.hWnd = XCreateWindow(m_pDisplay, m_wndRoot                /* Parent */,
    897                                    100, 100,                                 /* Position */
    898                                    100, 100,                                 /* Width + height */
    899                                    2,                                        /* Border width */
    900                                    CopyFromParent,                           /* Depth */
    901                                    InputOutput,                              /* Class */
    902                                    CopyFromParent,                           /* Visual */
    903                                      CWBackPixel
    904                                    | CWBorderPixel
    905                                    | CWOverrideRedirect
    906                                    | CWDontPropagate,                        /* Value mask */
    907                                    &attr);                                   /* Attributes for value mask */
    908 #else
    909         m_wndProxy.hWnd = XCreateWindow(m_pDisplay, m_wndRoot            /* Parent */,
    910                                    0, 0,                                 /* Position */
    911                                    1, 1,                                 /* Width + height */
    912                                    0,                                    /* Border width */
    913                                    CopyFromParent,                       /* Depth */
    914                                    InputOnly,                            /* Class */
    915                                    CopyFromParent,                       /* Visual */
    916                                    CWOverrideRedirect | CWDontPropagate, /* Value mask */
    917                                    &attr);                               /* Attributes for value mask */
    918 #endif
     897
     898        if (g_cVerbosity >= 3)
     899        {
     900            attr.background_pixel      = XWhitePixel(m_pDisplay, m_screenID);
     901            attr.border_pixel          = XBlackPixel(m_pDisplay, m_screenID);
     902            m_wndProxy.hWnd = XCreateWindow(m_pDisplay, m_wndRoot               /* Parent */,
     903                                            100, 100,                           /* Position */
     904                                            100, 100,                           /* Width + height */
     905                                            2,                                  /* Border width */
     906                                            CopyFromParent,                     /* Depth */
     907                                            InputOutput,                        /* Class */
     908                                            CopyFromParent,                     /* Visual */
     909                                              CWBackPixel
     910                                            | CWBorderPixel
     911                                            | CWOverrideRedirect
     912                                            | CWDontPropagate,                  /* Value mask */
     913                                            &attr);                             /* Attributes for value mask */
     914        }
     915
     916        m_wndProxy.hWnd = XCreateWindow(m_pDisplay, m_wndRoot                   /* Parent */,
     917                                        0, 0,                                   /* Position */
     918                                        1, 1,                                   /* Width + height */
     919                                        0,                                      /* Border width */
     920                                        CopyFromParent,                         /* Depth */
     921                                        InputOnly,                              /* Class */
     922                                        CopyFromParent,                         /* Visual */
     923                                        CWOverrideRedirect | CWDontPropagate,   /* Value mask */
     924                                        &attr);                                 /* Attributes for value mask */
     925
    919926        if (!m_wndProxy.hWnd)
    920927        {
     
    931938        }
    932939
    933 #ifdef VBOX_DND_DEBUG_WND
    934         XFlush(m_pDisplay);
    935         XMapWindow(m_pDisplay, m_wndProxy.hWnd);
    936         XRaiseWindow(m_pDisplay, m_wndProxy.hWnd);
    937         XFlush(m_pDisplay);
    938 #endif
    939         VBClLogInfo("Proxy window=%RU32, root window=%RU32 ...\n", m_wndProxy.hWnd, m_wndRoot);
     940        if (g_cVerbosity >= 3) /* Make debug window visible. */
     941        {
     942            XFlush(m_pDisplay);
     943            XMapWindow(m_pDisplay, m_wndProxy.hWnd);
     944            XRaiseWindow(m_pDisplay, m_wndProxy.hWnd);
     945            XFlush(m_pDisplay);
     946        }
     947
     948        VBClLogInfo("Proxy window=%#x (debug mode: %RTbool), root window=%#x ...\n",
     949                    m_wndProxy.hWnd, RT_BOOL(g_cVerbosity >= 3), m_wndRoot);
    940950
    941951        /* Set the window's name for easier lookup. */
     
    974984    int rc = VINF_SUCCESS;
    975985
     986    char *pszWndCurName = wndX11GetNameA(m_wndCur);
     987    AssertPtrReturn(pszWndCurName, VERR_NO_MEMORY);
     988
    976989    switch (m_enmMode)
    977990    {
     
    982995             * window, in response of some events we send to them.
    983996             */
     997
     998            /* The target window informs us of the current Xdnd status. */
    984999            if (e.xclient.message_type == xAtom(XA_XdndStatus))
    9851000            {
    986                 Window wndTarget = static_cast<Window>(e.xclient.data.l[XdndStatusWindow]);
     1001                Window wndTgt = static_cast<Window>(e.xclient.data.l[XdndStatusWindow]);
     1002
     1003                char *pszWndTgtName = wndX11GetNameA(wndTgt);
     1004                AssertPtrBreakStmt(pszWndTgtName, VERR_NO_MEMORY);
    9871005
    9881006                /* Does the target accept the drop? */
     
    9911009                const bool fWantsPosition = e.xclient.data.l[XdndStatusFlags] & VBOX_XDND_STATUS_FLAG_WANTS_POS;
    9921010                RT_NOREF(fWantsPosition);
    993 
    994                 char *pszWndName = wndX11GetNameA(m_wndCur);
    995                 AssertPtr(pszWndName);
    9961011
    9971012                /*
     
    10021017                RTCString strActions = xAtomToString(e.xclient.data.l[XdndStatusAction]);
    10031018
    1004                 VBClLogInfo("Target window %#x ('%s') %s accept data with actions '%s'\n",
    1005                             wndTarget, pszWndName, fAcceptDrop ? "does" : "does not", strActions.c_str());
    1006 
    1007                 const uint16_t x  = RT_HI_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgXY]);
    1008                 const uint16_t y  = RT_LO_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgXY]);
    1009                 const uint16_t cx = RT_HI_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgWH]);
    1010                 const uint16_t cy = RT_LO_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgWH]);
     1019                VBClLogInfo("Target window %#x ('%s')\n", wndTgt, pszWndTgtName);
     1020                VBClLogInfo("    - %s accept data (actions '%s')\n", fAcceptDrop ? "does" : "does not", strActions.c_str());
     1021                VBClLogInfo("    - %s want position messages\n", fWantsPosition ? "does" : "does not");
     1022
     1023                uint16_t const x  = RT_HI_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgXY]);
     1024                uint16_t const y  = RT_LO_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgXY]);
     1025                uint16_t const cx = RT_HI_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgWH]);
     1026                uint16_t const cy = RT_LO_U16((uint32_t)e.xclient.data.l[XdndStatusNoMsgWH]);
    10111027
    10121028                if (cx && cy)
    10131029                {
    10141030                    VBClLogInfo("Target window %#x ('%s') reported dead area at %RU16,%RU16 (%RU16 x %RU16)\n",
    1015                                 wndTarget, pszWndName, x, y, cx, cy);
     1031                                wndTgt, pszWndTgtName, x, y, cx, cy);
    10161032                    /** @todo Save dead area and don't send XdndPosition messages anymore into it. */
    10171033                }
    10181034
    1019                 if (m_wndCur == wndTarget)
     1035                if (m_wndCur == wndTgt)
    10201036                {
    10211037                    VBOXDNDACTION dndAction = VBOX_DND_ACTION_IGNORE; /* Default is ignoring. */
     
    10271043                }
    10281044                else
    1029                     VBClLogInfo("Target window %#x ('%s') is not our current window, skipping\n", wndTarget, pszWndName);
    1030 
    1031                 RTStrFree(pszWndName);
     1045                    VBClLogInfo("Target window %#x ('%s') is not our current window, skipping\n", wndTgt, pszWndTgtName);
     1046
     1047                RTStrFree(pszWndTgtName);
    10321048            }
     1049            /* The target window informs us that it finished the Xdnd operation and that we may free all data. */
    10331050            else if (e.xclient.message_type == xAtom(XA_XdndFinished))
    10341051            {
    10351052                Window wndTarget = static_cast<Window>(e.xclient.data.l[XdndFinishedWindow]);
    10361053
    1037                 const bool fSucceeded = e.xclient.data.l[XdndFinishedFlags] & VBOX_XDND_FINISHED_FLAG_SUCCEEDED;
    1038 
    1039                 char *pszWndName = wndX11GetNameA(wndTarget);
    1040                 AssertPtr(pszWndName);
    1041 
    1042                 const char *pcszAction = xAtomToString(e.xclient.data.l[XdndFinishedAction]).c_str();
    1043 
    1044                 /* This message is sent on an un/successful DnD drop request. */
    1045                 LogFlowThisFunc(("XA_XdndFinished: wnd=%#x ('%s'), success=%RTbool, action=%s\n",
    1046                                  wndTarget, pszWndName, fSucceeded, pcszAction));
    1047 
    1048                 VBClLogInfo("Target window %#x ('%s') has %s the data with action '%s'\n",
    1049                             wndTarget, pszWndName, fSucceeded ? "accepted" : "rejected", pcszAction ? "<None>" : pcszAction);
    1050 
    1051                 RTStrFree(pszWndName);
     1054                char *pszWndTgtName = wndX11GetNameA(wndTarget);
     1055                AssertPtrBreakStmt(pszWndTgtName, VERR_NO_MEMORY);
     1056
     1057                if (m_curVer >= 5)
     1058                {
     1059                    const bool  fSucceeded = e.xclient.data.l[XdndFinishedFlags] & VBOX_XDND_FINISHED_FLAG_SUCCEEDED;
     1060            #if 0 /** @todo Returns garbage -- investigate this! */
     1061                    //const char *pcszAction = fSucceeded ? xAtomToString(e.xclient.data.l[XdndFinishedAction]).c_str() : NULL;
     1062            #endif
     1063                    VBClLogInfo("Target window %#x ('%s') has %s the data\n",
     1064                                wndTarget, pszWndTgtName, fSucceeded ? "accepted" : "rejected");
     1065                }
     1066                else /* Xdnd < version 5 did not have the XdndFinishedFlags / XdndFinishedAction properties. */
     1067                    VBClLogInfo("Target window %#x ('%s') has accepted the data\n", wndTarget, pszWndTgtName);
     1068
     1069                RTStrFree(pszWndTgtName);
    10521070
    10531071                reset();
     
    10631081
    10641082        case Unknown: /* Mode not set (yet). */
     1083            RT_FALL_THROUGH();
    10651084        case GH:
    10661085        {
     
    10711090            if (e.xclient.message_type == xAtom(XA_XdndEnter))
    10721091            {
    1073                 LogFlowFunc(("XA_XdndEnter\n"));
    1074 
    10751092                /*
    10761093                 * Get the window which currently has the XA_XdndSelection
    10771094                 * bit set.
    10781095                 */
    1079                 Window wndSelection = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
    1080 
    1081                 char *pszWndName = wndX11GetNameA(wndSelection);
    1082                 AssertPtr(pszWndName);
    1083                 LogFlowThisFunc(("wndSelection=%RU32 ('%s'), wndProxy=%RU32\n", wndSelection, pszWndName, m_wndProxy.hWnd));
    1084                 RTStrFree(pszWndName);
     1096                Window wndSel = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
     1097                char *pszWndSelName = wndX11GetNameA(wndSel);
     1098                AssertPtrBreakStmt(pszWndSelName, VERR_NO_MEMORY);
    10851099
    10861100                mouseButtonSet(m_wndProxy.hWnd, -1, -1, 1, true /* fPress */);
     
    10891103                 * Update our state and the window handle to process.
    10901104                 */
    1091                 int rc2 = RTCritSectEnter(&m_dataCS);
    1092                 if (RT_SUCCESS(rc2))
     1105                rc = RTCritSectEnter(&m_dataCS);
     1106                if (RT_SUCCESS(rc))
    10931107                {
    1094                     m_wndCur = wndSelection;
    1095                     m_curVer = e.xclient.data.l[XdndEnterFlags] >> XdndEnterVersionRShift;
    1096                     Assert(m_wndCur == (Window)e.xclient.data.l[XdndEnterWindow]); /* Source window. */
     1108                    long const xdndVer = e.xclient.data.l[XdndEnterFlags] >> XdndEnterVersionRShift;
     1109
     1110                    VBClLogInfo("Entered new source window %#x ('%s'), supports Xdnd version %ld\n", wndSel, pszWndSelName, xdndVer);
    10971111#ifdef DEBUG
    10981112                    XWindowAttributes xwa;
     
    11071121                     * to fetch the XdndTypeList property from the window. */
    11081122                    bool fMoreTypes = e.xclient.data.l[XdndEnterFlags] & XdndEnterMoreTypesFlag;
    1109                     LogFlowThisFunc(("XdndVer=%d, fMoreTypes=%RTbool\n", m_curVer, fMoreTypes));
    11101123                    if (!fMoreTypes)
    11111124                    {
     
    11211134                    {
    11221135                        /* More than 3 format types supported. */
    1123                         rc = wndXDnDGetFormatList(wndSelection, m_lstAtomFormats);
     1136                        rc = wndXDnDGetFormatList(wndSel, m_lstAtomFormats);
     1137                    }
     1138
     1139                    if (RT_FAILURE(rc))
     1140                    {
     1141                        VBClLogError("Error retrieving supported formats, rc=%Rrc\n", rc);
     1142                        break;
    11241143                    }
    11251144
     
    11271146                     * Retrieve supported actions.
    11281147                     */
    1129                     if (RT_SUCCESS(rc))
     1148                    if (xdndVer >= 2) /* More than one action allowed since protocol version 2. */
    11301149                    {
    1131                         if (m_curVer >= 2) /* More than one action allowed since protocol version 2. */
    1132                         {
    1133                             rc = wndXDnDGetActionList(wndSelection, m_lstAtomActions);
    1134                         }
    1135                         else /* Only "copy" action allowed on legacy applications. */
    1136                             m_lstAtomActions.append(XA_XdndActionCopy);
     1150                        rc = wndXDnDGetActionList(wndSel, m_lstAtomActions);
    11371151                    }
    1138 
    1139                     if (RT_SUCCESS(rc))
     1152                    else /* Only "copy" action allowed on legacy applications. */
     1153                        m_lstAtomActions.append(XA_XdndActionCopy);
     1154
     1155                    if (RT_FAILURE(rc))
    11401156                    {
    1141                         m_enmMode  = GH;
    1142                         m_enmState = Dragging;
     1157                        VBClLogError("Error retrieving supported actions, rc=%Rrc\n", rc);
     1158                        break;
    11431159                    }
     1160
     1161                    VBClLogInfo("Source window %#x ('%s')\n", wndSel, pszWndSelName);
     1162                    VBClLogInfo("    - supports the formats ");
     1163                    for (size_t i = 0; i < m_lstAtomFormats.size(); i++)
     1164                    {
     1165                        if (i > 0)
     1166                            VBClLogInfo(", ");
     1167                        VBClLogInfo("%s", gX11->xAtomToString(m_lstAtomFormats[i]).c_str());
     1168                    }
     1169                    VBClLogInfo("\n");
     1170                    VBClLogInfo("    - supports the actions ");
     1171                    for (size_t i = 0; i < m_lstAtomActions.size(); i++)
     1172                    {
     1173                        if (i > 0)
     1174                            VBClLogInfo(", ");
     1175                        VBClLogInfo("%s", gX11->xAtomToString(m_lstAtomActions[i]).c_str());
     1176                    }
     1177                    VBClLogInfo("\n");
     1178
     1179                    AssertBreakStmt(wndSel == (Window)e.xclient.data.l[XdndEnterWindow],
     1180                                    rc = VERR_INVALID_PARAMETER); /* Source window. */
     1181
     1182                    m_wndCur   = wndSel;
     1183                    m_curVer   = xdndVer;
     1184                    m_enmMode  = GH;
     1185                    m_enmState = Dragging;
    11441186
    11451187                    RTCritSectLeave(&m_dataCS);
    11461188                }
     1189
     1190                RTStrFree(pszWndSelName);
    11471191            }
    11481192            else if (   e.xclient.message_type == xAtom(XA_XdndPosition)
     
    11581202                Atom    atmAction = m_curVer >= 2 /* Actions other than "copy" or only supported since protocol version 2. */
    11591203                                  ? e.xclient.data.l[XdndPositionAction] : xAtom(XA_XdndActionCopy);
    1160                 LogFlowThisFunc(("XA_XdndPosition: wndProxy=%RU32, wndCur=%RU32, x=%RI32, y=%RI32, strAction=%s\n",
     1204                LogFlowThisFunc(("XA_XdndPosition: wndProxy=%#x, wndCur=%#x, x=%RI32, y=%RI32, strAction=%s\n",
    11611205                                 m_wndProxy.hWnd, m_wndCur, RT_HIWORD(iPos), RT_LOWORD(iPos),
    11621206                                 xAtomToString(atmAction).c_str()));
    11631207#endif
    1164 
    11651208                bool fAcceptDrop = true;
    11661209
     
    11881231                                     False /* Propagate */, NoEventMask, reinterpret_cast<XEvent *>(&m));
    11891232                if (xRc == 0)
    1190                     VBClLogError("Error sending position XA_XdndStatus event to current window=%#x: %s\n",
    1191                                  m_wndCur, gX11->xErrorToString(xRc).c_str());
     1233                    VBClLogError("Error sending position status event to current window %#x ('%s'): %s\n",
     1234                                 m_wndCur, pszWndCurName, gX11->xErrorToString(xRc).c_str());
    11921235            }
    11931236            else if (   e.xclient.message_type == xAtom(XA_XdndLeave)
     
    12411284        }
    12421285    }
     1286
     1287    RTStrFree(pszWndCurName);
    12431288
    12441289    LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
     
    13271372    const XSelectionRequestEvent *pEvReq = &evReq.xselectionrequest;
    13281373
     1374    char *pszWndSrcName = wndX11GetNameA(pEvReq->owner);
     1375    AssertPtrReturn(pszWndSrcName, VERR_INVALID_POINTER);
     1376    char *pszWndTgtName = wndX11GetNameA(pEvReq->requestor);
     1377    AssertPtrReturn(pszWndTgtName, VERR_INVALID_POINTER);
     1378
    13291379    LogFlowThisFunc(("mode=%RU32, state=%RU32\n", m_enmMode, m_enmState));
    1330     LogFlowThisFunc(("Event owner=%#x, requestor=%#x, selection=%s, target=%s, prop=%s, time=%u\n",
    1331                      pEvReq->owner,
    1332                      pEvReq->requestor,
     1380    LogFlowThisFunc(("Event owner=%#x ('%s'), requestor=%#x ('%s'), selection=%s, target=%s, prop=%s, time=%u\n",
     1381                     pEvReq->owner, pszWndSrcName,
     1382                     pEvReq->requestor, pszWndTgtName,
    13331383                     xAtomToString(pEvReq->selection).c_str(),
    13341384                     xAtomToString(pEvReq->target).c_str(),
    13351385                     xAtomToString(pEvReq->property).c_str(),
    13361386                     pEvReq->time));
     1387
     1388    VBClLogInfo("Window '%s' is asking '%s' for '%s' / '%s'\n",
     1389                pszWndTgtName, pszWndSrcName, xAtomToString(pEvReq->selection).c_str(), xAtomToString(pEvReq->property).c_str());
     1390
     1391    RTStrFree(pszWndSrcName);
     1392    /* Note: pszWndTgtName will be free'd below. */
     1393
    13371394    int rc;
    13381395
     
    13421399        {
    13431400            rc = VINF_SUCCESS;
    1344 
    1345             char *pszWndName = wndX11GetNameA(pEvReq->requestor);
    1346             AssertPtr(pszWndName);
    13471401
    13481402            /*
     
    13641418            pEvResp->time      = pEvReq->time;
    13651419
    1366 #ifdef DEBUG
    1367             LogFlowFunc(("Supported formats:\n"));
    1368             for (size_t i = 0; i < m_lstAtomFormats.size(); i++)
    1369                 LogFlowFunc(("\t%s\n", xAtomToString(m_lstAtomFormats.at(i)).c_str()));
    1370 #endif
     1420            if (g_cVerbosity)
     1421            {
     1422                VBClLogVerbose(1, "Supported formats by VBoxClient:\n");
     1423                for (size_t i = 0; i < m_lstAtomFormats.size(); i++)
     1424                    VBClLogVerbose(1, "\t%s\n", xAtomToString(m_lstAtomFormats.at(i)).c_str());
     1425            }
     1426
    13711427            /* Is the requestor asking for the possible MIME types? */
    13721428            if (pEvReq->target == xAtom(XA_TARGETS))
    13731429            {
    1374                 VBClLogInfo("Target window %#x ('%s') asking for target list\n", pEvReq->requestor, pszWndName);
     1430                VBClLogInfo("Target window %#x ('%s') asking for target list\n", pEvReq->requestor, pszWndTgtName);
    13751431
    13761432                /* If so, set the window property with the formats on the requestor
     
    13841440            {
    13851441                VBClLogInfo("Target window %#x ('%s') is asking for data as '%s'\n",
    1386                             pEvReq->requestor, pszWndName, xAtomToString(pEvReq->target).c_str());
     1442                            pEvReq->requestor, pszWndTgtName, xAtomToString(pEvReq->target).c_str());
    13871443
    13881444#ifdef VBOX_WITH_DRAG_AND_DROP_PROMISES
     
    14001456#endif /* VBOX_WITH_DRAG_AND_DROP_PROMISES */
    14011457                    /* Get the data format the requestor wants from us. */
    1402                     RTCString strFormat = xAtomToString(pEvReq->target);
    1403                     Assert(strFormat.isNotEmpty());
    1404                     VBClLogInfo("Target window=%#x requested data from host as '%s', rc=%Rrc\n",
    1405                                 pEvReq->requestor, strFormat.c_str(), rc);
     1458                    VBClLogInfo("Target window %#x ('%s') requested data from host as '%s', rc=%Rrc\n",
     1459                                pEvReq->requestor, pszWndTgtName, xAtomToString(pEvReq->target).c_str(), rc);
    14061460
    14071461                    /* Make a copy of the MIME data to be passed back. The X server will be become
    14081462                     * the new owner of that data, so no deletion needed. */
    14091463                    /** @todo Do we need to do some more conversion here? XConvertSelection? */
    1410                     void *pvData = RTMemDup(m_pvSelReqData, m_cbSelReqData);
    1411                     uint32_t cbData = m_cbSelReqData;
     1464                    AssertMsgBreakStmt(m_pvSelReqData != NULL, ("Selection request data is NULL\n"),   rc = VERR_INVALID_PARAMETER);
     1465                    AssertMsgBreakStmt(m_cbSelReqData  > 0,    ("Selection request data size is 0\n"), rc = VERR_INVALID_PARAMETER);
     1466
     1467                    void    const *pvData = RTMemDup(m_pvSelReqData, m_cbSelReqData);
     1468                    AssertMsgBreakStmt(pvData != NULL, ("Duplicating selection request failed\n"), rc = VERR_NO_MEMORY);
     1469                    uint32_t const cbData = m_cbSelReqData;
    14121470
    14131471                    /* Always return the requested property. */
     
    14191477                                              reinterpret_cast<const unsigned char*>(pvData), cbData);
    14201478
    1421                     LogFlowFunc(("Changing property '%s' (target '%s') of window=%RU32: %s\n",
     1479                    LogFlowFunc(("Changing property '%s' (of type '%s') of window %#x ('%s'): %s\n",
    14221480                                 xAtomToString(pEvReq->property).c_str(),
    14231481                                 xAtomToString(pEvReq->target).c_str(),
    1424                                  pEvReq->requestor,
     1482                                 pEvReq->requestor, pszWndTgtName,
    14251483                                 gX11->xErrorToString(xRc).c_str()));
    14261484                    RT_NOREF(xRc);
     
    14331491            {
    14341492                VBClLogError("Refusing unknown command/format '%s' of wnd=%#x ('%s')\n",
    1435                              xAtomToString(pEvReq->target).c_str(), pEvReq->requestor, pszWndName);
     1493                             xAtomToString(pEvReq->target).c_str(), pEvReq->requestor, pszWndTgtName);
    14361494                rc = VERR_NOT_SUPPORTED;
    14371495            }
    14381496
    1439             LogFlowThisFunc(("Offering type '%s', property '%s' to wnd=%#x ...\n",
    1440                              xAtomToString(pEvReq->target).c_str(),
    1441                              xAtomToString(pEvReq->property).c_str(), pEvReq->requestor));
     1497            VBClLogVerbose(1, "Offering type '%s', property '%s' to window %#x ('%s') ...\n",
     1498                           xAtomToString(pEvReq->target).c_str(),
     1499                           xAtomToString(pEvReq->property).c_str(), pEvReq->requestor, pszWndTgtName);
    14421500
    14431501            int xRc = XSendEvent(pEvReq->display, pEvReq->requestor, True /* Propagate */, 0, &evResp);
    14441502            if (xRc == 0)
    1445                 VBClLogError("Error sending SelectionNotify(1) event to wnd=%#x: %s\n",
    1446                              pEvReq->requestor, gX11->xErrorToString(xRc).c_str());
     1503                VBClLogError("Error sending SelectionNotify(1) event to window %#x ('%s'): %s\n",
     1504                             pEvReq->requestor, pszWndTgtName, gX11->xErrorToString(xRc).c_str());
     1505
    14471506            XFlush(pEvReq->display);
    1448 
    1449             if (pszWndName)
    1450                 RTStrFree(pszWndName);
    14511507            break;
    14521508        }
     
    14561512            break;
    14571513    }
     1514
     1515    RTStrFree(pszWndTgtName);
     1516    pszWndTgtName = NULL;
    14581517
    14591518    LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
     
    17261785        XSetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection), m_wndProxy.hWnd, CurrentTime);
    17271786
     1787        if (g_cVerbosity)
     1788        {
     1789            RTCString strMsg("Enter: Host -> Guest\n\n");
     1790            strMsg += RTCStringFmt("Allowed actions: %#x\n", dndListActionsAllowed);
     1791            strMsg += "Formats:\n";
     1792            for (size_t i = 0; i < lstActions.size(); i++)
     1793            {
     1794                if (i > 0)
     1795                    strMsg += "\n";
     1796                strMsg += lstActions.at(i);
     1797            }
     1798
     1799            VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, strMsg.c_str());
     1800        }
     1801
    17281802        m_enmMode  = HG;
    17291803        m_enmState = Dragging;
     
    17411815int DragInstance::hgLeave(void)
    17421816{
     1817    if (g_cVerbosity)
     1818        VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, "Leave: Host -> Guest");
     1819
    17431820    if (m_enmMode == HG) /* Only reset if in the right operation mode. */
    17441821        reset();
     
    17741851    mouseCursorMove(uPosX, uPosY);
    17751852
     1853    /* Search for the application window below the cursor. */
     1854    Window wndBelowCursor       = gX11->applicationWindowBelowCursor(m_wndRoot);
     1855    char *pszWndBelowCursorName = wndX11GetNameA(wndBelowCursor);
     1856    AssertPtrReturn(pszWndBelowCursorName, VERR_NO_MEMORY);
     1857
    17761858    long newVer = -1; /* This means the current window is _not_ XdndAware. */
    17771859
    1778     /* Search for the application window below the cursor. */
    1779     Window wndCursor = gX11->applicationWindowBelowCursor(m_wndRoot);
    1780     if (wndCursor != None)
     1860    if (wndBelowCursor != None)
    17811861    {
    17821862        /* Temp stuff for the XGetWindowProperty call. */
     
    17881868        /* Query the XdndAware property from the window. We are interested in
    17891869         * the version and if it is XdndAware at all. */
    1790         xRc = XGetWindowProperty(m_pDisplay, wndCursor, xAtom(XA_XdndAware),
     1870        xRc = XGetWindowProperty(m_pDisplay, wndBelowCursor, xAtom(XA_XdndAware),
    17911871                                 0, 2, False, AnyPropertyType,
    17921872                                 &atmTmp, &fmt, &cItems, &cbRemaining, &pcData);
    17931873        if (xRc != Success)
    17941874        {
    1795             VBClLogError("Error getting properties of cursor window=%#x: %s\n", wndCursor, gX11->xErrorToString(xRc).c_str());
     1875            VBClLogError("Error getting properties of cursor window=%#x: %s\n", wndBelowCursor, gX11->xErrorToString(xRc).c_str());
    17961876        }
    17971877        else
     
    18011881                /** @todo Do we need to deal with this? */
    18021882                VBClLogError("Wrong window properties for window %#x: pcData=%#x, iFmt=%d, cItems=%ul\n",
    1803                              wndCursor, pcData, fmt, cItems);
     1883                             wndBelowCursor, pcData, fmt, cItems);
    18041884            }
    18051885            else
     
    18131893    }
    18141894
    1815 #ifdef DEBUG
    1816     char *pszNameCursor = wndX11GetNameA(wndCursor);
    1817     AssertPtr(pszNameCursor);
    1818     char *pszNameCur = wndX11GetNameA(m_wndCur);
    1819     AssertPtr(pszNameCur);
     1895    char *pszWndCurName = wndX11GetNameA(m_wndCur);
     1896    AssertPtrReturn(pszWndCurName, VERR_NO_MEMORY);
    18201897
    18211898    LogFlowThisFunc(("wndCursor=%x ('%s', Xdnd version %ld), wndCur=%x ('%s', Xdnd version %ld)\n",
    1822                      wndCursor, pszNameCursor, newVer, m_wndCur, pszNameCur, m_curVer));
    1823 
    1824     RTStrFree(pszNameCursor);
    1825     RTStrFree(pszNameCur);
    1826 #endif
    1827 
    1828     if (   wndCursor != m_wndCur
    1829         && m_curVer  != -1)
    1830     {
    1831         LogFlowThisFunc(("XA_XdndLeave: window=%#x\n", m_wndCur));
    1832 
    1833         char *pszWndName = wndX11GetNameA(m_wndCur);
    1834         AssertPtr(pszWndName);
    1835         VBClLogInfo("Left old window %#x ('%s'), Xdnd version=%ld\n", m_wndCur, pszWndName, newVer);
    1836         RTStrFree(pszWndName);
     1899                     wndBelowCursor, pszWndBelowCursorName, newVer, m_wndCur, pszWndCurName, m_curVer));
     1900
     1901    if (   wndBelowCursor != m_wndCur
     1902        && m_curVer       != -1)
     1903    {
     1904        VBClLogInfo("Left old window %#x ('%s'), supported Xdnd version %ld\n", m_wndCur, pszWndCurName, m_curVer);
    18371905
    18381906        /* We left the current XdndAware window. Announce this to the current indow. */
     
    18481916        xRc = XSendEvent(m_pDisplay, m_wndCur, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    18491917        if (xRc == 0)
    1850             VBClLogError("Error sending XA_XdndLeave event to old window=%#x: %s\n", m_wndCur, gX11->xErrorToString(xRc).c_str());
     1918            VBClLogError("Error sending leave event to old window %#x: %s\n", m_wndCur, gX11->xErrorToString(xRc).c_str());
    18511919
    18521920        /* Reset our current window. */
     
    18581926     * Do we have a new Xdnd-aware window which now is under the cursor?
    18591927     */
    1860     if (   wndCursor != m_wndCur
    1861         && newVer    != -1)
    1862     {
    1863         LogFlowThisFunc(("XA_XdndEnter: window=%#x\n", wndCursor));
    1864 
    1865         char *pszWndName = wndX11GetNameA(wndCursor);
    1866         AssertPtr(pszWndName);
    1867         VBClLogInfo("Entered new window %#x ('%s'), supports Xdnd version=%ld\n", wndCursor, pszWndName, newVer);
    1868         RTStrFree(pszWndName);
     1928    if (   wndBelowCursor != m_wndCur
     1929        && newVer         != -1)
     1930    {
     1931        VBClLogInfo("Entered new window %#x ('%s'), supports Xdnd version=%ld\n", wndBelowCursor, pszWndBelowCursorName, newVer);
    18691932
    18701933        /*
     
    18781941        m.type         = ClientMessage;
    18791942        m.display      = m_pDisplay;
    1880         m.window       = wndCursor;
     1943        m.window       = wndBelowCursor;
    18811944        m.message_type = xAtom(XA_XdndEnter);
    18821945        m.format       = 32;
     
    18931956        m.data.l[XdndEnterType3]  = m_lstAtomFormats.value(2, None); /* Third data type to use. */
    18941957
    1895         xRc = XSendEvent(m_pDisplay, wndCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     1958        xRc = XSendEvent(m_pDisplay, wndBelowCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    18961959        if (xRc == 0)
    1897             VBClLogError("Error sending XA_XdndEnter event to window=%#x: %s\n", wndCursor, gX11->xErrorToString(xRc).c_str());
     1960            VBClLogError("Error sending enter event to window %#x: %s\n", wndBelowCursor, gX11->xErrorToString(xRc).c_str());
    18981961    }
    18991962
    19001963    if (newVer != -1)
    19011964    {
    1902         Assert(wndCursor != None);
    1903 
    1904         LogFlowThisFunc(("XA_XdndPosition: xPos=%RU32, yPos=%RU32 to window=%#x\n", uPosX, uPosY, wndCursor));
     1965        Assert(wndBelowCursor != None);
     1966
     1967        Atom atmAction = toAtomAction(dndActionDefault);
     1968        LogFlowThisFunc(("strAction=%s\n", xAtomToString(atmAction).c_str()));
     1969
     1970        VBClLogInfo("Sent position event (%RU32 x %RU32) to window %#x ('%s') with actions '%s'\n",
     1971                    uPosX, uPosY, wndBelowCursor, pszWndBelowCursorName, xAtomToString(atmAction).c_str());
    19051972
    19061973        /*
    19071974         * Send a XdndPosition event with the proposed action to the guest.
    19081975         */
    1909         Atom atmAction = toAtomAction(dndActionDefault);
    1910         LogFlowThisFunc(("strAction=%s\n", xAtomToString(atmAction).c_str()));
    1911 
    19121976        XClientMessageEvent m;
    19131977        RT_ZERO(m);
    19141978        m.type         = ClientMessage;
    19151979        m.display      = m_pDisplay;
    1916         m.window       = wndCursor;
     1980        m.window       = wndBelowCursor;
    19171981        m.message_type = xAtom(XA_XdndPosition);
    19181982        m.format       = 32;
     
    19231987        m.data.l[XdndPositionAction]    = atmAction;                     /* Actions requested by the user. */
    19241988
    1925         xRc = XSendEvent(m_pDisplay, wndCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     1989        xRc = XSendEvent(m_pDisplay, wndBelowCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    19261990        if (xRc == 0)
    1927             VBClLogError("Error sending XA_XdndPosition event to current window=%#x: %s\n", wndCursor, gX11->xErrorToString(xRc).c_str());
     1991            VBClLogError("Error sending position event to current window %#x: %s\n", wndBelowCursor, gX11->xErrorToString(xRc).c_str());
    19281992    }
    19291993
     
    19351999    else
    19362000    {
    1937         Assert(wndCursor != None);
    1938 
    1939         m_wndCur = wndCursor;
     2001        Assert(wndBelowCursor != None);
     2002
     2003        m_wndCur = wndBelowCursor;
    19402004        m_curVer = newVer;
    19412005    }
     2006
     2007    RTStrFree(pszWndBelowCursorName);
     2008    RTStrFree(pszWndCurName);
    19422009
    19432010    LogFlowFuncLeaveRC(rc);
     
    19792046    int rc = VbglR3DnDHGSendReqData(&m_dndCtx, szFormat);
    19802047    VBClLogInfo("Drop event from host resulted in: %Rrc\n", rc);
     2048
     2049    if (g_cVerbosity)
     2050        VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, "Drop: Host -> Guest");
    19812051
    19822052    LogFlowFuncLeaveRC(rc);
     
    21602230
    21612231        /* Determine the current window which currently has the XdndSelection set. */
    2162         Window wndSelection = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
    2163         LogFlowThisFunc(("wndSelection=%#x, wndProxy=%#x, wndCur=%#x\n", wndSelection, m_wndProxy.hWnd, m_wndCur));
     2232        Window wndSel = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
     2233        LogFlowThisFunc(("wndSel=%#x, wndProxy=%#x, wndCur=%#x\n", wndSel, m_wndProxy.hWnd, m_wndCur));
    21642234
    21652235        /* Is this another window which has a Xdnd selection and not our proxy window? */
    21662236        if (   RT_SUCCESS(rc)
    2167             && wndSelection
    2168             && wndSelection != m_wndCur)
    2169         {
    2170             char *pszWndName = wndX11GetNameA(wndSelection);
    2171             AssertPtr(pszWndName);
    2172             VBClLogInfo("New guest source window %#x ('%s')\n", wndSelection, pszWndName);
     2237            && wndSel
     2238            && wndSel != m_wndCur)
     2239        {
     2240            char *pszWndSelName = wndX11GetNameA(wndSel);
     2241            AssertPtrReturn(pszWndSelName, VERR_NO_MEMORY);
     2242            VBClLogInfo("New guest source window %#x ('%s')\n", wndSel, pszWndSelName);
    21732243
    21742244            /* Start over. */
     
    22152285                    {
    22162286                        VBClLogError("Error mapping proxy window to guest source window %#x ('%s'), rc=%Rrc\n",
    2217                                      wndSelection, pszWndName, rc);
     2287                                     wndSel, pszWndSelName, rc);
    22182288
    22192289                        /* Reset the counter in any case. */
     
    22232293            }
    22242294
    2225             RTStrFree(pszWndName);
     2295            RTStrFree(pszWndSelName);
    22262296        }
    22272297        else
     
    22552325    if (RT_FAILURE(rc2))
    22562326    {
     2327        switch (rc2)
     2328        {
     2329            case VERR_ACCESS_DENIED:
     2330            {
     2331                rc = VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER,
     2332                                    "Drag and drop to the host either is not supported or disabled. "
     2333                                    "Please enable Guest to Host or Bidirectional drag and drop mode "
     2334                                    "or re-install the VirtualBox Guest Additions.");
     2335                AssertRC(rc);
     2336                break;
     2337            }
     2338
     2339            default:
     2340                break;
     2341        }
     2342
    22572343        VBClLogError("Error reporting pending drag and drop operation status to host: %Rrc\n", rc2);
    22582344        if (RT_SUCCESS(rc))
     
    30883174    if (xRc == 0)
    30893175    {
    3090         VBClLogError("Error sending XA_XdndFinished event to source window=%#x: %s\n",
     3176        VBClLogError("Error sending finished event to source window=%#x: %s\n",
    30913177                      hWndSource, gX11->xErrorToString(xRc).c_str());
    30923178
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette