< prev index next >

src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java

Print this page




  66     /* The event mask of the root window before the drag operation starts. */
  67     private long rootEventMask = 0;
  68     private boolean dndInProgress = false;
  69     private boolean dragInProgress = false;
  70     private long dragRootWindow = 0;
  71 
  72     /* The protocol chosen for the communication with the current drop target. */
  73     private XDragSourceProtocol dragProtocol = null;
  74     /* The drop action chosen by the current drop target. */
  75     private int targetAction = DnDConstants.ACTION_NONE;
  76     /* The set of drop actions supported by the drag source. */
  77     private int sourceActions = DnDConstants.ACTION_NONE;
  78     /* The drop action selected by the drag source based on the modifiers state
  79        and the action selected by the current drop target. */
  80     private int sourceAction = DnDConstants.ACTION_NONE;
  81     /* The data formats supported by the drag source for the current drag
  82        operation. */
  83     private long[] sourceFormats = null;
  84     /* The XID of the root subwindow that contains the current target. */
  85     private long targetRootSubwindow = 0;


  86     /* The pointer location. */
  87     private int xRoot = 0;
  88     private int yRoot = 0;
  89     /* Keyboard modifiers state. */
  90     private int eventState = 0;
  91 
  92     /* XEmbed DnD support. We act as a proxy between source and target. */
  93     private long proxyModeSourceWindow = 0;
  94 
  95     /* The singleton instance. */
  96     private static final XDragSourceContextPeer theInstance =
  97         new XDragSourceContextPeer(null);
  98 
  99     private XDragSourceContextPeer(DragGestureEvent dge) {
 100         super(dge);
 101     }
 102 
 103     static XDragSourceProtocolListener getXDragSourceProtocolListener() {
 104         return theInstance;
 105     }


 113     protected void startDrag(Transferable transferable,
 114                              long[] formats, Map<Long, DataFlavor> formatMap) {
 115         Component component = getTrigger().getComponent();
 116         Component c = null;
 117         XWindowPeer wpeer = null;
 118 
 119         for (c = component; c != null && !(c instanceof Window);
 120              c = AWTAccessor.getComponentAccessor().getParent(c));
 121 
 122         if (c instanceof Window) {
 123             wpeer = AWTAccessor.getComponentAccessor().getPeer(c);
 124         }
 125 
 126         if (wpeer == null) {
 127             throw new InvalidDnDOperationException(
 128                 "Cannot find top-level for the drag source component");
 129         }
 130 
 131         long xcursor = 0;
 132         long rootWindow = 0;
 133         long dragWindow = 0;
 134         long timeStamp = 0;

 135 
 136         /* Retrieve the X cursor for the drag operation. */
 137         {
 138             Cursor cursor = getCursor();
 139             if (cursor != null) {
 140                 xcursor = XGlobalCursorManager.getCursor(cursor);
 141             }
 142         }
 143 
 144         XToolkit.awtLock();
 145         try {
 146             if (proxyModeSourceWindow != 0) {
 147                 throw new InvalidDnDOperationException("Proxy drag in progress");
 148             }
 149             if (dndInProgress) {
 150                 throw new InvalidDnDOperationException("Drag in progress");
 151             }
 152 
 153             /* Determine the root window for the drag operation. */
 154             {
 155                 long screen = XlibWrapper.XScreenNumberOfScreen(wpeer.getScreen());
 156                 rootWindow = XlibWrapper.RootWindow(XToolkit.getDisplay(), screen);
 157             }
 158 
 159             dragWindow = XWindow.getXAWTRootWindow().getWindow();
 160 
 161             timeStamp = XToolkit.getCurrentServerTime();
 162 
 163             int dropActions = getDragSourceContext().getSourceActions();
 164 
 165             Iterator<XDragSourceProtocol> dragProtocols =
 166                 XDragAndDropProtocols.getDragSourceProtocols();
 167             while (dragProtocols.hasNext()) {
 168                 XDragSourceProtocol dragProtocol = dragProtocols.next();
 169                 try {
 170                     dragProtocol.initializeDrag(dropActions, transferable,
 171                                                 formatMap, formats);
 172                 } catch (XException xe) {
 173                     throw (InvalidDnDOperationException)
 174                         new InvalidDnDOperationException().initCause(xe);
 175                 }
 176             }
 177 
 178             /* Install X grabs. */
 179             {
 180                 int status;


 424             Iterator<XDragSourceProtocol> dragProtocols =
 425                 XDragAndDropProtocols.getDragSourceProtocols();
 426             while (dragProtocols.hasNext()) {
 427                 XDragSourceProtocol dragProtocol = dragProtocols.next();
 428                 if (dragProtocol.attachTargetWindow(clientWindow, time)) {
 429                     protocol = dragProtocol;
 430                     break;
 431                 }
 432             }
 433         }
 434 
 435         /* Update the global state. */
 436         dragProtocol = protocol;
 437         targetAction = DnDConstants.ACTION_NONE;
 438         targetRootSubwindow = subwindow;
 439     }
 440 
 441     private void updateTargetWindow(XMotionEvent xmotion) {
 442         assert XToolkit.isAWTLockHeldByCurrentThread();
 443 
 444         int x = xmotion.get_x_root();
 445         int y = xmotion.get_y_root();
 446         long time = xmotion.get_time();
 447         long subwindow = xmotion.get_subwindow();
 448 
 449         /*
 450          * If this event had occurred before the pointer was grabbed,
 451          * query the server for the current root subwindow.
 452          */
 453         if (xmotion.get_window() != xmotion.get_root()) {
 454             XlibWrapper.XQueryPointer(XToolkit.getDisplay(),
 455                                       xmotion.get_root(),
 456                                       XlibWrapper.larg1,  // root
 457                                       XlibWrapper.larg2,  // subwindow
 458                                       XlibWrapper.larg3,  // x_root
 459                                       XlibWrapper.larg4,  // y_root
 460                                       XlibWrapper.larg5,  // x
 461                                       XlibWrapper.larg6,  // y
 462                                       XlibWrapper.larg7); // modifiers
 463             subwindow = Native.getLong(XlibWrapper.larg2);
 464         }
 465 


 481             /* Update the global state. */
 482             doUpdateTargetWindow(subwindow, time);
 483 
 484             if (dragProtocol != null) {
 485                 dragProtocol.sendEnterMessage(sourceFormats,
 486                                               sourceAction,
 487                                               sourceActions,
 488                                               time);
 489             }
 490         }
 491     }
 492 
 493     /*
 494      * DO NOT USE is_hint field of xmotion since it could not be set when we
 495      * convert XKeyEvent or XButtonRelease to XMotionEvent.
 496      */
 497     private void processMouseMove(XMotionEvent xmotion) {
 498         if (!dragInProgress) {
 499             return;
 500         }
 501         if (xRoot != xmotion.get_x_root() || yRoot != xmotion.get_y_root()) {
 502             xRoot = xmotion.get_x_root();
 503             yRoot = xmotion.get_y_root();




 504 
 505             postDragSourceDragEvent(targetAction,
 506                                     XWindow.getModifiers(xmotion.get_state(),0,0),
 507                                     xRoot, yRoot, DISPATCH_MOUSE_MOVED);
 508         }
 509 
 510         if (eventState != xmotion.get_state()) {
 511             if (updateSourceAction(xmotion.get_state()) && dragProtocol != null) {
 512                 postDragSourceDragEvent(targetAction,
 513                                         XWindow.getModifiers(xmotion.get_state(),0,0),
 514                                         xRoot, yRoot, DISPATCH_CHANGED);
 515             }
 516             eventState = xmotion.get_state();
 517         }
 518 
 519         updateTargetWindow(xmotion);
 520 
 521         if (dragProtocol != null) {
 522             dragProtocol.sendMoveMessage(xmotion.get_x_root(),
 523                                          xmotion.get_y_root(),
 524                                          sourceAction, sourceActions,
 525                                          xmotion.get_time());
 526         }
 527     }
 528 
 529     private void processDrop(XButtonEvent xbutton) {
 530         try {
 531             dragProtocol.initiateDrop(xbutton.get_x_root(),
 532                                       xbutton.get_y_root(),
 533                                       sourceAction, sourceActions,
 534                                       xbutton.get_time());
 535         } catch (XException e) {
 536             cleanup(xbutton.get_time());
 537         }
 538     }
 539 
 540     private boolean processProxyModeEvent(XEvent ev) {
 541         if (getProxyModeSourceWindow() == 0) {
 542             return false;
 543         }
 544 
 545         if (ev.get_type() != XConstants.ClientMessage) {
 546             return false;
 547         }
 548 
 549         if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
 550             logger.finest("        proxyModeSourceWindow=" +
 551                           getProxyModeSourceWindow() +
 552                           " ev=" + ev);


 787         handleDragFinished(true);
 788     }
 789 
 790     public void handleDragFinished(boolean success) {
 791         /* Assume that the performed drop action is the latest drop action
 792            accepted by the drop target. */
 793         handleDragFinished(true, targetAction);
 794     }
 795 
 796     public void handleDragFinished(boolean success, int action) {
 797         // NOTE: we have to use the current pointer location, since
 798         // the target didn't specify the coordinates for the reply.
 799         handleDragFinished(success, action, xRoot, yRoot);
 800     }
 801 
 802     public void handleDragFinished(boolean success, int action, int x, int y) {
 803         dragDropFinished(success, action, x, y);
 804 
 805         dndInProgress = false;
 806         cleanup(XConstants.CurrentTime);








 807     }
 808 }


  66     /* The event mask of the root window before the drag operation starts. */
  67     private long rootEventMask = 0;
  68     private boolean dndInProgress = false;
  69     private boolean dragInProgress = false;
  70     private long dragRootWindow = 0;
  71 
  72     /* The protocol chosen for the communication with the current drop target. */
  73     private XDragSourceProtocol dragProtocol = null;
  74     /* The drop action chosen by the current drop target. */
  75     private int targetAction = DnDConstants.ACTION_NONE;
  76     /* The set of drop actions supported by the drag source. */
  77     private int sourceActions = DnDConstants.ACTION_NONE;
  78     /* The drop action selected by the drag source based on the modifiers state
  79        and the action selected by the current drop target. */
  80     private int sourceAction = DnDConstants.ACTION_NONE;
  81     /* The data formats supported by the drag source for the current drag
  82        operation. */
  83     private long[] sourceFormats = null;
  84     /* The XID of the root subwindow that contains the current target. */
  85     private long targetRootSubwindow = 0;
  86     /* window scale factor */
  87     int windowScale = 1;
  88     /* The pointer location. */
  89     private int xRoot = 0;
  90     private int yRoot = 0;
  91     /* Keyboard modifiers state. */
  92     private int eventState = 0;
  93 
  94     /* XEmbed DnD support. We act as a proxy between source and target. */
  95     private long proxyModeSourceWindow = 0;
  96 
  97     /* The singleton instance. */
  98     private static final XDragSourceContextPeer theInstance =
  99         new XDragSourceContextPeer(null);
 100 
 101     private XDragSourceContextPeer(DragGestureEvent dge) {
 102         super(dge);
 103     }
 104 
 105     static XDragSourceProtocolListener getXDragSourceProtocolListener() {
 106         return theInstance;
 107     }


 115     protected void startDrag(Transferable transferable,
 116                              long[] formats, Map<Long, DataFlavor> formatMap) {
 117         Component component = getTrigger().getComponent();
 118         Component c = null;
 119         XWindowPeer wpeer = null;
 120 
 121         for (c = component; c != null && !(c instanceof Window);
 122              c = AWTAccessor.getComponentAccessor().getParent(c));
 123 
 124         if (c instanceof Window) {
 125             wpeer = AWTAccessor.getComponentAccessor().getPeer(c);
 126         }
 127 
 128         if (wpeer == null) {
 129             throw new InvalidDnDOperationException(
 130                 "Cannot find top-level for the drag source component");
 131         }
 132 
 133         long xcursor = 0;
 134         long rootWindow = 0;

 135         long timeStamp = 0;
 136         windowScale = wpeer.getScale();
 137 
 138         /* Retrieve the X cursor for the drag operation. */
 139         {
 140             Cursor cursor = getCursor();
 141             if (cursor != null) {
 142                 xcursor = XGlobalCursorManager.getCursor(cursor);
 143             }
 144         }
 145 
 146         XToolkit.awtLock();
 147         try {
 148             if (proxyModeSourceWindow != 0) {
 149                 throw new InvalidDnDOperationException("Proxy drag in progress");
 150             }
 151             if (dndInProgress) {
 152                 throw new InvalidDnDOperationException("Drag in progress");
 153             }
 154 
 155             /* Determine the root window for the drag operation. */
 156             {
 157                 long screen = XlibWrapper.XScreenNumberOfScreen(wpeer.getScreen());
 158                 rootWindow = XlibWrapper.RootWindow(XToolkit.getDisplay(), screen);
 159             }
 160 


 161             timeStamp = XToolkit.getCurrentServerTime();
 162 
 163             int dropActions = getDragSourceContext().getSourceActions();
 164 
 165             Iterator<XDragSourceProtocol> dragProtocols =
 166                 XDragAndDropProtocols.getDragSourceProtocols();
 167             while (dragProtocols.hasNext()) {
 168                 XDragSourceProtocol dragProtocol = dragProtocols.next();
 169                 try {
 170                     dragProtocol.initializeDrag(dropActions, transferable,
 171                                                 formatMap, formats);
 172                 } catch (XException xe) {
 173                     throw (InvalidDnDOperationException)
 174                         new InvalidDnDOperationException().initCause(xe);
 175                 }
 176             }
 177 
 178             /* Install X grabs. */
 179             {
 180                 int status;


 424             Iterator<XDragSourceProtocol> dragProtocols =
 425                 XDragAndDropProtocols.getDragSourceProtocols();
 426             while (dragProtocols.hasNext()) {
 427                 XDragSourceProtocol dragProtocol = dragProtocols.next();
 428                 if (dragProtocol.attachTargetWindow(clientWindow, time)) {
 429                     protocol = dragProtocol;
 430                     break;
 431                 }
 432             }
 433         }
 434 
 435         /* Update the global state. */
 436         dragProtocol = protocol;
 437         targetAction = DnDConstants.ACTION_NONE;
 438         targetRootSubwindow = subwindow;
 439     }
 440 
 441     private void updateTargetWindow(XMotionEvent xmotion) {
 442         assert XToolkit.isAWTLockHeldByCurrentThread();
 443 
 444         int x = scaleDown(xmotion.get_x_root());
 445         int y = scaleDown(xmotion.get_y_root());
 446         long time = xmotion.get_time();
 447         long subwindow = xmotion.get_subwindow();
 448 
 449         /*
 450          * If this event had occurred before the pointer was grabbed,
 451          * query the server for the current root subwindow.
 452          */
 453         if (xmotion.get_window() != xmotion.get_root()) {
 454             XlibWrapper.XQueryPointer(XToolkit.getDisplay(),
 455                                       xmotion.get_root(),
 456                                       XlibWrapper.larg1,  // root
 457                                       XlibWrapper.larg2,  // subwindow
 458                                       XlibWrapper.larg3,  // x_root
 459                                       XlibWrapper.larg4,  // y_root
 460                                       XlibWrapper.larg5,  // x
 461                                       XlibWrapper.larg6,  // y
 462                                       XlibWrapper.larg7); // modifiers
 463             subwindow = Native.getLong(XlibWrapper.larg2);
 464         }
 465 


 481             /* Update the global state. */
 482             doUpdateTargetWindow(subwindow, time);
 483 
 484             if (dragProtocol != null) {
 485                 dragProtocol.sendEnterMessage(sourceFormats,
 486                                               sourceAction,
 487                                               sourceActions,
 488                                               time);
 489             }
 490         }
 491     }
 492 
 493     /*
 494      * DO NOT USE is_hint field of xmotion since it could not be set when we
 495      * convert XKeyEvent or XButtonRelease to XMotionEvent.
 496      */
 497     private void processMouseMove(XMotionEvent xmotion) {
 498         if (!dragInProgress) {
 499             return;
 500         }
 501 
 502         int motionXRoot = scaleDown(xmotion.get_x_root());
 503         int motionYRoot = scaleDown(xmotion.get_y_root());
 504 
 505         if (xRoot != motionXRoot || yRoot != motionYRoot) {
 506             xRoot = motionXRoot;
 507             yRoot = motionYRoot;
 508 
 509             postDragSourceDragEvent(targetAction,
 510                                     XWindow.getModifiers(xmotion.get_state(),0,0),
 511                                     xRoot, yRoot, DISPATCH_MOUSE_MOVED);
 512         }
 513 
 514         if (eventState != xmotion.get_state()) {
 515             if (updateSourceAction(xmotion.get_state()) && dragProtocol != null) {
 516                 postDragSourceDragEvent(targetAction,
 517                                         XWindow.getModifiers(xmotion.get_state(),0,0),
 518                                         xRoot, yRoot, DISPATCH_CHANGED);
 519             }
 520             eventState = xmotion.get_state();
 521         }
 522 
 523         updateTargetWindow(xmotion);
 524 
 525         if (dragProtocol != null) {
 526             dragProtocol.sendMoveMessage(scaleDown(xmotion.get_x_root()),
 527                                          scaleDown(xmotion.get_y_root()),
 528                                          sourceAction, sourceActions,
 529                                          xmotion.get_time());
 530         }
 531     }
 532 
 533     private void processDrop(XButtonEvent xbutton) {
 534         try {
 535             dragProtocol.initiateDrop(scaleDown(xbutton.get_x_root()),
 536                                       scaleDown(xbutton.get_y_root()),
 537                                       sourceAction, sourceActions,
 538                                       xbutton.get_time());
 539         } catch (XException e) {
 540             cleanup(xbutton.get_time());
 541         }
 542     }
 543 
 544     private boolean processProxyModeEvent(XEvent ev) {
 545         if (getProxyModeSourceWindow() == 0) {
 546             return false;
 547         }
 548 
 549         if (ev.get_type() != XConstants.ClientMessage) {
 550             return false;
 551         }
 552 
 553         if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
 554             logger.finest("        proxyModeSourceWindow=" +
 555                           getProxyModeSourceWindow() +
 556                           " ev=" + ev);


 791         handleDragFinished(true);
 792     }
 793 
 794     public void handleDragFinished(boolean success) {
 795         /* Assume that the performed drop action is the latest drop action
 796            accepted by the drop target. */
 797         handleDragFinished(true, targetAction);
 798     }
 799 
 800     public void handleDragFinished(boolean success, int action) {
 801         // NOTE: we have to use the current pointer location, since
 802         // the target didn't specify the coordinates for the reply.
 803         handleDragFinished(success, action, xRoot, yRoot);
 804     }
 805 
 806     public void handleDragFinished(boolean success, int action, int x, int y) {
 807         dragDropFinished(success, action, x, y);
 808 
 809         dndInProgress = false;
 810         cleanup(XConstants.CurrentTime);
 811     }
 812     
 813     public int scaleUp(int x) {
 814         return x * windowScale;
 815     }
 816 
 817     public int scaleDown(int x) {
 818         return x / windowScale;
 819     }
 820 }
< prev index next >