Changeset 97734 in vbox
- Timestamp:
- Dec 2, 2022 7:58:41 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r96407 r97734 50 50 #include <VBox/log.h> 51 51 #include <VBox/VBoxGuestLib.h> 52 #include <VBox/version.h> 52 53 53 54 #include "VBox/HostServices/DragAndDropSvc.h" 54 55 #include "VBoxClient.h" 55 56 56 /* Enable this define to see the proxy window(s) when debugging57 * their behavior. Don't have this enabled in release builds! */58 #ifdef DEBUG59 //# define VBOX_DND_DEBUG_WND60 #endif61 57 62 58 /* Enable this to handle drag'n drop "promises". … … 131 127 /** How many X properties our proxy window can hold. */ 132 128 #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" 133 132 134 133 /** … … 199 198 200 199 /** 201 * Xdnd message value ind exes, sorted by message type.200 * Xdnd message value indices, sorted by message type. 202 201 */ 203 202 typedef enum XdndMsg … … 251 250 /** XdndFinished. */ 252 251 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. */ 255 254 256 255 } XdndMsg; … … 628 627 /** Current source/target window handle. */ 629 628 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. */ 632 630 long m_curVer; 633 /** List of (Atom) formats the sourcewindow supports. */631 /** List of (Atom) formats the current source/target window supports. */ 634 632 VBoxDnDAtomList m_lstAtomFormats; 635 /** List of (Atom) actions the sourcewindow supports. */633 /** List of (Atom) actions the current source/target window supports. */ 636 634 VBoxDnDAtomList m_lstAtomActions; 637 635 /** Buffer for answering the target window's selection request. */ … … 645 643 /** The instance's own X event queue. */ 646 644 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. */ 649 646 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. */ 652 648 RTSEMEVENT m_eventQueueEvent; 653 649 /** Critical section for data access. */ … … 824 820 RTCritSectLeave(&m_dataCS); 825 821 } 822 823 LogFlowFuncLeave(); 826 824 } 827 825 … … 838 836 if (rc != VINF_SUCCESS) 839 837 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 } 840 844 841 845 do … … 891 895 attr.override_redirect = True; 892 896 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 919 926 if (!m_wndProxy.hWnd) 920 927 { … … 931 938 } 932 939 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); 940 950 941 951 /* Set the window's name for easier lookup. */ … … 974 984 int rc = VINF_SUCCESS; 975 985 986 char *pszWndCurName = wndX11GetNameA(m_wndCur); 987 AssertPtrReturn(pszWndCurName, VERR_NO_MEMORY); 988 976 989 switch (m_enmMode) 977 990 { … … 982 995 * window, in response of some events we send to them. 983 996 */ 997 998 /* The target window informs us of the current Xdnd status. */ 984 999 if (e.xclient.message_type == xAtom(XA_XdndStatus)) 985 1000 { 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); 987 1005 988 1006 /* Does the target accept the drop? */ … … 991 1009 const bool fWantsPosition = e.xclient.data.l[XdndStatusFlags] & VBOX_XDND_STATUS_FLAG_WANTS_POS; 992 1010 RT_NOREF(fWantsPosition); 993 994 char *pszWndName = wndX11GetNameA(m_wndCur);995 AssertPtr(pszWndName);996 1011 997 1012 /* … … 1002 1017 RTCString strActions = xAtomToString(e.xclient.data.l[XdndStatusAction]); 1003 1018 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]); 1011 1027 1012 1028 if (cx && cy) 1013 1029 { 1014 1030 VBClLogInfo("Target window %#x ('%s') reported dead area at %RU16,%RU16 (%RU16 x %RU16)\n", 1015 wndT arget, pszWndName, x, y, cx, cy);1031 wndTgt, pszWndTgtName, x, y, cx, cy); 1016 1032 /** @todo Save dead area and don't send XdndPosition messages anymore into it. */ 1017 1033 } 1018 1034 1019 if (m_wndCur == wndT arget)1035 if (m_wndCur == wndTgt) 1020 1036 { 1021 1037 VBOXDNDACTION dndAction = VBOX_DND_ACTION_IGNORE; /* Default is ignoring. */ … … 1027 1043 } 1028 1044 else 1029 VBClLogInfo("Target window %#x ('%s') is not our current window, skipping\n", wndT arget, pszWndName);1030 1031 RTStrFree(pszWnd Name);1045 VBClLogInfo("Target window %#x ('%s') is not our current window, skipping\n", wndTgt, pszWndTgtName); 1046 1047 RTStrFree(pszWndTgtName); 1032 1048 } 1049 /* The target window informs us that it finished the Xdnd operation and that we may free all data. */ 1033 1050 else if (e.xclient.message_type == xAtom(XA_XdndFinished)) 1034 1051 { 1035 1052 Window wndTarget = static_cast<Window>(e.xclient.data.l[XdndFinishedWindow]); 1036 1053 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); 1052 1070 1053 1071 reset(); … … 1063 1081 1064 1082 case Unknown: /* Mode not set (yet). */ 1083 RT_FALL_THROUGH(); 1065 1084 case GH: 1066 1085 { … … 1071 1090 if (e.xclient.message_type == xAtom(XA_XdndEnter)) 1072 1091 { 1073 LogFlowFunc(("XA_XdndEnter\n"));1074 1075 1092 /* 1076 1093 * Get the window which currently has the XA_XdndSelection 1077 1094 * bit set. 1078 1095 */ 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); 1085 1099 1086 1100 mouseButtonSet(m_wndProxy.hWnd, -1, -1, 1, true /* fPress */); … … 1089 1103 * Update our state and the window handle to process. 1090 1104 */ 1091 int rc2= RTCritSectEnter(&m_dataCS);1092 if (RT_SUCCESS(rc 2))1105 rc = RTCritSectEnter(&m_dataCS); 1106 if (RT_SUCCESS(rc)) 1093 1107 { 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); 1097 1111 #ifdef DEBUG 1098 1112 XWindowAttributes xwa; … … 1107 1121 * to fetch the XdndTypeList property from the window. */ 1108 1122 bool fMoreTypes = e.xclient.data.l[XdndEnterFlags] & XdndEnterMoreTypesFlag; 1109 LogFlowThisFunc(("XdndVer=%d, fMoreTypes=%RTbool\n", m_curVer, fMoreTypes));1110 1123 if (!fMoreTypes) 1111 1124 { … … 1121 1134 { 1122 1135 /* 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; 1124 1143 } 1125 1144 … … 1127 1146 * Retrieve supported actions. 1128 1147 */ 1129 if ( RT_SUCCESS(rc))1148 if (xdndVer >= 2) /* More than one action allowed since protocol version 2. */ 1130 1149 { 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); 1137 1151 } 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)) 1140 1156 { 1141 m_enmMode = GH;1142 m_enmState = Dragging;1157 VBClLogError("Error retrieving supported actions, rc=%Rrc\n", rc); 1158 break; 1143 1159 } 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; 1144 1186 1145 1187 RTCritSectLeave(&m_dataCS); 1146 1188 } 1189 1190 RTStrFree(pszWndSelName); 1147 1191 } 1148 1192 else if ( e.xclient.message_type == xAtom(XA_XdndPosition) … … 1158 1202 Atom atmAction = m_curVer >= 2 /* Actions other than "copy" or only supported since protocol version 2. */ 1159 1203 ? 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", 1161 1205 m_wndProxy.hWnd, m_wndCur, RT_HIWORD(iPos), RT_LOWORD(iPos), 1162 1206 xAtomToString(atmAction).c_str())); 1163 1207 #endif 1164 1165 1208 bool fAcceptDrop = true; 1166 1209 … … 1188 1231 False /* Propagate */, NoEventMask, reinterpret_cast<XEvent *>(&m)); 1189 1232 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()); 1192 1235 } 1193 1236 else if ( e.xclient.message_type == xAtom(XA_XdndLeave) … … 1241 1284 } 1242 1285 } 1286 1287 RTStrFree(pszWndCurName); 1243 1288 1244 1289 LogFlowThisFunc(("Returning rc=%Rrc\n", rc)); … … 1327 1372 const XSelectionRequestEvent *pEvReq = &evReq.xselectionrequest; 1328 1373 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 1329 1379 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, 1333 1383 xAtomToString(pEvReq->selection).c_str(), 1334 1384 xAtomToString(pEvReq->target).c_str(), 1335 1385 xAtomToString(pEvReq->property).c_str(), 1336 1386 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 1337 1394 int rc; 1338 1395 … … 1342 1399 { 1343 1400 rc = VINF_SUCCESS; 1344 1345 char *pszWndName = wndX11GetNameA(pEvReq->requestor);1346 AssertPtr(pszWndName);1347 1401 1348 1402 /* … … 1364 1418 pEvResp->time = pEvReq->time; 1365 1419 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 1371 1427 /* Is the requestor asking for the possible MIME types? */ 1372 1428 if (pEvReq->target == xAtom(XA_TARGETS)) 1373 1429 { 1374 VBClLogInfo("Target window %#x ('%s') asking for target list\n", pEvReq->requestor, pszWnd Name);1430 VBClLogInfo("Target window %#x ('%s') asking for target list\n", pEvReq->requestor, pszWndTgtName); 1375 1431 1376 1432 /* If so, set the window property with the formats on the requestor … … 1384 1440 { 1385 1441 VBClLogInfo("Target window %#x ('%s') is asking for data as '%s'\n", 1386 pEvReq->requestor, pszWnd Name, xAtomToString(pEvReq->target).c_str());1442 pEvReq->requestor, pszWndTgtName, xAtomToString(pEvReq->target).c_str()); 1387 1443 1388 1444 #ifdef VBOX_WITH_DRAG_AND_DROP_PROMISES … … 1400 1456 #endif /* VBOX_WITH_DRAG_AND_DROP_PROMISES */ 1401 1457 /* 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); 1406 1460 1407 1461 /* Make a copy of the MIME data to be passed back. The X server will be become 1408 1462 * the new owner of that data, so no deletion needed. */ 1409 1463 /** @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; 1412 1470 1413 1471 /* Always return the requested property. */ … … 1419 1477 reinterpret_cast<const unsigned char*>(pvData), cbData); 1420 1478 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", 1422 1480 xAtomToString(pEvReq->property).c_str(), 1423 1481 xAtomToString(pEvReq->target).c_str(), 1424 pEvReq->requestor, 1482 pEvReq->requestor, pszWndTgtName, 1425 1483 gX11->xErrorToString(xRc).c_str())); 1426 1484 RT_NOREF(xRc); … … 1433 1491 { 1434 1492 VBClLogError("Refusing unknown command/format '%s' of wnd=%#x ('%s')\n", 1435 xAtomToString(pEvReq->target).c_str(), pEvReq->requestor, pszWnd Name);1493 xAtomToString(pEvReq->target).c_str(), pEvReq->requestor, pszWndTgtName); 1436 1494 rc = VERR_NOT_SUPPORTED; 1437 1495 } 1438 1496 1439 LogFlowThisFunc(("Offering type '%s', property '%s' to wnd=%#x...\n",1440 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); 1442 1500 1443 1501 int xRc = XSendEvent(pEvReq->display, pEvReq->requestor, True /* Propagate */, 0, &evResp); 1444 1502 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 1447 1506 XFlush(pEvReq->display); 1448 1449 if (pszWndName)1450 RTStrFree(pszWndName);1451 1507 break; 1452 1508 } … … 1456 1512 break; 1457 1513 } 1514 1515 RTStrFree(pszWndTgtName); 1516 pszWndTgtName = NULL; 1458 1517 1459 1518 LogFlowThisFunc(("Returning rc=%Rrc\n", rc)); … … 1726 1785 XSetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection), m_wndProxy.hWnd, CurrentTime); 1727 1786 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 1728 1802 m_enmMode = HG; 1729 1803 m_enmState = Dragging; … … 1741 1815 int DragInstance::hgLeave(void) 1742 1816 { 1817 if (g_cVerbosity) 1818 VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, "Leave: Host -> Guest"); 1819 1743 1820 if (m_enmMode == HG) /* Only reset if in the right operation mode. */ 1744 1821 reset(); … … 1774 1851 mouseCursorMove(uPosX, uPosY); 1775 1852 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 1776 1858 long newVer = -1; /* This means the current window is _not_ XdndAware. */ 1777 1859 1778 /* Search for the application window below the cursor. */ 1779 Window wndCursor = gX11->applicationWindowBelowCursor(m_wndRoot); 1780 if (wndCursor != None) 1860 if (wndBelowCursor != None) 1781 1861 { 1782 1862 /* Temp stuff for the XGetWindowProperty call. */ … … 1788 1868 /* Query the XdndAware property from the window. We are interested in 1789 1869 * the version and if it is XdndAware at all. */ 1790 xRc = XGetWindowProperty(m_pDisplay, wnd Cursor, xAtom(XA_XdndAware),1870 xRc = XGetWindowProperty(m_pDisplay, wndBelowCursor, xAtom(XA_XdndAware), 1791 1871 0, 2, False, AnyPropertyType, 1792 1872 &atmTmp, &fmt, &cItems, &cbRemaining, &pcData); 1793 1873 if (xRc != Success) 1794 1874 { 1795 VBClLogError("Error getting properties of cursor window=%#x: %s\n", wnd Cursor, gX11->xErrorToString(xRc).c_str());1875 VBClLogError("Error getting properties of cursor window=%#x: %s\n", wndBelowCursor, gX11->xErrorToString(xRc).c_str()); 1796 1876 } 1797 1877 else … … 1801 1881 /** @todo Do we need to deal with this? */ 1802 1882 VBClLogError("Wrong window properties for window %#x: pcData=%#x, iFmt=%d, cItems=%ul\n", 1803 wnd Cursor, pcData, fmt, cItems);1883 wndBelowCursor, pcData, fmt, cItems); 1804 1884 } 1805 1885 else … … 1813 1893 } 1814 1894 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); 1820 1897 1821 1898 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); 1837 1905 1838 1906 /* We left the current XdndAware window. Announce this to the current indow. */ … … 1848 1916 xRc = XSendEvent(m_pDisplay, m_wndCur, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1849 1917 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()); 1851 1919 1852 1920 /* Reset our current window. */ … … 1858 1926 * Do we have a new Xdnd-aware window which now is under the cursor? 1859 1927 */ 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); 1869 1932 1870 1933 /* … … 1878 1941 m.type = ClientMessage; 1879 1942 m.display = m_pDisplay; 1880 m.window = wnd Cursor;1943 m.window = wndBelowCursor; 1881 1944 m.message_type = xAtom(XA_XdndEnter); 1882 1945 m.format = 32; … … 1893 1956 m.data.l[XdndEnterType3] = m_lstAtomFormats.value(2, None); /* Third data type to use. */ 1894 1957 1895 xRc = XSendEvent(m_pDisplay, wnd Cursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));1958 xRc = XSendEvent(m_pDisplay, wndBelowCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1896 1959 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()); 1898 1961 } 1899 1962 1900 1963 if (newVer != -1) 1901 1964 { 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()); 1905 1972 1906 1973 /* 1907 1974 * Send a XdndPosition event with the proposed action to the guest. 1908 1975 */ 1909 Atom atmAction = toAtomAction(dndActionDefault);1910 LogFlowThisFunc(("strAction=%s\n", xAtomToString(atmAction).c_str()));1911 1912 1976 XClientMessageEvent m; 1913 1977 RT_ZERO(m); 1914 1978 m.type = ClientMessage; 1915 1979 m.display = m_pDisplay; 1916 m.window = wnd Cursor;1980 m.window = wndBelowCursor; 1917 1981 m.message_type = xAtom(XA_XdndPosition); 1918 1982 m.format = 32; … … 1923 1987 m.data.l[XdndPositionAction] = atmAction; /* Actions requested by the user. */ 1924 1988 1925 xRc = XSendEvent(m_pDisplay, wnd Cursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));1989 xRc = XSendEvent(m_pDisplay, wndBelowCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1926 1990 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()); 1928 1992 } 1929 1993 … … 1935 1999 else 1936 2000 { 1937 Assert(wnd Cursor != None);1938 1939 m_wndCur = wnd Cursor;2001 Assert(wndBelowCursor != None); 2002 2003 m_wndCur = wndBelowCursor; 1940 2004 m_curVer = newVer; 1941 2005 } 2006 2007 RTStrFree(pszWndBelowCursorName); 2008 RTStrFree(pszWndCurName); 1942 2009 1943 2010 LogFlowFuncLeaveRC(rc); … … 1979 2046 int rc = VbglR3DnDHGSendReqData(&m_dndCtx, szFormat); 1980 2047 VBClLogInfo("Drop event from host resulted in: %Rrc\n", rc); 2048 2049 if (g_cVerbosity) 2050 VBClShowNotify(VBOX_DND_SHOWNOTIFY_HEADER, "Drop: Host -> Guest"); 1981 2051 1982 2052 LogFlowFuncLeaveRC(rc); … … 2160 2230 2161 2231 /* Determine the current window which currently has the XdndSelection set. */ 2162 Window wndSel ection= XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));2163 LogFlowThisFunc(("wndSel ection=%#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)); 2164 2234 2165 2235 /* Is this another window which has a Xdnd selection and not our proxy window? */ 2166 2236 if ( RT_SUCCESS(rc) 2167 && wndSel ection2168 && wndSel ection!= m_wndCur)2169 { 2170 char *pszWnd Name = wndX11GetNameA(wndSelection);2171 AssertPtr (pszWndName);2172 VBClLogInfo("New guest source window %#x ('%s')\n", wndSel ection, 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); 2173 2243 2174 2244 /* Start over. */ … … 2215 2285 { 2216 2286 VBClLogError("Error mapping proxy window to guest source window %#x ('%s'), rc=%Rrc\n", 2217 wndSel ection, pszWndName, rc);2287 wndSel, pszWndSelName, rc); 2218 2288 2219 2289 /* Reset the counter in any case. */ … … 2223 2293 } 2224 2294 2225 RTStrFree(pszWnd Name);2295 RTStrFree(pszWndSelName); 2226 2296 } 2227 2297 else … … 2255 2325 if (RT_FAILURE(rc2)) 2256 2326 { 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 2257 2343 VBClLogError("Error reporting pending drag and drop operation status to host: %Rrc\n", rc2); 2258 2344 if (RT_SUCCESS(rc)) … … 3088 3174 if (xRc == 0) 3089 3175 { 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", 3091 3177 hWndSource, gX11->xErrorToString(xRc).c_str()); 3092 3178
Note:
See TracChangeset
for help on using the changeset viewer.