Changeset 51529 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Jun 4, 2014 12:11:43 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r51451 r51529 76 76 * the data in the specified mime-type. This data is send back to the host. 77 77 * After that we send a XdndLeave event to the source window. 78 * 78 * 79 79 * To-do: 80 80 * - Cancelling (e.g. with ESC key) doesn't work. … … 365 365 366 366 /* X11 message processing. */ 367 int onX11ClientMessage(const XEvent &e); 367 int onX11ClientMessage(const XEvent &e); 368 368 int onX11SelectionNotify(const XEvent &e); 369 369 int onX11SelectionRequest(const XEvent &e); … … 578 578 << "UTF8_STRING" 579 579 << "text/plain" 580 << "COMPOUND_TEXT"581 580 << "TEXT" 582 581 << "STRING" … … 636 635 XSetWindowAttributes attr; 637 636 RT_ZERO(attr); 638 attr.event_mask = EnterWindowMask | LeaveWindowMask 637 attr.event_mask = EnterWindowMask | LeaveWindowMask 639 638 | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; 640 639 attr.do_not_propagate_mask = NoEventMask; … … 643 642 attr.background_pixel = WhitePixel(m_pDisplay, m_screenId); 644 643 #endif 645 m_wndProxy = XCreateWindow(m_pDisplay, m_wndRoot /* Parent */, 644 m_wndProxy = XCreateWindow(m_pDisplay, m_wndRoot /* Parent */, 646 645 0, 0, /* Position */ 647 646 1, 1, /* Width + height */ … … 658 657 } 659 658 660 LogFlowThisFunc(("Created proxy window 0x%x at m_wndRoot=0x%x ...\n", 659 LogFlowThisFunc(("Created proxy window 0x%x at m_wndRoot=0x%x ...\n", 661 660 m_wndProxy, m_wndRoot)); 662 661 … … 675 674 } 676 675 else 677 LogRel(("DnD: Initializing drag instance for screen %RU32 failed with rc=%Rrc\n", 676 LogRel(("DnD: Initializing drag instance for screen %RU32 failed with rc=%Rrc\n", 678 677 u32ScreenId, rc)); 679 678 … … 882 881 Assert(strFormat.isNotEmpty()); 883 882 rc = VbglR3DnDHGRequestData(m_uClientID, strFormat.c_str()); 884 LogFlowThisFunc(("Requesting data from host as \"%s\", rc=%Rrc\n", 883 LogFlowThisFunc(("Requesting data from host as \"%s\", rc=%Rrc\n", 885 884 strFormat.c_str(), rc)); 886 885 } … … 931 930 { 932 931 case ButtonPress: 933 LogFlowThisFunc(("ButtonPress\n")); 932 LogFlowThisFunc(("ButtonPress\n")); 934 933 rc = VINF_SUCCESS; 935 934 break; 936 935 937 936 case ButtonRelease: 938 LogFlowThisFunc(("ButtonRelease\n")); 937 LogFlowThisFunc(("ButtonRelease\n")); 939 938 rc = VINF_SUCCESS; 940 939 break; 941 940 942 case ClientMessage: 943 rc = onX11ClientMessage(e); 941 case ClientMessage: 942 rc = onX11ClientMessage(e); 944 943 break; 945 944 … … 951 950 952 951 case SelectionNotify: 953 rc = onX11SelectionNotify(e); 954 break; 955 956 case SelectionRequest: 957 rc = onX11SelectionRequest(e); 958 break; 959 960 /*case MotionNotify: 952 rc = onX11SelectionNotify(e); 953 break; 954 955 case SelectionRequest: 956 rc = onX11SelectionRequest(e); 957 break; 958 959 /*case MotionNotify: 961 960 hide(); 962 961 break;*/ … … 972 971 973 972 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 974 bool DragInstance::waitForX11Msg(XEvent &evX, int iType, 973 bool DragInstance::waitForX11Msg(XEvent &evX, int iType, 975 974 RTMSINTERVAL uTimeoutMS /* = 100 */) 976 975 { 977 LogFlowThisFunc(("iType=%d, uTimeoutMS=%RU32, cEventQueue=%zu\n", 976 LogFlowThisFunc(("iType=%d, uTimeoutMS=%RU32, cEventQueue=%zu\n", 978 977 iType, uTimeoutMS, m_eventQueue.size())); 979 978 … … 1018 1017 while (RTTimeMilliTS() - uiStart < uTimeoutMS); 1019 1018 1020 LogFlowThisFunc(("Returning fFound=%RTbool, msRuntime=%RU64\n", 1019 LogFlowThisFunc(("Returning fFound=%RTbool, msRuntime=%RU64\n", 1021 1020 fFound, RTTimeMilliTS() - uiStart)); 1022 1021 return fFound; 1023 1022 } 1024 1023 1025 bool DragInstance::waitForX11ClientMsg(XClientMessageEvent &evMsg, Atom aType, 1024 bool DragInstance::waitForX11ClientMsg(XClientMessageEvent &evMsg, Atom aType, 1026 1025 RTMSINTERVAL uTimeoutMS /*= 100 */) 1027 1026 { 1028 LogFlowThisFunc(("aType=%s, uTimeoutMS=%RU32, cEventQueue=%zu\n", 1027 LogFlowThisFunc(("aType=%s, uTimeoutMS=%RU32, cEventQueue=%zu\n", 1029 1028 xAtomToString(aType).c_str(), uTimeoutMS, m_eventQueue.size())); 1030 1029 … … 1039 1038 if (RT_SUCCESS(rc2)) 1040 1039 { 1041 XEvent e = m_eventQueue.at(i); 1042 if (e.type == ClientMessage) 1040 XEvent e = m_eventQueue.at(i); 1041 if (e.type == ClientMessage) 1043 1042 { 1044 1043 m_eventQueue.removeAt(i); … … 1069 1068 while (RTTimeMilliTS() - uiStart < uTimeoutMS); 1070 1069 1071 LogFlowThisFunc(("Returning fFound=%RTbool, msRuntime=%RU64\n", 1070 LogFlowThisFunc(("Returning fFound=%RTbool, msRuntime=%RU64\n", 1072 1071 fFound, RTTimeMilliTS() - uiStart)); 1073 1072 return fFound; … … 1160 1159 * Is the window under the cursor another one than our current one? 1161 1160 */ 1162 if ( wndCursor != m_wndCur 1161 if ( wndCursor != m_wndCur 1163 1162 && m_curVer != -1) 1164 1163 { … … 1239 1238 } 1240 1239 1241 if ( wndCursor == None 1240 if ( wndCursor == None 1242 1241 && newVer == -1) 1243 1242 { … … 1365 1364 AssertPtr(pEventClient); 1366 1365 1367 LogFlowThisFunc(("Received event=%s\n", 1366 LogFlowThisFunc(("Received event=%s\n", 1368 1367 gX11->xAtomToString(pEventClient->message_type).c_str())); 1369 1368 … … 1385 1384 XWindowAttributes xwa; 1386 1385 XGetWindowAttributes(m_pDisplay, m_wndCur, &xwa); 1387 LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 1386 LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 1388 1387 m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height)); 1389 1388 #endif … … 1394 1393 for (int i = 2; i < 5; ++i) 1395 1394 { 1396 LogFlowThisFunc(("Received format via message: %s\n", 1395 LogFlowThisFunc(("Received format via message: %s\n", 1397 1396 gX11->xAtomToString(pEventClient->data.l[i]).c_str())); 1398 1397 … … 1402 1401 else 1403 1402 { 1404 xRc = XGetWindowProperty(m_pDisplay, wndSelection, 1405 xAtom(XA_XdndTypeList), 1406 0, VBOX_MAX_XPROPERTIES, 1403 xRc = XGetWindowProperty(m_pDisplay, wndSelection, 1404 xAtom(XA_XdndTypeList), 1405 0, VBOX_MAX_XPROPERTIES, 1407 1406 False, XA_ATOM, &type, &f, &n, &a, &ret); 1408 1407 if ( xRc == Success … … 1413 1412 for (unsigned i = 0; i < RT_MIN(VBOX_MAX_XPROPERTIES, n); ++i) 1414 1413 { 1415 LogFlowThisFunc(("Received format via XdndTypeList: %s\n", 1414 LogFlowThisFunc(("Received format via XdndTypeList: %s\n", 1416 1415 gX11->xAtomToString(data[i]).c_str())); 1417 1416 … … 1424 1423 1425 1424 /* Fetch the possible list of actions, if this property is set. */ 1426 xRc = XGetWindowProperty(m_pDisplay, wndSelection, 1427 xAtom(XA_XdndActionList), 1428 0, VBOX_MAX_XPROPERTIES, 1425 xRc = XGetWindowProperty(m_pDisplay, wndSelection, 1426 xAtom(XA_XdndActionList), 1427 0, VBOX_MAX_XPROPERTIES, 1429 1428 False, XA_ATOM, &type, &f, &n, &a, &ret); 1430 1429 if ( xRc == Success … … 1435 1434 for (unsigned i = 0; i < RT_MIN(VBOX_MAX_XPROPERTIES, n); ++i) 1436 1435 { 1437 LogFlowThisFunc(("Received action: %s\n", 1436 LogFlowThisFunc(("Received action: %s\n", 1438 1437 gX11->xAtomToString(data[i]).c_str())); 1439 1438 … … 1457 1456 m.data.l[4] = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */ 1458 1457 1459 xRc = XSendEvent(m_pDisplay, m_wndCur, 1458 xRc = XSendEvent(m_pDisplay, m_wndCur, 1460 1459 False, 0, reinterpret_cast<XEvent*>(&m)); 1461 1460 if (RT_UNLIKELY(xRc == 0)) … … 1480 1479 m.data.l[4] = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */ 1481 1480 1482 xRc = XSendEvent(m_pDisplay, m_wndCur, 1481 xRc = XSendEvent(m_pDisplay, m_wndCur, 1483 1482 False, 0, reinterpret_cast<XEvent*>(&m)); 1484 1483 if (RT_UNLIKELY(xRc == 0)) … … 1499 1498 1500 1499 rc = VbglR3DnDGHAcknowledgePending(m_uClientID, uDefAction, uAllActions, strFormats.c_str()); 1501 LogFlowThisFunc(("Acknowledging m_uClientID=%RU32, allActions=0x%x, strFormats=%s, rc=%Rrc\n", 1500 LogFlowThisFunc(("Acknowledging m_uClientID=%RU32, allActions=0x%x, strFormats=%s, rc=%Rrc\n", 1502 1501 m_uClientID, uAllActions, strFormats.c_str(), rc)); 1503 1502 } … … 1510 1509 int DragInstance::ghDropped(const RTCString &strFormat, uint32_t uAction) 1511 1510 { 1512 LogFlowThisFunc(("strFormat=%s, uAction=%RU32\n", 1511 LogFlowThisFunc(("strFormat=%s, uAction=%RU32\n", 1513 1512 strFormat.c_str(), uAction)); 1514 1513 … … 1525 1524 XWindowAttributes xwa; 1526 1525 XGetWindowAttributes(m_pDisplay, m_wndCur, &xwa); 1527 LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 1526 LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 1528 1527 m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height)); 1529 1528 … … 1534 1533 /* We send a fake release event to the current window, cause 1535 1534 * this should have the grab. */ 1536 mouseButtonSet(m_wndCur /* Source window */, iRootX, iRootY, 1535 mouseButtonSet(m_wndCur /* Source window */, iRootX, iRootY, 1537 1536 1 /* Button */, false /* Release button */); 1538 1537 1539 1538 /* The fake button release event should lead to a XdndDrop event from the 1540 * source. Because of showing our proxy window, other Xdnd events can 1539 * source. Because of showing our proxy window, other Xdnd events can 1541 1540 * occur before, e.g. a XdndPosition event. We are not interested 1542 1541 * in those, so just try to get the right one. */ 1543 1542 1544 1543 XClientMessageEvent evDnDDrop; 1545 bool fDrop = waitForX11ClientMsg(evDnDDrop, xAtom(XA_XdndDrop), 1544 bool fDrop = waitForX11ClientMsg(evDnDDrop, xAtom(XA_XdndDrop), 1546 1545 5 * 1000 /* Timeout in ms */); 1547 1546 if (fDrop) … … 1553 1552 Atom aFormat = gX11->stringToxAtom(strFormat.c_str()); 1554 1553 1555 XConvertSelection(m_pDisplay, xAtom(XA_XdndSelection), 1556 aFormat, xAtom(XA_XdndSelection), 1554 XConvertSelection(m_pDisplay, xAtom(XA_XdndSelection), 1555 aFormat, xAtom(XA_XdndSelection), 1557 1556 m_wndProxy, evDnDDrop.data.l[2]); 1558 1557 … … 1577 1576 unsigned long cItems, cbRemaining; 1578 1577 unsigned char *pcData = NULL; 1579 XGetWindowProperty(m_pDisplay, m_wndProxy, 1578 XGetWindowProperty(m_pDisplay, m_wndProxy, 1580 1579 xAtom(XA_XdndSelection) /* Property */, 1581 1580 0 /* Offset */, 1582 1581 VBOX_MAX_XPROPERTIES /* Length of 32-bit multiples */, 1583 True /* Delete property? */, 1582 True /* Delete property? */, 1584 1583 AnyPropertyType, /* Property type */ 1585 1584 &aPropType, &iPropFormat, &cItems, &cbRemaining, &pcData); 1586 1585 1587 LogFlowThisFunc(("strType=%s, iPropFormat=%d, cItems=%RU32, cbRemaining=%RU32\n", 1586 LogFlowThisFunc(("strType=%s, iPropFormat=%d, cItems=%RU32, cbRemaining=%RU32\n", 1588 1587 gX11->xAtomToString(aPropType).c_str(), iPropFormat, cItems, cbRemaining)); 1589 1588 … … 1608 1607 memcpy(pvDataTmp, pcData, cbData); 1609 1608 pvDataTmp[cbData++] = '\0'; 1610 1611 rc = VbglR3DnDGHSendData(m_uClientID, strFormat.c_str(), 1609 1610 rc = VbglR3DnDGHSendData(m_uClientID, strFormat.c_str(), 1612 1611 pvDataTmp, cbData); 1613 1612 RTMemFree(pvDataTmp); … … 1623 1622 } 1624 1623 1625 LogFlowThisFunc(("Sent strFormat=%s with rc=%Rrc\n", 1624 LogFlowThisFunc(("Sent strFormat=%s with rc=%Rrc\n", 1626 1625 strFormat.c_str(), rc)); 1627 1626 … … 1657 1656 else 1658 1657 { 1659 AssertMsgFailed(("Not supported data type (%s)\n", 1658 AssertMsgFailed(("Not supported data type (%s)\n", 1660 1659 gX11->xAtomToString(aPropType).c_str())); 1661 1660 rc = VERR_INVALID_PARAMETER; … … 1665 1664 } 1666 1665 1667 if (fCancel) 1666 if (fCancel) 1668 1667 { 1669 1668 LogFlowFunc(("Cancelling drop ...\n")); … … 1754 1753 LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n")); 1755 1754 XFlush (m_pDisplay); 1756 1755 1757 1756 // Release 1758 1757 event.type = ButtonRelease; … … 1760 1759 LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n")); 1761 1760 XFlush (m_pDisplay); 1762 1761 1763 1762 #else 1764 1763 #ifdef VBOX_DND_WITH_XTEST … … 1801 1800 //XTranslateCoordinates(m_pDisplay, eBtn.root, eBtn.window, eBtn.x_root, eBtn.y_root, &eBtn.x, &eBtn.y, &eBtn.subwindow); 1802 1801 #if 0 1803 int xrc = XSendEvent(m_pDisplay, eBtn.window, True /* fPropagate */, 1804 fPress 1805 ? ButtonPressMask : ButtonReleaseMask, 1802 int xrc = XSendEvent(m_pDisplay, eBtn.window, True /* fPropagate */, 1803 fPress 1804 ? ButtonPressMask : ButtonReleaseMask, 1806 1805 reinterpret_cast<XEvent*>(&eBtn)); 1807 1806 #else 1808 int xrc = XSendEvent(m_pDisplay, eBtn.window, False /* fPropagate */, 1807 int xrc = XSendEvent(m_pDisplay, eBtn.window, False /* fPropagate */, 1809 1808 0 /* Mask */, 1810 1809 reinterpret_cast<XEvent*>(&eBtn)); … … 1826 1825 } 1827 1826 1828 int DragInstance::proxyWinShow(int *piRootX /*= NULL*/, 1827 int DragInstance::proxyWinShow(int *piRootX /*= NULL*/, 1829 1828 int *piRootY /*= NULL*/, 1830 1829 bool fMouseMove /*= false */) const … … 1841 1840 1842 1841 // XTestGrabControl(m_pDisplay, False); 1843 Bool fInRootWnd = XQueryPointer(m_pDisplay, m_wndRoot, &wndRoot, &wndChild, 1844 &iRootX, &iRootY, 1842 Bool fInRootWnd = XQueryPointer(m_pDisplay, m_wndRoot, &wndRoot, &wndChild, 1843 &iRootX, &iRootY, 1845 1844 &iChildX, &iChildY, &iMask); 1846 1845 #ifdef DEBUG_andy 1847 LogFlowThisFunc(("fInRootWnd=%RTbool, wndRoot=0x%x, wndChild=0x%x, iRootX=%d, iRootY=%d\n", 1846 LogFlowThisFunc(("fInRootWnd=%RTbool, wndRoot=0x%x, wndChild=0x%x, iRootX=%d, iRootY=%d\n", 1848 1847 RT_BOOL(fInRootWnd), wndRoot, wndChild, iRootX, iRootY)); 1849 1848 #endif … … 1901 1900 } 1902 1901 1903 void DragInstance::setActionsWindowProperty(Window wndThis, 1902 void DragInstance::setActionsWindowProperty(Window wndThis, 1904 1903 const RTCList<Atom> &lstActions) const 1905 1904 { … … 1907 1906 return; 1908 1907 1909 XChangeProperty(m_pDisplay, wndThis, 1910 xAtom(XA_XdndActionList), 1908 XChangeProperty(m_pDisplay, wndThis, 1909 xAtom(XA_XdndActionList), 1911 1910 XA_ATOM, 32, PropModeReplace, 1912 reinterpret_cast<const unsigned char*>(lstActions.raw()), 1911 reinterpret_cast<const unsigned char*>(lstActions.raw()), 1913 1912 lstActions.size()); 1914 1913 } … … 1919 1918 } 1920 1919 1921 void DragInstance::setFormatsWindowProperty(Window wndThis, 1920 void DragInstance::setFormatsWindowProperty(Window wndThis, 1922 1921 Atom property) const 1923 1922 { … … 1931 1930 1932 1931 /* Add the property with the property data to the window. */ 1933 XChangeProperty(m_pDisplay, wndThis, property, 1932 XChangeProperty(m_pDisplay, wndThis, property, 1934 1933 XA_ATOM, 32, PropModeReplace, 1935 reinterpret_cast<const unsigned char*>(targets.raw()), 1934 reinterpret_cast<const unsigned char*>(targets.raw()), 1936 1935 targets.size()); 1937 1936 } … … 1939 1938 void DragInstance::clearFormatsWindowProperty(Window wndThis) const 1940 1939 { 1941 XDeleteProperty(m_pDisplay, wndThis, 1940 XDeleteProperty(m_pDisplay, wndThis, 1942 1941 xAtom(XA_XdndTypeList)); 1943 1942 } … … 2103 2102 LogFlowFunc(("Waiting for new event ...\n")); 2104 2103 rc = RTSemEventWait(m_hEventSem, RT_INDEFINITE_WAIT); 2105 if (RT_FAILURE(rc)) 2104 if (RT_FAILURE(rc)) 2106 2105 break; 2107 2106 … … 2119 2118 case DragAndDropSvc::HOST_DND_HG_EVT_ENTER: 2120 2119 { 2121 if (e.hgcm.cbFormats) 2120 if (e.hgcm.cbFormats) 2122 2121 { 2123 RTCList<RTCString> lstFormats 2122 RTCList<RTCString> lstFormats 2124 2123 = RTCString(e.hgcm.pszFormats, e.hgcm.cbFormats - 1).split("\r\n"); 2125 2124 m_pCurDnD->hgEnter(lstFormats, e.hgcm.u.a.uAllActions); … … 2133 2132 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE: 2134 2133 { 2135 m_pCurDnD->hgMove(e.hgcm.u.a.uXpos, e.hgcm.u.a.uYpos, 2134 m_pCurDnD->hgMove(e.hgcm.u.a.uXpos, e.hgcm.u.a.uYpos, 2136 2135 e.hgcm.u.a.uDefAction); 2137 2136 break; … … 2162 2161 { 2163 2162 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 2164 m_pCurDnD->ghDropped(e.hgcm.pszFormats, 2163 m_pCurDnD->ghDropped(e.hgcm.pszFormats, 2165 2164 e.hgcm.u.a.uDefAction); 2166 2165 #endif … … 2203 2202 else if (e.type == DnDEvent::X11_Type) 2204 2203 { 2205 m_pCurDnD->onX11Event(e.x11); 2204 m_pCurDnD->onX11Event(e.x11); 2206 2205 } 2207 2206 else … … 2259 2258 /* No clean-up code for now, as we have no good way of testing it and things 2260 2259 * should get cleaned up when the user process/X11 client exits. */ 2261 if (RT_FAILURE(rc)) 2260 if (RT_FAILURE(rc)) 2262 2261 LogRel(("DnD: Failed to start, rc=%Rrc\n", rc)); 2263 2262 … … 2274 2273 uint32_t uClientID; 2275 2274 int rc = VbglR3DnDConnect(&uClientID); 2276 if (RT_FAILURE(rc)) 2275 if (RT_FAILURE(rc)) 2277 2276 { 2278 2277 LogRel(("DnD: Unable to connect to drag'n drop service, rc=%Rrc\n", rc)); … … 2336 2335 do 2337 2336 { 2338 /* 2337 /* 2339 2338 * Wait for new events. We can't use XIfEvent here, cause this locks 2340 2339 * the window connection with a mutex and if no X11 events occurs this 2341 2340 * blocks any other calls we made to X11. So instead check for new 2342 2341 * events and if there are not any new one, sleep for a certain amount 2343 * of time. 2344 */ 2342 * of time. 2343 */ 2345 2344 if (XEventsQueued(pThis->m_pDisplay, QueuedAfterFlush) > 0) 2346 2345 { … … 2350 2349 /* XNextEvent will block until a new X event becomes available. */ 2351 2350 XNextEvent(pThis->m_pDisplay, &e.x11); 2352 { 2351 { 2353 2352 #ifdef DEBUG 2354 2353 switch (e.x11.type) … … 2368 2367 int32_t dwAction = pEvent->data.l[4]; 2369 2368 2370 LogFlowFunc(("XA_XdndPosition x=%RI32, y=%RI32, dwAction=%RI32\n", 2369 LogFlowFunc(("XA_XdndPosition x=%RI32, y=%RI32, dwAction=%RI32\n", 2371 2370 RT_HIWORD(dwPos), RT_LOWORD(dwPos), dwAction)); 2372 2371 } … … 2382 2381 LogFlowFunc(("Received X event type=%d\n", e.x11.type)); 2383 2382 break; 2384 } 2383 } 2385 2384 #endif 2386 2385 LogFlowFunc(("Adding new X11 event ...\n"));
Note:
See TracChangeset
for help on using the changeset viewer.