0N/A/*
6447N/A * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.X11;
0N/A
0N/Aimport java.awt.Point;
0N/A
0N/Aimport java.awt.dnd.DnDConstants;
0N/A
0N/Aimport java.awt.event.MouseEvent;
0N/A
0N/Aimport java.io.IOException;
0N/A
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
0N/Aimport sun.misc.Unsafe;
0N/A
0N/A/**
0N/A * XDropTargetProtocol implementation for XDnD protocol.
0N/A *
0N/A * @since 1.5
0N/A */
0N/Aclass XDnDDropTargetProtocol extends XDropTargetProtocol {
1696N/A private static final PlatformLogger logger =
1696N/A PlatformLogger.getLogger("sun.awt.X11.xembed.xdnd.XDnDDropTargetProtocol");
0N/A
0N/A private static final Unsafe unsafe = XlibWrapper.unsafe;
0N/A
0N/A private long sourceWindow = 0;
0N/A private long sourceWindowMask = 0;
0N/A private int sourceProtocolVersion = 0;
0N/A private int sourceActions = DnDConstants.ACTION_NONE;
0N/A private long[] sourceFormats = null;
0N/A private boolean trackSourceActions = false;
0N/A private int userAction = DnDConstants.ACTION_NONE;
0N/A private int sourceX = 0;
0N/A private int sourceY = 0;
0N/A private XWindow targetXWindow = null;
0N/A
0N/A // XEmbed stuff.
0N/A private long prevCtxt = 0;
0N/A private boolean overXEmbedClient = false;
0N/A
0N/A protected XDnDDropTargetProtocol(XDropTargetProtocolListener listener) {
0N/A super(listener);
0N/A }
0N/A
0N/A /**
0N/A * Creates an instance associated with the specified listener.
0N/A *
0N/A * @throws NullPointerException if listener is <code>null</code>.
0N/A */
0N/A static XDropTargetProtocol createInstance(XDropTargetProtocolListener listener) {
0N/A return new XDnDDropTargetProtocol(listener);
0N/A }
0N/A
0N/A public String getProtocolName() {
0N/A return XDragAndDropProtocols.XDnD;
0N/A }
0N/A
0N/A public void registerDropTarget(long window) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A long data = Native.allocateLongArray(1);
0N/A
0N/A try {
0N/A Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndAware.setAtomData(window, XAtom.XA_ATOM, data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndAware property");
0N/A }
0N/A } finally {
0N/A unsafe.freeMemory(data);
0N/A data = 0;
0N/A }
0N/A }
0N/A
0N/A public void unregisterDropTarget(long window) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A XDnDConstants.XA_XdndAware.DeleteProperty(window);
0N/A }
0N/A
0N/A public void registerEmbedderDropSite(long embedder) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A boolean overriden = false;
0N/A int version = 0;
0N/A long proxy = 0;
0N/A long newProxy = XDropTargetRegistry.getDnDProxyWindow();
0N/A int status = 0;
0N/A
0N/A WindowPropertyGetter wpg1 =
0N/A new WindowPropertyGetter(embedder, XDnDConstants.XA_XdndAware, 0, 1,
216N/A false, XConstants.AnyPropertyType);
0N/A
0N/A try {
1216N/A status = wpg1.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status == XConstants.Success &&
0N/A wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
0N/A
0N/A overriden = true;
0N/A version = (int)Native.getLong(wpg1.getData());
0N/A }
0N/A } finally {
0N/A wpg1.dispose();
0N/A }
0N/A
0N/A /* XdndProxy is not supported for prior to XDnD version 4 */
0N/A if (overriden && version >= 4) {
0N/A WindowPropertyGetter wpg2 =
0N/A new WindowPropertyGetter(embedder, XDnDConstants.XA_XdndProxy,
0N/A 0, 1, false, XAtom.XA_WINDOW);
0N/A
0N/A try {
1216N/A status = wpg2.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status == XConstants.Success &&
0N/A wpg2.getData() != 0 &&
0N/A wpg2.getActualType() == XAtom.XA_WINDOW) {
0N/A
0N/A proxy = Native.getLong(wpg2.getData());
0N/A }
0N/A } finally {
0N/A wpg2.dispose();
0N/A }
0N/A
0N/A if (proxy != 0) {
0N/A WindowPropertyGetter wpg3 =
0N/A new WindowPropertyGetter(proxy, XDnDConstants.XA_XdndProxy,
0N/A 0, 1, false, XAtom.XA_WINDOW);
0N/A
0N/A try {
1216N/A status = wpg3.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status != XConstants.Success ||
0N/A wpg3.getData() == 0 ||
0N/A wpg3.getActualType() != XAtom.XA_WINDOW ||
0N/A Native.getLong(wpg3.getData()) != proxy) {
0N/A
0N/A proxy = 0;
0N/A } else {
0N/A WindowPropertyGetter wpg4 =
0N/A new WindowPropertyGetter(proxy,
0N/A XDnDConstants.XA_XdndAware,
0N/A 0, 1, false,
216N/A XConstants.AnyPropertyType);
0N/A
0N/A try {
1216N/A status = wpg4.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status != XConstants.Success ||
0N/A wpg4.getData() == 0 ||
0N/A wpg4.getActualType() != XAtom.XA_ATOM) {
0N/A
0N/A proxy = 0;
0N/A }
0N/A } finally {
0N/A wpg4.dispose();
0N/A }
0N/A }
0N/A } finally {
0N/A wpg3.dispose();
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (proxy == newProxy) {
0N/A // Embedder already registered.
0N/A return;
0N/A }
0N/A
0N/A long data = Native.allocateLongArray(1);
0N/A
0N/A try {
0N/A Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
0N/A
0N/A /* The proxy window must have the XdndAware set, as XDnD protocol
0N/A prescribes to check the proxy window for XdndAware. */
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndAware.setAtomData(newProxy, XAtom.XA_ATOM,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndAware property");
0N/A }
0N/A
0N/A Native.putLong(data, 0, newProxy);
0N/A
0N/A /* The proxy window must have the XdndProxy set to point to itself.*/
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndProxy.setAtomData(newProxy, XAtom.XA_WINDOW,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndProxy property");
0N/A }
0N/A
0N/A Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndAware.setAtomData(embedder, XAtom.XA_ATOM,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndAware property");
0N/A }
0N/A
0N/A Native.putLong(data, 0, newProxy);
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndProxy.setAtomData(embedder, XAtom.XA_WINDOW,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndProxy property");
0N/A }
0N/A } finally {
0N/A unsafe.freeMemory(data);
0N/A data = 0;
0N/A }
0N/A
0N/A putEmbedderRegistryEntry(embedder, overriden, version, proxy);
0N/A }
0N/A
0N/A public void unregisterEmbedderDropSite(long embedder) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A EmbedderRegistryEntry entry = getEmbedderRegistryEntry(embedder);
0N/A
0N/A if (entry == null) {
0N/A return;
0N/A }
0N/A
0N/A if (entry.isOverriden()) {
0N/A long data = Native.allocateLongArray(1);
0N/A
0N/A try {
0N/A Native.putLong(data, 0, entry.getVersion());
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndAware.setAtomData(embedder, XAtom.XA_ATOM,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndAware property");
0N/A }
0N/A
0N/A Native.putLong(data, 0, (int)entry.getProxy());
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndProxy.setAtomData(embedder, XAtom.XA_WINDOW,
0N/A data, 1);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("Cannot write XdndProxy property");
0N/A }
0N/A } finally {
0N/A unsafe.freeMemory(data);
0N/A data = 0;
0N/A }
0N/A } else {
0N/A XDnDConstants.XA_XdndAware.DeleteProperty(embedder);
0N/A XDnDConstants.XA_XdndProxy.DeleteProperty(embedder);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Gets and stores in the registry the embedder's XDnD drop site info
0N/A * from the embedded.
0N/A */
0N/A public void registerEmbeddedDropSite(long embedded) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A boolean overriden = false;
0N/A int version = 0;
0N/A long proxy = 0;
0N/A long newProxy = XDropTargetRegistry.getDnDProxyWindow();
0N/A int status = 0;
0N/A
0N/A WindowPropertyGetter wpg1 =
0N/A new WindowPropertyGetter(embedded, XDnDConstants.XA_XdndAware, 0, 1,
216N/A false, XConstants.AnyPropertyType);
0N/A
0N/A try {
1216N/A status = wpg1.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status == XConstants.Success &&
0N/A wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
0N/A
0N/A overriden = true;
0N/A version = (int)Native.getLong(wpg1.getData());
0N/A }
0N/A } finally {
0N/A wpg1.dispose();
0N/A }
0N/A
0N/A /* XdndProxy is not supported for prior to XDnD version 4 */
0N/A if (overriden && version >= 4) {
0N/A WindowPropertyGetter wpg2 =
0N/A new WindowPropertyGetter(embedded, XDnDConstants.XA_XdndProxy,
0N/A 0, 1, false, XAtom.XA_WINDOW);
0N/A
0N/A try {
1216N/A status = wpg2.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status == XConstants.Success &&
0N/A wpg2.getData() != 0 &&
0N/A wpg2.getActualType() == XAtom.XA_WINDOW) {
0N/A
0N/A proxy = Native.getLong(wpg2.getData());
0N/A }
0N/A } finally {
0N/A wpg2.dispose();
0N/A }
0N/A
0N/A if (proxy != 0) {
0N/A WindowPropertyGetter wpg3 =
0N/A new WindowPropertyGetter(proxy, XDnDConstants.XA_XdndProxy,
0N/A 0, 1, false, XAtom.XA_WINDOW);
0N/A
0N/A try {
1216N/A status = wpg3.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status != XConstants.Success ||
0N/A wpg3.getData() == 0 ||
0N/A wpg3.getActualType() != XAtom.XA_WINDOW ||
0N/A Native.getLong(wpg3.getData()) != proxy) {
0N/A
0N/A proxy = 0;
0N/A } else {
0N/A WindowPropertyGetter wpg4 =
0N/A new WindowPropertyGetter(proxy,
0N/A XDnDConstants.XA_XdndAware,
0N/A 0, 1, false,
216N/A XConstants.AnyPropertyType);
0N/A
0N/A try {
1216N/A status = wpg4.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status != XConstants.Success ||
0N/A wpg4.getData() == 0 ||
0N/A wpg4.getActualType() != XAtom.XA_ATOM) {
0N/A
0N/A proxy = 0;
0N/A }
0N/A } finally {
0N/A wpg4.dispose();
0N/A }
0N/A }
0N/A } finally {
0N/A wpg3.dispose();
0N/A }
0N/A }
0N/A }
0N/A
0N/A putEmbedderRegistryEntry(embedded, overriden, version, proxy);
0N/A }
0N/A
0N/A public boolean isProtocolSupported(long window) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A WindowPropertyGetter wpg1 =
0N/A new WindowPropertyGetter(window, XDnDConstants.XA_XdndAware, 0, 1,
216N/A false, XConstants.AnyPropertyType);
0N/A
0N/A try {
1216N/A int status = wpg1.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
216N/A if (status == XConstants.Success &&
0N/A wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
0N/A
0N/A return true;
0N/A } else {
0N/A return false;
0N/A }
0N/A } finally {
0N/A wpg1.dispose();
0N/A }
0N/A }
0N/A
0N/A private boolean processXdndEnter(XClientMessageEvent xclient) {
0N/A long source_win = 0;
0N/A long source_win_mask = 0;
0N/A int protocol_version = 0;
0N/A int actions = DnDConstants.ACTION_NONE;
0N/A boolean track = true;
0N/A long[] formats = null;
0N/A
0N/A if (getSourceWindow() != 0) {
0N/A return false;
0N/A }
0N/A
0N/A if (!(XToolkit.windowToXWindow(xclient.get_window()) instanceof XWindow)
0N/A && getEmbedderRegistryEntry(xclient.get_window()) == null) {
0N/A return false;
0N/A }
0N/A
0N/A if (xclient.get_message_type() != XDnDConstants.XA_XdndEnter.getAtom()){
0N/A return false;
0N/A }
0N/A
0N/A protocol_version =
0N/A (int)((xclient.get_data(1) & XDnDConstants.XDND_PROTOCOL_MASK) >>
0N/A XDnDConstants.XDND_PROTOCOL_SHIFT);
0N/A
0N/A /* XDnD compliance only requires supporting version 3 and up. */
0N/A if (protocol_version < XDnDConstants.XDND_MIN_PROTOCOL_VERSION) {
0N/A return false;
0N/A }
0N/A
0N/A /* Ignore the source if the protocol version is higher than we support. */
0N/A if (protocol_version > XDnDConstants.XDND_PROTOCOL_VERSION) {
0N/A return false;
0N/A }
0N/A
0N/A source_win = xclient.get_data(0);
0N/A
0N/A /* Extract the list of supported actions. */
0N/A if (protocol_version < 2) {
0N/A /* Prior to XDnD version 2 only COPY action was supported. */
0N/A actions = DnDConstants.ACTION_COPY;
0N/A } else {
0N/A WindowPropertyGetter wpg =
0N/A new WindowPropertyGetter(source_win,
0N/A XDnDConstants.XA_XdndActionList,
0N/A 0, 0xFFFF, false,
0N/A XAtom.XA_ATOM);
0N/A try {
1216N/A wpg.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
0N/A if (wpg.getActualType() == XAtom.XA_ATOM &&
0N/A wpg.getActualFormat() == 32) {
0N/A long data = wpg.getData();
0N/A
0N/A for (int i = 0; i < wpg.getNumberOfItems(); i++) {
0N/A actions |=
0N/A XDnDConstants.getJavaActionForXDnDAction(Native.getLong(data, i));
0N/A }
0N/A } else {
0N/A /*
0N/A * According to XDnD protocol, XdndActionList is optional.
0N/A * If XdndActionList is not set we try to guess which actions are
0N/A * supported.
0N/A */
0N/A actions = DnDConstants.ACTION_COPY;
0N/A track = true;
0N/A }
0N/A } finally {
0N/A wpg.dispose();
0N/A }
0N/A }
0N/A
0N/A /* Extract the available data types. */
0N/A if ((xclient.get_data(1) & XDnDConstants.XDND_DATA_TYPES_BIT) != 0) {
0N/A WindowPropertyGetter wpg =
0N/A new WindowPropertyGetter(source_win,
0N/A XDnDConstants.XA_XdndTypeList,
0N/A 0, 0xFFFF, false,
0N/A XAtom.XA_ATOM);
0N/A try {
1216N/A wpg.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
0N/A if (wpg.getActualType() == XAtom.XA_ATOM &&
0N/A wpg.getActualFormat() == 32) {
0N/A formats = Native.toLongs(wpg.getData(),
0N/A wpg.getNumberOfItems());
0N/A } else {
0N/A formats = new long[0];
0N/A }
0N/A } finally {
0N/A wpg.dispose();
0N/A }
0N/A } else {
0N/A int countFormats = 0;
0N/A long[] formats3 = new long[3];
0N/A
0N/A for (int i = 0; i < 3; i++) {
0N/A long j;
216N/A if ((j = xclient.get_data(2 + i)) != XConstants.None) {
0N/A formats3[countFormats++] = j;
0N/A }
0N/A }
0N/A
0N/A formats = new long[countFormats];
0N/A
0N/A System.arraycopy(formats3, 0, formats, 0, countFormats);
0N/A }
0N/A
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A /*
0N/A * Select for StructureNotifyMask to receive DestroyNotify in case of source
0N/A * crash.
0N/A */
0N/A XWindowAttributes wattr = new XWindowAttributes();
0N/A try {
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
0N/A source_win, wattr.pData);
0N/A
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((status == 0) ||
6447N/A ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success))) {
0N/A throw new XException("XGetWindowAttributes failed");
0N/A }
0N/A
0N/A source_win_mask = wattr.get_your_event_mask();
0N/A } finally {
0N/A wattr.dispose();
0N/A }
0N/A
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A XlibWrapper.XSelectInput(XToolkit.getDisplay(), source_win,
0N/A source_win_mask |
216N/A XConstants.StructureNotifyMask);
0N/A
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
0N/A throw new XException("XSelectInput failed");
0N/A }
0N/A
0N/A sourceWindow = source_win;
0N/A sourceWindowMask = source_win_mask;
0N/A sourceProtocolVersion = protocol_version;
0N/A sourceActions = actions;
0N/A sourceFormats = formats;
0N/A trackSourceActions = track;
0N/A
0N/A return true;
0N/A }
0N/A
0N/A private boolean processXdndPosition(XClientMessageEvent xclient) {
216N/A long time_stamp = (int)XConstants.CurrentTime;
0N/A long xdnd_action = 0;
0N/A int java_action = DnDConstants.ACTION_NONE;
0N/A int x = 0;
0N/A int y = 0;
0N/A
0N/A /* Ignore XDnD messages from all other windows. */
0N/A if (sourceWindow != xclient.get_data(0)) {
0N/A return false;
0N/A }
0N/A
0N/A XWindow xwindow = null;
0N/A {
0N/A XBaseWindow xbasewindow = XToolkit.windowToXWindow(xclient.get_window());
0N/A if (xbasewindow instanceof XWindow) {
0N/A xwindow = (XWindow)xbasewindow;
0N/A }
0N/A }
0N/A
0N/A x = (int)(xclient.get_data(2) >> 16);
0N/A y = (int)(xclient.get_data(2) & 0xFFFF);
0N/A
0N/A if (xwindow == null) {
0N/A long receiver =
0N/A XDropTargetRegistry.getRegistry().getEmbeddedDropSite(
0N/A xclient.get_window(), x, y);
0N/A
0N/A if (receiver != 0) {
0N/A XBaseWindow xbasewindow = XToolkit.windowToXWindow(receiver);
0N/A if (xbasewindow instanceof XWindow) {
0N/A xwindow = (XWindow)xbasewindow;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (xwindow != null) {
0N/A /* Translate mouse position from root coordinates
0N/A to the target window coordinates. */
0N/A Point p = xwindow.toLocal(x, y);
0N/A x = p.x;
0N/A y = p.y;
0N/A }
0N/A
0N/A /* Time stamp - new in XDnD version 1. */
0N/A if (sourceProtocolVersion > 0) {
0N/A time_stamp = xclient.get_data(3);
0N/A }
0N/A
0N/A /* User action - new in XDnD version 2. */
0N/A if (sourceProtocolVersion > 1) {
0N/A xdnd_action = xclient.get_data(4);
0N/A } else {
0N/A /* The default action is XdndActionCopy */
0N/A xdnd_action = XDnDConstants.XA_XdndActionCopy.getAtom();
0N/A }
0N/A
0N/A java_action = XDnDConstants.getJavaActionForXDnDAction(xdnd_action);
0N/A
0N/A if (trackSourceActions) {
0N/A sourceActions |= java_action;
0N/A }
0N/A
0N/A if (xwindow == null) {
0N/A if (targetXWindow != null) {
0N/A notifyProtocolListener(targetXWindow, x, y,
0N/A DnDConstants.ACTION_NONE, xclient,
0N/A MouseEvent.MOUSE_EXITED);
0N/A }
0N/A } else {
0N/A int java_event_id = 0;
0N/A
0N/A if (targetXWindow == null) {
0N/A java_event_id = MouseEvent.MOUSE_ENTERED;
0N/A } else {
0N/A java_event_id = MouseEvent.MOUSE_DRAGGED;
0N/A }
0N/A
0N/A notifyProtocolListener(xwindow, x, y, java_action, xclient,
0N/A java_event_id);
0N/A }
0N/A
0N/A userAction = java_action;
0N/A sourceX = x;
0N/A sourceY = y;
0N/A targetXWindow = xwindow;
0N/A
0N/A return true;
0N/A }
0N/A
0N/A private boolean processXdndLeave(XClientMessageEvent xclient) {
0N/A /* Ignore XDnD messages from all other windows. */
0N/A if (sourceWindow != xclient.get_data(0)) {
0N/A return false;
0N/A }
0N/A
0N/A cleanup();
0N/A
0N/A return true;
0N/A }
0N/A
0N/A private boolean processXdndDrop(XClientMessageEvent xclient) {
0N/A /* Ignore XDnD messages from all other windows. */
0N/A if (sourceWindow != xclient.get_data(0)) {
0N/A return false;
0N/A }
0N/A
0N/A if (targetXWindow != null) {
0N/A notifyProtocolListener(targetXWindow, sourceX, sourceY, userAction,
0N/A xclient, MouseEvent.MOUSE_RELEASED);
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A public int getMessageType(XClientMessageEvent xclient) {
0N/A long messageType = xclient.get_message_type();
0N/A
0N/A if (messageType == XDnDConstants.XA_XdndEnter.getAtom()) {
0N/A return ENTER_MESSAGE;
0N/A } else if (messageType == XDnDConstants.XA_XdndPosition.getAtom()) {
0N/A return MOTION_MESSAGE;
0N/A } else if (messageType == XDnDConstants.XA_XdndLeave.getAtom()) {
0N/A return LEAVE_MESSAGE;
0N/A } else if (messageType == XDnDConstants.XA_XdndDrop.getAtom()) {
0N/A return DROP_MESSAGE;
0N/A } else {
0N/A return UNKNOWN_MESSAGE;
0N/A }
0N/A }
0N/A
0N/A protected boolean processClientMessageImpl(XClientMessageEvent xclient) {
0N/A long messageType = xclient.get_message_type();
0N/A
0N/A if (messageType == XDnDConstants.XA_XdndEnter.getAtom()) {
0N/A return processXdndEnter(xclient);
0N/A } else if (messageType == XDnDConstants.XA_XdndPosition.getAtom()) {
0N/A return processXdndPosition(xclient);
0N/A } else if (messageType == XDnDConstants.XA_XdndLeave.getAtom()) {
0N/A return processXdndLeave(xclient);
0N/A } else if (messageType == XDnDConstants.XA_XdndDrop.getAtom()) {
0N/A return processXdndDrop(xclient);
0N/A } else {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A protected void sendEnterMessageToToplevel(long toplevel,
0N/A XClientMessageEvent xclient) {
0N/A /* flags */
0N/A long data1 = sourceProtocolVersion << XDnDConstants.XDND_PROTOCOL_SHIFT;
0N/A if (sourceFormats != null && sourceFormats.length > 3) {
0N/A data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
0N/A }
0N/A long data2 = sourceFormats.length > 0 ? sourceFormats[0] : 0;
0N/A long data3 = sourceFormats.length > 1 ? sourceFormats[1] : 0;
0N/A long data4 = sourceFormats.length > 2 ? sourceFormats[2] : 0;
0N/A sendEnterMessageToToplevelImpl(toplevel, xclient.get_data(0),
0N/A data1, data2, data3, data4);
0N/A
0N/A }
0N/A
0N/A private void sendEnterMessageToToplevelImpl(long toplevel,
0N/A long sourceWindow,
0N/A long data1, long data2,
0N/A long data3, long data4) {
0N/A XClientMessageEvent enter = new XClientMessageEvent();
0N/A try {
216N/A enter.set_type((int)XConstants.ClientMessage);
0N/A enter.set_window(toplevel);
0N/A enter.set_format(32);
0N/A enter.set_message_type(XDnDConstants.XA_XdndEnter.getAtom());
0N/A /* XID of the source window */
0N/A enter.set_data(0, sourceWindow);
0N/A enter.set_data(1, data1);
0N/A enter.set_data(2, data2);
0N/A enter.set_data(3, data3);
0N/A enter.set_data(4, data4);
0N/A
0N/A forwardClientMessageToToplevel(toplevel, enter);
0N/A } finally {
0N/A enter.dispose();
0N/A }
0N/A }
0N/A
0N/A protected void sendLeaveMessageToToplevel(long toplevel,
0N/A XClientMessageEvent xclient) {
0N/A sendLeaveMessageToToplevelImpl(toplevel, xclient.get_data(0));
0N/A }
0N/A
0N/A protected void sendLeaveMessageToToplevelImpl(long toplevel,
0N/A long sourceWindow) {
0N/A XClientMessageEvent leave = new XClientMessageEvent();
0N/A try {
216N/A leave.set_type((int)XConstants.ClientMessage);
0N/A leave.set_window(toplevel);
0N/A leave.set_format(32);
0N/A leave.set_message_type(XDnDConstants.XA_XdndLeave.getAtom());
0N/A /* XID of the source window */
0N/A leave.set_data(0, sourceWindow);
0N/A /* flags */
0N/A leave.set_data(1, 0);
0N/A
0N/A forwardClientMessageToToplevel(toplevel, leave);
0N/A } finally {
0N/A leave.dispose();
0N/A }
0N/A }
0N/A
0N/A public boolean sendResponse(long ctxt, int eventID, int action) {
0N/A XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
0N/A
0N/A if (xclient.get_message_type() !=
0N/A XDnDConstants.XA_XdndPosition.getAtom()) {
0N/A
0N/A return false;
0N/A }
0N/A
0N/A if (eventID == MouseEvent.MOUSE_EXITED) {
0N/A action = DnDConstants.ACTION_NONE;
0N/A }
0N/A
0N/A XClientMessageEvent msg = new XClientMessageEvent();
0N/A try {
216N/A msg.set_type((int)XConstants.ClientMessage);
0N/A msg.set_window(xclient.get_data(0));
0N/A msg.set_format(32);
0N/A msg.set_message_type(XDnDConstants.XA_XdndStatus.getAtom());
0N/A /* target window */
0N/A msg.set_data(0, xclient.get_window());
0N/A /* flags */
0N/A long flags = 0;
0N/A if (action != DnDConstants.ACTION_NONE) {
0N/A flags |= XDnDConstants.XDND_ACCEPT_DROP_FLAG;
0N/A }
0N/A msg.set_data(1, flags);
0N/A /* specify an empty rectangle */
0N/A msg.set_data(2, 0); /* x, y */
0N/A msg.set_data(3, 0); /* w, h */
0N/A /* action accepted by the target */
0N/A msg.set_data(4, XDnDConstants.getXDnDActionForJavaAction(action));
0N/A
0N/A XToolkit.awtLock();
0N/A try {
0N/A XlibWrapper.XSendEvent(XToolkit.getDisplay(),
0N/A xclient.get_data(0),
216N/A false, XConstants.NoEventMask,
0N/A msg.pData);
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A } finally {
0N/A msg.dispose();
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A public Object getData(long ctxt, long format)
0N/A throws IllegalArgumentException, IOException {
0N/A XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
0N/A long message_type = xclient.get_message_type();
216N/A long time_stamp = XConstants.CurrentTime;
0N/A
0N/A // NOTE: we assume that the source supports at least version 1, so we
0N/A // can use the time stamp
0N/A if (message_type == XDnDConstants.XA_XdndPosition.getAtom()) {
0N/A // X server time is an unsigned 32-bit number!
0N/A time_stamp = xclient.get_data(3) & 0xFFFFFFFFL;
0N/A } else if (message_type == XDnDConstants.XA_XdndDrop.getAtom()) {
0N/A // X server time is an unsigned 32-bit number!
0N/A time_stamp = xclient.get_data(2) & 0xFFFFFFFFL;
0N/A } else {
0N/A throw new IllegalArgumentException();
0N/A }
0N/A
0N/A return XDnDConstants.XDnDSelection.getData(format, time_stamp);
0N/A }
0N/A
0N/A public boolean sendDropDone(long ctxt, boolean success, int dropAction) {
0N/A XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
0N/A
0N/A if (xclient.get_message_type() !=
0N/A XDnDConstants.XA_XdndDrop.getAtom()) {
0N/A return false;
0N/A }
0N/A
0N/A /*
0N/A * The XDnD protocol recommends that the target requests the special
0N/A * target DELETE in case if the drop action is XdndActionMove.
0N/A */
0N/A if (dropAction == DnDConstants.ACTION_MOVE && success) {
0N/A
0N/A long time_stamp = xclient.get_data(2);
0N/A long xdndSelectionAtom =
0N/A XDnDConstants.XDnDSelection.getSelectionAtom().getAtom();
0N/A
0N/A XToolkit.awtLock();
0N/A try {
0N/A XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
0N/A xdndSelectionAtom,
0N/A XAtom.get("DELETE").getAtom(),
0N/A XAtom.get("XAWT_SELECTION").getAtom(),
0N/A XWindow.getXAWTRootWindow().getWindow(),
0N/A time_stamp);
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A XClientMessageEvent msg = new XClientMessageEvent();
0N/A try {
216N/A msg.set_type((int)XConstants.ClientMessage);
0N/A msg.set_window(xclient.get_data(0));
0N/A msg.set_format(32);
0N/A msg.set_message_type(XDnDConstants.XA_XdndFinished.getAtom());
0N/A msg.set_data(0, xclient.get_window()); /* target window */
0N/A msg.set_data(1, 0); /* flags */
0N/A /* specify an empty rectangle */
0N/A msg.set_data(2, 0);
0N/A if (sourceProtocolVersion >= 5) {
0N/A if (success) {
0N/A msg.set_data(1, XDnDConstants.XDND_ACCEPT_DROP_FLAG);
0N/A }
0N/A /* action performed by the target */
0N/A msg.set_data(2, XDnDConstants.getXDnDActionForJavaAction(dropAction));
0N/A }
0N/A msg.set_data(3, 0);
0N/A msg.set_data(4, 0);
0N/A
0N/A XToolkit.awtLock();
0N/A try {
0N/A XlibWrapper.XSendEvent(XToolkit.getDisplay(),
0N/A xclient.get_data(0),
216N/A false, XConstants.NoEventMask,
0N/A msg.pData);
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A } finally {
0N/A msg.dispose();
0N/A }
0N/A
0N/A /*
0N/A * Flush the buffer to guarantee that the drop completion event is sent
0N/A * to the source before the method returns.
0N/A */
0N/A XToolkit.awtLock();
0N/A try {
0N/A XlibWrapper.XFlush(XToolkit.getDisplay());
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A
0N/A /* Trick to prevent cleanup() from posting dragExit */
0N/A targetXWindow = null;
0N/A
0N/A /* Cannot do cleanup before the drop finishes as we may need
0N/A source protocol version to send drop finished message. */
0N/A cleanup();
0N/A return true;
0N/A }
0N/A
0N/A public final long getSourceWindow() {
0N/A return sourceWindow;
0N/A }
0N/A
0N/A /**
0N/A * Reset the state of the object.
0N/A */
0N/A public void cleanup() {
0N/A // Clear the reference to this protocol.
0N/A XDropTargetEventProcessor.reset();
0N/A
0N/A if (targetXWindow != null) {
0N/A notifyProtocolListener(targetXWindow, 0, 0,
0N/A DnDConstants.ACTION_NONE, null,
0N/A MouseEvent.MOUSE_EXITED);
0N/A }
0N/A
0N/A if (sourceWindow != 0) {
0N/A XToolkit.awtLock();
0N/A try {
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A XlibWrapper.XSelectInput(XToolkit.getDisplay(), sourceWindow,
0N/A sourceWindowMask);
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A sourceWindow = 0;
0N/A sourceWindowMask = 0;
0N/A sourceProtocolVersion = 0;
0N/A sourceActions = DnDConstants.ACTION_NONE;
0N/A sourceFormats = null;
0N/A trackSourceActions = false;
0N/A userAction = DnDConstants.ACTION_NONE;
0N/A sourceX = 0;
0N/A sourceY = 0;
0N/A targetXWindow = null;
0N/A }
0N/A
0N/A public boolean isDragOverComponent() {
0N/A return targetXWindow != null;
0N/A }
0N/A
0N/A public void adjustEventForForwarding(XClientMessageEvent xclient,
0N/A EmbedderRegistryEntry entry) {
0N/A /* Adjust the event to match the XDnD protocol version. */
0N/A int version = entry.getVersion();
0N/A if (xclient.get_message_type() == XDnDConstants.XA_XdndEnter.getAtom()) {
0N/A int min_version = sourceProtocolVersion < version ?
0N/A sourceProtocolVersion : version;
0N/A long data1 = min_version << XDnDConstants.XDND_PROTOCOL_SHIFT;
0N/A if (sourceFormats != null && sourceFormats.length > 3) {
0N/A data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
0N/A }
1696N/A if (logger.isLoggable(PlatformLogger.FINEST)) {
0N/A logger.finest(" "
0N/A + " entryVersion=" + version
0N/A + " sourceProtocolVersion=" +
0N/A sourceProtocolVersion
0N/A + " sourceFormats.length=" +
0N/A (sourceFormats != null ? sourceFormats.length : 0));
0N/A }
0N/A xclient.set_data(1, data1);
0N/A }
0N/A }
0N/A
0N/A private void notifyProtocolListener(XWindow xwindow, int x, int y,
0N/A int dropAction,
0N/A XClientMessageEvent xclient,
0N/A int eventID) {
0N/A long nativeCtxt = 0;
0N/A
0N/A // Make a copy of the passed XClientMessageEvent structure, since
0N/A // the original structure can be freed before this
0N/A // SunDropTargetEvent is dispatched.
0N/A if (xclient != null) {
0N/A int size = new XClientMessageEvent(nativeCtxt).getSize();
0N/A
0N/A nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
0N/A
0N/A unsafe.copyMemory(xclient.pData, nativeCtxt, size);
0N/A
0N/A long data1 = sourceProtocolVersion << XDnDConstants.XDND_PROTOCOL_SHIFT;
0N/A if (sourceFormats != null && sourceFormats.length > 3) {
0N/A data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
0N/A }
0N/A // Append information from the latest XdndEnter event.
0N/A Native.putLong(nativeCtxt + size, data1);
0N/A Native.putLong(nativeCtxt + size + Native.getLongSize(),
0N/A sourceFormats.length > 0 ? sourceFormats[0] : 0);
0N/A Native.putLong(nativeCtxt + size + 2 * Native.getLongSize(),
0N/A sourceFormats.length > 1 ? sourceFormats[1] : 0);
0N/A Native.putLong(nativeCtxt + size + 3 * Native.getLongSize(),
0N/A sourceFormats.length > 2 ? sourceFormats[2] : 0);
0N/A }
0N/A
0N/A getProtocolListener().handleDropTargetNotification(xwindow, x, y,
0N/A dropAction,
0N/A sourceActions,
0N/A sourceFormats,
0N/A nativeCtxt,
0N/A eventID);
0N/A }
0N/A
0N/A /*
0N/A * The methods/fields defined below are executed/accessed only on
0N/A * the toolkit thread.
0N/A * The methods/fields defined below are executed/accessed only on the event
0N/A * dispatch thread.
0N/A */
0N/A
0N/A public boolean forwardEventToEmbedded(long embedded, long ctxt,
0N/A int eventID) {
1696N/A if (logger.isLoggable(PlatformLogger.FINEST)) {
0N/A logger.finest(" ctxt=" + ctxt +
0N/A " type=" + (ctxt != 0 ?
0N/A getMessageType(new
0N/A XClientMessageEvent(ctxt)) : 0) +
0N/A " prevCtxt=" + prevCtxt +
0N/A " prevType=" + (prevCtxt != 0 ?
0N/A getMessageType(new
0N/A XClientMessageEvent(prevCtxt)) : 0));
0N/A }
0N/A if ((ctxt == 0 ||
0N/A getMessageType(new XClientMessageEvent(ctxt)) == UNKNOWN_MESSAGE) &&
0N/A (prevCtxt == 0 ||
0N/A getMessageType(new XClientMessageEvent(prevCtxt)) == UNKNOWN_MESSAGE)) {
0N/A return false;
0N/A }
0N/A
0N/A // The size of XClientMessageEvent structure.
0N/A int size = XClientMessageEvent.getSize();
0N/A
0N/A if (ctxt != 0) {
0N/A XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
0N/A if (!overXEmbedClient) {
0N/A long data1 = Native.getLong(ctxt + size);
0N/A long data2 = Native.getLong(ctxt + size + Native.getLongSize());
0N/A long data3 = Native.getLong(ctxt + size + 2 * Native.getLongSize());
0N/A long data4 = Native.getLong(ctxt + size + 3 * Native.getLongSize());
0N/A
1696N/A if (logger.isLoggable(PlatformLogger.FINEST)) {
0N/A logger.finest(" 1 "
0N/A + " embedded=" + embedded
0N/A + " source=" + xclient.get_data(0)
0N/A + " data1=" + data1
0N/A + " data2=" + data2
0N/A + " data3=" + data3
0N/A + " data4=" + data4);
0N/A }
0N/A
0N/A // Copy XdndTypeList from source to proxy.
0N/A if ((data1 & XDnDConstants.XDND_DATA_TYPES_BIT) != 0) {
0N/A WindowPropertyGetter wpg =
0N/A new WindowPropertyGetter(xclient.get_data(0),
0N/A XDnDConstants.XA_XdndTypeList,
0N/A 0, 0xFFFF, false,
0N/A XAtom.XA_ATOM);
0N/A try {
1216N/A wpg.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A
0N/A if (wpg.getActualType() == XAtom.XA_ATOM &&
0N/A wpg.getActualFormat() == 32) {
0N/A
0N/A XToolkit.awtLock();
0N/A try {
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
0N/A XDnDConstants.XA_XdndTypeList.setAtomData(xclient.get_window(),
0N/A XAtom.XA_ATOM,
0N/A wpg.getData(),
0N/A wpg.getNumberOfItems());
6447N/A XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
0N/A
6447N/A if ((XErrorHandlerUtil.saved_error != null) &&
6447N/A (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
1696N/A if (logger.isLoggable(PlatformLogger.WARNING)) {
0N/A logger.warning("Cannot set XdndTypeList on the proxy window");
0N/A }
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A } else {
1696N/A if (logger.isLoggable(PlatformLogger.WARNING)) {
0N/A logger.warning("Cannot read XdndTypeList from the source window");
0N/A }
0N/A }
0N/A } finally {
0N/A wpg.dispose();
0N/A }
0N/A }
0N/A XDragSourceContextPeer.setProxyModeSourceWindow(xclient.get_data(0));
0N/A
0N/A sendEnterMessageToToplevelImpl(embedded, xclient.get_window(),
0N/A data1, data2, data3, data4);
0N/A overXEmbedClient = true;
0N/A }
0N/A
1696N/A if (logger.isLoggable(PlatformLogger.FINEST)) {
0N/A logger.finest(" 2 "
0N/A + " embedded=" + embedded
0N/A + " xclient=" + xclient);
0N/A }
0N/A
0N/A /* Make a copy of the original event, since we are going to modify the
0N/A event while it still can be referenced from other Java events. */
0N/A {
0N/A XClientMessageEvent copy = new XClientMessageEvent();
0N/A unsafe.copyMemory(xclient.pData, copy.pData, copy.getSize());
0N/A
0N/A copy.set_data(0, xclient.get_window());
0N/A
0N/A forwardClientMessageToToplevel(embedded, copy);
0N/A }
0N/A }
0N/A
0N/A if (eventID == MouseEvent.MOUSE_EXITED) {
0N/A if (overXEmbedClient) {
0N/A if (ctxt != 0 || prevCtxt != 0) {
0N/A // Last chance to send XdndLeave to the XEmbed client.
0N/A XClientMessageEvent xclient = ctxt != 0 ?
0N/A new XClientMessageEvent(ctxt) :
0N/A new XClientMessageEvent(prevCtxt);
0N/A sendLeaveMessageToToplevelImpl(embedded, xclient.get_window());
0N/A }
0N/A overXEmbedClient = false;
0N/A // We have to clear the proxy mode source window here,
0N/A // when the drag exits the XEmbedCanvasPeer.
0N/A // NOTE: at this point the XEmbed client still might have some
0N/A // drag notifications to process and it will send responses to
0N/A // us. With the proxy mode source window cleared we won't be
0N/A // able to forward these responses to the actual source. This is
0N/A // not a problem if the drag operation was initiated in this
0N/A // JVM. However, if it was initiated in another processes the
0N/A // responses will be lost. We bear with it for now, as it seems
0N/A // there is no other reliable point to clear.
0N/A XDragSourceContextPeer.setProxyModeSourceWindow(0);
0N/A }
0N/A }
0N/A
0N/A if (eventID == MouseEvent.MOUSE_RELEASED) {
0N/A overXEmbedClient = false;
0N/A cleanup();
0N/A }
0N/A
0N/A if (prevCtxt != 0) {
0N/A unsafe.freeMemory(prevCtxt);
0N/A prevCtxt = 0;
0N/A }
0N/A
0N/A if (ctxt != 0 && overXEmbedClient) {
0N/A prevCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
0N/A
0N/A unsafe.copyMemory(ctxt, prevCtxt, size + 4 * Native.getLongSize());
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A public boolean isXEmbedSupported() {
0N/A return true;
0N/A }
0N/A}