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