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.util.ArrayList;
0N/Aimport java.util.Collections;
0N/Aimport java.util.HashMap;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.List;
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
0N/Aimport java.awt.Point;
0N/A
0N/A
0N/A/**
0N/A * The class responsible for registration/deregistration of drop sites.
0N/A *
0N/A * @since 1.5
0N/A */
0N/Afinal class XDropTargetRegistry {
1696N/A private static final PlatformLogger logger =
1696N/A PlatformLogger.getLogger("sun.awt.X11.xembed.xdnd.XDropTargetRegistry");
0N/A
0N/A private static final long DELAYED_REGISTRATION_PERIOD = 200;
0N/A
0N/A private static final XDropTargetRegistry theInstance =
0N/A new XDropTargetRegistry();
0N/A
0N/A private final HashMap<Long, Runnable> delayedRegistrationMap =
0N/A new HashMap<Long, Runnable>();
0N/A
0N/A private XDropTargetRegistry() {}
0N/A
0N/A static XDropTargetRegistry getRegistry() {
0N/A return theInstance;
0N/A }
0N/A
0N/A /**
0N/A * Returns the XID of the topmost window with WM_STATE set in the ancestor
0N/A * heirarchy of the specified window or 0 if none found.
0N/A */
0N/A private long getToplevelWindow(long window) {
0N/A XBaseWindow candWindow = XToolkit.windowToXWindow(window);
0N/A if (candWindow != null) {
0N/A XWindowPeer toplevel = candWindow.getToplevelXWindow();
0N/A if (toplevel != null && !(toplevel instanceof XEmbeddedFramePeer)) {
0N/A return toplevel.getWindow();
0N/A }
0N/A }
0N/A
0N/A /* Traverse the ancestor tree from window up to the root and find
0N/A the top-level client window nearest to the root. */
0N/A do {
0N/A if (XlibUtil.isTrueToplevelWindow(window)) {
0N/A return window;
0N/A }
0N/A
0N/A window = XlibUtil.getParentWindow(window);
0N/A
0N/A } while (window != 0);
0N/A
0N/A return window;
0N/A }
0N/A
0N/A static final long getDnDProxyWindow() {
0N/A return XWindow.getXAWTRootWindow().getWindow();
0N/A }
0N/A
0N/A private static final class EmbeddedDropSiteEntry {
0N/A private final long root;
0N/A private final long event_mask;
0N/A private List<XDropTargetProtocol> supportedProtocols;
0N/A private final HashSet<Long> nonXEmbedClientSites = new HashSet<Long>();
0N/A private final List<Long> sites = new ArrayList<Long>();
0N/A
0N/A public EmbeddedDropSiteEntry(long root, long event_mask,
0N/A List<XDropTargetProtocol> supportedProtocols) {
0N/A if (supportedProtocols == null) {
0N/A throw new NullPointerException("Null supportedProtocols");
0N/A }
0N/A this.root = root;
0N/A this.event_mask = event_mask;
0N/A this.supportedProtocols = supportedProtocols;
0N/A }
0N/A
0N/A public long getRoot() {
0N/A return root;
0N/A }
0N/A public long getEventMask() {
0N/A return event_mask;
0N/A }
0N/A public boolean hasNonXEmbedClientSites() {
0N/A return !nonXEmbedClientSites.isEmpty();
0N/A }
0N/A public synchronized void addSite(long window, boolean isXEmbedClient) {
0N/A Long lWindow = Long.valueOf(window);
0N/A if (!sites.contains(lWindow)) {
0N/A sites.add(lWindow);
0N/A }
0N/A if (!isXEmbedClient) {
0N/A nonXEmbedClientSites.add(lWindow);
0N/A }
0N/A }
0N/A public synchronized void removeSite(long window) {
0N/A Long lWindow = Long.valueOf(window);
0N/A sites.remove(lWindow);
0N/A nonXEmbedClientSites.remove(lWindow);
0N/A }
0N/A public void setSupportedProtocols(List<XDropTargetProtocol> list) {
0N/A supportedProtocols = list;
0N/A }
0N/A public List<XDropTargetProtocol> getSupportedProtocols() {
0N/A return supportedProtocols;
0N/A }
0N/A public boolean hasSites() {
0N/A return !sites.isEmpty();
0N/A }
0N/A public long[] getSites() {
0N/A long[] ret = new long[sites.size()];
0N/A Iterator iter = sites.iterator();
0N/A int index = 0;
0N/A while (iter.hasNext()) {
0N/A Long l = (Long)iter.next();
0N/A ret[index++] = l.longValue();
0N/A }
0N/A return ret;
0N/A }
0N/A public long getSite(int x, int y) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A Iterator<Long> iter = sites.iterator();
0N/A while (iter.hasNext()) {
0N/A Long l = iter.next();
0N/A long window = l.longValue();
0N/A
0N/A Point p = XBaseWindow.toOtherWindow(getRoot(), window, x, y);
0N/A
0N/A if (p == null) {
0N/A continue;
0N/A }
0N/A
0N/A int dest_x = p.x;
0N/A int dest_y = p.y;
0N/A if (dest_x >= 0 && dest_y >= 0) {
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 window, wattr.pData);
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 continue;
0N/A }
0N/A
216N/A if (wattr.get_map_state() != XConstants.IsUnmapped
0N/A && dest_x < wattr.get_width()
0N/A && dest_y < wattr.get_height()) {
0N/A return window;
0N/A }
0N/A } finally {
0N/A wattr.dispose();
0N/A }
0N/A }
0N/A }
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A private final HashMap<Long, EmbeddedDropSiteEntry> embeddedDropSiteRegistry =
0N/A new HashMap<Long, EmbeddedDropSiteEntry>();
0N/A
0N/A private EmbeddedDropSiteEntry registerEmbedderDropSite(long embedder) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A // The list of protocols supported by the embedder.
0N/A List<XDropTargetProtocol> embedderProtocols = new ArrayList();
0N/A
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A if (dropTargetProtocol.isProtocolSupported(embedder)) {
0N/A embedderProtocols.add(dropTargetProtocol);
0N/A }
0N/A }
0N/A
0N/A embedderProtocols = Collections.unmodifiableList(embedderProtocols);
0N/A
0N/A /* Grab server, since we are working with the window that belongs to
0N/A another client. */
0N/A XlibWrapper.XGrabServer(XToolkit.getDisplay());
0N/A try {
0N/A long root = 0;
0N/A long event_mask = 0;
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 embedder, wattr.pData);
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 event_mask = wattr.get_your_event_mask();
0N/A root = wattr.get_root();
0N/A } finally {
0N/A wattr.dispose();
0N/A }
0N/A
216N/A if ((event_mask & XConstants.PropertyChangeMask) == 0) {
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A XlibWrapper.XSelectInput(XToolkit.getDisplay(), embedder,
216N/A event_mask | XConstants.PropertyChangeMask);
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
0N/A return new EmbeddedDropSiteEntry(root, event_mask, embedderProtocols);
0N/A } finally {
0N/A XlibWrapper.XUngrabServer(XToolkit.getDisplay());
0N/A }
0N/A }
0N/A
0N/A private static final boolean XEMBED_PROTOCOLS = true;
0N/A private static final boolean NON_XEMBED_PROTOCOLS = false;
0N/A
0N/A private void registerProtocols(long embedder, boolean protocols,
0N/A List<XDropTargetProtocol> supportedProtocols) {
0N/A Iterator dropTargetProtocols = null;
0N/A
0N/A /*
0N/A * By default, we register a drop site that supports all dnd
0N/A * protocols. This approach is not appropriate in plugin
0N/A * scenario if the browser supports Motif DnD and doesn't support
0N/A * XDnD. If we forcibly set XdndAware on the browser toplevel, any drag
0N/A * source that supports both protocols and prefers XDnD will be unable
0N/A * to drop anything on the browser.
0N/A * The solution for this problem is not to register XDnD drop site
0N/A * if the browser supports only Motif DnD.
0N/A * In general, if the browser already supports some protocols, we
0N/A * register the embedded drop site only for those protocols. Otherwise
0N/A * we register the embedded drop site for all protocols.
0N/A */
0N/A if (!supportedProtocols.isEmpty()) {
0N/A dropTargetProtocols = supportedProtocols.iterator();
0N/A } else {
0N/A dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A }
0N/A
0N/A /* Grab server, since we are working with the window that belongs to
0N/A another client. */
0N/A XlibWrapper.XGrabServer(XToolkit.getDisplay());
0N/A try {
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A if ((protocols == XEMBED_PROTOCOLS) ==
0N/A dropTargetProtocol.isXEmbedSupported()) {
0N/A dropTargetProtocol.registerEmbedderDropSite(embedder);
0N/A }
0N/A }
0N/A } finally {
0N/A XlibWrapper.XUngrabServer(XToolkit.getDisplay());
0N/A }
0N/A }
0N/A
0N/A public void updateEmbedderDropSite(long embedder) {
0N/A XBaseWindow xbaseWindow = XToolkit.windowToXWindow(embedder);
0N/A // No need to update our own drop sites.
0N/A if (xbaseWindow != null) {
0N/A return;
0N/A }
0N/A
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A // The list of protocols supported by the embedder.
0N/A List<XDropTargetProtocol> embedderProtocols = new ArrayList();
0N/A
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A if (dropTargetProtocol.isProtocolSupported(embedder)) {
0N/A embedderProtocols.add(dropTargetProtocol);
0N/A }
0N/A }
0N/A
0N/A embedderProtocols = Collections.unmodifiableList(embedderProtocols);
0N/A
215N/A Long lToplevel = Long.valueOf(embedder);
0N/A boolean isXEmbedServer = false;
0N/A synchronized (this) {
0N/A EmbeddedDropSiteEntry entry =
0N/A (EmbeddedDropSiteEntry)embeddedDropSiteRegistry.get(lToplevel);
0N/A if (entry == null) {
0N/A return;
0N/A }
0N/A entry.setSupportedProtocols(embedderProtocols);
0N/A isXEmbedServer = !entry.hasNonXEmbedClientSites();
0N/A }
0N/A
0N/A /*
0N/A * By default, we register a drop site that supports all dnd
0N/A * protocols. This approach is not appropriate in plugin
0N/A * scenario if the browser supports Motif DnD and doesn't support
0N/A * XDnD. If we forcibly set XdndAware on the browser toplevel, any drag
0N/A * source that supports both protocols and prefers XDnD will be unable
0N/A * to drop anything on the browser.
0N/A * The solution for this problem is not to register XDnD drop site
0N/A * if the browser supports only Motif DnD.
0N/A * In general, if the browser already supports some protocols, we
0N/A * register the embedded drop site only for those protocols. Otherwise
0N/A * we register the embedded drop site for all protocols.
0N/A */
0N/A if (!embedderProtocols.isEmpty()) {
0N/A dropTargetProtocols = embedderProtocols.iterator();
0N/A } else {
0N/A dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A }
0N/A
0N/A /* Grab server, since we are working with the window that belongs to
0N/A another client. */
0N/A XlibWrapper.XGrabServer(XToolkit.getDisplay());
0N/A try {
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A if (!isXEmbedServer || !dropTargetProtocol.isXEmbedSupported()) {
0N/A dropTargetProtocol.registerEmbedderDropSite(embedder);
0N/A }
0N/A }
0N/A } finally {
0N/A XlibWrapper.XUngrabServer(XToolkit.getDisplay());
0N/A }
0N/A }
0N/A
0N/A private void unregisterEmbedderDropSite(long embedder,
0N/A EmbeddedDropSiteEntry entry) {
0N/A assert XToolkit.isAWTLockHeldByCurrentThread();
0N/A
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A
0N/A /* Grab server, since we are working with the window that belongs to
0N/A another client. */
0N/A XlibWrapper.XGrabServer(XToolkit.getDisplay());
0N/A try {
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A dropTargetProtocol.unregisterEmbedderDropSite(embedder);
0N/A }
0N/A
0N/A long event_mask = entry.getEventMask();
0N/A
0N/A /* Restore the original event mask for the embedder. */
216N/A if ((event_mask & XConstants.PropertyChangeMask) == 0) {
6447N/A XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
0N/A XlibWrapper.XSelectInput(XToolkit.getDisplay(), embedder,
0N/A event_mask);
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 } finally {
0N/A XlibWrapper.XUngrabServer(XToolkit.getDisplay());
0N/A }
0N/A }
0N/A
0N/A private void registerEmbeddedDropSite(long toplevel, long window) {
0N/A XBaseWindow xBaseWindow = XToolkit.windowToXWindow(window);
0N/A boolean isXEmbedClient =
0N/A (xBaseWindow instanceof XEmbeddedFramePeer) &&
0N/A ((XEmbeddedFramePeer)xBaseWindow).isXEmbedActive();
0N/A
0N/A XEmbedCanvasPeer peer = null;
0N/A {
0N/A XBaseWindow xbaseWindow = XToolkit.windowToXWindow(toplevel);
0N/A if (xbaseWindow != null) {
0N/A if (xbaseWindow instanceof XEmbedCanvasPeer) {
0N/A peer = (XEmbedCanvasPeer)xbaseWindow;
0N/A } else {
0N/A throw new UnsupportedOperationException();
0N/A }
0N/A }
0N/A }
0N/A
0N/A Long lToplevel = Long.valueOf(toplevel);
0N/A EmbeddedDropSiteEntry entry = null;
0N/A synchronized (this) {
0N/A entry =
0N/A (EmbeddedDropSiteEntry)embeddedDropSiteRegistry.get(lToplevel);
0N/A if (entry == null) {
0N/A if (peer != null) {
0N/A // Toplevel is an XEmbed server within this VM.
0N/A // Register an XEmbed drop site.
0N/A peer.setXEmbedDropTarget();
0N/A // Create a dummy entry to register the embedded site.
0N/A entry = new EmbeddedDropSiteEntry(0, 0,
0N/A Collections.<XDropTargetProtocol>emptyList());
0N/A } else {
0N/A // Foreign toplevel.
0N/A // Select for PropertyNotify events on the toplevel, so that
0N/A // we can track changes of the properties relevant to DnD
0N/A // protocols.
0N/A entry = registerEmbedderDropSite(toplevel);
0N/A // Register the toplevel with all DnD protocols that are not
0N/A // supported by XEmbed - actually setup a proxy, so that
0N/A // all DnD notifications sent to the toplevel are first
0N/A // routed to us.
0N/A registerProtocols(toplevel, NON_XEMBED_PROTOCOLS,
0N/A entry.getSupportedProtocols());
0N/A }
0N/A embeddedDropSiteRegistry.put(lToplevel, entry);
0N/A }
0N/A }
0N/A
0N/A assert entry != null;
0N/A
0N/A synchronized (entry) {
0N/A // For a foreign toplevel.
0N/A if (peer == null) {
0N/A if (!isXEmbedClient) {
0N/A // Since this is not an XEmbed client we can no longer rely
0N/A // on XEmbed to route DnD notifications even for DnD
0N/A // protocols that are supported by XEmbed.
0N/A // We rollback to the XEmbed-unfriendly solution - setup
0N/A // a proxy, so that all DnD notifications sent to the
0N/A // toplevel are first routed to us.
0N/A registerProtocols(toplevel, XEMBED_PROTOCOLS,
0N/A entry.getSupportedProtocols());
0N/A } else {
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A
0N/A // Register the embedded window as a plain drop site with
0N/A // all DnD protocols that are supported by XEmbed.
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A if (dropTargetProtocol.isXEmbedSupported()) {
0N/A dropTargetProtocol.registerEmbedderDropSite(window);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A entry.addSite(window, isXEmbedClient);
0N/A }
0N/A }
0N/A
0N/A private void unregisterEmbeddedDropSite(long toplevel, long window) {
0N/A Long lToplevel = Long.valueOf(toplevel);
0N/A EmbeddedDropSiteEntry entry = null;
0N/A synchronized (this) {
0N/A entry =
0N/A (EmbeddedDropSiteEntry)embeddedDropSiteRegistry.get(lToplevel);
0N/A if (entry == null) {
0N/A return;
0N/A }
0N/A entry.removeSite(window);
0N/A if (!entry.hasSites()) {
0N/A embeddedDropSiteRegistry.remove(lToplevel);
0N/A
0N/A XBaseWindow xbaseWindow = XToolkit.windowToXWindow(toplevel);
0N/A if (xbaseWindow != null) {
0N/A if (xbaseWindow instanceof XEmbedCanvasPeer) {
0N/A XEmbedCanvasPeer peer = (XEmbedCanvasPeer)xbaseWindow;
0N/A // Unregister an XEmbed drop site.
0N/A peer.removeXEmbedDropTarget();
0N/A } else {
0N/A throw new UnsupportedOperationException();
0N/A }
0N/A } else {
0N/A unregisterEmbedderDropSite(toplevel, entry);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Returns a drop site that is embedded in the specified embedder window and
0N/A * contains the point with the specified root coordinates.
0N/A */
0N/A public long getEmbeddedDropSite(long embedder, int x, int y) {
0N/A Long lToplevel = Long.valueOf(embedder);
0N/A EmbeddedDropSiteEntry entry =
0N/A (EmbeddedDropSiteEntry)embeddedDropSiteRegistry.get(lToplevel);
0N/A if (entry == null) {
0N/A return 0;
0N/A }
0N/A return entry.getSite(x, y);
0N/A }
0N/A
1888N/A /*
1888N/A * Note: this method should be called under AWT lock.
1888N/A */
0N/A public void registerDropSite(long window) {
1888N/A assert XToolkit.isAWTLockHeldByCurrentThread();
1888N/A
0N/A if (window == 0) {
0N/A throw new IllegalArgumentException();
0N/A }
0N/A
0N/A XDropTargetEventProcessor.activate();
0N/A
1888N/A long toplevel = getToplevelWindow(window);
0N/A
1888N/A /*
1888N/A * No window with WM_STATE property is found.
1888N/A * Since the window can be a plugin window reparented to the browser
1888N/A * toplevel, we cannot determine which window will eventually have
1888N/A * WM_STATE property set. So we schedule a timer callback that will
1888N/A * periodically attempt to find an ancestor with WM_STATE and
1888N/A * register the drop site appropriately.
1888N/A */
1888N/A if (toplevel == 0) {
1888N/A addDelayedRegistrationEntry(window);
1888N/A return;
1888N/A }
1888N/A
1888N/A if (toplevel == window) {
1888N/A Iterator dropTargetProtocols =
1888N/A XDragAndDropProtocols.getDropTargetProtocols();
1888N/A
1888N/A while (dropTargetProtocols.hasNext()) {
1888N/A XDropTargetProtocol dropTargetProtocol =
1888N/A (XDropTargetProtocol)dropTargetProtocols.next();
1888N/A dropTargetProtocol.registerDropTarget(toplevel);
0N/A }
1888N/A } else {
1888N/A registerEmbeddedDropSite(toplevel, window);
0N/A }
0N/A }
0N/A
1888N/A /*
1888N/A * Note: this method should be called under AWT lock.
1888N/A */
0N/A public void unregisterDropSite(long window) {
1888N/A assert XToolkit.isAWTLockHeldByCurrentThread();
1888N/A
0N/A if (window == 0) {
0N/A throw new IllegalArgumentException();
0N/A }
0N/A
1888N/A long toplevel = getToplevelWindow(window);
0N/A
1888N/A if (toplevel == window) {
1888N/A Iterator dropProtocols =
1888N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A
1888N/A removeDelayedRegistrationEntry(window);
1888N/A
1888N/A while (dropProtocols.hasNext()) {
1888N/A XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
1888N/A dropProtocol.unregisterDropTarget(window);
0N/A }
1888N/A } else {
1888N/A unregisterEmbeddedDropSite(toplevel, window);
0N/A }
0N/A }
0N/A
0N/A public void registerXEmbedClient(long canvasWindow, long clientWindow) {
0N/A // If the client has an associated XDnD drop site, add a drop target
0N/A // to the XEmbedCanvasPeer's target to route drag notifications to the
0N/A // client.
0N/A
0N/A XDragSourceProtocol xdndDragProtocol =
0N/A XDragAndDropProtocols.getDragSourceProtocol(XDragAndDropProtocols.XDnD);
0N/A XDragSourceProtocol.TargetWindowInfo info =
0N/A xdndDragProtocol.getTargetWindowInfo(clientWindow);
0N/A if (info != null &&
0N/A info.getProtocolVersion() >= XDnDConstants.XDND_MIN_PROTOCOL_VERSION) {
0N/A
1696N/A if (logger.isLoggable(PlatformLogger.FINE)) {
0N/A logger.fine(" XEmbed drop site will be registered for " + Long.toHexString(clientWindow));
0N/A }
0N/A registerEmbeddedDropSite(canvasWindow, clientWindow);
0N/A
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A dropTargetProtocol.registerEmbeddedDropSite(clientWindow);
0N/A }
0N/A
1696N/A if (logger.isLoggable(PlatformLogger.FINE)) {
0N/A logger.fine(" XEmbed drop site has been registered for " + Long.toHexString(clientWindow));
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void unregisterXEmbedClient(long canvasWindow, long clientWindow) {
1696N/A if (logger.isLoggable(PlatformLogger.FINE)) {
0N/A logger.fine(" XEmbed drop site will be unregistered for " + Long.toHexString(clientWindow));
0N/A }
0N/A Iterator dropTargetProtocols =
0N/A XDragAndDropProtocols.getDropTargetProtocols();
0N/A
0N/A while (dropTargetProtocols.hasNext()) {
0N/A XDropTargetProtocol dropTargetProtocol =
0N/A (XDropTargetProtocol)dropTargetProtocols.next();
0N/A dropTargetProtocol.unregisterEmbeddedDropSite(clientWindow);
0N/A }
0N/A
0N/A unregisterEmbeddedDropSite(canvasWindow, clientWindow);
0N/A
1696N/A if (logger.isLoggable(PlatformLogger.FINE)) {
0N/A logger.fine(" XEmbed drop site has beed unregistered for " + Long.toHexString(clientWindow));
0N/A }
0N/A }
0N/A
0N/A /**************** Delayed drop site registration *******************************/
0N/A
0N/A private void addDelayedRegistrationEntry(final long window) {
0N/A Long lWindow = Long.valueOf(window);
0N/A Runnable runnable = new Runnable() {
0N/A public void run() {
0N/A removeDelayedRegistrationEntry(window);
0N/A registerDropSite(window);
0N/A }
0N/A };
0N/A
0N/A XToolkit.awtLock();
0N/A try {
0N/A removeDelayedRegistrationEntry(window);
0N/A delayedRegistrationMap.put(lWindow, runnable);
0N/A XToolkit.schedule(runnable, DELAYED_REGISTRATION_PERIOD);
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A private void removeDelayedRegistrationEntry(long window) {
0N/A Long lWindow = Long.valueOf(window);
0N/A
0N/A XToolkit.awtLock();
0N/A try {
0N/A Runnable runnable = delayedRegistrationMap.remove(lWindow);
0N/A if (runnable != null) {
0N/A XToolkit.remove(runnable);
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A /*******************************************************************************/
0N/A}