jdk/src/solaris/classes/sun/awt/X11/XDnDDropTargetProtocol.java
changeset 2 90ce3da70b43
child 439 3488710b02f8
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2003-2005 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.awt.X11;
       
    27 
       
    28 import java.awt.Point;
       
    29 
       
    30 import java.awt.dnd.DnDConstants;
       
    31 
       
    32 import java.awt.event.MouseEvent;
       
    33 
       
    34 import java.io.IOException;
       
    35 
       
    36 import java.util.logging.*;
       
    37 
       
    38 import sun.misc.Unsafe;
       
    39 
       
    40 /**
       
    41  * XDropTargetProtocol implementation for XDnD protocol.
       
    42  *
       
    43  * @since 1.5
       
    44  */
       
    45 class XDnDDropTargetProtocol extends XDropTargetProtocol {
       
    46     private static final Logger logger =
       
    47         Logger.getLogger("sun.awt.X11.xembed.xdnd.XDnDDropTargetProtocol");
       
    48 
       
    49     private static final Unsafe unsafe = XlibWrapper.unsafe;
       
    50 
       
    51     private long sourceWindow = 0;
       
    52     private long sourceWindowMask = 0;
       
    53     private int sourceProtocolVersion = 0;
       
    54     private int sourceActions = DnDConstants.ACTION_NONE;
       
    55     private long[] sourceFormats = null;
       
    56     private boolean trackSourceActions = false;
       
    57     private int userAction = DnDConstants.ACTION_NONE;
       
    58     private int sourceX = 0;
       
    59     private int sourceY = 0;
       
    60     private XWindow targetXWindow = null;
       
    61 
       
    62     // XEmbed stuff.
       
    63     private long prevCtxt = 0;
       
    64     private boolean overXEmbedClient = false;
       
    65 
       
    66     protected XDnDDropTargetProtocol(XDropTargetProtocolListener listener) {
       
    67         super(listener);
       
    68     }
       
    69 
       
    70     /**
       
    71      * Creates an instance associated with the specified listener.
       
    72      *
       
    73      * @throws NullPointerException if listener is <code>null</code>.
       
    74      */
       
    75     static XDropTargetProtocol createInstance(XDropTargetProtocolListener listener) {
       
    76         return new XDnDDropTargetProtocol(listener);
       
    77     }
       
    78 
       
    79     public String getProtocolName() {
       
    80         return XDragAndDropProtocols.XDnD;
       
    81     }
       
    82 
       
    83     public void registerDropTarget(long window) {
       
    84         assert XToolkit.isAWTLockHeldByCurrentThread();
       
    85 
       
    86         long data = Native.allocateLongArray(1);
       
    87 
       
    88         try {
       
    89             Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
       
    90 
       
    91             XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
    92             XDnDConstants.XA_XdndAware.setAtomData(window, XAtom.XA_ATOM, data, 1);
       
    93             XToolkit.RESTORE_XERROR_HANDLER();
       
    94 
       
    95             if (XToolkit.saved_error != null &&
       
    96                 XToolkit.saved_error.get_error_code() != XlibWrapper.Success) {
       
    97                 throw new XException("Cannot write XdndAware property");
       
    98             }
       
    99         } finally {
       
   100             unsafe.freeMemory(data);
       
   101             data = 0;
       
   102         }
       
   103     }
       
   104 
       
   105     public void unregisterDropTarget(long window) {
       
   106         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   107 
       
   108         XDnDConstants.XA_XdndAware.DeleteProperty(window);
       
   109     }
       
   110 
       
   111     public void registerEmbedderDropSite(long embedder) {
       
   112         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   113 
       
   114         boolean overriden = false;
       
   115         int version = 0;
       
   116         long proxy = 0;
       
   117         long newProxy = XDropTargetRegistry.getDnDProxyWindow();
       
   118         int status = 0;
       
   119 
       
   120         WindowPropertyGetter wpg1 =
       
   121             new WindowPropertyGetter(embedder, XDnDConstants.XA_XdndAware, 0, 1,
       
   122                                      false, XlibWrapper.AnyPropertyType);
       
   123 
       
   124         try {
       
   125             status = wpg1.execute(XToolkit.IgnoreBadWindowHandler);
       
   126 
       
   127             if (status == XlibWrapper.Success &&
       
   128                 wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
       
   129 
       
   130                 overriden = true;
       
   131                 version = (int)Native.getLong(wpg1.getData());
       
   132             }
       
   133         } finally {
       
   134             wpg1.dispose();
       
   135         }
       
   136 
       
   137         /* XdndProxy is not supported for prior to XDnD version 4 */
       
   138         if (overriden && version >= 4) {
       
   139             WindowPropertyGetter wpg2 =
       
   140                 new WindowPropertyGetter(embedder, XDnDConstants.XA_XdndProxy,
       
   141                                          0, 1, false, XAtom.XA_WINDOW);
       
   142 
       
   143             try {
       
   144                 status = wpg2.execute(XToolkit.IgnoreBadWindowHandler);
       
   145 
       
   146                 if (status == XlibWrapper.Success &&
       
   147                     wpg2.getData() != 0 &&
       
   148                     wpg2.getActualType() == XAtom.XA_WINDOW) {
       
   149 
       
   150                     proxy = Native.getLong(wpg2.getData());
       
   151                 }
       
   152             } finally {
       
   153                 wpg2.dispose();
       
   154             }
       
   155 
       
   156             if (proxy != 0) {
       
   157                 WindowPropertyGetter wpg3 =
       
   158                     new WindowPropertyGetter(proxy, XDnDConstants.XA_XdndProxy,
       
   159                                              0, 1, false, XAtom.XA_WINDOW);
       
   160 
       
   161                 try {
       
   162                     status = wpg3.execute(XToolkit.IgnoreBadWindowHandler);
       
   163 
       
   164                     if (status != XlibWrapper.Success ||
       
   165                         wpg3.getData() == 0 ||
       
   166                         wpg3.getActualType() != XAtom.XA_WINDOW ||
       
   167                         Native.getLong(wpg3.getData()) != proxy) {
       
   168 
       
   169                         proxy = 0;
       
   170                     } else {
       
   171                         WindowPropertyGetter wpg4 =
       
   172                             new WindowPropertyGetter(proxy,
       
   173                                                      XDnDConstants.XA_XdndAware,
       
   174                                                      0, 1, false,
       
   175                                                      XlibWrapper.AnyPropertyType);
       
   176 
       
   177                         try {
       
   178                             status = wpg4.execute(XToolkit.IgnoreBadWindowHandler);
       
   179 
       
   180                             if (status != XlibWrapper.Success ||
       
   181                                 wpg4.getData() == 0 ||
       
   182                                 wpg4.getActualType() != XAtom.XA_ATOM) {
       
   183 
       
   184                                 proxy = 0;
       
   185                             }
       
   186                         } finally {
       
   187                             wpg4.dispose();
       
   188                         }
       
   189                     }
       
   190                 } finally {
       
   191                     wpg3.dispose();
       
   192                 }
       
   193             }
       
   194         }
       
   195 
       
   196         if (proxy == newProxy) {
       
   197             // Embedder already registered.
       
   198             return;
       
   199         }
       
   200 
       
   201         long data = Native.allocateLongArray(1);
       
   202 
       
   203         try {
       
   204             Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
       
   205 
       
   206             /* The proxy window must have the XdndAware set, as XDnD protocol
       
   207                prescribes to check the proxy window for XdndAware. */
       
   208             XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   209             XDnDConstants.XA_XdndAware.setAtomData(newProxy, XAtom.XA_ATOM,
       
   210                                                    data, 1);
       
   211             XToolkit.RESTORE_XERROR_HANDLER();
       
   212 
       
   213             if (XToolkit.saved_error != null &&
       
   214                 XToolkit.saved_error.get_error_code() !=
       
   215                 XlibWrapper.Success) {
       
   216                 throw new XException("Cannot write XdndAware property");
       
   217             }
       
   218 
       
   219             Native.putLong(data, 0, newProxy);
       
   220 
       
   221             /* The proxy window must have the XdndProxy set to point to itself.*/
       
   222             XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   223             XDnDConstants.XA_XdndProxy.setAtomData(newProxy, XAtom.XA_WINDOW,
       
   224                                                    data, 1);
       
   225             XToolkit.RESTORE_XERROR_HANDLER();
       
   226 
       
   227             if (XToolkit.saved_error != null &&
       
   228                 XToolkit.saved_error.get_error_code() !=
       
   229                 XlibWrapper.Success) {
       
   230                 throw new XException("Cannot write XdndProxy property");
       
   231             }
       
   232 
       
   233             Native.putLong(data, 0, XDnDConstants.XDND_PROTOCOL_VERSION);
       
   234 
       
   235             XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   236             XDnDConstants.XA_XdndAware.setAtomData(embedder, XAtom.XA_ATOM,
       
   237                                                    data, 1);
       
   238             XToolkit.RESTORE_XERROR_HANDLER();
       
   239 
       
   240             if (XToolkit.saved_error != null &&
       
   241                 XToolkit.saved_error.get_error_code() !=
       
   242                 XlibWrapper.Success) {
       
   243                 throw new XException("Cannot write XdndAware property");
       
   244             }
       
   245 
       
   246             Native.putLong(data, 0, newProxy);
       
   247 
       
   248             XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   249             XDnDConstants.XA_XdndProxy.setAtomData(embedder, XAtom.XA_WINDOW,
       
   250                                                    data, 1);
       
   251             XToolkit.RESTORE_XERROR_HANDLER();
       
   252 
       
   253             if (XToolkit.saved_error != null &&
       
   254                 XToolkit.saved_error.get_error_code() !=
       
   255                 XlibWrapper.Success) {
       
   256                 throw new XException("Cannot write XdndProxy property");
       
   257             }
       
   258         } finally {
       
   259             unsafe.freeMemory(data);
       
   260             data = 0;
       
   261         }
       
   262 
       
   263         putEmbedderRegistryEntry(embedder, overriden, version, proxy);
       
   264     }
       
   265 
       
   266     public void unregisterEmbedderDropSite(long embedder) {
       
   267         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   268 
       
   269         EmbedderRegistryEntry entry = getEmbedderRegistryEntry(embedder);
       
   270 
       
   271         if (entry == null) {
       
   272             return;
       
   273         }
       
   274 
       
   275         if (entry.isOverriden()) {
       
   276             long data = Native.allocateLongArray(1);
       
   277 
       
   278             try {
       
   279                 Native.putLong(data, 0, entry.getVersion());
       
   280 
       
   281                 XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   282                 XDnDConstants.XA_XdndAware.setAtomData(embedder, XAtom.XA_ATOM,
       
   283                                                        data, 1);
       
   284                 XToolkit.RESTORE_XERROR_HANDLER();
       
   285 
       
   286                 if (XToolkit.saved_error != null &&
       
   287                     XToolkit.saved_error.get_error_code() !=
       
   288                     XlibWrapper.Success) {
       
   289                     throw new XException("Cannot write XdndAware property");
       
   290                 }
       
   291 
       
   292                 Native.putLong(data, 0, (int)entry.getProxy());
       
   293 
       
   294                 XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
   295                 XDnDConstants.XA_XdndProxy.setAtomData(embedder, XAtom.XA_WINDOW,
       
   296                                                        data, 1);
       
   297                 XToolkit.RESTORE_XERROR_HANDLER();
       
   298 
       
   299                 if (XToolkit.saved_error != null &&
       
   300                     XToolkit.saved_error.get_error_code() !=
       
   301                     XlibWrapper.Success) {
       
   302                     throw new XException("Cannot write XdndProxy property");
       
   303                 }
       
   304             } finally {
       
   305                 unsafe.freeMemory(data);
       
   306                 data = 0;
       
   307             }
       
   308         } else {
       
   309             XDnDConstants.XA_XdndAware.DeleteProperty(embedder);
       
   310             XDnDConstants.XA_XdndProxy.DeleteProperty(embedder);
       
   311         }
       
   312     }
       
   313 
       
   314     /*
       
   315      * Gets and stores in the registry the embedder's XDnD drop site info
       
   316      * from the embedded.
       
   317      */
       
   318     public void registerEmbeddedDropSite(long embedded) {
       
   319         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   320 
       
   321         boolean overriden = false;
       
   322         int version = 0;
       
   323         long proxy = 0;
       
   324         long newProxy = XDropTargetRegistry.getDnDProxyWindow();
       
   325         int status = 0;
       
   326 
       
   327         WindowPropertyGetter wpg1 =
       
   328             new WindowPropertyGetter(embedded, XDnDConstants.XA_XdndAware, 0, 1,
       
   329                                      false, XlibWrapper.AnyPropertyType);
       
   330 
       
   331         try {
       
   332             status = wpg1.execute(XToolkit.IgnoreBadWindowHandler);
       
   333 
       
   334             if (status == XlibWrapper.Success &&
       
   335                 wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
       
   336 
       
   337                 overriden = true;
       
   338                 version = (int)Native.getLong(wpg1.getData());
       
   339             }
       
   340         } finally {
       
   341             wpg1.dispose();
       
   342         }
       
   343 
       
   344         /* XdndProxy is not supported for prior to XDnD version 4 */
       
   345         if (overriden && version >= 4) {
       
   346             WindowPropertyGetter wpg2 =
       
   347                 new WindowPropertyGetter(embedded, XDnDConstants.XA_XdndProxy,
       
   348                                          0, 1, false, XAtom.XA_WINDOW);
       
   349 
       
   350             try {
       
   351                 status = wpg2.execute(XToolkit.IgnoreBadWindowHandler);
       
   352 
       
   353                 if (status == XlibWrapper.Success &&
       
   354                     wpg2.getData() != 0 &&
       
   355                     wpg2.getActualType() == XAtom.XA_WINDOW) {
       
   356 
       
   357                     proxy = Native.getLong(wpg2.getData());
       
   358                 }
       
   359             } finally {
       
   360                 wpg2.dispose();
       
   361             }
       
   362 
       
   363             if (proxy != 0) {
       
   364                 WindowPropertyGetter wpg3 =
       
   365                     new WindowPropertyGetter(proxy, XDnDConstants.XA_XdndProxy,
       
   366                                              0, 1, false, XAtom.XA_WINDOW);
       
   367 
       
   368                 try {
       
   369                     status = wpg3.execute(XToolkit.IgnoreBadWindowHandler);
       
   370 
       
   371                     if (status != XlibWrapper.Success ||
       
   372                         wpg3.getData() == 0 ||
       
   373                         wpg3.getActualType() != XAtom.XA_WINDOW ||
       
   374                         Native.getLong(wpg3.getData()) != proxy) {
       
   375 
       
   376                         proxy = 0;
       
   377                     } else {
       
   378                         WindowPropertyGetter wpg4 =
       
   379                             new WindowPropertyGetter(proxy,
       
   380                                                      XDnDConstants.XA_XdndAware,
       
   381                                                      0, 1, false,
       
   382                                                      XlibWrapper.AnyPropertyType);
       
   383 
       
   384                         try {
       
   385                             status = wpg4.execute(XToolkit.IgnoreBadWindowHandler);
       
   386 
       
   387                             if (status != XlibWrapper.Success ||
       
   388                                 wpg4.getData() == 0 ||
       
   389                                 wpg4.getActualType() != XAtom.XA_ATOM) {
       
   390 
       
   391                                 proxy = 0;
       
   392                             }
       
   393                         } finally {
       
   394                             wpg4.dispose();
       
   395                         }
       
   396                     }
       
   397                 } finally {
       
   398                     wpg3.dispose();
       
   399                 }
       
   400             }
       
   401         }
       
   402 
       
   403         putEmbedderRegistryEntry(embedded, overriden, version, proxy);
       
   404     }
       
   405 
       
   406     public boolean isProtocolSupported(long window) {
       
   407         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   408 
       
   409         WindowPropertyGetter wpg1 =
       
   410             new WindowPropertyGetter(window, XDnDConstants.XA_XdndAware, 0, 1,
       
   411                                      false, XlibWrapper.AnyPropertyType);
       
   412 
       
   413         try {
       
   414             int status = wpg1.execute(XToolkit.IgnoreBadWindowHandler);
       
   415 
       
   416             if (status == XlibWrapper.Success &&
       
   417                 wpg1.getData() != 0 && wpg1.getActualType() == XAtom.XA_ATOM) {
       
   418 
       
   419                 return true;
       
   420             } else {
       
   421                 return false;
       
   422             }
       
   423         } finally {
       
   424             wpg1.dispose();
       
   425         }
       
   426     }
       
   427 
       
   428     private boolean processXdndEnter(XClientMessageEvent xclient) {
       
   429         long source_win = 0;
       
   430         long source_win_mask = 0;
       
   431         int protocol_version = 0;
       
   432         int actions = DnDConstants.ACTION_NONE;
       
   433         boolean track = true;
       
   434         long[] formats = null;
       
   435 
       
   436         if (getSourceWindow() != 0) {
       
   437             return false;
       
   438         }
       
   439 
       
   440         if (!(XToolkit.windowToXWindow(xclient.get_window()) instanceof XWindow)
       
   441             && getEmbedderRegistryEntry(xclient.get_window()) == null) {
       
   442             return false;
       
   443         }
       
   444 
       
   445         if (xclient.get_message_type() != XDnDConstants.XA_XdndEnter.getAtom()){
       
   446             return false;
       
   447         }
       
   448 
       
   449         protocol_version =
       
   450             (int)((xclient.get_data(1) & XDnDConstants.XDND_PROTOCOL_MASK) >>
       
   451                   XDnDConstants.XDND_PROTOCOL_SHIFT);
       
   452 
       
   453         /* XDnD compliance only requires supporting version 3 and up. */
       
   454         if (protocol_version < XDnDConstants.XDND_MIN_PROTOCOL_VERSION) {
       
   455             return false;
       
   456         }
       
   457 
       
   458         /* Ignore the source if the protocol version is higher than we support. */
       
   459         if (protocol_version > XDnDConstants.XDND_PROTOCOL_VERSION) {
       
   460             return false;
       
   461         }
       
   462 
       
   463         source_win = xclient.get_data(0);
       
   464 
       
   465         /* Extract the list of supported actions. */
       
   466         if (protocol_version < 2) {
       
   467             /* Prior to XDnD version 2 only COPY action was supported. */
       
   468             actions = DnDConstants.ACTION_COPY;
       
   469         } else {
       
   470             WindowPropertyGetter wpg =
       
   471                 new WindowPropertyGetter(source_win,
       
   472                                          XDnDConstants.XA_XdndActionList,
       
   473                                          0, 0xFFFF, false,
       
   474                                          XAtom.XA_ATOM);
       
   475             try {
       
   476                 wpg.execute(XToolkit.IgnoreBadWindowHandler);
       
   477 
       
   478                 if (wpg.getActualType() == XAtom.XA_ATOM &&
       
   479                     wpg.getActualFormat() == 32) {
       
   480                     long data = wpg.getData();
       
   481 
       
   482                     for (int i = 0; i < wpg.getNumberOfItems(); i++) {
       
   483                         actions |=
       
   484                             XDnDConstants.getJavaActionForXDnDAction(Native.getLong(data, i));
       
   485                     }
       
   486                 } else {
       
   487                     /*
       
   488                      * According to XDnD protocol, XdndActionList is optional.
       
   489                      * If XdndActionList is not set we try to guess which actions are
       
   490                      * supported.
       
   491                      */
       
   492                     actions = DnDConstants.ACTION_COPY;
       
   493                     track = true;
       
   494                 }
       
   495             } finally {
       
   496                 wpg.dispose();
       
   497             }
       
   498         }
       
   499 
       
   500         /* Extract the available data types. */
       
   501         if ((xclient.get_data(1) & XDnDConstants.XDND_DATA_TYPES_BIT) != 0) {
       
   502             WindowPropertyGetter wpg =
       
   503                 new WindowPropertyGetter(source_win,
       
   504                                          XDnDConstants.XA_XdndTypeList,
       
   505                                          0, 0xFFFF, false,
       
   506                                          XAtom.XA_ATOM);
       
   507             try {
       
   508                 wpg.execute(XToolkit.IgnoreBadWindowHandler);
       
   509 
       
   510                 if (wpg.getActualType() == XAtom.XA_ATOM &&
       
   511                     wpg.getActualFormat() == 32) {
       
   512                     formats = Native.toLongs(wpg.getData(),
       
   513                                              wpg.getNumberOfItems());
       
   514                 } else {
       
   515                     formats = new long[0];
       
   516                 }
       
   517             } finally {
       
   518                 wpg.dispose();
       
   519             }
       
   520         } else {
       
   521             int countFormats = 0;
       
   522             long[] formats3 = new long[3];
       
   523 
       
   524             for (int i = 0; i < 3; i++) {
       
   525                 long j;
       
   526                 if ((j = xclient.get_data(2 + i)) != XlibWrapper.None) {
       
   527                     formats3[countFormats++] = j;
       
   528                 }
       
   529             }
       
   530 
       
   531             formats = new long[countFormats];
       
   532 
       
   533             System.arraycopy(formats3, 0, formats, 0, countFormats);
       
   534         }
       
   535 
       
   536         assert XToolkit.isAWTLockHeldByCurrentThread();
       
   537 
       
   538         /*
       
   539          * Select for StructureNotifyMask to receive DestroyNotify in case of source
       
   540          * crash.
       
   541          */
       
   542         XWindowAttributes wattr = new XWindowAttributes();
       
   543         try {
       
   544             XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
       
   545             int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
       
   546                                                           source_win, wattr.pData);
       
   547 
       
   548             XToolkit.RESTORE_XERROR_HANDLER();
       
   549 
       
   550             if (status == 0 ||
       
   551                 (XToolkit.saved_error != null &&
       
   552                  XToolkit.saved_error.get_error_code() != XlibWrapper.Success)) {
       
   553                 throw new XException("XGetWindowAttributes failed");
       
   554             }
       
   555 
       
   556             source_win_mask = wattr.get_your_event_mask();
       
   557         } finally {
       
   558             wattr.dispose();
       
   559         }
       
   560 
       
   561         XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
       
   562         XlibWrapper.XSelectInput(XToolkit.getDisplay(), source_win,
       
   563                                  source_win_mask |
       
   564                                  XlibWrapper.StructureNotifyMask);
       
   565 
       
   566         XToolkit.RESTORE_XERROR_HANDLER();
       
   567 
       
   568         if (XToolkit.saved_error != null &&
       
   569             XToolkit.saved_error.get_error_code() != XlibWrapper.Success) {
       
   570             throw new XException("XSelectInput failed");
       
   571         }
       
   572 
       
   573         sourceWindow = source_win;
       
   574         sourceWindowMask = source_win_mask;
       
   575         sourceProtocolVersion = protocol_version;
       
   576         sourceActions = actions;
       
   577         sourceFormats = formats;
       
   578         trackSourceActions = track;
       
   579 
       
   580         return true;
       
   581     }
       
   582 
       
   583     private boolean processXdndPosition(XClientMessageEvent xclient) {
       
   584         long time_stamp = (int)XlibWrapper.CurrentTime;
       
   585         long xdnd_action = 0;
       
   586         int java_action = DnDConstants.ACTION_NONE;
       
   587         int x = 0;
       
   588         int y = 0;
       
   589 
       
   590         /* Ignore XDnD messages from all other windows. */
       
   591         if (sourceWindow != xclient.get_data(0)) {
       
   592             return false;
       
   593         }
       
   594 
       
   595         XWindow xwindow = null;
       
   596         {
       
   597             XBaseWindow xbasewindow = XToolkit.windowToXWindow(xclient.get_window());
       
   598             if (xbasewindow instanceof XWindow) {
       
   599                 xwindow = (XWindow)xbasewindow;
       
   600             }
       
   601         }
       
   602 
       
   603         x = (int)(xclient.get_data(2) >> 16);
       
   604         y = (int)(xclient.get_data(2) & 0xFFFF);
       
   605 
       
   606         if (xwindow == null) {
       
   607             long receiver =
       
   608                 XDropTargetRegistry.getRegistry().getEmbeddedDropSite(
       
   609                     xclient.get_window(), x, y);
       
   610 
       
   611             if (receiver != 0) {
       
   612                 XBaseWindow xbasewindow = XToolkit.windowToXWindow(receiver);
       
   613                 if (xbasewindow instanceof XWindow) {
       
   614                     xwindow = (XWindow)xbasewindow;
       
   615                 }
       
   616             }
       
   617         }
       
   618 
       
   619         if (xwindow != null) {
       
   620             /* Translate mouse position from root coordinates
       
   621                to the target window coordinates. */
       
   622             Point p = xwindow.toLocal(x, y);
       
   623             x = p.x;
       
   624             y = p.y;
       
   625         }
       
   626 
       
   627         /* Time stamp - new in XDnD version 1. */
       
   628         if (sourceProtocolVersion > 0) {
       
   629             time_stamp = xclient.get_data(3);
       
   630         }
       
   631 
       
   632         /* User action - new in XDnD version 2. */
       
   633         if (sourceProtocolVersion > 1) {
       
   634             xdnd_action = xclient.get_data(4);
       
   635         } else {
       
   636             /* The default action is XdndActionCopy */
       
   637             xdnd_action = XDnDConstants.XA_XdndActionCopy.getAtom();
       
   638         }
       
   639 
       
   640         java_action = XDnDConstants.getJavaActionForXDnDAction(xdnd_action);
       
   641 
       
   642         if (trackSourceActions) {
       
   643             sourceActions |= java_action;
       
   644         }
       
   645 
       
   646         if (xwindow == null) {
       
   647             if (targetXWindow != null) {
       
   648                 notifyProtocolListener(targetXWindow, x, y,
       
   649                                        DnDConstants.ACTION_NONE, xclient,
       
   650                                        MouseEvent.MOUSE_EXITED);
       
   651             }
       
   652         } else {
       
   653             int java_event_id = 0;
       
   654 
       
   655             if (targetXWindow == null) {
       
   656                 java_event_id = MouseEvent.MOUSE_ENTERED;
       
   657             } else {
       
   658                 java_event_id = MouseEvent.MOUSE_DRAGGED;
       
   659             }
       
   660 
       
   661             notifyProtocolListener(xwindow, x, y, java_action, xclient,
       
   662                                    java_event_id);
       
   663         }
       
   664 
       
   665         userAction = java_action;
       
   666         sourceX = x;
       
   667         sourceY = y;
       
   668         targetXWindow = xwindow;
       
   669 
       
   670         return true;
       
   671     }
       
   672 
       
   673     private boolean processXdndLeave(XClientMessageEvent xclient) {
       
   674         /* Ignore XDnD messages from all other windows. */
       
   675         if (sourceWindow != xclient.get_data(0)) {
       
   676             return false;
       
   677         }
       
   678 
       
   679         cleanup();
       
   680 
       
   681         return true;
       
   682     }
       
   683 
       
   684     private boolean processXdndDrop(XClientMessageEvent xclient) {
       
   685         /* Ignore XDnD messages from all other windows. */
       
   686         if (sourceWindow != xclient.get_data(0)) {
       
   687             return false;
       
   688         }
       
   689 
       
   690         if (targetXWindow != null) {
       
   691             notifyProtocolListener(targetXWindow, sourceX, sourceY, userAction,
       
   692                                    xclient, MouseEvent.MOUSE_RELEASED);
       
   693         }
       
   694 
       
   695         return true;
       
   696     }
       
   697 
       
   698     public int getMessageType(XClientMessageEvent xclient) {
       
   699         long messageType = xclient.get_message_type();
       
   700 
       
   701         if (messageType == XDnDConstants.XA_XdndEnter.getAtom()) {
       
   702             return ENTER_MESSAGE;
       
   703         } else if (messageType == XDnDConstants.XA_XdndPosition.getAtom()) {
       
   704             return MOTION_MESSAGE;
       
   705         } else if (messageType == XDnDConstants.XA_XdndLeave.getAtom()) {
       
   706             return LEAVE_MESSAGE;
       
   707         } else if (messageType == XDnDConstants.XA_XdndDrop.getAtom()) {
       
   708             return DROP_MESSAGE;
       
   709         } else {
       
   710             return UNKNOWN_MESSAGE;
       
   711         }
       
   712     }
       
   713 
       
   714     protected boolean processClientMessageImpl(XClientMessageEvent xclient) {
       
   715         long messageType = xclient.get_message_type();
       
   716 
       
   717         if (messageType == XDnDConstants.XA_XdndEnter.getAtom()) {
       
   718             return processXdndEnter(xclient);
       
   719         } else if (messageType == XDnDConstants.XA_XdndPosition.getAtom()) {
       
   720             return processXdndPosition(xclient);
       
   721         } else if (messageType == XDnDConstants.XA_XdndLeave.getAtom()) {
       
   722             return processXdndLeave(xclient);
       
   723         } else if (messageType == XDnDConstants.XA_XdndDrop.getAtom()) {
       
   724             return processXdndDrop(xclient);
       
   725         } else {
       
   726             return false;
       
   727         }
       
   728     }
       
   729 
       
   730     protected void sendEnterMessageToToplevel(long toplevel,
       
   731                                               XClientMessageEvent xclient) {
       
   732         /* flags */
       
   733         long data1 = sourceProtocolVersion << XDnDConstants.XDND_PROTOCOL_SHIFT;
       
   734         if (sourceFormats != null && sourceFormats.length > 3) {
       
   735             data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
       
   736         }
       
   737         long data2 = sourceFormats.length > 0 ? sourceFormats[0] : 0;
       
   738         long data3 = sourceFormats.length > 1 ? sourceFormats[1] : 0;
       
   739         long data4 = sourceFormats.length > 2 ? sourceFormats[2] : 0;
       
   740         sendEnterMessageToToplevelImpl(toplevel, xclient.get_data(0),
       
   741                                        data1, data2, data3, data4);
       
   742 
       
   743     }
       
   744 
       
   745     private void sendEnterMessageToToplevelImpl(long toplevel,
       
   746                                                 long sourceWindow,
       
   747                                                 long data1, long data2,
       
   748                                                 long data3, long data4) {
       
   749         XClientMessageEvent enter = new XClientMessageEvent();
       
   750         try {
       
   751             enter.set_type((int)XlibWrapper.ClientMessage);
       
   752             enter.set_window(toplevel);
       
   753             enter.set_format(32);
       
   754             enter.set_message_type(XDnDConstants.XA_XdndEnter.getAtom());
       
   755             /* XID of the source window */
       
   756             enter.set_data(0, sourceWindow);
       
   757             enter.set_data(1, data1);
       
   758             enter.set_data(2, data2);
       
   759             enter.set_data(3, data3);
       
   760             enter.set_data(4, data4);
       
   761 
       
   762             forwardClientMessageToToplevel(toplevel, enter);
       
   763         } finally {
       
   764             enter.dispose();
       
   765         }
       
   766     }
       
   767 
       
   768     protected void sendLeaveMessageToToplevel(long toplevel,
       
   769                                               XClientMessageEvent xclient) {
       
   770         sendLeaveMessageToToplevelImpl(toplevel, xclient.get_data(0));
       
   771     }
       
   772 
       
   773     protected void sendLeaveMessageToToplevelImpl(long toplevel,
       
   774                                                   long sourceWindow) {
       
   775         XClientMessageEvent leave = new XClientMessageEvent();
       
   776         try {
       
   777             leave.set_type((int)XlibWrapper.ClientMessage);
       
   778             leave.set_window(toplevel);
       
   779             leave.set_format(32);
       
   780             leave.set_message_type(XDnDConstants.XA_XdndLeave.getAtom());
       
   781             /* XID of the source window */
       
   782             leave.set_data(0, sourceWindow);
       
   783             /* flags */
       
   784             leave.set_data(1, 0);
       
   785 
       
   786             forwardClientMessageToToplevel(toplevel, leave);
       
   787         } finally {
       
   788             leave.dispose();
       
   789         }
       
   790     }
       
   791 
       
   792     public boolean sendResponse(long ctxt, int eventID, int action) {
       
   793         XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
       
   794 
       
   795         if (xclient.get_message_type() !=
       
   796             XDnDConstants.XA_XdndPosition.getAtom()) {
       
   797 
       
   798             return false;
       
   799         }
       
   800 
       
   801         if (eventID == MouseEvent.MOUSE_EXITED) {
       
   802             action = DnDConstants.ACTION_NONE;
       
   803         }
       
   804 
       
   805         XClientMessageEvent msg = new XClientMessageEvent();
       
   806         try {
       
   807             msg.set_type((int)XlibWrapper.ClientMessage);
       
   808             msg.set_window(xclient.get_data(0));
       
   809             msg.set_format(32);
       
   810             msg.set_message_type(XDnDConstants.XA_XdndStatus.getAtom());
       
   811             /* target window */
       
   812             msg.set_data(0, xclient.get_window());
       
   813             /* flags */
       
   814             long flags = 0;
       
   815             if (action != DnDConstants.ACTION_NONE) {
       
   816                 flags |= XDnDConstants.XDND_ACCEPT_DROP_FLAG;
       
   817             }
       
   818             msg.set_data(1, flags);
       
   819             /* specify an empty rectangle */
       
   820             msg.set_data(2, 0); /* x, y */
       
   821             msg.set_data(3, 0); /* w, h */
       
   822             /* action accepted by the target */
       
   823             msg.set_data(4, XDnDConstants.getXDnDActionForJavaAction(action));
       
   824 
       
   825             XToolkit.awtLock();
       
   826             try {
       
   827                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
       
   828                                        xclient.get_data(0),
       
   829                                        false, XlibWrapper.NoEventMask,
       
   830                                        msg.pData);
       
   831             } finally {
       
   832                 XToolkit.awtUnlock();
       
   833             }
       
   834         } finally {
       
   835             msg.dispose();
       
   836         }
       
   837 
       
   838         return true;
       
   839     }
       
   840 
       
   841     public Object getData(long ctxt, long format)
       
   842       throws IllegalArgumentException, IOException {
       
   843         XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
       
   844         long message_type = xclient.get_message_type();
       
   845         long time_stamp = XlibWrapper.CurrentTime;
       
   846 
       
   847         // NOTE: we assume that the source supports at least version 1, so we
       
   848         // can use the time stamp
       
   849         if (message_type == XDnDConstants.XA_XdndPosition.getAtom()) {
       
   850             // X server time is an unsigned 32-bit number!
       
   851             time_stamp = xclient.get_data(3) & 0xFFFFFFFFL;
       
   852         } else if (message_type == XDnDConstants.XA_XdndDrop.getAtom()) {
       
   853             // X server time is an unsigned 32-bit number!
       
   854             time_stamp = xclient.get_data(2) & 0xFFFFFFFFL;
       
   855         } else {
       
   856             throw new IllegalArgumentException();
       
   857         }
       
   858 
       
   859         return XDnDConstants.XDnDSelection.getData(format, time_stamp);
       
   860     }
       
   861 
       
   862     public boolean sendDropDone(long ctxt, boolean success, int dropAction) {
       
   863         XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
       
   864 
       
   865         if (xclient.get_message_type() !=
       
   866             XDnDConstants.XA_XdndDrop.getAtom()) {
       
   867             return false;
       
   868         }
       
   869 
       
   870         /*
       
   871          * The XDnD protocol recommends that the target requests the special
       
   872          * target DELETE in case if the drop action is XdndActionMove.
       
   873          */
       
   874         if (dropAction == DnDConstants.ACTION_MOVE && success) {
       
   875 
       
   876             long time_stamp = xclient.get_data(2);
       
   877             long xdndSelectionAtom =
       
   878                 XDnDConstants.XDnDSelection.getSelectionAtom().getAtom();
       
   879 
       
   880             XToolkit.awtLock();
       
   881             try {
       
   882                 XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
       
   883                                               xdndSelectionAtom,
       
   884                                               XAtom.get("DELETE").getAtom(),
       
   885                                               XAtom.get("XAWT_SELECTION").getAtom(),
       
   886                                               XWindow.getXAWTRootWindow().getWindow(),
       
   887                                               time_stamp);
       
   888             } finally {
       
   889                 XToolkit.awtUnlock();
       
   890             }
       
   891         }
       
   892 
       
   893         XClientMessageEvent msg = new XClientMessageEvent();
       
   894         try {
       
   895             msg.set_type((int)XlibWrapper.ClientMessage);
       
   896             msg.set_window(xclient.get_data(0));
       
   897             msg.set_format(32);
       
   898             msg.set_message_type(XDnDConstants.XA_XdndFinished.getAtom());
       
   899             msg.set_data(0, xclient.get_window()); /* target window */
       
   900             msg.set_data(1, 0); /* flags */
       
   901             /* specify an empty rectangle */
       
   902             msg.set_data(2, 0);
       
   903             if (sourceProtocolVersion >= 5) {
       
   904                 if (success) {
       
   905                     msg.set_data(1, XDnDConstants.XDND_ACCEPT_DROP_FLAG);
       
   906                 }
       
   907                 /* action performed by the target */
       
   908                 msg.set_data(2, XDnDConstants.getXDnDActionForJavaAction(dropAction));
       
   909             }
       
   910             msg.set_data(3, 0);
       
   911             msg.set_data(4, 0);
       
   912 
       
   913             XToolkit.awtLock();
       
   914             try {
       
   915                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
       
   916                                        xclient.get_data(0),
       
   917                                        false, XlibWrapper.NoEventMask,
       
   918                                        msg.pData);
       
   919             } finally {
       
   920                 XToolkit.awtUnlock();
       
   921             }
       
   922         } finally {
       
   923             msg.dispose();
       
   924         }
       
   925 
       
   926         /*
       
   927          * Flush the buffer to guarantee that the drop completion event is sent
       
   928          * to the source before the method returns.
       
   929          */
       
   930         XToolkit.awtLock();
       
   931         try {
       
   932             XlibWrapper.XFlush(XToolkit.getDisplay());
       
   933         } finally {
       
   934             XToolkit.awtUnlock();
       
   935         }
       
   936 
       
   937         /* Trick to prevent cleanup() from posting dragExit */
       
   938         targetXWindow = null;
       
   939 
       
   940         /* Cannot do cleanup before the drop finishes as we may need
       
   941            source protocol version to send drop finished message. */
       
   942         cleanup();
       
   943         return true;
       
   944     }
       
   945 
       
   946     public final long getSourceWindow() {
       
   947         return sourceWindow;
       
   948     }
       
   949 
       
   950     /**
       
   951      * Reset the state of the object.
       
   952      */
       
   953     public void cleanup() {
       
   954         // Clear the reference to this protocol.
       
   955         XDropTargetEventProcessor.reset();
       
   956 
       
   957         if (targetXWindow != null) {
       
   958             notifyProtocolListener(targetXWindow, 0, 0,
       
   959                                    DnDConstants.ACTION_NONE, null,
       
   960                                    MouseEvent.MOUSE_EXITED);
       
   961         }
       
   962 
       
   963         if (sourceWindow != 0) {
       
   964             XToolkit.awtLock();
       
   965             try {
       
   966                 XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
       
   967                 XlibWrapper.XSelectInput(XToolkit.getDisplay(), sourceWindow,
       
   968                                          sourceWindowMask);
       
   969                 XToolkit.RESTORE_XERROR_HANDLER();
       
   970             } finally {
       
   971                 XToolkit.awtUnlock();
       
   972             }
       
   973         }
       
   974 
       
   975         sourceWindow = 0;
       
   976         sourceWindowMask = 0;
       
   977         sourceProtocolVersion = 0;
       
   978         sourceActions = DnDConstants.ACTION_NONE;
       
   979         sourceFormats = null;
       
   980         trackSourceActions = false;
       
   981         userAction = DnDConstants.ACTION_NONE;
       
   982         sourceX = 0;
       
   983         sourceY = 0;
       
   984         targetXWindow = null;
       
   985     }
       
   986 
       
   987     public boolean isDragOverComponent() {
       
   988         return targetXWindow != null;
       
   989     }
       
   990 
       
   991     public void adjustEventForForwarding(XClientMessageEvent xclient,
       
   992                                          EmbedderRegistryEntry entry) {
       
   993         /* Adjust the event to match the XDnD protocol version. */
       
   994         int version = entry.getVersion();
       
   995         if (xclient.get_message_type() == XDnDConstants.XA_XdndEnter.getAtom()) {
       
   996             int min_version = sourceProtocolVersion < version ?
       
   997                 sourceProtocolVersion : version;
       
   998             long data1 = min_version << XDnDConstants.XDND_PROTOCOL_SHIFT;
       
   999             if (sourceFormats != null && sourceFormats.length > 3) {
       
  1000                 data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
       
  1001             }
       
  1002             if (logger.isLoggable(Level.FINEST)) {
       
  1003                 logger.finest("         "
       
  1004                               + " entryVersion=" + version
       
  1005                               + " sourceProtocolVersion=" +
       
  1006                               sourceProtocolVersion
       
  1007                               + " sourceFormats.length=" +
       
  1008                               (sourceFormats != null ? sourceFormats.length : 0));
       
  1009             }
       
  1010             xclient.set_data(1, data1);
       
  1011         }
       
  1012     }
       
  1013 
       
  1014     private void notifyProtocolListener(XWindow xwindow, int x, int y,
       
  1015                                         int dropAction,
       
  1016                                         XClientMessageEvent xclient,
       
  1017                                         int eventID) {
       
  1018         long nativeCtxt = 0;
       
  1019 
       
  1020         // Make a copy of the passed XClientMessageEvent structure, since
       
  1021         // the original structure can be freed before this
       
  1022         // SunDropTargetEvent is dispatched.
       
  1023         if (xclient != null) {
       
  1024             int size = new XClientMessageEvent(nativeCtxt).getSize();
       
  1025 
       
  1026             nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
       
  1027 
       
  1028             unsafe.copyMemory(xclient.pData, nativeCtxt, size);
       
  1029 
       
  1030             long data1 = sourceProtocolVersion << XDnDConstants.XDND_PROTOCOL_SHIFT;
       
  1031             if (sourceFormats != null && sourceFormats.length > 3) {
       
  1032                 data1 |= XDnDConstants.XDND_DATA_TYPES_BIT;
       
  1033             }
       
  1034             // Append information from the latest XdndEnter event.
       
  1035             Native.putLong(nativeCtxt + size, data1);
       
  1036             Native.putLong(nativeCtxt + size + Native.getLongSize(),
       
  1037                            sourceFormats.length > 0 ? sourceFormats[0] : 0);
       
  1038             Native.putLong(nativeCtxt + size + 2 * Native.getLongSize(),
       
  1039                            sourceFormats.length > 1 ? sourceFormats[1] : 0);
       
  1040             Native.putLong(nativeCtxt + size + 3 * Native.getLongSize(),
       
  1041                            sourceFormats.length > 2 ? sourceFormats[2] : 0);
       
  1042         }
       
  1043 
       
  1044         getProtocolListener().handleDropTargetNotification(xwindow, x, y,
       
  1045                                                            dropAction,
       
  1046                                                            sourceActions,
       
  1047                                                            sourceFormats,
       
  1048                                                            nativeCtxt,
       
  1049                                                            eventID);
       
  1050     }
       
  1051 
       
  1052     /*
       
  1053      * The methods/fields defined below are executed/accessed only on
       
  1054      * the toolkit thread.
       
  1055      * The methods/fields defined below are executed/accessed only on the event
       
  1056      * dispatch thread.
       
  1057      */
       
  1058 
       
  1059     public boolean forwardEventToEmbedded(long embedded, long ctxt,
       
  1060                                           int eventID) {
       
  1061         if (logger.isLoggable(Level.FINEST)) {
       
  1062             logger.finest("        ctxt=" + ctxt +
       
  1063                           " type=" + (ctxt != 0 ?
       
  1064                                       getMessageType(new
       
  1065                                           XClientMessageEvent(ctxt)) : 0) +
       
  1066                           " prevCtxt=" + prevCtxt +
       
  1067                           " prevType=" + (prevCtxt != 0 ?
       
  1068                                       getMessageType(new
       
  1069                                           XClientMessageEvent(prevCtxt)) : 0));
       
  1070         }
       
  1071         if ((ctxt == 0 ||
       
  1072              getMessageType(new XClientMessageEvent(ctxt)) == UNKNOWN_MESSAGE) &&
       
  1073             (prevCtxt == 0 ||
       
  1074              getMessageType(new XClientMessageEvent(prevCtxt)) == UNKNOWN_MESSAGE)) {
       
  1075             return false;
       
  1076         }
       
  1077 
       
  1078         // The size of XClientMessageEvent structure.
       
  1079         int size = XClientMessageEvent.getSize();
       
  1080 
       
  1081         if (ctxt != 0) {
       
  1082             XClientMessageEvent xclient = new XClientMessageEvent(ctxt);
       
  1083             if (!overXEmbedClient) {
       
  1084                 long data1 = Native.getLong(ctxt + size);
       
  1085                 long data2 = Native.getLong(ctxt + size + Native.getLongSize());
       
  1086                 long data3 = Native.getLong(ctxt + size + 2 * Native.getLongSize());
       
  1087                 long data4 = Native.getLong(ctxt + size + 3 * Native.getLongSize());
       
  1088 
       
  1089                 if (logger.isLoggable(Level.FINEST)) {
       
  1090                     logger.finest("         1 "
       
  1091                                   + " embedded=" + embedded
       
  1092                                   + " source=" + xclient.get_data(0)
       
  1093                                   + " data1=" + data1
       
  1094                                   + " data2=" + data2
       
  1095                                   + " data3=" + data3
       
  1096                                   + " data4=" + data4);
       
  1097                 }
       
  1098 
       
  1099                 // Copy XdndTypeList from source to proxy.
       
  1100                 if ((data1 & XDnDConstants.XDND_DATA_TYPES_BIT) != 0) {
       
  1101                     WindowPropertyGetter wpg =
       
  1102                         new WindowPropertyGetter(xclient.get_data(0),
       
  1103                                                  XDnDConstants.XA_XdndTypeList,
       
  1104                                                  0, 0xFFFF, false,
       
  1105                                                  XAtom.XA_ATOM);
       
  1106                     try {
       
  1107                         wpg.execute(XToolkit.IgnoreBadWindowHandler);
       
  1108 
       
  1109                         if (wpg.getActualType() == XAtom.XA_ATOM &&
       
  1110                             wpg.getActualFormat() == 32) {
       
  1111 
       
  1112                             XToolkit.awtLock();
       
  1113                             try {
       
  1114                                 XToolkit.WITH_XERROR_HANDLER(XWM.VerifyChangePropertyHandler);
       
  1115                                 XDnDConstants.XA_XdndTypeList.setAtomData(xclient.get_window(),
       
  1116                                                                           XAtom.XA_ATOM,
       
  1117                                                                           wpg.getData(),
       
  1118                                                                           wpg.getNumberOfItems());
       
  1119                                 XToolkit.RESTORE_XERROR_HANDLER();
       
  1120 
       
  1121                                 if (XToolkit.saved_error != null &&
       
  1122                                     XToolkit.saved_error.get_error_code() != XlibWrapper.Success) {
       
  1123                                     if (logger.isLoggable(Level.WARNING)) {
       
  1124                                         logger.warning("Cannot set XdndTypeList on the proxy window");
       
  1125                                     }
       
  1126                                 }
       
  1127                             } finally {
       
  1128                                 XToolkit.awtUnlock();
       
  1129                             }
       
  1130                         } else {
       
  1131                             if (logger.isLoggable(Level.WARNING)) {
       
  1132                                 logger.warning("Cannot read XdndTypeList from the source window");
       
  1133                             }
       
  1134                         }
       
  1135                     } finally {
       
  1136                         wpg.dispose();
       
  1137                     }
       
  1138                 }
       
  1139                 XDragSourceContextPeer.setProxyModeSourceWindow(xclient.get_data(0));
       
  1140 
       
  1141                 sendEnterMessageToToplevelImpl(embedded, xclient.get_window(),
       
  1142                                                data1, data2, data3, data4);
       
  1143                 overXEmbedClient = true;
       
  1144             }
       
  1145 
       
  1146             if (logger.isLoggable(Level.FINEST)) {
       
  1147                 logger.finest("         2 "
       
  1148                               + " embedded=" + embedded
       
  1149                               + " xclient=" + xclient);
       
  1150             }
       
  1151 
       
  1152             /* Make a copy of the original event, since we are going to modify the
       
  1153                event while it still can be referenced from other Java events. */
       
  1154             {
       
  1155                 XClientMessageEvent copy = new XClientMessageEvent();
       
  1156                 unsafe.copyMemory(xclient.pData, copy.pData, copy.getSize());
       
  1157 
       
  1158                 copy.set_data(0, xclient.get_window());
       
  1159 
       
  1160                 forwardClientMessageToToplevel(embedded, copy);
       
  1161             }
       
  1162         }
       
  1163 
       
  1164         if (eventID == MouseEvent.MOUSE_EXITED) {
       
  1165             if (overXEmbedClient) {
       
  1166                 if (ctxt != 0 || prevCtxt != 0) {
       
  1167                     // Last chance to send XdndLeave to the XEmbed client.
       
  1168                     XClientMessageEvent xclient = ctxt != 0 ?
       
  1169                         new XClientMessageEvent(ctxt) :
       
  1170                         new XClientMessageEvent(prevCtxt);
       
  1171                     sendLeaveMessageToToplevelImpl(embedded, xclient.get_window());
       
  1172                 }
       
  1173                 overXEmbedClient = false;
       
  1174                 // We have to clear the proxy mode source window here,
       
  1175                 // when the drag exits the XEmbedCanvasPeer.
       
  1176                 // NOTE: at this point the XEmbed client still might have some
       
  1177                 // drag notifications to process and it will send responses to
       
  1178                 // us. With the proxy mode source window cleared we won't be
       
  1179                 // able to forward these responses to the actual source. This is
       
  1180                 // not a problem if the drag operation was initiated in this
       
  1181                 // JVM. However, if it was initiated in another processes the
       
  1182                 // responses will be lost. We bear with it for now, as it seems
       
  1183                 // there is no other reliable point to clear.
       
  1184                 XDragSourceContextPeer.setProxyModeSourceWindow(0);
       
  1185             }
       
  1186         }
       
  1187 
       
  1188         if (eventID == MouseEvent.MOUSE_RELEASED) {
       
  1189             overXEmbedClient = false;
       
  1190             cleanup();
       
  1191         }
       
  1192 
       
  1193         if (prevCtxt != 0) {
       
  1194             unsafe.freeMemory(prevCtxt);
       
  1195             prevCtxt = 0;
       
  1196         }
       
  1197 
       
  1198         if (ctxt != 0 && overXEmbedClient) {
       
  1199             prevCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
       
  1200 
       
  1201             unsafe.copyMemory(ctxt, prevCtxt, size + 4 * Native.getLongSize());
       
  1202         }
       
  1203 
       
  1204         return true;
       
  1205     }
       
  1206 
       
  1207     public boolean isXEmbedSupported() {
       
  1208         return true;
       
  1209     }
       
  1210 }