Path: blob/master/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceProtocol.java
41159 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt.X11;2627import java.awt.datatransfer.Transferable;28import java.awt.datatransfer.DataFlavor;2930import java.awt.dnd.DnDConstants;31import java.awt.dnd.InvalidDnDOperationException;3233import java.util.Map;3435/**36* An abstract class for drag protocols on X11 systems.37* Contains protocol-independent drag source code.38*39* @since 1.540*/41abstract class XDragSourceProtocol {42private final XDragSourceProtocolListener listener;4344private boolean initialized = false;4546private long targetWindow = 0;47private long targetProxyWindow = 0;48private int targetProtocolVersion = 0;49private long targetWindowMask = 0;5051// Always use the XAWT root window as the drag source window.52static long getDragSourceWindow() {53return XWindow.getXAWTRootWindow().getWindow();54}5556protected XDragSourceProtocol(XDragSourceProtocolListener listener) {57if (listener == null) {58throw new NullPointerException("Null XDragSourceProtocolListener");59}60this.listener = listener;61}6263protected final XDragSourceProtocolListener getProtocolListener() {64return listener;65}6667/**68* Returns the protocol name. The protocol name cannot be null.69*/70public abstract String getProtocolName();7172/**73* Initializes a drag operation with the specified supported drop actions,74* contents and data formats.75*76* @param actions a bitwise mask of {@code DnDConstants} that represent77* 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 already82* initialized.83* @throws IllegalArgumentException if some argument has invalid value.84* @throws XException if some X call failed.85*/86public final void initializeDrag(int actions, Transferable contents,87Map<Long, DataFlavor> formatMap, long[] formats)88throws InvalidDnDOperationException,89IllegalArgumentException, XException {90XToolkit.awtLock();91try {92try {93if (initialized) {94throw new InvalidDnDOperationException("Already initialized");95}9697initializeDragImpl(actions, contents, formatMap, formats);9899initialized = true;100} finally {101if (!initialized) {102cleanup();103}104}105} finally {106XToolkit.awtUnlock();107}108}109110/* The caller must hold AWT_LOCK. */111protected abstract void initializeDragImpl(int actions,112Transferable contents,113Map<Long, DataFlavor> formatMap,114long[] formats)115throws InvalidDnDOperationException, IllegalArgumentException, XException;116117/**118* Terminates the current drag operation (if any) and resets the internal119* state of this object.120*121* @throws XException if some X call failed.122*/123public void cleanup() {124initialized = false;125cleanupTargetInfo();126}127128/**129* Clears the information on the current drop target.130*131* @throws XException if some X call failed.132*/133public void cleanupTargetInfo() {134targetWindow = 0;135targetProxyWindow = 0;136targetProtocolVersion = 0;137}138139/**140* Processes the specified client message event.141*142* @return true if the event was successfully processed.143*/144public abstract boolean processClientMessage(XClientMessageEvent xclient)145throws XException;146147/* The caller must hold AWT_LOCK. */148public final boolean attachTargetWindow(long window, long time) {149assert XToolkit.isAWTLockHeldByCurrentThread();150151TargetWindowInfo info = getTargetWindowInfo(window);152if (info == null) {153return false;154} else {155targetWindow = window;156targetProxyWindow = info.getProxyWindow();157targetProtocolVersion = info.getProtocolVersion();158return true;159}160}161162/* The caller must hold AWT_LOCK. */163public abstract TargetWindowInfo getTargetWindowInfo(long window);164165/* The caller must hold AWT_LOCK. */166public abstract void sendEnterMessage(long[] formats, int sourceAction,167int sourceActions, long time);168/* The caller must hold AWT_LOCK. */169public abstract void sendMoveMessage(int xRoot, int yRoot,170int sourceAction, int sourceActions,171long time);172/* The caller must hold AWT_LOCK. */173public abstract void sendLeaveMessage(long time);174175/* The caller must hold AWT_LOCK. */176protected abstract void sendDropMessage(int xRoot, int yRoot,177int sourceAction, int sourceActions,178long time);179180public final void initiateDrop(int xRoot, int yRoot,181int sourceAction, int sourceActions,182long time) {183XWindowAttributes wattr = new XWindowAttributes();184try {185XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());186int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),187targetWindow, wattr.pData);188189XErrorHandlerUtil.RESTORE_XERROR_HANDLER();190191if ((status == 0) ||192((XErrorHandlerUtil.saved_error != null) &&193(XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success))) {194throw new XException("XGetWindowAttributes failed");195}196197targetWindowMask = wattr.get_your_event_mask();198} finally {199wattr.dispose();200}201202XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());203XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow,204targetWindowMask |205XConstants.StructureNotifyMask);206207XErrorHandlerUtil.RESTORE_XERROR_HANDLER();208209if ((XErrorHandlerUtil.saved_error != null) &&210(XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {211throw new XException("XSelectInput failed");212}213214sendDropMessage(xRoot, yRoot, sourceAction, sourceActions, time);215}216217protected final void finalizeDrop() {218XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());219XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow,220targetWindowMask);221XErrorHandlerUtil.RESTORE_XERROR_HANDLER();222}223224public abstract boolean processProxyModeEvent(XClientMessageEvent xclient,225long sourceWindow);226227protected final long getTargetWindow() {228return targetWindow;229}230231protected final long getTargetProxyWindow() {232if (targetProxyWindow != 0) {233return targetProxyWindow;234} else {235return targetWindow;236}237}238239protected final int getTargetProtocolVersion() {240return targetProtocolVersion;241}242243public static class TargetWindowInfo {244private final long proxyWindow;245private final int protocolVersion;246public TargetWindowInfo(long proxy, int version) {247proxyWindow = proxy;248protocolVersion = version;249}250public long getProxyWindow() {251return proxyWindow;252}253public int getProtocolVersion() {254return protocolVersion;255}256}257}258259260