Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java
32288 views
1
/*
2
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.awt.X11;
27
28
import java.awt.Component;
29
import java.awt.Cursor;
30
import java.awt.Window;
31
32
import java.awt.datatransfer.Transferable;
33
34
import java.awt.dnd.DnDConstants;
35
import java.awt.dnd.DragGestureEvent;
36
import java.awt.dnd.InvalidDnDOperationException;
37
38
import java.util.*;
39
40
import sun.util.logging.PlatformLogger;
41
42
import sun.awt.dnd.SunDragSourceContextPeer;
43
import sun.awt.dnd.SunDropTargetContextPeer;
44
import sun.awt.SunToolkit;
45
import sun.awt.AWTAccessor;
46
47
/**
48
* The XDragSourceContextPeer class is the class responsible for handling
49
* the interaction between the XDnD/Motif DnD subsystem and Java drag sources.
50
*
51
* @since 1.5
52
*/
53
public final class XDragSourceContextPeer
54
extends SunDragSourceContextPeer implements XDragSourceProtocolListener {
55
private static final PlatformLogger logger =
56
PlatformLogger.getLogger("sun.awt.X11.xembed.xdnd.XDragSourceContextPeer");
57
58
/* The events selected on the root window when the drag begins. */
59
private static final int ROOT_EVENT_MASK = (int)XConstants.ButtonMotionMask |
60
(int)XConstants.KeyPressMask | (int)XConstants.KeyReleaseMask;
61
/* The events to be delivered during grab. */
62
private static final int GRAB_EVENT_MASK = (int)XConstants.ButtonPressMask |
63
(int)XConstants.ButtonMotionMask | (int)XConstants.ButtonReleaseMask;
64
65
/* The event mask of the root window before the drag operation starts. */
66
private long rootEventMask = 0;
67
private boolean dndInProgress = false;
68
private boolean dragInProgress = false;
69
private long dragRootWindow = 0;
70
71
/* The protocol chosen for the communication with the current drop target. */
72
private XDragSourceProtocol dragProtocol = null;
73
/* The drop action chosen by the current drop target. */
74
private int targetAction = DnDConstants.ACTION_NONE;
75
/* The set of drop actions supported by the drag source. */
76
private int sourceActions = DnDConstants.ACTION_NONE;
77
/* The drop action selected by the drag source based on the modifiers state
78
and the action selected by the current drop target. */
79
private int sourceAction = DnDConstants.ACTION_NONE;
80
/* The data formats supported by the drag source for the current drag
81
operation. */
82
private long[] sourceFormats = null;
83
/* The XID of the root subwindow that contains the current target. */
84
private long targetRootSubwindow = 0;
85
/* The pointer location. */
86
private int xRoot = 0;
87
private int yRoot = 0;
88
/* Keyboard modifiers state. */
89
private int eventState = 0;
90
91
/* XEmbed DnD support. We act as a proxy between source and target. */
92
private long proxyModeSourceWindow = 0;
93
94
/* The singleton instance. */
95
private static final XDragSourceContextPeer theInstance =
96
new XDragSourceContextPeer(null);
97
98
private XDragSourceContextPeer(DragGestureEvent dge) {
99
super(dge);
100
}
101
102
static XDragSourceProtocolListener getXDragSourceProtocolListener() {
103
return theInstance;
104
}
105
106
static XDragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge)
107
throws InvalidDnDOperationException {
108
theInstance.setTrigger(dge);
109
return theInstance;
110
}
111
112
protected void startDrag(Transferable transferable,
113
long[] formats, Map formatMap) {
114
Component component = getTrigger().getComponent();
115
Component c = null;
116
XWindowPeer wpeer = null;
117
118
for (c = component; c != null && !(c instanceof Window);
119
c = AWTAccessor.getComponentAccessor().getParent(c));
120
121
if (c instanceof Window) {
122
wpeer = (XWindowPeer)c.getPeer();
123
}
124
125
if (wpeer == null) {
126
throw new InvalidDnDOperationException(
127
"Cannot find top-level for the drag source component");
128
}
129
130
long xcursor = 0;
131
long rootWindow = 0;
132
long dragWindow = 0;
133
long timeStamp = 0;
134
135
/* Retrieve the X cursor for the drag operation. */
136
{
137
Cursor cursor = getCursor();
138
if (cursor != null) {
139
xcursor = XGlobalCursorManager.getCursor(cursor);
140
}
141
}
142
143
XToolkit.awtLock();
144
try {
145
if (proxyModeSourceWindow != 0) {
146
throw new InvalidDnDOperationException("Proxy drag in progress");
147
}
148
if (dndInProgress) {
149
throw new InvalidDnDOperationException("Drag in progress");
150
}
151
152
/* Determine the root window for the drag operation. */
153
{
154
long screen = XlibWrapper.XScreenNumberOfScreen(wpeer.getScreen());
155
rootWindow = XlibWrapper.RootWindow(XToolkit.getDisplay(), screen);
156
}
157
158
dragWindow = XWindow.getXAWTRootWindow().getWindow();
159
160
timeStamp = XToolkit.getCurrentServerTime();
161
162
int dropActions = getDragSourceContext().getSourceActions();
163
164
Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols();
165
while (dragProtocols.hasNext()) {
166
XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next();
167
try {
168
dragProtocol.initializeDrag(dropActions, transferable,
169
formatMap, formats);
170
} catch (XException xe) {
171
throw (InvalidDnDOperationException)
172
new InvalidDnDOperationException().initCause(xe);
173
}
174
}
175
176
/* Install X grabs. */
177
{
178
int status;
179
XWindowAttributes wattr = new XWindowAttributes();
180
try {
181
status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
182
rootWindow, wattr.pData);
183
184
if (status == 0) {
185
throw new InvalidDnDOperationException("XGetWindowAttributes failed");
186
}
187
188
rootEventMask = wattr.get_your_event_mask();
189
190
XlibWrapper.XSelectInput(XToolkit.getDisplay(), rootWindow,
191
rootEventMask | ROOT_EVENT_MASK);
192
} finally {
193
wattr.dispose();
194
}
195
196
XBaseWindow.ungrabInput();
197
198
status = XlibWrapper.XGrabPointer(XToolkit.getDisplay(), rootWindow,
199
0, GRAB_EVENT_MASK,
200
XConstants.GrabModeAsync,
201
XConstants.GrabModeAsync,
202
XConstants.None, xcursor, timeStamp);
203
204
if (status != XConstants.GrabSuccess) {
205
cleanup(timeStamp);
206
throwGrabFailureException("Cannot grab pointer", status);
207
return;
208
}
209
210
status = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(), rootWindow,
211
0,
212
XConstants.GrabModeAsync,
213
XConstants.GrabModeAsync,
214
timeStamp);
215
216
if (status != XConstants.GrabSuccess) {
217
cleanup(timeStamp);
218
throwGrabFailureException("Cannot grab keyboard", status);
219
return;
220
}
221
}
222
223
/* Update the global state. */
224
dndInProgress = true;
225
dragInProgress = true;
226
dragRootWindow = rootWindow;
227
sourceActions = dropActions;
228
sourceFormats = formats;
229
} finally {
230
XToolkit.awtUnlock();
231
}
232
233
/* This implementation doesn't use native context */
234
setNativeContext(0);
235
236
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable);
237
}
238
239
public long getProxyModeSourceWindow() {
240
return proxyModeSourceWindow;
241
}
242
243
private void setProxyModeSourceWindowImpl(long window) {
244
proxyModeSourceWindow = window;
245
}
246
247
public static void setProxyModeSourceWindow(long window) {
248
theInstance.setProxyModeSourceWindowImpl(window);
249
}
250
251
/**
252
* set cursor
253
*/
254
255
public void setCursor(Cursor c) throws InvalidDnDOperationException {
256
XToolkit.awtLock();
257
try {
258
super.setCursor(c);
259
} finally {
260
XToolkit.awtUnlock();
261
}
262
}
263
264
protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) {
265
assert XToolkit.isAWTLockHeldByCurrentThread();
266
267
if (c == null) {
268
return;
269
}
270
271
long xcursor = XGlobalCursorManager.getCursor(c);
272
273
if (xcursor == 0) {
274
return;
275
}
276
277
XlibWrapper.XChangeActivePointerGrab(XToolkit.getDisplay(),
278
GRAB_EVENT_MASK,
279
xcursor,
280
XConstants.CurrentTime);
281
}
282
283
protected boolean needsBogusExitBeforeDrop() {
284
return false;
285
}
286
287
private void throwGrabFailureException(String msg, int grabStatus)
288
throws InvalidDnDOperationException {
289
String msgCause = "";
290
switch (grabStatus) {
291
case XConstants.GrabNotViewable: msgCause = "not viewable"; break;
292
case XConstants.AlreadyGrabbed: msgCause = "already grabbed"; break;
293
case XConstants.GrabInvalidTime: msgCause = "invalid time"; break;
294
case XConstants.GrabFrozen: msgCause = "grab frozen"; break;
295
default: msgCause = "unknown failure"; break;
296
}
297
throw new InvalidDnDOperationException(msg + ": " + msgCause);
298
}
299
300
/**
301
* The caller must own awtLock.
302
*/
303
public void cleanup(long time) {
304
if (dndInProgress) {
305
if (dragProtocol != null) {
306
dragProtocol.sendLeaveMessage(time);
307
}
308
309
if (targetAction != DnDConstants.ACTION_NONE) {
310
dragExit(xRoot, yRoot);
311
}
312
313
dragDropFinished(false, DnDConstants.ACTION_NONE, xRoot, yRoot);
314
}
315
316
Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols();
317
while (dragProtocols.hasNext()) {
318
XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next();
319
try {
320
dragProtocol.cleanup();
321
} catch (XException xe) {
322
// Ignore the exception.
323
}
324
}
325
326
dndInProgress = false;
327
dragInProgress = false;
328
dragRootWindow = 0;
329
sourceFormats = null;
330
sourceActions = DnDConstants.ACTION_NONE;
331
sourceAction = DnDConstants.ACTION_NONE;
332
eventState = 0;
333
xRoot = 0;
334
yRoot = 0;
335
336
cleanupTargetInfo();
337
338
removeDnDGrab(time);
339
}
340
341
/**
342
* The caller must own awtLock.
343
*/
344
private void cleanupTargetInfo() {
345
targetAction = DnDConstants.ACTION_NONE;
346
dragProtocol = null;
347
targetRootSubwindow = 0;
348
}
349
350
private void removeDnDGrab(long time) {
351
assert XToolkit.isAWTLockHeldByCurrentThread();
352
353
XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), time);
354
XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), time);
355
356
/* Restore the root event mask if it was changed. */
357
if ((rootEventMask | ROOT_EVENT_MASK) != rootEventMask &&
358
dragRootWindow != 0) {
359
360
XlibWrapper.XSelectInput(XToolkit.getDisplay(),
361
dragRootWindow,
362
rootEventMask);
363
}
364
365
rootEventMask = 0;
366
dragRootWindow = 0;
367
}
368
369
private boolean processClientMessage(XClientMessageEvent xclient) {
370
if (dragProtocol != null) {
371
return dragProtocol.processClientMessage(xclient);
372
}
373
return false;
374
}
375
376
/**
377
* Updates the source action according to the specified state.
378
*
379
* @returns true if the source
380
*/
381
private boolean updateSourceAction(int state) {
382
int action = SunDragSourceContextPeer.convertModifiersToDropAction(XWindow.getModifiers(state, 0, 0),
383
sourceActions);
384
if (sourceAction == action) {
385
return false;
386
}
387
sourceAction = action;
388
return true;
389
}
390
391
/**
392
* Returns the client window under the specified root subwindow.
393
*/
394
private static long findClientWindow(long window) {
395
if (XlibUtil.isTrueToplevelWindow(window)) {
396
return window;
397
}
398
399
Set<Long> children = XlibUtil.getChildWindows(window);
400
for (Long child : children) {
401
long win = findClientWindow(child);
402
if (win != 0) {
403
return win;
404
}
405
}
406
407
return 0;
408
}
409
410
private void doUpdateTargetWindow(long subwindow, long time) {
411
long clientWindow = 0;
412
long proxyWindow = 0;
413
XDragSourceProtocol protocol = null;
414
boolean isReceiver = false;
415
416
if (subwindow != 0) {
417
clientWindow = findClientWindow(subwindow);
418
}
419
420
if (clientWindow != 0) {
421
Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols();
422
while (dragProtocols.hasNext()) {
423
XDragSourceProtocol dragProtocol = (XDragSourceProtocol)dragProtocols.next();
424
if (dragProtocol.attachTargetWindow(clientWindow, time)) {
425
protocol = dragProtocol;
426
break;
427
}
428
}
429
}
430
431
/* Update the global state. */
432
dragProtocol = protocol;
433
targetAction = DnDConstants.ACTION_NONE;
434
targetRootSubwindow = subwindow;
435
}
436
437
private void updateTargetWindow(XMotionEvent xmotion) {
438
assert XToolkit.isAWTLockHeldByCurrentThread();
439
440
int x = xmotion.get_x_root();
441
int y = xmotion.get_y_root();
442
long time = xmotion.get_time();
443
long subwindow = xmotion.get_subwindow();
444
445
/*
446
* If this event had occurred before the pointer was grabbed,
447
* query the server for the current root subwindow.
448
*/
449
if (xmotion.get_window() != xmotion.get_root()) {
450
XlibWrapper.XQueryPointer(XToolkit.getDisplay(),
451
xmotion.get_root(),
452
XlibWrapper.larg1, // root
453
XlibWrapper.larg2, // subwindow
454
XlibWrapper.larg3, // x_root
455
XlibWrapper.larg4, // y_root
456
XlibWrapper.larg5, // x
457
XlibWrapper.larg6, // y
458
XlibWrapper.larg7); // modifiers
459
subwindow = Native.getLong(XlibWrapper.larg2);
460
}
461
462
if (targetRootSubwindow != subwindow) {
463
if (dragProtocol != null) {
464
dragProtocol.sendLeaveMessage(time);
465
466
/*
467
* Neither Motif DnD nor XDnD provide a mean for the target
468
* to notify the source that the pointer exits the drop site
469
* that occupies the whole top level.
470
* We detect this situation and post dragExit.
471
*/
472
if (targetAction != DnDConstants.ACTION_NONE) {
473
dragExit(x, y);
474
}
475
}
476
477
/* Update the global state. */
478
doUpdateTargetWindow(subwindow, time);
479
480
if (dragProtocol != null) {
481
dragProtocol.sendEnterMessage(sourceFormats,
482
sourceAction,
483
sourceActions,
484
time);
485
}
486
}
487
}
488
489
/*
490
* DO NOT USE is_hint field of xmotion since it could not be set when we
491
* convert XKeyEvent or XButtonRelease to XMotionEvent.
492
*/
493
private void processMouseMove(XMotionEvent xmotion) {
494
if (!dragInProgress) {
495
return;
496
}
497
if (xRoot != xmotion.get_x_root() || yRoot != xmotion.get_y_root()) {
498
xRoot = xmotion.get_x_root();
499
yRoot = xmotion.get_y_root();
500
501
postDragSourceDragEvent(targetAction,
502
XWindow.getModifiers(xmotion.get_state(),0,0),
503
xRoot, yRoot, DISPATCH_MOUSE_MOVED);
504
}
505
506
if (eventState != xmotion.get_state()) {
507
if (updateSourceAction(xmotion.get_state()) && dragProtocol != null) {
508
postDragSourceDragEvent(targetAction,
509
XWindow.getModifiers(xmotion.get_state(),0,0),
510
xRoot, yRoot, DISPATCH_CHANGED);
511
}
512
eventState = xmotion.get_state();
513
}
514
515
updateTargetWindow(xmotion);
516
517
if (dragProtocol != null) {
518
dragProtocol.sendMoveMessage(xmotion.get_x_root(),
519
xmotion.get_y_root(),
520
sourceAction, sourceActions,
521
xmotion.get_time());
522
}
523
}
524
525
private void processDrop(XButtonEvent xbutton) {
526
try {
527
dragProtocol.initiateDrop(xbutton.get_x_root(),
528
xbutton.get_y_root(),
529
sourceAction, sourceActions,
530
xbutton.get_time());
531
} catch (XException e) {
532
cleanup(xbutton.get_time());
533
}
534
}
535
536
private boolean processProxyModeEvent(XEvent ev) {
537
if (getProxyModeSourceWindow() == 0) {
538
return false;
539
}
540
541
if (ev.get_type() != (int)XConstants.ClientMessage) {
542
return false;
543
}
544
545
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
546
logger.finest(" proxyModeSourceWindow=" +
547
getProxyModeSourceWindow() +
548
" ev=" + ev);
549
}
550
551
XClientMessageEvent xclient = ev.get_xclient();
552
553
Iterator dragProtocols = XDragAndDropProtocols.getDragSourceProtocols();
554
while (dragProtocols.hasNext()) {
555
XDragSourceProtocol dragProtocol =
556
(XDragSourceProtocol)dragProtocols.next();
557
if (dragProtocol.processProxyModeEvent(xclient,
558
getProxyModeSourceWindow())) {
559
return true;
560
}
561
}
562
563
return false;
564
}
565
566
/**
567
* The caller must own awtLock.
568
*
569
* @returns true if the even was processed and shouldn't be passed along.
570
*/
571
private boolean doProcessEvent(XEvent ev) {
572
assert XToolkit.isAWTLockHeldByCurrentThread();
573
574
if (processProxyModeEvent(ev)) {
575
return true;
576
}
577
578
if (!dndInProgress) {
579
return false;
580
}
581
582
switch (ev.get_type()) {
583
case XConstants.ClientMessage: {
584
XClientMessageEvent xclient = ev.get_xclient();
585
return processClientMessage(xclient);
586
}
587
case XConstants.DestroyNotify: {
588
XDestroyWindowEvent xde = ev.get_xdestroywindow();
589
590
/* Target crashed during drop processing - cleanup. */
591
if (!dragInProgress &&
592
dragProtocol != null &&
593
xde.get_window() == dragProtocol.getTargetWindow()) {
594
cleanup(XConstants.CurrentTime);
595
return true;
596
}
597
/* Pass along */
598
return false;
599
}
600
}
601
602
if (!dragInProgress) {
603
return false;
604
}
605
606
/* Process drag-only messages. */
607
switch (ev.get_type()) {
608
case XConstants.KeyRelease:
609
case XConstants.KeyPress: {
610
XKeyEvent xkey = ev.get_xkey();
611
long keysym = XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(),
612
xkey.get_keycode(), 0);
613
switch ((int)keysym) {
614
case (int)XKeySymConstants.XK_Escape: {
615
if (ev.get_type() == (int)XConstants.KeyRelease) {
616
cleanup(xkey.get_time());
617
}
618
break;
619
}
620
case (int)XKeySymConstants.XK_Control_R:
621
case (int)XKeySymConstants.XK_Control_L:
622
case (int)XKeySymConstants.XK_Shift_R:
623
case (int)XKeySymConstants.XK_Shift_L: {
624
XlibWrapper.XQueryPointer(XToolkit.getDisplay(),
625
xkey.get_root(),
626
XlibWrapper.larg1, // root
627
XlibWrapper.larg2, // subwindow
628
XlibWrapper.larg3, // x_root
629
XlibWrapper.larg4, // y_root
630
XlibWrapper.larg5, // x
631
XlibWrapper.larg6, // y
632
XlibWrapper.larg7); // modifiers
633
XMotionEvent xmotion = new XMotionEvent();
634
try {
635
xmotion.set_type(XConstants.MotionNotify);
636
xmotion.set_serial(xkey.get_serial());
637
xmotion.set_send_event(xkey.get_send_event());
638
xmotion.set_display(xkey.get_display());
639
xmotion.set_window(xkey.get_window());
640
xmotion.set_root(xkey.get_root());
641
xmotion.set_subwindow(xkey.get_subwindow());
642
xmotion.set_time(xkey.get_time());
643
xmotion.set_x(xkey.get_x());
644
xmotion.set_y(xkey.get_y());
645
xmotion.set_x_root(xkey.get_x_root());
646
xmotion.set_y_root(xkey.get_y_root());
647
xmotion.set_state((int)Native.getLong(XlibWrapper.larg7));
648
// we do not use this field, so it's unset for now
649
// xmotion.set_is_hint(???);
650
xmotion.set_same_screen(xkey.get_same_screen());
651
652
//It's safe to use key event as motion event since we use only their common fields.
653
processMouseMove(xmotion);
654
} finally {
655
xmotion.dispose();
656
}
657
break;
658
}
659
}
660
return true;
661
}
662
case XConstants.ButtonPress:
663
return true;
664
case XConstants.MotionNotify:
665
processMouseMove(ev.get_xmotion());
666
return true;
667
case XConstants.ButtonRelease: {
668
XButtonEvent xbutton = ev.get_xbutton();
669
/*
670
* Ignore the buttons above 20 due to the bit limit for
671
* InputEvent.BUTTON_DOWN_MASK.
672
* One more bit is reserved for FIRST_HIGH_BIT.
673
*/
674
if (xbutton.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
675
return true;
676
}
677
678
/*
679
* On some X servers it could happen that ButtonRelease coordinates
680
* differ from the latest MotionNotify coordinates, so we need to
681
* process it as a mouse motion.
682
*/
683
XMotionEvent xmotion = new XMotionEvent();
684
try {
685
xmotion.set_type(XConstants.MotionNotify);
686
xmotion.set_serial(xbutton.get_serial());
687
xmotion.set_send_event(xbutton.get_send_event());
688
xmotion.set_display(xbutton.get_display());
689
xmotion.set_window(xbutton.get_window());
690
xmotion.set_root(xbutton.get_root());
691
xmotion.set_subwindow(xbutton.get_subwindow());
692
xmotion.set_time(xbutton.get_time());
693
xmotion.set_x(xbutton.get_x());
694
xmotion.set_y(xbutton.get_y());
695
xmotion.set_x_root(xbutton.get_x_root());
696
xmotion.set_y_root(xbutton.get_y_root());
697
xmotion.set_state(xbutton.get_state());
698
// we do not use this field, so it's unset for now
699
// xmotion.set_is_hint(???);
700
xmotion.set_same_screen(xbutton.get_same_screen());
701
702
//It's safe to use key event as motion event since we use only their common fields.
703
processMouseMove(xmotion);
704
} finally {
705
xmotion.dispose();
706
}
707
if (xbutton.get_button() == XConstants.buttons[0]
708
|| xbutton.get_button() == XConstants.buttons[1]) {
709
// drag is initiated with Button1 or Button2 pressed and
710
// ended on release of either of these buttons (as the same
711
// behavior was with our old Motif DnD-based implementation)
712
removeDnDGrab(xbutton.get_time());
713
dragInProgress = false;
714
if (dragProtocol != null && targetAction != DnDConstants.ACTION_NONE) {
715
/*
716
* ACTION_NONE indicates that either the drop target rejects the
717
* drop or it haven't responded yet. The latter could happen in
718
* case of fast drag, slow target-server connection or slow
719
* drag notifications processing on the target side.
720
*/
721
processDrop(xbutton);
722
} else {
723
cleanup(xbutton.get_time());
724
}
725
}
726
return true;
727
}
728
}
729
730
return false;
731
}
732
733
static boolean processEvent(XEvent ev) {
734
XToolkit.awtLock();
735
try {
736
try {
737
return theInstance.doProcessEvent(ev);
738
} catch (XException e) {
739
e.printStackTrace();
740
return false;
741
}
742
} finally {
743
XToolkit.awtUnlock();
744
}
745
}
746
747
/* XDragSourceProtocolListener implementation */
748
749
public void handleDragReply(int action) {
750
// NOTE: we have to use the current pointer location, since
751
// the target didn't specify the coordinates for the reply.
752
handleDragReply(action, xRoot, yRoot);
753
}
754
755
public void handleDragReply(int action, int x, int y) {
756
// NOTE: we have to use the current modifiers state, since
757
// the target didn't specify the modifiers state for the reply.
758
handleDragReply(action, xRoot, yRoot, XWindow.getModifiers(eventState,0,0));
759
}
760
761
public void handleDragReply(int action, int x, int y, int modifiers) {
762
if (action == DnDConstants.ACTION_NONE &&
763
targetAction != DnDConstants.ACTION_NONE) {
764
dragExit(x, y);
765
} else if (action != DnDConstants.ACTION_NONE) {
766
int type = 0;
767
768
if (targetAction == DnDConstants.ACTION_NONE) {
769
type = SunDragSourceContextPeer.DISPATCH_ENTER;
770
} else {
771
type = SunDragSourceContextPeer.DISPATCH_MOTION;
772
}
773
774
// Note that we use the modifiers state a
775
postDragSourceDragEvent(action, modifiers, x, y, type);
776
}
777
778
targetAction = action;
779
}
780
781
public void handleDragFinished() {
782
/* Assume that the drop was successful. */
783
handleDragFinished(true);
784
}
785
786
public void handleDragFinished(boolean success) {
787
/* Assume that the performed drop action is the latest drop action
788
accepted by the drop target. */
789
handleDragFinished(true, targetAction);
790
}
791
792
public void handleDragFinished(boolean success, int action) {
793
// NOTE: we have to use the current pointer location, since
794
// the target didn't specify the coordinates for the reply.
795
handleDragFinished(success, action, xRoot, yRoot);
796
}
797
798
public void handleDragFinished(boolean success, int action, int x, int y) {
799
dragDropFinished(success, action, x, y);
800
801
dndInProgress = false;
802
cleanup(XConstants.CurrentTime);
803
}
804
}
805
806