Changeset 55846 in vbox for trunk/src/VBox/Additions
- Timestamp:
- May 13, 2015 1:39:39 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 100297
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r55820 r55846 389 389 /* H->G */ 390 390 int hgEnter(const RTCList<RTCString> &formats, uint32_t actions); 391 int hgLeave(void); 391 392 int hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t action); 392 393 int hgDrop(); … … 401 402 /* X11 helpers. */ 402 403 int mouseCursorMove(int iPosX, int iPosY) const; 403 void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const;404 void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress); 404 405 int proxyWinShow(int *piRootX = NULL, int *piRootY = NULL, bool fMouseMove = false) const; 405 406 int proxyWinHide(void); … … 830 831 rc = VINF_SUCCESS; 831 832 833 #ifdef DEBUG 834 XTextProperty propName; 835 XGetWMName(m_pDisplay, e.xselectionrequest.requestor, &propName); 836 #endif 832 837 /* 833 838 * A window is asking for some data. Normally here the data would be copied … … 841 846 if (e.xselectionrequest.target == xAtom(XA_TARGETS)) 842 847 { 843 LogFlowThisFunc(("wnd=%#x asking for target list\n", e.xselectionrequest.requestor)); 848 LogFlowThisFunc(("wnd=%#x '%s' asking for target list\n", 849 e.xselectionrequest.requestor, propName.value)); 844 850 845 851 /* If so, set the window property with the formats on the requestor … … 857 863 else if (m_lstFormats.contains(e.xselectionrequest.target)) 858 864 { 859 LogFlowThisFunc(("wnd=%#x asking for data, format=%s\n", 860 e.xselectionrequest.requestor, xAtomToString(e.xselectionrequest.target).c_str())); 865 LogFlowThisFunc(("wnd=%#x '%s' asking for data, format=%s\n", 866 e.xselectionrequest.requestor, propName.value, 867 xAtomToString(e.xselectionrequest.target).c_str())); 861 868 862 869 /* If so, we need to inform the host about this request. Save the … … 873 880 else 874 881 { 875 LogFlowThisFunc(("Saving selection notify message\n")); 882 LogFlowThisFunc(("Saving selection notify message of wnd=%#x '%s'\n", 883 e.xselectionrequest.requestor, propName.value)); 876 884 877 885 memcpy(&m_eventHgSelection, &e, sizeof(XEvent)); … … 887 895 else 888 896 { 889 LogFlowThisFunc(("Refusing unknown command \n"));897 LogFlowThisFunc(("Refusing unknown command of wnd=%#x '%s'\n", e.xselectionrequest.requestor, propName.value)); 890 898 891 899 /* We don't understand this request message and therefore answer with an … … 913 921 } 914 922 923 #ifdef DEBUG 924 if (propName.value) 925 XFree(propName.value); 926 #endif 915 927 break; 916 928 } … … 1133 1145 } 1134 1146 1147 int DragInstance::hgLeave(void) 1148 { 1149 if (m_enmMode == HG) 1150 reset(); 1151 1152 return VINF_SUCCESS; 1153 } 1154 1135 1155 int DragInstance::hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction) 1136 1156 { … … 1177 1197 { 1178 1198 newVer = reinterpret_cast<long*>(pcData)[0]; 1179 1180 LogFlowThisFunc(("Current: wndCursor=%#x, XdndAware=%ld\n", wndCursor, newVer));1181 1199 #ifdef DEBUG 1182 1200 XTextProperty propName; 1183 1201 if (XGetWMName(m_pDisplay, wndCursor, &propName)) 1184 1202 { 1185 LogFlowThisFunc((" \tTitle: %s\n", propName.value));1203 LogFlowThisFunc(("Current: wndCursor=%#x '%s', XdndAware=%ld\n", wndCursor, propName.value, newVer)); 1186 1204 XFree(propName.value); 1187 1205 } … … 1551 1569 XWindowAttributes xwa; 1552 1570 XGetWindowAttributes(m_pDisplay, m_wndCur, &xwa); 1553 LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 1554 m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height)); 1555 1556 iRootX = xwa.x; 1557 iRootY = xwa.y; 1571 LogFlowThisFunc(("wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height)); 1558 1572 #endif 1559 1573 1560 1574 /* We send a fake release event to the current window, cause 1561 1575 * this should have the grab. */ 1562 mouseButtonSet(m_wndCur /* Sourcewindow */, iRootX, iRootY,1563 1 /* Button */, false /* Release button*/);1576 mouseButtonSet(m_wndCur /* Destination window */, iRootX, iRootY, 1577 1 /* Button */, false /* fPress */); 1564 1578 1565 1579 /** … … 1656 1670 if (RT_SUCCESS(rc)) 1657 1671 { 1658 /* Confirm the result of the transfer to the sourcewindow. */1672 /* Confirm the result of the transfer to the target window. */ 1659 1673 XClientMessageEvent m; 1660 1674 RT_ZERO(m); 1661 1675 m.type = ClientMessage; 1662 1676 m.display = m_pDisplay; 1663 m.window = m_wndProxy;1677 m.window = wndSource; 1664 1678 m.message_type = xAtom(XA_XdndFinished); 1665 1679 m.format = 32; 1666 m.data.l[0] = m_wndProxy; /* Target window. */ 1667 m.data.l[1] = 0; /* Don't accept the drop to not make the guest stuck. */ 1668 m.data.l[2] = RT_SUCCESS(rc) ? toAtomAction(uAction) : None; /* Action used on success */ 1680 m.data.l[0] = m_wndProxy; /* Target window. */ 1681 m.data.l[1] = 0; /* Don't accept the drop to not make the guest stuck. */ 1682 m.data.l[2] = RT_SUCCESS(rc) 1683 ? toAtomAction(uAction) : None; /* Action used on success */ 1669 1684 1670 1685 xRc = XSendEvent(m_pDisplay, wndSource, True, NoEventMask, reinterpret_cast<XEvent*>(&m)); … … 1697 1712 LogFlowFunc(("Cancelling drop ...\n")); 1698 1713 1699 /* Cancel th is. */1714 /* Cancel the operation -- inform the source window. */ 1700 1715 XClientMessageEvent m; 1701 1716 RT_ZERO(m); … … 1703 1718 m.display = m_pDisplay; 1704 1719 m.window = m_wndProxy; 1705 m.message_type = xAtom(XA_Xdnd Finished);1720 m.message_type = xAtom(XA_XdndLeave); 1706 1721 m.format = 32; 1707 m.data.l[0] = m_wndProxy; /* Target window. */ 1708 m.data.l[1] = 0; /* Don't accept the drop to not make the guest stuck. */ 1722 m.data.l[0] = wndSource; /* Source window. */ 1709 1723 1710 1724 xRc = XSendEvent(m_pDisplay, wndSource, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1711 1725 if (RT_UNLIKELY(xRc == 0)) 1712 1726 { 1713 logError("Error sending XA_Xdnd Finishedevent to proxy window=%#x: %s\n",1727 logError("Error sending XA_XdndLeave event to proxy window=%#x: %s\n", 1714 1728 m_wndProxy, gX11->xErrorToString(xRc).c_str()); 1715 1729 } … … 1751 1765 int DragInstance::mouseCursorMove(int iPosX, int iPosY) const 1752 1766 { 1767 int iScreenID = XDefaultScreen(m_pDisplay); 1768 /** @todo What about multiple screens? Test this! */ 1769 1770 const int iScrX = DisplayWidth(m_pDisplay, iScreenID); 1771 const int iScrY = XDisplayHeight(m_pDisplay, iScreenID); 1772 1773 iPosX = RT_CLAMP(iPosX, 0, iScrX); 1774 iPosY = RT_CLAMP(iPosY, 0, iScrY); 1775 1753 1776 LogFlowThisFunc(("iPosX=%d, iPosY=%d\n", iPosX, iPosY)); 1754 1777 1755 1778 /* Move the guest pointer to the DnD position, so we can find the window 1756 1779 * below that position. */ 1757 XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, RT_MAX(0, iPosX), RT_MAX(0, iPosY));1780 XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, iPosX, iPosY); 1758 1781 return VINF_SUCCESS; 1759 1782 } 1760 1783 1761 void DragInstance::mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const1784 void DragInstance::mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) 1762 1785 { 1763 1786 LogFlowThisFunc(("wndDest=%#x, rx=%d, ry=%d, iBtn=%d, fPress=%RTbool\n", 1764 1787 wndDest, rx, ry, iButton, fPress)); 1765 #if 0 1766 // Create and setting up the event 1767 XEvent event; 1768 memset (&event, 0, sizeof (event)); 1769 event.xbutton.button = iButton; 1770 event.xbutton.same_screen = True; 1771 event.xbutton.subwindow = DefaultRootWindow (m_pDisplay); 1772 1773 while (event.xbutton.subwindow) 1774 { 1775 event.xbutton.window = event.xbutton.subwindow; 1776 XQueryPointer (m_pDisplay, event.xbutton.window, 1777 &event.xbutton.root, &event.xbutton.subwindow, 1778 &event.xbutton.x_root, &event.xbutton.y_root, 1779 &event.xbutton.x, &event.xbutton.y, 1780 &event.xbutton.state); 1781 } 1782 // Press 1783 event.type = ButtonPress; 1784 if (XSendEvent (m_pDisplay, PointerWindow, True, ButtonPressMask, &event) == 0) 1785 LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n")); 1786 XFlush (m_pDisplay); 1787 1788 // Release 1789 event.type = ButtonRelease; 1790 if (XSendEvent (m_pDisplay, PointerWindow, True, ButtonReleaseMask, &event) == 0) 1791 LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n")); 1792 XFlush (m_pDisplay); 1793 1794 #else 1788 1795 1789 #ifdef VBOX_DND_WITH_XTEST 1796 1790 /** @todo Make this check run only once. */ … … 1802 1796 int xRc = XTestFakeButtonEvent(m_pDisplay, 1, fPress ? True : False, CurrentTime); 1803 1797 if (RT_UNLIKELY(xRc == 0)) 1804 LogFlowThisFunc(("Error sending XTestFakeButtonEvent event: %s\n", gX11->xErrorToString(xRc).c_str()));1798 logError("Error sending XTestFakeButtonEvent event: %s\n", gX11->xErrorToString(xRc).c_str()); 1805 1799 XFlush(m_pDisplay); 1806 1800 } … … 1839 1833 int xRc = XSendEvent(m_pDisplay, eBtn.window, False /* fPropagate */, 1840 1834 0 /* Mask */, reinterpret_cast<XEvent*>(&eBtn)); 1835 if (RT_UNLIKELY(xRc == 0)) 1836 logError("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str()); 1841 1837 #endif 1842 if (RT_UNLIKELY(xRc == 0))1843 LogFlowThisFunc(("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str()));1844 1838 1845 1839 #ifdef DEBUG … … 1847 1841 int wx, wy; unsigned int mask; 1848 1842 XQueryPointer(m_pDisplay, m_wndRoot, &wndTemp, &wndChild, &rx, &ry, &wx, &wy, &mask); 1849 LogFlow Func(("cursorRootX=%d, cursorRootY=%d\n", rx, ry));1843 LogFlowThisFunc(("cursorRootX=%d, cursorRootY=%d\n", rx, ry)); 1850 1844 #endif 1851 1845 1852 1846 #ifdef VBOX_DND_WITH_XTEST 1853 1847 } 1854 #endif1855 1848 #endif 1856 1849 } … … 1865 1858 LogFlowThisFuncEnter(); 1866 1859 1860 int rc = VINF_SUCCESS; 1861 1867 1862 #if 0 1868 1863 XTestGrabControl(m_pDisplay, False); … … 1870 1865 1871 1866 /* Get the mouse pointer position and determine if we're on the same screen as the root window 1872 * and return sthe current child window beneath our mouse pointer, if any. */1867 * and return the current child window beneath our mouse pointer, if any. */ 1873 1868 int iRootX, iRootY; 1874 1869 int iChildX, iChildY; … … 1899 1894 1900 1895 if (fMouseMove) 1901 XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0,iRootX, iRootY);1896 rc = mouseCursorMove(iRootX, iRootY); 1902 1897 1903 1898 XSynchronize(m_pDisplay, False /* Disable sync */); … … 1907 1902 #endif 1908 1903 1909 return VINF_SUCCESS; /** @todo Add error checking. */1904 return rc; 1910 1905 } 1911 1906 … … 2241 2236 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE: 2242 2237 { 2243 m_pCurDnD->reset();2238 rc = m_pCurDnD->hgLeave(); 2244 2239 break; 2245 2240 } … … 2274 2269 } 2275 2270 2276 if (RT_FAILURE(rc)) 2271 LogFlowFunc(("Message %RU32 processed with %Rrc\n", e.hgcm.uType, rc)); 2272 if ( RT_FAILURE(rc) 2273 /* 2274 * Note: The hgXXX and ghXXX functions of the DnD instance above may return 2275 * VERR_INVALID_STATE in case we're not in the expected state they want 2276 * to operate in. As the user might drag content back and forth to/from 2277 * the host/guest we don't want to reset the overall state here in case 2278 * a VERR_INVALID_STATE occurs. Just continue in our initially set mode. 2279 */ 2280 && rc != VERR_INVALID_STATE) 2277 2281 { 2278 2282 m_pCurDnD->logError("Error: Processing message %RU32 failed with %Rrc\n", e.hgcm.uType, rc);
Note:
See TracChangeset
for help on using the changeset viewer.