001: /*
002: * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.motif;
027:
028: import java.awt.Component;
029: import java.awt.peer.ComponentPeer;
030:
031: import sun.awt.AppContext;
032: import sun.awt.SunToolkit;
033:
034: import sun.awt.dnd.SunDropTargetContextPeer;
035: import sun.awt.dnd.SunDropTargetEvent;
036:
037: /**
038: * The X11DropTargetContextPeer class is the class responsible for handling
039: * the interaction between the XDnD/Motif DnD subsystem and Java drop targets.
040: *
041: * @since 1.5
042: */
043: final class X11DropTargetContextPeer extends SunDropTargetContextPeer {
044:
045: /*
046: * A key to store a peer instance for an AppContext.
047: */
048: private static final Object DTCP_KEY = "DropTargetContextPeer";
049:
050: private X11DropTargetContextPeer() {
051: }
052:
053: public static X11DropTargetContextPeer getPeer(AppContext appContext) {
054: synchronized (_globalLock) {
055: X11DropTargetContextPeer peer = (X11DropTargetContextPeer) appContext
056: .get(DTCP_KEY);
057: if (peer == null) {
058: peer = new X11DropTargetContextPeer();
059: appContext.put(DTCP_KEY, peer);
060: }
061:
062: return peer;
063: }
064: }
065:
066: /*
067: * Note:
068: * the method can be called on the toolkit thread while holding AWT_LOCK.
069: */
070: private static void postDropTargetEventToPeer(
071: final Component component, final int x, final int y,
072: final int dropAction, final int actions,
073: final long[] formats, final long nativeCtxt,
074: final int eventID) {
075:
076: AppContext appContext = SunToolkit
077: .targetToAppContext(component);
078: X11DropTargetContextPeer peer = getPeer(appContext);
079:
080: peer.postDropTargetEvent(component, x, y, dropAction, actions,
081: formats, nativeCtxt, eventID,
082: !SunDropTargetContextPeer.DISPATCH_SYNC);
083: }
084:
085: protected void eventProcessed(SunDropTargetEvent e,
086: int returnValue, boolean dispatcherDone) {
087: /* If the event was not consumed, send a response to the source. */
088: long ctxt = getNativeDragContext();
089: if (ctxt != 0) {
090: sendResponse(e.getID(), returnValue, ctxt, dispatcherDone,
091: e.isConsumed());
092: }
093: }
094:
095: protected void doDropDone(boolean success, int dropAction,
096: boolean isLocal) {
097: dropDone(getNativeDragContext(), success, dropAction);
098: }
099:
100: protected Object getNativeData(long format) {
101: return getData(getNativeDragContext(), format);
102: }
103:
104: protected void processEnterMessage(SunDropTargetEvent event) {
105: if (!processSunDropTargetEvent(event)) {
106: super .processEnterMessage(event);
107: }
108: }
109:
110: protected void processExitMessage(SunDropTargetEvent event) {
111: if (!processSunDropTargetEvent(event)) {
112: super .processExitMessage(event);
113: }
114: }
115:
116: protected void processMotionMessage(SunDropTargetEvent event,
117: boolean operationChanged) {
118: if (!processSunDropTargetEvent(event)) {
119: super .processMotionMessage(event, operationChanged);
120: }
121: }
122:
123: protected void processDropMessage(SunDropTargetEvent event) {
124: if (!processSunDropTargetEvent(event)) {
125: super .processDropMessage(event);
126: }
127: }
128:
129: // If source is an XEmbedCanvasPeer, passes the event to it for processing and
130: // return true if the event is forwarded to the XEmbed child.
131: // Otherwise, does nothing and return false.
132: private boolean processSunDropTargetEvent(SunDropTargetEvent event) {
133: Object source = event.getSource();
134:
135: if (source instanceof Component) {
136: ComponentPeer peer = ((Component) source).getPeer();
137: if (peer instanceof MEmbedCanvasPeer) {
138: MEmbedCanvasPeer mEmbedCanvasPeer = (MEmbedCanvasPeer) peer;
139: /* The native context is the pointer to the XClientMessageEvent
140: structure. */
141: long ctxt = getNativeDragContext();
142:
143: /* If the event is not consumed, pass it to the
144: MEmbedCanvasPeer for processing. */
145: if (!event.isConsumed()) {
146: // NOTE: ctxt can be zero at this point.
147: if (mEmbedCanvasPeer.processXEmbedDnDEvent(ctxt,
148: event.getID())) {
149: event.consume();
150: return true;
151: }
152: }
153: }
154: }
155:
156: return false;
157: }
158:
159: private native void sendResponse(int eventID, int returnValue,
160: long nativeCtxt, boolean dispatcherDone, boolean consumed);
161:
162: private native void dropDone(long nativeCtxt, boolean success,
163: int dropAction);
164:
165: private native Object getData(long nativeCtxt, long format);
166: }
|