1 /* 2 * Copyright (c) 2003, 2008, 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.datatransfer.Transferable; 29 30 import java.awt.dnd.DnDConstants; 31 import java.awt.dnd.InvalidDnDOperationException; 32 33 import java.util.Map; 34 35 /** 36 * An abstract class for drag protocols on X11 systems. 37 * Contains protocol-independent drag source code. 38 * 39 * @since 1.5 40 */ 41 abstract class XDragSourceProtocol { 42 private final XDragSourceProtocolListener listener; 43 44 private boolean initialized = false; 45 46 private long targetWindow = 0; 47 private long targetProxyWindow = 0; 48 private int targetProtocolVersion = 0; 49 private long targetWindowMask = 0; 50 51 // Always use the XAWT root window as the drag source window. 52 static long getDragSourceWindow() { 53 return XWindow.getXAWTRootWindow().getWindow(); 54 } 55 56 protected XDragSourceProtocol(XDragSourceProtocolListener listener) { 57 if (listener == null) { 58 throw new NullPointerException("Null XDragSourceProtocolListener"); 59 } 60 this.listener = listener; 61 } 62 63 protected final XDragSourceProtocolListener getProtocolListener() { 64 return listener; 65 } 66 67 /** 68 * Returns the protocol name. The protocol name cannot be null. 69 */ 70 public abstract String getProtocolName(); 71 72 /** 73 * Initalizes a drag operation with the specified supported drop actions, 74 * contents and data formats. 75 * 76 * @param actions a bitwise mask of <code>DnDConstants</code> that represent 77 * the supported drop actions. 78 * @param contents the contents for the drag operation. 79 * @param formats an array of Atoms that represent the supported data formats. 80 * @param formats an array of Atoms that represent the supported data formats. 81 * @throws InvalidDnDOperationException if a drag operation is already 82 * initialized. 83 * @throws IllegalArgumentException if some argument has invalid value. 84 * @throws XException if some X call failed. 85 */ 86 public final void initializeDrag(int actions, Transferable contents, 87 Map formatMap, long[] formats) 88 throws InvalidDnDOperationException, 89 IllegalArgumentException, XException { 90 XToolkit.awtLock(); 91 try { 92 try { 93 if (initialized) { 94 throw new InvalidDnDOperationException("Already initialized"); 95 } 96 97 initializeDragImpl(actions, contents, formatMap, formats); 98 99 initialized = true; 100 } finally { 101 if (!initialized) { 102 cleanup(); 103 } 104 } 105 } finally { 106 XToolkit.awtUnlock(); 107 } 108 } 109 110 /* The caller must hold AWT_LOCK. */ 111 protected abstract void initializeDragImpl(int actions, 112 Transferable contents, 113 Map formatMap, long[] formats) 114 throws InvalidDnDOperationException, IllegalArgumentException, XException; 115 116 /** 117 * Terminates the current drag operation (if any) and resets the internal 118 * state of this object. 119 * 120 * @throws XException if some X call failed. 121 */ 122 public void cleanup() { 123 initialized = false; 124 cleanupTargetInfo(); 125 } 126 127 /** 128 * Clears the information on the current drop target. 129 * 130 * @throws XException if some X call failed. 131 */ 132 public void cleanupTargetInfo() { 133 targetWindow = 0; 134 targetProxyWindow = 0; 135 targetProtocolVersion = 0; 136 } 137 138 /** 139 * Processes the specified client message event. 140 * 141 * @returns true if the event was successfully processed. 142 */ 143 public abstract boolean processClientMessage(XClientMessageEvent xclient) 144 throws XException; 145 146 /* The caller must hold AWT_LOCK. */ 147 public final boolean attachTargetWindow(long window, long time) { 148 assert XToolkit.isAWTLockHeldByCurrentThread(); 149 150 TargetWindowInfo info = getTargetWindowInfo(window); 151 if (info == null) { 152 return false; 153 } else { 154 targetWindow = window; 155 targetProxyWindow = info.getProxyWindow(); 156 targetProtocolVersion = info.getProtocolVersion(); 157 return true; 158 } 159 } 160 161 /* The caller must hold AWT_LOCK. */ 162 public abstract TargetWindowInfo getTargetWindowInfo(long window); 163 164 /* The caller must hold AWT_LOCK. */ 165 public abstract void sendEnterMessage(long[] formats, int sourceAction, 166 int sourceActions, long time); 167 /* The caller must hold AWT_LOCK. */ 168 public abstract void sendMoveMessage(int xRoot, int yRoot, 169 int sourceAction, int sourceActions, 170 long time); 171 /* The caller must hold AWT_LOCK. */ 172 public abstract void sendLeaveMessage(long time); 173 174 /* The caller must hold AWT_LOCK. */ 175 protected abstract void sendDropMessage(int xRoot, int yRoot, 176 int sourceAction, int sourceActions, 177 long time); 178 179 public final void initiateDrop(int xRoot, int yRoot, 180 int sourceAction, int sourceActions, 181 long time) { 182 XWindowAttributes wattr = new XWindowAttributes(); 183 try { 184 XToolkit.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 185 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), 186 targetWindow, wattr.pData); 187 188 XToolkit.RESTORE_XERROR_HANDLER(); 189 190 if (status == 0 || 191 (XToolkit.saved_error != null && 192 XToolkit.saved_error.get_error_code() != XConstants.Success)) { 193 throw new XException("XGetWindowAttributes failed"); 194 } 195 196 targetWindowMask = wattr.get_your_event_mask(); 197 } finally { 198 wattr.dispose(); 199 } 200 201 XToolkit.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 202 XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow, 203 targetWindowMask | 204 XConstants.StructureNotifyMask); 205 206 XToolkit.RESTORE_XERROR_HANDLER(); 207 208 if (XToolkit.saved_error != null && 209 XToolkit.saved_error.get_error_code() != XConstants.Success) { 210 throw new XException("XSelectInput failed"); 211 } 212 213 sendDropMessage(xRoot, yRoot, sourceAction, sourceActions, time); 214 } 215 216 protected final void finalizeDrop() { 217 XToolkit.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 218 XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow, 219 targetWindowMask); 220 XToolkit.RESTORE_XERROR_HANDLER(); 221 } 222 223 public abstract boolean processProxyModeEvent(XClientMessageEvent xclient, 224 long sourceWindow); 225 226 protected final long getTargetWindow() { 227 return targetWindow; 228 } 229 230 protected final long getTargetProxyWindow() { 231 if (targetProxyWindow != 0) { 232 return targetProxyWindow; 233 } else { 234 return targetWindow; 235 } 236 } 237 238 protected final int getTargetProtocolVersion() { 239 return targetProtocolVersion; 240 } 241 242 public static class TargetWindowInfo { 243 private final long proxyWindow; 244 private final int protocolVersion; 245 public TargetWindowInfo(long proxy, int version) { 246 proxyWindow = proxy; 247 protocolVersion = version; 248 } 249 public long getProxyWindow() { 250 return proxyWindow; 251 } 252 public int getProtocolVersion() { 253 return protocolVersion; 254 } 255 } 256 } --- EOF ---