1 /* 2 * Copyright (c) 2003, 2014, 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.util.ArrayList; 29 import java.util.Collections; 30 import java.util.HashMap; 31 import java.util.HashSet; 32 import java.util.Iterator; 33 import java.util.List; 34 import sun.util.logging.PlatformLogger; 35 36 import java.awt.Point; 37 38 39 /** 40 * The class responsible for registration/deregistration of drop sites. 41 * 42 * @since 1.5 43 */ 44 final class XDropTargetRegistry { 45 private static final PlatformLogger logger = 46 PlatformLogger.getLogger("sun.awt.X11.xembed.xdnd.XDropTargetRegistry"); 47 48 private static final long DELAYED_REGISTRATION_PERIOD = 200; 49 50 private static final XDropTargetRegistry theInstance = 51 new XDropTargetRegistry(); 52 53 private final HashMap<Long, Runnable> delayedRegistrationMap = 54 new HashMap<Long, Runnable>(); 55 XDropTargetRegistry()56 private XDropTargetRegistry() {} 57 getRegistry()58 static XDropTargetRegistry getRegistry() { 59 return theInstance; 60 } 61 62 /** 63 * Returns the XID of the topmost window with WM_STATE set in the ancestor 64 * hierarchy of the specified window or 0 if none found. 65 */ getToplevelWindow(long window)66 private long getToplevelWindow(long window) { 67 XBaseWindow candWindow = XToolkit.windowToXWindow(window); 68 if (candWindow != null) { 69 XWindowPeer toplevel = candWindow.getToplevelXWindow(); 70 if (toplevel != null && !(toplevel instanceof XEmbeddedFramePeer)) { 71 return toplevel.getWindow(); 72 } 73 } 74 75 /* Traverse the ancestor tree from window up to the root and find 76 the top-level client window nearest to the root. */ 77 do { 78 if (XlibUtil.isTrueToplevelWindow(window)) { 79 return window; 80 } 81 82 window = XlibUtil.getParentWindow(window); 83 84 } while (window != 0); 85 86 return window; 87 } 88 getDnDProxyWindow()89 static long getDnDProxyWindow() { 90 return XWindow.getXAWTRootWindow().getWindow(); 91 } 92 93 private static final class EmbeddedDropSiteEntry { 94 private final long root; 95 private final long event_mask; 96 private List<XDropTargetProtocol> supportedProtocols; 97 private final HashSet<Long> nonXEmbedClientSites = new HashSet<Long>(); 98 private final List<Long> sites = new ArrayList<Long>(); 99 EmbeddedDropSiteEntry(long root, long event_mask, List<XDropTargetProtocol> supportedProtocols)100 public EmbeddedDropSiteEntry(long root, long event_mask, 101 List<XDropTargetProtocol> supportedProtocols) { 102 if (supportedProtocols == null) { 103 throw new NullPointerException("Null supportedProtocols"); 104 } 105 this.root = root; 106 this.event_mask = event_mask; 107 this.supportedProtocols = supportedProtocols; 108 } 109 getRoot()110 public long getRoot() { 111 return root; 112 } getEventMask()113 public long getEventMask() { 114 return event_mask; 115 } hasNonXEmbedClientSites()116 public boolean hasNonXEmbedClientSites() { 117 return !nonXEmbedClientSites.isEmpty(); 118 } addSite(long window, boolean isXEmbedClient)119 public synchronized void addSite(long window, boolean isXEmbedClient) { 120 Long lWindow = Long.valueOf(window); 121 if (!sites.contains(lWindow)) { 122 sites.add(lWindow); 123 } 124 if (!isXEmbedClient) { 125 nonXEmbedClientSites.add(lWindow); 126 } 127 } removeSite(long window)128 public synchronized void removeSite(long window) { 129 Long lWindow = Long.valueOf(window); 130 sites.remove(lWindow); 131 nonXEmbedClientSites.remove(lWindow); 132 } setSupportedProtocols(List<XDropTargetProtocol> list)133 public void setSupportedProtocols(List<XDropTargetProtocol> list) { 134 supportedProtocols = list; 135 } getSupportedProtocols()136 public List<XDropTargetProtocol> getSupportedProtocols() { 137 return supportedProtocols; 138 } hasSites()139 public boolean hasSites() { 140 return !sites.isEmpty(); 141 } getSites()142 public long[] getSites() { 143 long[] ret = new long[sites.size()]; 144 Iterator<Long> iter = sites.iterator(); 145 int index = 0; 146 while (iter.hasNext()) { 147 Long l = iter.next(); 148 ret[index++] = l.longValue(); 149 } 150 return ret; 151 } getSite(int x, int y)152 public long getSite(int x, int y) { 153 assert XToolkit.isAWTLockHeldByCurrentThread(); 154 155 Iterator<Long> iter = sites.iterator(); 156 while (iter.hasNext()) { 157 Long l = iter.next(); 158 long window = l.longValue(); 159 160 Point p = XBaseWindow.toOtherWindow(getRoot(), window, x, y); 161 162 if (p == null) { 163 continue; 164 } 165 166 int dest_x = p.x; 167 int dest_y = p.y; 168 if (dest_x >= 0 && dest_y >= 0) { 169 XWindowAttributes wattr = new XWindowAttributes(); 170 try { 171 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 172 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), 173 window, wattr.pData); 174 XErrorHandlerUtil.RESTORE_XERROR_HANDLER(); 175 176 if ((status == 0) || 177 ((XErrorHandlerUtil.saved_error != null) && 178 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success))) { 179 continue; 180 } 181 182 if (wattr.get_map_state() != XConstants.IsUnmapped 183 && dest_x < wattr.get_width() 184 && dest_y < wattr.get_height()) { 185 return window; 186 } 187 } finally { 188 wattr.dispose(); 189 } 190 } 191 } 192 return 0; 193 } 194 } 195 196 private final HashMap<Long, EmbeddedDropSiteEntry> embeddedDropSiteRegistry = 197 new HashMap<Long, EmbeddedDropSiteEntry>(); 198 registerEmbedderDropSite(long embedder)199 private EmbeddedDropSiteEntry registerEmbedderDropSite(long embedder) { 200 assert XToolkit.isAWTLockHeldByCurrentThread(); 201 202 Iterator<XDropTargetProtocol> dropTargetProtocols = 203 XDragAndDropProtocols.getDropTargetProtocols(); 204 // The list of protocols supported by the embedder. 205 List<XDropTargetProtocol> embedderProtocols = new ArrayList<>(); 206 207 while (dropTargetProtocols.hasNext()) { 208 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 209 if (dropTargetProtocol.isProtocolSupported(embedder)) { 210 embedderProtocols.add(dropTargetProtocol); 211 } 212 } 213 214 embedderProtocols = Collections.unmodifiableList(embedderProtocols); 215 216 /* Grab server, since we are working with the window that belongs to 217 another client. */ 218 XlibWrapper.XGrabServer(XToolkit.getDisplay()); 219 try { 220 long root = 0; 221 long event_mask = 0; 222 XWindowAttributes wattr = new XWindowAttributes(); 223 try { 224 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 225 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), 226 embedder, wattr.pData); 227 XErrorHandlerUtil.RESTORE_XERROR_HANDLER(); 228 229 if ((status == 0) || 230 ((XErrorHandlerUtil.saved_error != null) && 231 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success))) { 232 throw new XException("XGetWindowAttributes failed"); 233 } 234 235 event_mask = wattr.get_your_event_mask(); 236 root = wattr.get_root(); 237 } finally { 238 wattr.dispose(); 239 } 240 241 if ((event_mask & XConstants.PropertyChangeMask) == 0) { 242 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 243 XlibWrapper.XSelectInput(XToolkit.getDisplay(), embedder, 244 event_mask | XConstants.PropertyChangeMask); 245 XErrorHandlerUtil.RESTORE_XERROR_HANDLER(); 246 247 if ((XErrorHandlerUtil.saved_error != null) && 248 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) { 249 throw new XException("XSelectInput failed"); 250 } 251 } 252 253 return new EmbeddedDropSiteEntry(root, event_mask, embedderProtocols); 254 } finally { 255 XlibWrapper.XUngrabServer(XToolkit.getDisplay()); 256 } 257 } 258 259 private static final boolean XEMBED_PROTOCOLS = true; 260 private static final boolean NON_XEMBED_PROTOCOLS = false; 261 registerProtocols(long embedder, boolean protocols, List<XDropTargetProtocol> supportedProtocols)262 private void registerProtocols(long embedder, boolean protocols, 263 List<XDropTargetProtocol> supportedProtocols) { 264 Iterator<XDropTargetProtocol> dropTargetProtocols = null; 265 266 /* 267 * By default, we register a drop site that supports all dnd 268 * protocols. This approach is not appropriate in plugin 269 * scenario if the browser supports Motif DnD and doesn't support 270 * XDnD. If we forcibly set XdndAware on the browser toplevel, any drag 271 * source that supports both protocols and prefers XDnD will be unable 272 * to drop anything on the browser. 273 * The solution for this problem is not to register XDnD drop site 274 * if the browser supports only Motif DnD. 275 * In general, if the browser already supports some protocols, we 276 * register the embedded drop site only for those protocols. Otherwise 277 * we register the embedded drop site for all protocols. 278 */ 279 if (!supportedProtocols.isEmpty()) { 280 dropTargetProtocols = supportedProtocols.iterator(); 281 } else { 282 dropTargetProtocols = 283 XDragAndDropProtocols.getDropTargetProtocols(); 284 } 285 286 /* Grab server, since we are working with the window that belongs to 287 another client. */ 288 XlibWrapper.XGrabServer(XToolkit.getDisplay()); 289 try { 290 while (dropTargetProtocols.hasNext()) { 291 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 292 if ((protocols == XEMBED_PROTOCOLS) == 293 dropTargetProtocol.isXEmbedSupported()) { 294 dropTargetProtocol.registerEmbedderDropSite(embedder); 295 } 296 } 297 } finally { 298 XlibWrapper.XUngrabServer(XToolkit.getDisplay()); 299 } 300 } 301 updateEmbedderDropSite(long embedder)302 public void updateEmbedderDropSite(long embedder) { 303 XBaseWindow xbaseWindow = XToolkit.windowToXWindow(embedder); 304 // No need to update our own drop sites. 305 if (xbaseWindow != null) { 306 return; 307 } 308 309 assert XToolkit.isAWTLockHeldByCurrentThread(); 310 311 Iterator<XDropTargetProtocol> dropTargetProtocols = 312 XDragAndDropProtocols.getDropTargetProtocols(); 313 // The list of protocols supported by the embedder. 314 List<XDropTargetProtocol> embedderProtocols = new ArrayList<>(); 315 316 while (dropTargetProtocols.hasNext()) { 317 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 318 if (dropTargetProtocol.isProtocolSupported(embedder)) { 319 embedderProtocols.add(dropTargetProtocol); 320 } 321 } 322 323 embedderProtocols = Collections.unmodifiableList(embedderProtocols); 324 325 Long lToplevel = Long.valueOf(embedder); 326 boolean isXEmbedServer = false; 327 synchronized (this) { 328 EmbeddedDropSiteEntry entry = embeddedDropSiteRegistry.get(lToplevel); 329 if (entry == null) { 330 return; 331 } 332 entry.setSupportedProtocols(embedderProtocols); 333 isXEmbedServer = !entry.hasNonXEmbedClientSites(); 334 } 335 336 /* 337 * By default, we register a drop site that supports all dnd 338 * protocols. This approach is not appropriate in plugin 339 * scenario if the browser supports Motif DnD and doesn't support 340 * XDnD. If we forcibly set XdndAware on the browser toplevel, any drag 341 * source that supports both protocols and prefers XDnD will be unable 342 * to drop anything on the browser. 343 * The solution for this problem is not to register XDnD drop site 344 * if the browser supports only Motif DnD. 345 * In general, if the browser already supports some protocols, we 346 * register the embedded drop site only for those protocols. Otherwise 347 * we register the embedded drop site for all protocols. 348 */ 349 if (!embedderProtocols.isEmpty()) { 350 dropTargetProtocols = embedderProtocols.iterator(); 351 } else { 352 dropTargetProtocols = 353 XDragAndDropProtocols.getDropTargetProtocols(); 354 } 355 356 /* Grab server, since we are working with the window that belongs to 357 another client. */ 358 XlibWrapper.XGrabServer(XToolkit.getDisplay()); 359 try { 360 while (dropTargetProtocols.hasNext()) { 361 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 362 if (!isXEmbedServer || !dropTargetProtocol.isXEmbedSupported()) { 363 dropTargetProtocol.registerEmbedderDropSite(embedder); 364 } 365 } 366 } finally { 367 XlibWrapper.XUngrabServer(XToolkit.getDisplay()); 368 } 369 } 370 unregisterEmbedderDropSite(long embedder, EmbeddedDropSiteEntry entry)371 private void unregisterEmbedderDropSite(long embedder, 372 EmbeddedDropSiteEntry entry) { 373 assert XToolkit.isAWTLockHeldByCurrentThread(); 374 375 Iterator<XDropTargetProtocol> dropTargetProtocols = 376 XDragAndDropProtocols.getDropTargetProtocols(); 377 378 /* Grab server, since we are working with the window that belongs to 379 another client. */ 380 XlibWrapper.XGrabServer(XToolkit.getDisplay()); 381 try { 382 while (dropTargetProtocols.hasNext()) { 383 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 384 dropTargetProtocol.unregisterEmbedderDropSite(embedder); 385 } 386 387 long event_mask = entry.getEventMask(); 388 389 /* Restore the original event mask for the embedder. */ 390 if ((event_mask & XConstants.PropertyChangeMask) == 0) { 391 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 392 XlibWrapper.XSelectInput(XToolkit.getDisplay(), embedder, 393 event_mask); 394 XErrorHandlerUtil.RESTORE_XERROR_HANDLER(); 395 396 if ((XErrorHandlerUtil.saved_error != null) && 397 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) { 398 throw new XException("XSelectInput failed"); 399 } 400 } 401 } finally { 402 XlibWrapper.XUngrabServer(XToolkit.getDisplay()); 403 } 404 } 405 registerEmbeddedDropSite(long toplevel, long window)406 private void registerEmbeddedDropSite(long toplevel, long window) { 407 XBaseWindow xBaseWindow = XToolkit.windowToXWindow(window); 408 boolean isXEmbedClient = 409 (xBaseWindow instanceof XEmbeddedFramePeer) && 410 ((XEmbeddedFramePeer)xBaseWindow).isXEmbedActive(); 411 412 XEmbedCanvasPeer peer = null; 413 { 414 XBaseWindow xbaseWindow = XToolkit.windowToXWindow(toplevel); 415 if (xbaseWindow != null) { 416 if (xbaseWindow instanceof XEmbedCanvasPeer) { 417 peer = (XEmbedCanvasPeer)xbaseWindow; 418 } else { 419 throw new UnsupportedOperationException(); 420 } 421 } 422 } 423 424 Long lToplevel = Long.valueOf(toplevel); 425 EmbeddedDropSiteEntry entry = null; 426 synchronized (this) { 427 entry = embeddedDropSiteRegistry.get(lToplevel); 428 if (entry == null) { 429 if (peer != null) { 430 // Toplevel is an XEmbed server within this VM. 431 // Register an XEmbed drop site. 432 peer.setXEmbedDropTarget(); 433 // Create a dummy entry to register the embedded site. 434 entry = new EmbeddedDropSiteEntry(0, 0, 435 Collections.<XDropTargetProtocol>emptyList()); 436 } else { 437 // Foreign toplevel. 438 // Select for PropertyNotify events on the toplevel, so that 439 // we can track changes of the properties relevant to DnD 440 // protocols. 441 entry = registerEmbedderDropSite(toplevel); 442 // Register the toplevel with all DnD protocols that are not 443 // supported by XEmbed - actually setup a proxy, so that 444 // all DnD notifications sent to the toplevel are first 445 // routed to us. 446 registerProtocols(toplevel, NON_XEMBED_PROTOCOLS, 447 entry.getSupportedProtocols()); 448 } 449 embeddedDropSiteRegistry.put(lToplevel, entry); 450 } 451 } 452 453 assert entry != null; 454 455 synchronized (entry) { 456 // For a foreign toplevel. 457 if (peer == null) { 458 if (!isXEmbedClient) { 459 // Since this is not an XEmbed client we can no longer rely 460 // on XEmbed to route DnD notifications even for DnD 461 // protocols that are supported by XEmbed. 462 // We rollback to the XEmbed-unfriendly solution - setup 463 // a proxy, so that all DnD notifications sent to the 464 // toplevel are first routed to us. 465 registerProtocols(toplevel, XEMBED_PROTOCOLS, 466 entry.getSupportedProtocols()); 467 } else { 468 Iterator<XDropTargetProtocol> dropTargetProtocols = 469 XDragAndDropProtocols.getDropTargetProtocols(); 470 471 // Register the embedded window as a plain drop site with 472 // all DnD protocols that are supported by XEmbed. 473 while (dropTargetProtocols.hasNext()) { 474 XDropTargetProtocol dropTargetProtocol = 475 dropTargetProtocols.next(); 476 if (dropTargetProtocol.isXEmbedSupported()) { 477 dropTargetProtocol.registerEmbedderDropSite(window); 478 } 479 } 480 } 481 } 482 483 entry.addSite(window, isXEmbedClient); 484 } 485 } 486 unregisterEmbeddedDropSite(long toplevel, long window)487 private void unregisterEmbeddedDropSite(long toplevel, long window) { 488 Long lToplevel = Long.valueOf(toplevel); 489 EmbeddedDropSiteEntry entry = null; 490 synchronized (this) { 491 entry = embeddedDropSiteRegistry.get(lToplevel); 492 if (entry == null) { 493 return; 494 } 495 entry.removeSite(window); 496 if (!entry.hasSites()) { 497 embeddedDropSiteRegistry.remove(lToplevel); 498 499 XBaseWindow xbaseWindow = XToolkit.windowToXWindow(toplevel); 500 if (xbaseWindow != null) { 501 if (xbaseWindow instanceof XEmbedCanvasPeer) { 502 XEmbedCanvasPeer peer = (XEmbedCanvasPeer)xbaseWindow; 503 // Unregister an XEmbed drop site. 504 peer.removeXEmbedDropTarget(); 505 } else { 506 throw new UnsupportedOperationException(); 507 } 508 } else { 509 unregisterEmbedderDropSite(toplevel, entry); 510 } 511 } 512 } 513 } 514 515 /* 516 * Returns a drop site that is embedded in the specified embedder window and 517 * contains the point with the specified root coordinates. 518 */ getEmbeddedDropSite(long embedder, int x, int y)519 public long getEmbeddedDropSite(long embedder, int x, int y) { 520 Long lToplevel = Long.valueOf(embedder); 521 EmbeddedDropSiteEntry entry = embeddedDropSiteRegistry.get(lToplevel); 522 if (entry == null) { 523 return 0; 524 } 525 return entry.getSite(x, y); 526 } 527 528 /* 529 * Note: this method should be called under AWT lock. 530 */ registerDropSite(long window)531 public void registerDropSite(long window) { 532 assert XToolkit.isAWTLockHeldByCurrentThread(); 533 534 if (window == 0) { 535 throw new IllegalArgumentException(); 536 } 537 538 XDropTargetEventProcessor.activate(); 539 540 long toplevel = getToplevelWindow(window); 541 542 /* 543 * No window with WM_STATE property is found. 544 * Since the window can be a plugin window reparented to the browser 545 * toplevel, we cannot determine which window will eventually have 546 * WM_STATE property set. So we schedule a timer callback that will 547 * periodically attempt to find an ancestor with WM_STATE and 548 * register the drop site appropriately. 549 */ 550 if (toplevel == 0) { 551 addDelayedRegistrationEntry(window); 552 return; 553 } 554 555 if (toplevel == window) { 556 Iterator<XDropTargetProtocol> dropTargetProtocols = 557 XDragAndDropProtocols.getDropTargetProtocols(); 558 559 while (dropTargetProtocols.hasNext()) { 560 XDropTargetProtocol dropTargetProtocol = 561 dropTargetProtocols.next(); 562 dropTargetProtocol.registerDropTarget(toplevel); 563 } 564 } else { 565 registerEmbeddedDropSite(toplevel, window); 566 } 567 } 568 569 /* 570 * Note: this method should be called under AWT lock. 571 */ unregisterDropSite(long window)572 public void unregisterDropSite(long window) { 573 assert XToolkit.isAWTLockHeldByCurrentThread(); 574 575 if (window == 0) { 576 throw new IllegalArgumentException(); 577 } 578 579 long toplevel = getToplevelWindow(window); 580 581 if (toplevel == window) { 582 Iterator<XDropTargetProtocol> dropProtocols = 583 XDragAndDropProtocols.getDropTargetProtocols(); 584 585 removeDelayedRegistrationEntry(window); 586 587 while (dropProtocols.hasNext()) { 588 XDropTargetProtocol dropProtocol = dropProtocols.next(); 589 dropProtocol.unregisterDropTarget(window); 590 } 591 } else { 592 unregisterEmbeddedDropSite(toplevel, window); 593 } 594 } 595 registerXEmbedClient(long canvasWindow, long clientWindow)596 public void registerXEmbedClient(long canvasWindow, long clientWindow) { 597 // If the client has an associated XDnD drop site, add a drop target 598 // to the XEmbedCanvasPeer's target to route drag notifications to the 599 // client. 600 601 XDragSourceProtocol xdndDragProtocol = 602 XDragAndDropProtocols.getDragSourceProtocol(XDragAndDropProtocols.XDnD); 603 XDragSourceProtocol.TargetWindowInfo info = 604 xdndDragProtocol.getTargetWindowInfo(clientWindow); 605 if (info != null && 606 info.getProtocolVersion() >= XDnDConstants.XDND_MIN_PROTOCOL_VERSION) { 607 608 if (logger.isLoggable(PlatformLogger.Level.FINE)) { 609 logger.fine(" XEmbed drop site will be registered for " + Long.toHexString(clientWindow)); 610 } 611 registerEmbeddedDropSite(canvasWindow, clientWindow); 612 613 Iterator<XDropTargetProtocol> dropTargetProtocols = 614 XDragAndDropProtocols.getDropTargetProtocols(); 615 616 while (dropTargetProtocols.hasNext()) { 617 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 618 dropTargetProtocol.registerEmbeddedDropSite(clientWindow); 619 } 620 621 if (logger.isLoggable(PlatformLogger.Level.FINE)) { 622 logger.fine(" XEmbed drop site has been registered for " + Long.toHexString(clientWindow)); 623 } 624 } 625 } 626 unregisterXEmbedClient(long canvasWindow, long clientWindow)627 public void unregisterXEmbedClient(long canvasWindow, long clientWindow) { 628 if (logger.isLoggable(PlatformLogger.Level.FINE)) { 629 logger.fine(" XEmbed drop site will be unregistered for " + Long.toHexString(clientWindow)); 630 } 631 Iterator<XDropTargetProtocol> dropTargetProtocols = 632 XDragAndDropProtocols.getDropTargetProtocols(); 633 634 while (dropTargetProtocols.hasNext()) { 635 XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next(); 636 dropTargetProtocol.unregisterEmbeddedDropSite(clientWindow); 637 } 638 639 unregisterEmbeddedDropSite(canvasWindow, clientWindow); 640 641 if (logger.isLoggable(PlatformLogger.Level.FINE)) { 642 logger.fine(" XEmbed drop site has beed unregistered for " + Long.toHexString(clientWindow)); 643 } 644 } 645 646 /**************** Delayed drop site registration *******************************/ 647 addDelayedRegistrationEntry(final long window)648 private void addDelayedRegistrationEntry(final long window) { 649 Long lWindow = Long.valueOf(window); 650 Runnable runnable = new Runnable() { 651 public void run() { 652 removeDelayedRegistrationEntry(window); 653 registerDropSite(window); 654 } 655 }; 656 657 XToolkit.awtLock(); 658 try { 659 removeDelayedRegistrationEntry(window); 660 delayedRegistrationMap.put(lWindow, runnable); 661 XToolkit.schedule(runnable, DELAYED_REGISTRATION_PERIOD); 662 } finally { 663 XToolkit.awtUnlock(); 664 } 665 } 666 removeDelayedRegistrationEntry(long window)667 private void removeDelayedRegistrationEntry(long window) { 668 Long lWindow = Long.valueOf(window); 669 670 XToolkit.awtLock(); 671 try { 672 Runnable runnable = delayedRegistrationMap.remove(lWindow); 673 if (runnable != null) { 674 XToolkit.remove(runnable); 675 } 676 } finally { 677 XToolkit.awtUnlock(); 678 } 679 } 680 /*******************************************************************************/ 681 } 682