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 }
|