Changeset 50734 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Mar 10, 2014 1:54:03 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92721
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r50724 r50734 45 45 * their behavior. Don't have this enabled in release builds! */ 46 46 #ifdef DEBUG 47 # define VBOX_DND_DEBUG_WND47 //# define VBOX_DND_DEBUG_WND 48 48 #endif 49 49 … … 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 * Todo: 79 * - this isn't finished, yet. Currently the mouse isn't correctly released 80 * in the guest (both, when the drop was successfully or canceled). 81 * - cancel (e.g. with the ESC key) doesn't work 78 * 79 * To-do: 80 * - Cancelling (e.g. with ESC key) doesn't work. 82 81 * 83 * Todo: 84 * - XdndProxy window support 85 * - INCR support 86 * - make this much more robust for crashes of the other party 87 * - really check for the Xdnd version and the supported features 82 * To-do: 83 * - INCR (incremental transfers) support. 84 * - Make this much more robust for crashes of the other party. 85 * - Really check for the Xdnd version and the supported features. 88 86 */ 89 87 … … 390 388 void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const; 391 389 int proxyWinShow(int *piRootX = NULL, int *piRootY = NULL, bool fMouseMove = false) const; 392 int proxyWinHide(void) const;390 int proxyWinHide(void); 393 391 void registerForEvents(Window w) const; 394 392 … … 569 567 m_curVer = -1; 570 568 m_state = Initialized; 569 m_eventQueue.clear(); 571 570 } 572 571 … … 740 739 case GH: 741 740 { 742 //if (m_state == Dropped) 743 //{ 744 LogFlowThisFunc(("Enqueuing ClientMessage\n")); 745 746 m_eventQueue.append(e); 747 rc = RTSemEventSignal(m_hEventSem); 748 //} 749 750 //rc = VINF_SUCCESS; 741 LogFlowThisFunc(("Enqueuing ClientMessage\n")); 742 743 m_eventQueue.append(e); 744 rc = RTSemEventSignal(m_hEventSem); 751 745 break; 752 746 } … … 885 879 memcpy(&m_eventHgSelection, &e, sizeof(XEvent)); 886 880 887 const char *pcszFormat = xAtomToString(e.xselectionrequest.target).c_str();888 Assert Ptr(pcszFormat);889 rc = VbglR3DnDHGRequestData(m_uClientID, pcszFormat);881 RTCString strFormat = xAtomToString(e.xselectionrequest.target); 882 Assert(strFormat.isNotEmpty()); 883 rc = VbglR3DnDHGRequestData(m_uClientID, strFormat.c_str()); 890 884 LogFlowThisFunc(("Requesting data from host as \"%s\", rc=%Rrc\n", 891 pcszFormat, rc));885 strFormat.c_str(), rc)); 892 886 } 893 887 } … … 936 930 switch (e.type) 937 931 { 932 case ButtonPress: 933 LogFlowThisFunc(("ButtonPress\n")); 934 rc = VINF_SUCCESS; 935 break; 936 937 case ButtonRelease: 938 LogFlowThisFunc(("ButtonRelease\n")); 939 rc = VINF_SUCCESS; 940 break; 941 942 case ClientMessage: 943 rc = onX11ClientMessage(e); 944 break; 945 946 case SelectionClear: 947 LogFlowThisFunc(("SelectionClear\n")); 948 reset(); 949 rc = VINF_SUCCESS; 950 break; 951 938 952 case SelectionNotify: 939 953 rc = onX11SelectionNotify(e); … … 943 957 rc = onX11SelectionRequest(e); 944 958 break; 945 946 case ClientMessage:947 rc = onX11ClientMessage(e);948 break;949 950 case SelectionClear:951 LogFlowThisFunc(("SelectionClear\n"));952 rc = VINF_SUCCESS;953 break;954 959 955 960 /*case MotionNotify: … … 1135 1140 0, 2, False, AnyPropertyType, 1136 1141 &atmp, &fmt, &cItems, &cbRemaining, &pcData); 1142 1137 1143 if (RT_UNLIKELY(xrc != Success)) 1138 1144 LogFlowThisFunc(("Error in getting the window property: %s\n", gX11->xErrorToString(xrc).c_str())); … … 1146 1152 LogFlowThisFunc(("wndCursor=%#x, XdndAware=%u\n", newVer)); 1147 1153 } 1154 1148 1155 XFree(pcData); 1149 1156 } … … 1153 1160 * Is the window under the cursor another one than our current one? 1154 1161 */ 1155 if (wndCursor != m_wndCur && m_curVer != -1) 1162 if ( wndCursor != m_wndCur 1163 && m_curVer != -1) 1156 1164 { 1157 1165 LogFlowThisFunc(("Leaving window=%#x\n", m_wndCur)); … … 1212 1220 */ 1213 1221 Atom pa = toX11Action(uAction); 1214 LogFlowThisFunc(("strAction= '%s'", xAtomToString(pa).c_str()));1222 LogFlowThisFunc(("strAction=%s\n", xAtomToString(pa).c_str())); 1215 1223 1216 1224 XClientMessageEvent m; … … 1231 1239 } 1232 1240 1233 if (wndCursor == None && newVer == -1) 1241 if ( wndCursor == None 1242 && newVer == -1) 1234 1243 { 1235 1244 /* No window to process, so send a ignore ack event to the host. */ … … 1356 1365 AssertPtr(pEventClient); 1357 1366 1358 LogFlowThisFunc((" Next X event is:%s\n",1367 LogFlowThisFunc(("Received event=%s\n", 1359 1368 gX11->xAtomToString(pEventClient->message_type).c_str())); 1360 1369 … … 1370 1379 m_state = Dragging; 1371 1380 m_wndCur = wndSelection; 1381 Assert(m_wndCur == pEventClient->data.l[0]); 1372 1382 1373 1383 LogFlowThisFunc(("XA_XdndEnter\n")); … … 1438 1448 XClientMessageEvent m; 1439 1449 RT_ZERO(m); 1440 1441 1450 m.type = ClientMessage; 1442 1451 m.display = m_pDisplay; 1443 m.window = pEventClient->data.l[0];1452 m.window = m_wndCur; 1444 1453 m.message_type = xAtom(XA_XdndStatus); 1445 1454 m.format = 32; 1446 1455 m.data.l[0] = m_wndProxy; 1447 m.data.l[1] = 1;1448 m.data.l[4] = xAtom(XA_XdndActionCopy); 1449 1450 xRc = XSendEvent(m_pDisplay, pEventClient->data.l[0],1456 m.data.l[1] = RT_BIT(0); /* Accept the drop. */ 1457 m.data.l[4] = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */ 1458 1459 xRc = XSendEvent(m_pDisplay, m_wndCur, 1451 1460 False, 0, reinterpret_cast<XEvent*>(&m)); 1452 1461 if (RT_UNLIKELY(xRc == 0)) … … 1464 1473 m.type = ClientMessage; 1465 1474 m.display = m_pDisplay; 1466 m.window = pEventClient->data.l[0];1475 m.window = m_wndCur; 1467 1476 m.message_type = xAtom(XA_XdndStatus); 1468 1477 m.format = 32; 1469 1478 m.data.l[0] = m_wndProxy; 1470 m.data.l[1] = 1;1471 m.data.l[4] = pEventClient->data.l[4];1472 1473 xRc = XSendEvent(m_pDisplay, pEventClient->data.l[0],1479 m.data.l[1] = RT_BIT(0); /* Accept the drop. */ 1480 m.data.l[4] = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */ 1481 1482 xRc = XSendEvent(m_pDisplay, m_wndCur, 1474 1483 False, 0, reinterpret_cast<XEvent*>(&m)); 1475 1484 if (RT_UNLIKELY(xRc == 0)) … … 1482 1491 } 1483 1492 1484 proxyWinHide();1485 1486 1493 /* Do we need to acknowledge at least one format to the host? */ 1487 1494 if (!m_formats.isEmpty()) … … 1527 1534 /* We send a fake release event to the current window, cause 1528 1535 * this should have the grab. */ 1529 mouseButtonSet(m_wndCur , iRootX, iRootY,1536 mouseButtonSet(m_wndCur /* Source window */, iRootX, iRootY, 1530 1537 1 /* Button */, false /* Release button */); 1531 1538 … … 1542 1549 /* Request to convert the selection in the specific format and 1543 1550 * place it to our proxy window as property. */ 1544 Window srcWin = m_wndCur;//clme->data.l[0]; 1551 Window wndSource = evDnDDrop.data.l[0]; /* Source window which sent the message. */ 1552 Assert(wndSource == m_wndCur); 1545 1553 Atom aFormat = gX11->stringToxAtom(strFormat.c_str()); 1546 1554 … … 1554 1562 if (waitForX11Msg(evSelNotify, SelectionNotify)) 1555 1563 { 1564 bool fCancel = false; 1565 1556 1566 /* Make some paranoid checks. */ 1557 1567 if ( evSelNotify.xselection.type == SelectionNotify … … 1616 1626 strFormat.c_str(), rc)); 1617 1627 1618 /* Confirm the result of the transfer to the source window. */ 1619 XClientMessageEvent m; 1620 RT_ZERO(m); 1621 m.type = ClientMessage; 1622 m.display = m_pDisplay; 1623 m.window = srcWin; 1624 m.message_type = xAtom(XA_XdndFinished); 1625 m.format = 32; 1626 m.data.l[0] = m_wndProxy; 1627 m.data.l[1] = RT_SUCCESS(rc) ? 1 : 0; /* Confirm or deny success */ 1628 m.data.l[2] = RT_SUCCESS(rc) ? toX11Action(uAction) : None; /* Action used on success */ 1629 1630 int xrc = XSendEvent(m_pDisplay, srcWin, True, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1631 if (RT_UNLIKELY(xrc == 0)) 1632 LogFlowThisFunc(("Error sending xEvent\n")); 1628 if (RT_SUCCESS(rc)) 1629 { 1630 /* Confirm the result of the transfer to the source window. */ 1631 XClientMessageEvent m; 1632 RT_ZERO(m); 1633 m.type = ClientMessage; 1634 m.display = m_pDisplay; 1635 m.window = m_wndProxy; 1636 m.message_type = xAtom(XA_XdndFinished); 1637 m.format = 32; 1638 m.data.l[0] = m_wndProxy; /* Target window. */ 1639 m.data.l[1] = 0; /* Don't accept the drop to not make the guest stuck. */ 1640 m.data.l[2] = RT_SUCCESS(rc) ? toX11Action(uAction) : None; /* Action used on success */ 1641 1642 int xrc = XSendEvent(m_pDisplay, wndSource, True, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1643 if (RT_UNLIKELY(xrc == 0)) 1644 LogFlowThisFunc(("Error sending xEvent\n")); 1645 } 1646 else 1647 fCancel = true; 1633 1648 } 1634 1649 else … … 1642 1657 else 1643 1658 { 1644 AssertMsgFailed(("Not supported data type\n")); 1659 AssertMsgFailed(("Not supported data type (%s)\n", 1660 gX11->xAtomToString(aPropType).c_str())); 1645 1661 rc = VERR_INVALID_PARAMETER; 1646 1662 } 1663 1664 fCancel = true; 1665 } 1666 1667 if (fCancel) 1668 { 1669 LogFlowFunc(("Cancelling drop ...\n")); 1647 1670 1648 1671 /* Cancel this. */ … … 1651 1674 m.type = ClientMessage; 1652 1675 m.display = m_pDisplay; 1653 m.window = srcWin;1676 m.window = m_wndProxy; 1654 1677 m.message_type = xAtom(XA_XdndFinished); 1655 1678 m.format = 32; 1656 m.data.l[0] = m_wndProxy; 1657 m.data.l[1] = 0; 1658 m.data.l[2] = None; 1659 1660 int xrc = XSendEvent(m_pDisplay, srcWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1679 m.data.l[0] = m_wndProxy; /* Target window. */ 1680 m.data.l[1] = 0; /* Don't accept the drop to not make the guest stuck. */ 1681 1682 int xrc = XSendEvent(m_pDisplay, wndSource, False, NoEventMask, reinterpret_cast<XEvent*>(&m)); 1661 1683 if (RT_UNLIKELY(xrc == 0)) 1662 LogFlowThisFunc(("Error sending xEvent\n")); 1663 m_wndCur = 0; 1684 LogFlowThisFunc(("Error sending cancel event\n")); 1664 1685 } 1665 1686 … … 1848 1869 } 1849 1870 1850 int DragInstance::proxyWinHide(void) const 1851 { 1852 LogFlowThisFuncEnter(); 1853 return 0; 1871 int DragInstance::proxyWinHide(void) 1872 { 1873 LogFlowFuncEnter(); 1854 1874 1855 1875 XUnmapWindow(m_pDisplay, m_wndProxy); 1876 m_eventQueue.clear(); 1856 1877 1857 1878 return VINF_SUCCESS; /** @todo Add error checking. */
Note:
See TracChangeset
for help on using the changeset viewer.