1 /*
2  * Copyright (c) 2003, 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.Toolkit;
29 import java.awt.Component;
30 
31 import java.awt.Point;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DragSource;
34 import java.awt.dnd.MouseDragGestureRecognizer;
35 import java.awt.dnd.DragGestureListener;
36 
37 import java.awt.event.InputEvent;
38 import java.awt.event.MouseEvent;
39 
40 import sun.awt.dnd.SunDragSourceContextPeer;
41 
42 /**
43  * <p>
44  * This subclass of MouseDragGestureRecognizer defines a DragGestureRecognizer
45  * for Mouse based gestures on OSF/Motif.
46  * </p>
47  *
48  * @author Laurence P. G. Cable
49  *
50  * @see java.awt.dnd.DragGestureListener
51  * @see java.awt.dnd.DragGestureEvent
52  * @see java.awt.dnd.DragSource
53  */
54 
55 class XMouseDragGestureRecognizer extends MouseDragGestureRecognizer {
56 
57     private static final long serialVersionUID = -841711780352520383L;
58 
59     /*
60      * constant for number of pixels hysterisis before drag is determined
61      * to have started
62      */
63 
64     protected static int motionThreshold;
65 
66 
67     protected static final int ButtonMask = InputEvent.BUTTON1_DOWN_MASK |
68                                             InputEvent.BUTTON2_DOWN_MASK |
69                                             InputEvent.BUTTON3_DOWN_MASK;
70 
71     /**
72      * construct a new XMouseDragGestureRecognizer
73      *
74      * @param ds  The DragSource for the Component c
75      * @param c   The Component to observe
76      * @param act The actions permitted for this Drag
77      * @param dgl The DragGestureRecognizer to notify when a gesture is detected
78      *
79      */
80 
XMouseDragGestureRecognizer(DragSource ds, Component c, int act, DragGestureListener dgl)81     protected XMouseDragGestureRecognizer(DragSource ds, Component c, int act, DragGestureListener dgl) {
82         super(ds, c, act, dgl);
83     }
84 
85     /**
86      * construct a new XMouseDragGestureRecognizer
87      *
88      * @param ds  The DragSource for the Component c
89      * @param c   The Component to observe
90      * @param act The actions permitted for this Drag
91      */
92 
XMouseDragGestureRecognizer(DragSource ds, Component c, int act)93     protected XMouseDragGestureRecognizer(DragSource ds, Component c, int act) {
94         this(ds, c, act, null);
95     }
96 
97     /**
98      * construct a new XMouseDragGestureRecognizer
99      *
100      * @param ds  The DragSource for the Component c
101      * @param c   The Component to observe
102      */
103 
XMouseDragGestureRecognizer(DragSource ds, Component c)104     protected XMouseDragGestureRecognizer(DragSource ds, Component c) {
105         this(ds, c, DnDConstants.ACTION_NONE);
106     }
107 
108     /**
109      * construct a new XMouseDragGestureRecognizer
110      *
111      * @param ds  The DragSource for the Component c
112      */
113 
XMouseDragGestureRecognizer(DragSource ds)114     protected XMouseDragGestureRecognizer(DragSource ds) {
115         this(ds, null);
116     }
117 
118     /**
119      * determine the drop action from the event
120      */
121 
mapDragOperationFromModifiers(MouseEvent e)122     protected int mapDragOperationFromModifiers(MouseEvent e) {
123         int mods = e.getModifiersEx();
124         int btns = mods & ButtonMask;
125 
126         // Do not allow right mouse button drag since Motif DnD does not
127         // terminate drag operation on right mouse button release.
128         if (!(btns == InputEvent.BUTTON1_DOWN_MASK ||
129               btns == InputEvent.BUTTON2_DOWN_MASK)) {
130             return DnDConstants.ACTION_NONE;
131         }
132 
133         return
134             SunDragSourceContextPeer.convertModifiersToDropAction(mods,
135                                                                   getSourceActions());
136     }
137 
138     /**
139      * Invoked when the mouse has been clicked on a component.
140      */
141 
mouseClicked(MouseEvent e)142     public void mouseClicked(MouseEvent e) {
143         // do nothing
144     }
145 
146     /**
147      * Invoked when a mouse button has been pressed on a component.
148      */
149 
mousePressed(MouseEvent e)150     public void mousePressed(MouseEvent e) {
151         events.clear();
152 
153         if (mapDragOperationFromModifiers(e) != DnDConstants.ACTION_NONE) {
154             try {
155                 motionThreshold = DragSource.getDragThreshold();
156             } catch (Exception exc) {
157                 motionThreshold = 5;
158             }
159             appendEvent(e);
160         }
161     }
162 
163     /**
164      * Invoked when a mouse button has been released on a component.
165      */
166 
mouseReleased(MouseEvent e)167     public void mouseReleased(MouseEvent e) {
168         events.clear();
169     }
170 
171     /**
172      * Invoked when the mouse enters a component.
173      */
174 
mouseEntered(MouseEvent e)175     public void mouseEntered(MouseEvent e) {
176         events.clear();
177     }
178 
179     /**
180      * Invoked when the mouse exits a component.
181      */
182 
mouseExited(MouseEvent e)183     public void mouseExited(MouseEvent e) {
184         if (!events.isEmpty()) { // gesture pending
185             int dragAction = mapDragOperationFromModifiers(e);
186 
187             if (dragAction == DnDConstants.ACTION_NONE) {
188                 events.clear();
189             }
190         }
191     }
192 
193     /**
194      * Invoked when a mouse button is pressed on a component.
195      */
196 
mouseDragged(MouseEvent e)197     public void mouseDragged(MouseEvent e) {
198         if (!events.isEmpty()) { // gesture pending
199             int dop = mapDragOperationFromModifiers(e);
200 
201 
202             if (dop == DnDConstants.ACTION_NONE) {
203                 return;
204             }
205 
206             MouseEvent trigger = (MouseEvent)events.get(0);
207 
208             Point      origin  = trigger.getPoint();
209             Point      current = e.getPoint();
210 
211             int        dx      = Math.abs(origin.x - current.x);
212             int        dy      = Math.abs(origin.y - current.y);
213 
214             if (dx > motionThreshold || dy > motionThreshold) {
215                 fireDragGestureRecognized(dop, ((MouseEvent)getTriggerEvent()).getPoint());
216             } else
217                 appendEvent(e);
218         }
219     }
220 
221     /**
222      * Invoked when the mouse button has been moved on a component
223      * (with no buttons no down).
224      */
225 
mouseMoved(MouseEvent e)226     public void mouseMoved(MouseEvent e) {
227         // do nothing
228     }
229 }
230