124 if (!isXEmbedClient) {
125 nonXEmbedClientSites.add(lWindow);
126 }
127 }
128 public synchronized void removeSite(long window) {
129 Long lWindow = Long.valueOf(window);
130 sites.remove(lWindow);
131 nonXEmbedClientSites.remove(lWindow);
132 }
133 public void setSupportedProtocols(List<XDropTargetProtocol> list) {
134 supportedProtocols = list;
135 }
136 public List<XDropTargetProtocol> getSupportedProtocols() {
137 return supportedProtocols;
138 }
139 public boolean hasSites() {
140 return !sites.isEmpty();
141 }
142 public long[] getSites() {
143 long[] ret = new long[sites.size()];
144 Iterator iter = sites.iterator();
145 int index = 0;
146 while (iter.hasNext()) {
147 Long l = (Long)iter.next();
148 ret[index++] = l.longValue();
149 }
150 return ret;
151 }
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;
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
199 private EmbeddedDropSiteEntry registerEmbedderDropSite(long embedder) {
200 assert XToolkit.isAWTLockHeldByCurrentThread();
201
202 Iterator 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 =
209 (XDropTargetProtocol)dropTargetProtocols.next();
210 if (dropTargetProtocol.isProtocolSupported(embedder)) {
211 embedderProtocols.add(dropTargetProtocol);
212 }
213 }
214
215 embedderProtocols = Collections.unmodifiableList(embedderProtocols);
216
217 /* Grab server, since we are working with the window that belongs to
218 another client. */
219 XlibWrapper.XGrabServer(XToolkit.getDisplay());
220 try {
221 long root = 0;
222 long event_mask = 0;
223 XWindowAttributes wattr = new XWindowAttributes();
224 try {
225 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
226 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
227 embedder, wattr.pData);
228 XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
229
245 event_mask | XConstants.PropertyChangeMask);
246 XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
247
248 if ((XErrorHandlerUtil.saved_error != null) &&
249 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
250 throw new XException("XSelectInput failed");
251 }
252 }
253
254 return new EmbeddedDropSiteEntry(root, event_mask, embedderProtocols);
255 } finally {
256 XlibWrapper.XUngrabServer(XToolkit.getDisplay());
257 }
258 }
259
260 private static final boolean XEMBED_PROTOCOLS = true;
261 private static final boolean NON_XEMBED_PROTOCOLS = false;
262
263 private void registerProtocols(long embedder, boolean protocols,
264 List<XDropTargetProtocol> supportedProtocols) {
265 Iterator dropTargetProtocols = null;
266
267 /*
268 * By default, we register a drop site that supports all dnd
269 * protocols. This approach is not appropriate in plugin
270 * scenario if the browser supports Motif DnD and doesn't support
271 * XDnD. If we forcibly set XdndAware on the browser toplevel, any drag
272 * source that supports both protocols and prefers XDnD will be unable
273 * to drop anything on the browser.
274 * The solution for this problem is not to register XDnD drop site
275 * if the browser supports only Motif DnD.
276 * In general, if the browser already supports some protocols, we
277 * register the embedded drop site only for those protocols. Otherwise
278 * we register the embedded drop site for all protocols.
279 */
280 if (!supportedProtocols.isEmpty()) {
281 dropTargetProtocols = supportedProtocols.iterator();
282 } else {
283 dropTargetProtocols =
284 XDragAndDropProtocols.getDropTargetProtocols();
285 }
286
287 /* Grab server, since we are working with the window that belongs to
288 another client. */
289 XlibWrapper.XGrabServer(XToolkit.getDisplay());
290 try {
291 while (dropTargetProtocols.hasNext()) {
292 XDropTargetProtocol dropTargetProtocol =
293 (XDropTargetProtocol)dropTargetProtocols.next();
294 if ((protocols == XEMBED_PROTOCOLS) ==
295 dropTargetProtocol.isXEmbedSupported()) {
296 dropTargetProtocol.registerEmbedderDropSite(embedder);
297 }
298 }
299 } finally {
300 XlibWrapper.XUngrabServer(XToolkit.getDisplay());
301 }
302 }
303
304 public void updateEmbedderDropSite(long embedder) {
305 XBaseWindow xbaseWindow = XToolkit.windowToXWindow(embedder);
306 // No need to update our own drop sites.
307 if (xbaseWindow != null) {
308 return;
309 }
310
311 assert XToolkit.isAWTLockHeldByCurrentThread();
312
313 Iterator dropTargetProtocols =
314 XDragAndDropProtocols.getDropTargetProtocols();
315 // The list of protocols supported by the embedder.
316 List<XDropTargetProtocol> embedderProtocols = new ArrayList();
317
318 while (dropTargetProtocols.hasNext()) {
319 XDropTargetProtocol dropTargetProtocol =
320 (XDropTargetProtocol)dropTargetProtocols.next();
321 if (dropTargetProtocol.isProtocolSupported(embedder)) {
322 embedderProtocols.add(dropTargetProtocol);
323 }
324 }
325
326 embedderProtocols = Collections.unmodifiableList(embedderProtocols);
327
328 Long lToplevel = Long.valueOf(embedder);
329 boolean isXEmbedServer = false;
330 synchronized (this) {
331 EmbeddedDropSiteEntry entry = embeddedDropSiteRegistry.get(lToplevel);
332 if (entry == null) {
333 return;
334 }
335 entry.setSupportedProtocols(embedderProtocols);
336 isXEmbedServer = !entry.hasNonXEmbedClientSites();
337 }
338
339 /*
340 * By default, we register a drop site that supports all dnd
344 * source that supports both protocols and prefers XDnD will be unable
345 * to drop anything on the browser.
346 * The solution for this problem is not to register XDnD drop site
347 * if the browser supports only Motif DnD.
348 * In general, if the browser already supports some protocols, we
349 * register the embedded drop site only for those protocols. Otherwise
350 * we register the embedded drop site for all protocols.
351 */
352 if (!embedderProtocols.isEmpty()) {
353 dropTargetProtocols = embedderProtocols.iterator();
354 } else {
355 dropTargetProtocols =
356 XDragAndDropProtocols.getDropTargetProtocols();
357 }
358
359 /* Grab server, since we are working with the window that belongs to
360 another client. */
361 XlibWrapper.XGrabServer(XToolkit.getDisplay());
362 try {
363 while (dropTargetProtocols.hasNext()) {
364 XDropTargetProtocol dropTargetProtocol =
365 (XDropTargetProtocol)dropTargetProtocols.next();
366 if (!isXEmbedServer || !dropTargetProtocol.isXEmbedSupported()) {
367 dropTargetProtocol.registerEmbedderDropSite(embedder);
368 }
369 }
370 } finally {
371 XlibWrapper.XUngrabServer(XToolkit.getDisplay());
372 }
373 }
374
375 private void unregisterEmbedderDropSite(long embedder,
376 EmbeddedDropSiteEntry entry) {
377 assert XToolkit.isAWTLockHeldByCurrentThread();
378
379 Iterator dropTargetProtocols =
380 XDragAndDropProtocols.getDropTargetProtocols();
381
382 /* Grab server, since we are working with the window that belongs to
383 another client. */
384 XlibWrapper.XGrabServer(XToolkit.getDisplay());
385 try {
386 while (dropTargetProtocols.hasNext()) {
387 XDropTargetProtocol dropTargetProtocol =
388 (XDropTargetProtocol)dropTargetProtocols.next();
389 dropTargetProtocol.unregisterEmbedderDropSite(embedder);
390 }
391
392 long event_mask = entry.getEventMask();
393
394 /* Restore the original event mask for the embedder. */
395 if ((event_mask & XConstants.PropertyChangeMask) == 0) {
396 XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
397 XlibWrapper.XSelectInput(XToolkit.getDisplay(), embedder,
398 event_mask);
399 XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
400
401 if ((XErrorHandlerUtil.saved_error != null) &&
402 (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
403 throw new XException("XSelectInput failed");
404 }
405 }
406 } finally {
407 XlibWrapper.XUngrabServer(XToolkit.getDisplay());
408 }
453 }
454 embeddedDropSiteRegistry.put(lToplevel, entry);
455 }
456 }
457
458 assert entry != null;
459
460 synchronized (entry) {
461 // For a foreign toplevel.
462 if (peer == null) {
463 if (!isXEmbedClient) {
464 // Since this is not an XEmbed client we can no longer rely
465 // on XEmbed to route DnD notifications even for DnD
466 // protocols that are supported by XEmbed.
467 // We rollback to the XEmbed-unfriendly solution - setup
468 // a proxy, so that all DnD notifications sent to the
469 // toplevel are first routed to us.
470 registerProtocols(toplevel, XEMBED_PROTOCOLS,
471 entry.getSupportedProtocols());
472 } else {
473 Iterator dropTargetProtocols =
474 XDragAndDropProtocols.getDropTargetProtocols();
475
476 // Register the embedded window as a plain drop site with
477 // all DnD protocols that are supported by XEmbed.
478 while (dropTargetProtocols.hasNext()) {
479 XDropTargetProtocol dropTargetProtocol =
480 (XDropTargetProtocol)dropTargetProtocols.next();
481 if (dropTargetProtocol.isXEmbedSupported()) {
482 dropTargetProtocol.registerEmbedderDropSite(window);
483 }
484 }
485 }
486 }
487
488 entry.addSite(window, isXEmbedClient);
489 }
490 }
491
492 private void unregisterEmbeddedDropSite(long toplevel, long window) {
493 Long lToplevel = Long.valueOf(toplevel);
494 EmbeddedDropSiteEntry entry = null;
495 synchronized (this) {
496 entry = embeddedDropSiteRegistry.get(lToplevel);
497 if (entry == null) {
498 return;
499 }
500 entry.removeSite(window);
541 }
542
543 XDropTargetEventProcessor.activate();
544
545 long toplevel = getToplevelWindow(window);
546
547 /*
548 * No window with WM_STATE property is found.
549 * Since the window can be a plugin window reparented to the browser
550 * toplevel, we cannot determine which window will eventually have
551 * WM_STATE property set. So we schedule a timer callback that will
552 * periodically attempt to find an ancestor with WM_STATE and
553 * register the drop site appropriately.
554 */
555 if (toplevel == 0) {
556 addDelayedRegistrationEntry(window);
557 return;
558 }
559
560 if (toplevel == window) {
561 Iterator dropTargetProtocols =
562 XDragAndDropProtocols.getDropTargetProtocols();
563
564 while (dropTargetProtocols.hasNext()) {
565 XDropTargetProtocol dropTargetProtocol =
566 (XDropTargetProtocol)dropTargetProtocols.next();
567 dropTargetProtocol.registerDropTarget(toplevel);
568 }
569 } else {
570 registerEmbeddedDropSite(toplevel, window);
571 }
572 }
573
574 /*
575 * Note: this method should be called under AWT lock.
576 */
577 public void unregisterDropSite(long window) {
578 assert XToolkit.isAWTLockHeldByCurrentThread();
579
580 if (window == 0) {
581 throw new IllegalArgumentException();
582 }
583
584 long toplevel = getToplevelWindow(window);
585
586 if (toplevel == window) {
587 Iterator dropProtocols =
588 XDragAndDropProtocols.getDropTargetProtocols();
589
590 removeDelayedRegistrationEntry(window);
591
592 while (dropProtocols.hasNext()) {
593 XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
594 dropProtocol.unregisterDropTarget(window);
595 }
596 } else {
597 unregisterEmbeddedDropSite(toplevel, window);
598 }
599 }
600
601 public void registerXEmbedClient(long canvasWindow, long clientWindow) {
602 // If the client has an associated XDnD drop site, add a drop target
603 // to the XEmbedCanvasPeer's target to route drag notifications to the
604 // client.
605
606 XDragSourceProtocol xdndDragProtocol =
607 XDragAndDropProtocols.getDragSourceProtocol(XDragAndDropProtocols.XDnD);
608 XDragSourceProtocol.TargetWindowInfo info =
609 xdndDragProtocol.getTargetWindowInfo(clientWindow);
610 if (info != null &&
611 info.getProtocolVersion() >= XDnDConstants.XDND_MIN_PROTOCOL_VERSION) {
612
613 if (logger.isLoggable(PlatformLogger.Level.FINE)) {
614 logger.fine(" XEmbed drop site will be registered for " + Long.toHexString(clientWindow));
615 }
616 registerEmbeddedDropSite(canvasWindow, clientWindow);
617
618 Iterator dropTargetProtocols =
619 XDragAndDropProtocols.getDropTargetProtocols();
620
621 while (dropTargetProtocols.hasNext()) {
622 XDropTargetProtocol dropTargetProtocol =
623 (XDropTargetProtocol)dropTargetProtocols.next();
624 dropTargetProtocol.registerEmbeddedDropSite(clientWindow);
625 }
626
627 if (logger.isLoggable(PlatformLogger.Level.FINE)) {
628 logger.fine(" XEmbed drop site has been registered for " + Long.toHexString(clientWindow));
629 }
630 }
631 }
632
633 public void unregisterXEmbedClient(long canvasWindow, long clientWindow) {
634 if (logger.isLoggable(PlatformLogger.Level.FINE)) {
635 logger.fine(" XEmbed drop site will be unregistered for " + Long.toHexString(clientWindow));
636 }
637 Iterator dropTargetProtocols =
638 XDragAndDropProtocols.getDropTargetProtocols();
639
640 while (dropTargetProtocols.hasNext()) {
641 XDropTargetProtocol dropTargetProtocol =
642 (XDropTargetProtocol)dropTargetProtocols.next();
643 dropTargetProtocol.unregisterEmbeddedDropSite(clientWindow);
644 }
645
646 unregisterEmbeddedDropSite(canvasWindow, clientWindow);
647
648 if (logger.isLoggable(PlatformLogger.Level.FINE)) {
649 logger.fine(" XEmbed drop site has beed unregistered for " + Long.toHexString(clientWindow));
650 }
651 }
652
653 /**************** Delayed drop site registration *******************************/
654
655 private void addDelayedRegistrationEntry(final long window) {
656 Long lWindow = Long.valueOf(window);
657 Runnable runnable = new Runnable() {
658 public void run() {
659 removeDelayedRegistrationEntry(window);
660 registerDropSite(window);
661 }
662 };
|
124 if (!isXEmbedClient) {
125 nonXEmbedClientSites.add(lWindow);
126 }
127 }
128 public synchronized void removeSite(long window) {
129 Long lWindow = Long.valueOf(window);
130 sites.remove(lWindow);
131 nonXEmbedClientSites.remove(lWindow);
132 }
133 public void setSupportedProtocols(List<XDropTargetProtocol> list) {
134 supportedProtocols = list;
135 }
136 public List<XDropTargetProtocol> getSupportedProtocols() {
137 return supportedProtocols;
138 }
139 public boolean hasSites() {
140 return !sites.isEmpty();
141 }
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 }
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;
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
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
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
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
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
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
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 }
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
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);
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 */
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
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
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
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 };
|