jdk/src/solaris/native/sun/awt/awt_dnd_ds.c
changeset 1203 3e5496df0d2b
parent 1202 5a725d2f0daa
parent 1201 e87f9c042699
child 1211 b659a7cee935
--- a/jdk/src/solaris/native/sun/awt/awt_dnd_ds.c	Thu Sep 11 11:25:48 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1796 +0,0 @@
-/*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-#ifdef HEADLESS
-    #error This file should not be included in headless library
-#endif
-
-#include "awt_dnd.h"
-
-/* Declares getCursor(JNIEnv, jobject) */
-#include "awt_Cursor.h"
-
-/* Define java constants */
-#include "java_awt_dnd_DnDConstants.h"
-#include "sun_awt_dnd_SunDragSourceContextPeer.h"
-
-/* Define DECLARE_* macros */
-#include "awt_DataTransferer.h"
-
-#define GRAB_EVENT_MASK                                          \
-   (ButtonPressMask | ButtonMotionMask | ButtonReleaseMask)
-
-/* Events selected on the root window during drag. */
-#define ROOT_EVENT_MASK                                          \
-   (ButtonMotionMask | KeyPressMask | KeyReleaseMask)
-
-/* Events selected on registered receiver windows during drag. */
-#define RECEIVER_EVENT_MASK                                      \
-   (StructureNotifyMask)
-
-
-/* in canvas.c */
-extern jint getModifiers(uint32_t state, jint button, jint keyCode);
-
-typedef struct {
-    CARD8    byte_order;
-    CARD8    protocol_version;
-    CARD16   index;
-    CARD32   selection_atom;
-} InitiatorInfo;
-
-typedef enum {
-    /*
-     * Communicate with receivers of both protocols.
-     * If the receiver supports both protocols,
-     * choose Motif DnD for communication.
-     */
-    DS_POLICY_PREFER_MOTIF,
-    /*
-     * Communicate with receivers of both protocols.
-     * If the receiver supports both protocols,
-     * choose XDnD for communication. [default]
-     */
-    DS_POLICY_PREFER_XDND,
-    /* Communicate only with Motif DnD receivers. */
-    DS_POLICY_ONLY_MOTIF,
-    /* Communicate only with XDnD receivers. */
-    DS_POLICY_ONLY_XDND
-} DragSourcePolicy;
-
-
-/* The drag source policy. */
-static DragSourcePolicy drag_source_policy = DS_POLICY_PREFER_XDND;
-
-static Boolean dnd_in_progress = False;
-static Boolean drag_in_progress = False;
-static jobject source_peer = NULL;
-static Atom* data_types = NULL;
-static unsigned int data_types_count = 0;
-static Window drag_root_window = None;
-static EventMask your_root_event_mask = NoEventMask;
-static Time latest_time_stamp = CurrentTime;
-
-/* The child of the root which is currently under the mouse. */
-static Window target_root_subwindow = None;
-
-static Window target_window = None;
-static long target_window_mask = 0;
-static Window target_proxy_window = None;
-static Protocol target_protocol = NO_PROTOCOL;
-static unsigned int target_protocol_version = 0;
-/*
- * The server time when the pointer entered the current target -
- * needed on Motif DnD to filter out messages from the previous
- * target.
- * It is updated whenever the target_window is updated.
- * If the target_window is set to non-None, it is set to the time stamp
- * of the X event that trigger the update. Otherwise, it is set to CurrentTime.
- */
-static Time target_enter_server_time = CurrentTime;
-
-static int x_root = 0;
-static int y_root = 0;
-static unsigned int event_state = 0;
-
-static jint source_action = java_awt_dnd_DnDConstants_ACTION_NONE;
-static jint source_actions = java_awt_dnd_DnDConstants_ACTION_NONE;
-static jint target_action = java_awt_dnd_DnDConstants_ACTION_NONE;
-
-/* Forward declarations */
-static void cleanup_drag(Display* dpy, Time time);
-static Boolean process_proxy_mode_event(XEvent* xev);
-
-/**************************** XEmbed server DnD support ***********************/
-static Window proxy_mode_source_window = None;
-/******************************************************************************/
-
-/**************************** JNI stuff ***************************************/
-
-DECLARE_JAVA_CLASS(dscp_clazz, "sun/awt/dnd/SunDragSourceContextPeer")
-
-static void
-ds_postDragSourceDragEvent(JNIEnv* env, jint targetAction, unsigned int state,
-                           int x, int y, jint dispatch_type) {
-    DECLARE_VOID_JAVA_METHOD(dscp_postDragSourceDragEvent, dscp_clazz,
-                             "postDragSourceDragEvent", "(IIIII)V");
-
-    DASSERT(!JNU_IsNull(env, source_peer));
-    if (JNU_IsNull(env, source_peer)) {
-        return;
-    }
-
-    (*env)->CallVoidMethod(env, source_peer, dscp_postDragSourceDragEvent,
-                           targetAction, getModifiers(state, 0, 0), x, y,
-                           dispatch_type);
-}
-
-static jint
-ds_convertModifiersToDropAction(JNIEnv* env, unsigned int state) {
-    jint action;
-    DECLARE_STATIC_JINT_JAVA_METHOD(dscp_convertModifiersToDropAction, dscp_clazz,
-                                    "convertModifiersToDropAction", "(II)I");
-    action = (*env)->CallStaticIntMethod(env, clazz, dscp_convertModifiersToDropAction,
-                                              getModifiers(state, 0, 0), source_actions);
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        return java_awt_dnd_DnDConstants_ACTION_NONE;
-    }
-    return action;
-}
-
-static void
-ds_postDragSourceEvent(JNIEnv* env, int x, int y) {
-    DECLARE_VOID_JAVA_METHOD(dscp_dragExit, dscp_clazz,
-                             "dragExit", "(II)V");
-
-    DASSERT(!JNU_IsNull(env, source_peer));
-    if (JNU_IsNull(env, source_peer)) {
-        return;
-    }
-
-    (*env)->CallVoidMethod(env, source_peer, dscp_dragExit, x, y);
-}
-
-static void
-ds_postDragSourceDropEvent(JNIEnv* env, jboolean success, jint targetAction,
-                           int x, int y) {
-    DECLARE_VOID_JAVA_METHOD(dscp_dragDropFinished, dscp_clazz,
-                             "dragDropFinished", "(ZIII)V");
-
-    DASSERT(!JNU_IsNull(env, source_peer));
-    if (JNU_IsNull(env, source_peer)) {
-        return;
-    }
-
-    (*env)->CallVoidMethod(env, source_peer, dscp_dragDropFinished,
-                           success, targetAction, x, y);
-}
-
-/******************************************************************************/
-
-static void
-cancel_drag(XtPointer client_data, XtIntervalId* id) {
-    Time time_stamp = awt_util_getCurrentServerTime();
-
-    cleanup_drag(awt_display, time_stamp);
-}
-
-#define DONT_CARE -1
-
-static void
-awt_popupCallback(Widget shell, XtPointer closure, XtPointer call_data) {
-    XtGrabKind grab_kind = XtGrabNone;
-
-    if (call_data != NULL) {
-        grab_kind = *((XtGrabKind*)call_data);
-    }
-
-    if (XmIsVendorShell(shell)) {
-        int input_mode;
-        XtVaGetValues(shell, XmNmwmInputMode, &input_mode, NULL);
-        switch (input_mode) {
-        case DONT_CARE:
-        case MWM_INPUT_MODELESS:
-            grab_kind = XtGrabNonexclusive; break;
-        case MWM_INPUT_PRIMARY_APPLICATION_MODAL:
-        case MWM_INPUT_SYSTEM_MODAL:
-        case MWM_INPUT_FULL_APPLICATION_MODAL:
-            grab_kind = XtGrabExclusive; break;
-        }
-    }
-
-    if (grab_kind == XtGrabExclusive) {
-        /*
-         * We should cancel the drag on the toolkit thread. Otherwise, it can be
-         * called while the toolkit thread is waiting inside some drag callback.
-         * In this case Motif will crash when the drag callback returns.
-         */
-        XtAppAddTimeOut(awt_appContext, 0L, cancel_drag, NULL);
-    }
-}
-
-static XtInitProc xt_shell_initialize = NULL;
-
-static void
-awt_ShellInitialize(Widget req, Widget new, ArgList args, Cardinal *num_args) {
-    XtAddCallback(new, XtNpopupCallback, awt_popupCallback, NULL);
-    (*xt_shell_initialize)(req, new, args, num_args);
-}
-
-/*
- * Fix for 4484572 (copied from awt_XmDnD.c).
- * Modify the 'initialize' routine for all ShellWidget instances, so that it
- * will install an XtNpopupCallback that cancels the current drag operation.
- * It is needed, since AWT doesn't have full control over all ShellWidget
- * instances (e.g. XmPopupMenu internally creates and popups an XmMenuShell).
- */
-static void
-awt_set_ShellInitialize() {
-    static Boolean inited = False;
-
-    DASSERT(!inited);
-    if (inited) {
-        return;
-    }
-
-    xt_shell_initialize = shellWidgetClass->core_class.initialize;
-    shellWidgetClass->core_class.initialize = (XtInitProc)awt_ShellInitialize;
-    inited = True;
-}
-
-/*
- * Returns True if initialization completes successfully.
- */
-Boolean
-awt_dnd_ds_init(Display* display) {
-    if (XSaveContext(display, XA_XdndSelection, awt_convertDataContext,
-                     (XPointer)NULL) == XCNOMEM) {
-        return False;
-    }
-
-    if (XSaveContext(display, _XA_MOTIF_ATOM_0, awt_convertDataContext,
-                     (XPointer)NULL) == XCNOMEM) {
-        return False;
-    }
-
-    {
-        char *ev = getenv("_JAVA_DRAG_SOURCE_POLICY");
-
-        /* By default XDnD protocol is preferred. */
-        drag_source_policy = DS_POLICY_PREFER_XDND;
-
-        if (ev != NULL) {
-            if (strcmp(ev, "PREFER_XDND") == 0) {
-                drag_source_policy = DS_POLICY_PREFER_XDND;
-            } else if (strcmp(ev, "PREFER_MOTIF") == 0) {
-                drag_source_policy = DS_POLICY_PREFER_MOTIF;
-            } else if (strcmp(ev, "ONLY_MOTIF") == 0) {
-                drag_source_policy = DS_POLICY_ONLY_MOTIF;
-            } else if (strcmp(ev, "ONLY_XDND") == 0) {
-                drag_source_policy = DS_POLICY_ONLY_XDND;
-            }
-        }
-    }
-
-    awt_set_ShellInitialize();
-
-    return True;
-}
-
-/*
- * Returns a handle of the window used as a drag source.
- */
-Window
-awt_dnd_ds_get_source_window() {
-    return get_awt_root_window();
-}
-
-/*
- * Returns True if a drag operation initiated by this client
- * is still in progress.
- */
-Boolean
-awt_dnd_ds_in_progress() {
-    return dnd_in_progress;
-}
-
-static void
-ds_send_event_to_target(XClientMessageEvent* xclient) {
-    /* Shortcut if the source is in the same JVM. */
-    if (XtWindowToWidget(xclient->display, target_proxy_window) != NULL) {
-        awt_dnd_dt_process_event((XEvent*)xclient);
-    } else {
-        XSendEvent(xclient->display, target_proxy_window, False, NoEventMask,
-                   (XEvent*)xclient);
-    }
-}
-
-static void
-xdnd_send_enter(Display* dpy, Time time) {
-    XClientMessageEvent enter;
-
-    enter.display = dpy;
-    enter.type = ClientMessage;
-    enter.window = target_window;
-    enter.format = 32;
-    enter.message_type = XA_XdndEnter;
-    enter.data.l[0] = awt_dnd_ds_get_source_window();
-    enter.data.l[1] = target_protocol_version << XDND_PROTOCOL_SHIFT;
-    enter.data.l[1] |= data_types_count > 3 ? XDND_DATA_TYPES_BIT : 0;
-    enter.data.l[2] = data_types_count > 0 ? data_types[0] : None;
-    enter.data.l[3] = data_types_count > 1 ? data_types[1] : None;
-    enter.data.l[4] = data_types_count > 2 ? data_types[2] : None;
-
-    ds_send_event_to_target(&enter);
-}
-
-static void
-motif_send_enter(Display* dpy, Time time) {
-    XClientMessageEvent enter;
-
-    enter.display = dpy;
-    enter.type = ClientMessage;
-    enter.window = target_window;
-    enter.format = 8;
-    enter.message_type = _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
-
-    {
-        void* p = &enter.data.b[0];
-        int flags = 0;
-
-        flags |= java_to_motif_actions(source_action) << MOTIF_DND_ACTION_SHIFT;
-        flags |= java_to_motif_actions(source_actions) << MOTIF_DND_ACTIONS_SHIFT;
-
-        write_card8(&p, TOP_LEVEL_ENTER | MOTIF_MESSAGE_FROM_INITIATOR);
-        write_card8(&p, MOTIF_BYTE_ORDER);
-        write_card16(&p, flags);
-        write_card32(&p, time);
-        write_card32(&p, awt_dnd_ds_get_source_window());
-        write_card32(&p, _XA_MOTIF_ATOM_0);
-    }
-
-    ds_send_event_to_target(&enter);
-}
-
-static void
-send_enter(Display* dpy, Time time) {
-    switch (target_protocol) {
-    case XDND_PROTOCOL:
-        xdnd_send_enter(dpy, time);
-        break;
-    case MOTIF_DND_PROTOCOL:
-        motif_send_enter(dpy, time);
-        break;
-    case NO_PROTOCOL:
-    default:
-        DTRACE_PRINTLN2("%s:%d send_enter: unknown DnD protocol.", __FILE__, __LINE__);
-        break;
-    }
-}
-
-static void
-xdnd_send_move(XMotionEvent* event) {
-    XClientMessageEvent move;
-
-    move.display = event->display;
-    move.type = ClientMessage;
-    move.window = target_window;
-    move.format = 32;
-    move.message_type = XA_XdndPosition;
-    move.data.l[0] = awt_dnd_ds_get_source_window();
-    move.data.l[1] = 0; /* flags */
-    move.data.l[2] = event->x_root << 16 | event->y_root;
-    move.data.l[3] = event->time;
-    move.data.l[4] = java_to_xdnd_action(source_action);
-
-    ds_send_event_to_target(&move);
-}
-
-static void
-motif_send_move(XMotionEvent* event) {
-    XClientMessageEvent move;
-
-    move.display = event->display;
-    move.type = ClientMessage;
-    move.window = target_window;
-    move.format = 8;
-    move.message_type = _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
-
-    {
-        void* p = move.data.b;
-        int flags = 0;
-
-        flags |= java_to_motif_actions(source_action) << MOTIF_DND_ACTION_SHIFT;
-        flags |= java_to_motif_actions(source_actions) << MOTIF_DND_ACTIONS_SHIFT;
-
-        write_card8(&p, DRAG_MOTION | MOTIF_MESSAGE_FROM_INITIATOR);
-        write_card8(&p, MOTIF_BYTE_ORDER);
-        write_card16(&p, flags);
-        write_card32(&p, event->time);
-        write_card16(&p, event->x_root);
-        write_card16(&p, event->y_root);
-    }
-
-    ds_send_event_to_target(&move);
-}
-
-static void
-send_move(XMotionEvent* event) {
-    switch (target_protocol) {
-    case XDND_PROTOCOL:
-        xdnd_send_move(event);
-        break;
-    case MOTIF_DND_PROTOCOL:
-        motif_send_move(event);
-        break;
-    case NO_PROTOCOL:
-    default:
-        DTRACE_PRINTLN2("%s:%d send_move: unknown DnD protocol.", __FILE__, __LINE__);
-        break;
-    }
-}
-
-static void
-xdnd_send_leave(Display* dpy, Time time) {
-    XClientMessageEvent leave;
-
-    leave.display = dpy;
-    leave.type = ClientMessage;
-    leave.window = target_window;
-    leave.format = 32;
-    leave.message_type = XA_XdndLeave;
-    leave.data.l[0] = awt_dnd_ds_get_source_window();
-    leave.data.l[1] = 0;
-    leave.data.l[2] = 0;
-    leave.data.l[3] = 0;
-    leave.data.l[4] = 0;
-
-    ds_send_event_to_target(&leave);
-}
-
-static void
-motif_send_leave(Display* dpy, Time time) {
-    XClientMessageEvent leave;
-
-    leave.display = dpy;
-    leave.type = ClientMessage;
-    leave.window = target_window;
-    leave.format = 8;
-    leave.message_type = _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
-
-    {
-        void* p = &leave.data.b[0];
-
-        write_card8(&p, TOP_LEVEL_LEAVE | MOTIF_MESSAGE_FROM_INITIATOR);
-        write_card8(&p, MOTIF_BYTE_ORDER);
-        write_card16(&p, 0);
-        write_card32(&p, time);
-        write_card32(&p, awt_dnd_ds_get_source_window());
-    }
-
-    ds_send_event_to_target(&leave);
-}
-
-static void
-send_leave(Display* dpy, Time time) {
-    switch (target_protocol) {
-    case XDND_PROTOCOL:
-        xdnd_send_leave(dpy, time);
-        break;
-    case MOTIF_DND_PROTOCOL:
-        motif_send_leave(dpy, time);
-        break;
-    case NO_PROTOCOL:
-    default:
-        DTRACE_PRINTLN2("%s:%d send_leave: unknown DnD protocol.", __FILE__, __LINE__);
-        break;
-    }
-}
-
-
-static void
-xdnd_send_drop(XButtonEvent* event) {
-    XClientMessageEvent drop;
-
-    drop.display = event->display;
-    drop.type = ClientMessage;
-    drop.window = target_window;
-    drop.format = 32;
-    drop.message_type = XA_XdndDrop;
-    drop.data.l[0] = awt_dnd_ds_get_source_window();
-    drop.data.l[1] = 0; /* flags */
-    drop.data.l[2] = event->time; /* ### */
-    drop.data.l[3] = 0;
-    drop.data.l[4] = 0;
-
-    ds_send_event_to_target(&drop);
-}
-
-static void
-motif_send_drop(XButtonEvent* event) {
-    XClientMessageEvent drop;
-
-    /*
-     * Motif drop sites expect TOP_LEVEL_LEAVE before DROP_START.
-     */
-    motif_send_leave(event->display, event->time);
-
-    drop.display = event->display;
-    drop.type = ClientMessage;
-    drop.window = target_window;
-    drop.format = 8;
-    drop.message_type = _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
-
-    {
-        void* p = &drop.data.b[0];
-        int flags = 0;
-
-        flags |= java_to_motif_actions(source_action) << MOTIF_DND_ACTION_SHIFT;
-        flags |= java_to_motif_actions(source_actions) << MOTIF_DND_ACTIONS_SHIFT;
-
-        write_card8(&p, DROP_START | MOTIF_MESSAGE_FROM_INITIATOR);
-        write_card8(&p, MOTIF_BYTE_ORDER);
-        write_card16(&p, flags);
-        write_card32(&p, event->time);
-        write_card16(&p, event->x_root);
-        write_card16(&p, event->y_root);
-        write_card32(&p, _XA_MOTIF_ATOM_0);
-        write_card32(&p, awt_dnd_ds_get_source_window());
-    }
-
-    ds_send_event_to_target(&drop);
-}
-
-static void
-send_drop(XButtonEvent* event) {
-    switch (target_protocol) {
-    case XDND_PROTOCOL:
-        xdnd_send_drop(event);
-        break;
-    case MOTIF_DND_PROTOCOL:
-        motif_send_drop(event);
-        break;
-    case NO_PROTOCOL:
-    default:
-        DTRACE_PRINTLN2("%s:%d send_drop: unknown DnD protocol.", __FILE__, __LINE__);
-        break;
-    }
-}
-
-static void
-remove_dnd_grab(Display* dpy, Time time) {
-    XUngrabPointer(dpy, time);
-    XUngrabKeyboard(dpy, time);
-
-    /* Restore the root event mask if it was changed. */
-    if ((your_root_event_mask | ROOT_EVENT_MASK) != your_root_event_mask &&
-        drag_root_window != None) {
-
-        XSelectInput(dpy, drag_root_window, your_root_event_mask);
-
-        drag_root_window = None;
-        your_root_event_mask = NoEventMask;
-    }
-}
-
-static void
-cleanup_target_info(Display* dpy) {
-    target_root_subwindow = None;
-
-    target_window = None;
-    target_proxy_window = None;
-    target_protocol = NO_PROTOCOL;
-    target_protocol_version = 0;
-    target_enter_server_time = CurrentTime;
-    target_action = java_awt_dnd_DnDConstants_ACTION_NONE;
-}
-
-static void
-cleanup_drag(Display* dpy, Time time) {
-    JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-
-    if (dnd_in_progress) {
-        if (target_window != None) {
-            send_leave(dpy, time);
-        }
-
-        if (target_action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-            JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-            ds_postDragSourceEvent(env, x_root, y_root);
-        }
-
-        ds_postDragSourceDropEvent(env, JNI_FALSE,
-                                   java_awt_dnd_DnDConstants_ACTION_NONE,
-                                   x_root, y_root);
-    }
-
-    /* Cleanup the global state */
-    dnd_in_progress = False;
-    drag_in_progress = False;
-    data_types_count = 0;
-    if (data_types != NULL) {
-        free(data_types);
-        data_types = NULL;
-    }
-    if (!JNU_IsNull(env, source_peer)) {
-        (*env)->DeleteGlobalRef(env, source_peer);
-        source_peer = NULL;
-    }
-
-    cleanup_target_info(dpy);
-
-    remove_dnd_grab(dpy, time);
-
-    XDeleteProperty(awt_display, awt_dnd_ds_get_source_window(), _XA_MOTIF_ATOM_0);
-    XDeleteProperty(awt_display, awt_dnd_ds_get_source_window(), XA_XdndTypeList);
-    XDeleteProperty(awt_display, awt_dnd_ds_get_source_window(), XA_XdndActionList);
-    XtDisownSelection(awt_root_shell, _XA_MOTIF_ATOM_0, time);
-    XtDisownSelection(awt_root_shell, XA_XdndSelection, time);
-
-    awt_cleanupConvertDataContext(env, _XA_MOTIF_ATOM_0);
-    awt_cleanupConvertDataContext(env, XA_XdndSelection);
-}
-
-static void
-process_drop(XButtonEvent* event) {
-    unsigned char ret;
-    XWindowAttributes xwa;
-
-    DASSERT(target_window != None);
-
-    XGetWindowAttributes(event->display, target_window, &xwa);
-
-    target_window_mask = xwa.your_event_mask;
-
-    /* Select for DestoyNotify to cleanup if the target crashes. */
-    ret = checked_XSelectInput(event->display, target_window,
-                               (target_window_mask | StructureNotifyMask));
-
-    if (ret == Success) {
-        send_drop(event);
-    } else {
-        DTRACE_PRINTLN2("%s:%d drop rejected - invalid window.",
-                        __FILE__, __LINE__);
-        cleanup_drag(event->display, event->time);
-    }
-}
-
-static Window
-find_client_window(Display* dpy, Window window) {
-    Window root, parent, *children;
-    unsigned int nchildren, idx;
-
-    Atom           type;
-    int            format;
-    unsigned long  nitems;
-    unsigned long  after;
-    unsigned char  *data;
-    Status ret;
-
-    if (XGetWindowProperty(dpy, window, XA_WM_STATE, 0, 0, False,
-                           AnyPropertyType, &type, &format, &nitems,
-                           &after, &data) == Success) {
-        XFree(data);
-    }
-
-    if (type != None) {
-        return window;
-    }
-
-    if (!XQueryTree(dpy, window, &root, &parent, &children, &nchildren)) {
-        return None;
-    }
-
-    if (children == NULL) {
-        return None;
-    }
-
-    for (idx = 0; idx < nchildren; idx++) {
-        Window win = find_client_window(dpy, children[idx]);
-        if (win != None) {
-            XFree(children);
-            return win;
-        }
-    }
-
-    XFree(children);
-    return None;
-}
-
-static void
-do_update_target_window(Display* dpy, Window subwindow, Time time) {
-    Window client_window = None;
-    Window proxy_window = None;
-    Protocol protocol = NO_PROTOCOL;
-    unsigned int protocol_version = 0;
-    Boolean is_receiver = False;
-
-    client_window = find_client_window(dpy, subwindow);
-
-    if (client_window != None) {
-        /* Request status */
-        int            status;
-
-        /* Returns of XGetWindowProperty */
-        Atom           type;
-        int            format;
-        unsigned long  nitems;
-        unsigned long  after;
-        unsigned char  *data;
-
-        /*
-         * No need for checked_XGetWindowProperty, since we check the returned
-         * property type anyway.
-         */
-        if (drag_source_policy != DS_POLICY_ONLY_XDND) {
-
-            data = NULL;
-            status = XGetWindowProperty(dpy, client_window,
-                                        _XA_MOTIF_DRAG_RECEIVER_INFO,
-                                        0, 0xFFFF, False, AnyPropertyType,
-                                        &type, &format, &nitems, &after, &data);
-
-            if (status == Success && data != NULL && type != None && format == 8
-                && nitems >= MOTIF_RECEIVER_INFO_SIZE) {
-                unsigned char byte_order = read_card8((char*)data, 0);
-                unsigned char drag_protocol_style = read_card8((char*)data, 2);
-
-                switch (drag_protocol_style) {
-                case MOTIF_PREFER_PREREGISTER_STYLE :
-                case MOTIF_PREFER_DYNAMIC_STYLE :
-                case MOTIF_DYNAMIC_STYLE :
-                case MOTIF_PREFER_RECEIVER_STYLE :
-                    proxy_window = read_card32((char*)data, 4, byte_order);
-                    protocol = MOTIF_DND_PROTOCOL;
-                    protocol_version = read_card8((char*)data, 1);
-                    is_receiver = True;
-                    break;
-                default:
-                    DTRACE_PRINTLN3("%s:%d unsupported protocol style (%d).",
-                                    __FILE__, __LINE__, (int)drag_protocol_style);
-                }
-            }
-
-            if (status == Success) {
-                XFree(data);
-                data = NULL;
-            }
-        }
-
-        if (drag_source_policy != DS_POLICY_ONLY_MOTIF &&
-            (drag_source_policy != DS_POLICY_PREFER_MOTIF || !is_receiver)) {
-
-            data = NULL;
-            status = XGetWindowProperty(dpy, client_window, XA_XdndAware, 0, 1,
-                                        False, AnyPropertyType, &type, &format,
-                                        &nitems, &after, &data);
-
-            if (status == Success && data != NULL && type == XA_ATOM) {
-                unsigned int target_version = *((unsigned int*)data);
-
-                if (target_version >= XDND_MIN_PROTOCOL_VERSION) {
-                    proxy_window = None;
-                    protocol = XDND_PROTOCOL;
-                    protocol_version = target_version < XDND_PROTOCOL_VERSION ?
-                        target_version : XDND_PROTOCOL_VERSION;
-                    is_receiver = True;
-                }
-            }
-
-            /* Retrieve the proxy window handle and check if it is valid. */
-            if (protocol == XDND_PROTOCOL) {
-                if (status == Success) {
-                    XFree(data);
-                }
-
-                data = NULL;
-                status = XGetWindowProperty(dpy, client_window, XA_XdndProxy, 0,
-                                            1, False, XA_WINDOW, &type, &format,
-                                            &nitems, &after, &data);
-
-                if (status == Success && data != NULL && type == XA_WINDOW) {
-                    proxy_window = *((Window*)data);
-                }
-
-                if (proxy_window != None) {
-                    if (status == Success) {
-                        XFree(data);
-                    }
-
-                    data = NULL;
-                    status = XGetWindowProperty(dpy, proxy_window, XA_XdndProxy,
-                                                0, 1, False, XA_WINDOW, &type,
-                                                &format, &nitems, &after, &data);
-
-                    if (status != Success || data == NULL || type != XA_WINDOW ||
-                        *((Window*)data) != proxy_window) {
-                        proxy_window = None;
-                    } else {
-                        if (status == Success) {
-                            XFree(data);
-                        }
-
-                        data = NULL;
-                        status = XGetWindowProperty(dpy, proxy_window,
-                                                    XA_XdndAware,  0, 1, False,
-                                                    AnyPropertyType, &type,
-                                                    &format, &nitems, &after,
-                                                    &data);
-
-                        if (status != Success || data == NULL || type != XA_ATOM) {
-                            proxy_window = None;
-                        }
-                    }
-                }
-            }
-
-            XFree(data);
-        }
-
-        if (proxy_window == None) {
-            proxy_window = client_window;
-        }
-    }
-
-    if (is_receiver) {
-        target_window = client_window;
-        target_proxy_window = proxy_window;
-        target_protocol = protocol;
-        target_protocol_version = protocol_version;
-    } else {
-        target_window = None;
-        target_proxy_window = None;
-        target_protocol = NO_PROTOCOL;
-        target_protocol_version = 0;
-    }
-
-    target_action = java_awt_dnd_DnDConstants_ACTION_NONE;
-
-    if (target_window != None) {
-        target_enter_server_time = time;
-    } else {
-        target_enter_server_time = CurrentTime;
-    }
-
-    target_root_subwindow = subwindow;
-}
-
-static void
-update_target_window(XMotionEvent* event) {
-    Display* dpy = event->display;
-    int x = event->x_root;
-    int y = event->x_root;
-    Time time = event->time;
-    Window subwindow = event->subwindow;
-
-    /*
-     * If this event had occurred before the pointer was grabbed,
-     * query the server for the current root subwindow.
-     */
-    if (event->window != event->root) {
-        int xw, yw, xr, yr;
-        unsigned int modifiers;
-        XQueryPointer(dpy, event->root, &event->root, &subwindow,
-                      &xr, &yr, &xw, &yw, &modifiers);
-    }
-
-    if (target_root_subwindow != subwindow) {
-        if (target_window != None) {
-            send_leave(dpy, time);
-
-            /*
-             * Neither Motif DnD nor XDnD provide a mean for the target
-             * to notify the source that the pointer exits the drop site
-             * that occupies the whole top level.
-             * We detect this situation and post dragExit.
-             */
-            if (target_action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-                JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-                ds_postDragSourceEvent(env, x, y);
-            }
-        }
-
-        /* Update the global state. */
-        do_update_target_window(dpy, subwindow, time);
-
-        if (target_window != None) {
-            send_enter(dpy, time);
-        }
-    }
-}
-
-/*
- * Updates the source action based on the specified event state.
- * Returns True if source action changed, False otherwise.
- */
-static Boolean
-update_source_action(unsigned int state) {
-    JNIEnv* env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-    jint action = ds_convertModifiersToDropAction(env, state);
-    if (source_action == action) {
-        return False;
-    }
-    source_action = action;
-    return True;
-}
-
-static void
-handle_mouse_move(XMotionEvent* event) {
-    if (!drag_in_progress) {
-        return;
-    }
-
-    if (x_root != event->x_root || y_root != event->y_root) {
-        JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-        ds_postDragSourceDragEvent(env, target_action, event->state,
-                                   event->x_root, event->y_root,
-                                   sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_MOUSE_MOVED);
-
-        x_root = event->x_root;
-        y_root = event->y_root;
-    }
-
-    if (event_state != event->state) {
-        if (update_source_action(event->state) && target_window != None) {
-            JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-            ds_postDragSourceDragEvent(env, target_action, event->state,
-                                       event->x_root, event->y_root,
-                                       sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_CHANGED);
-        }
-        event_state = event->state;
-    }
-
-    update_target_window(event);
-
-    if (target_window != None) {
-        send_move(event);
-    }
-}
-
-static Boolean
-handle_xdnd_status(XClientMessageEvent* event) {
-    JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-    long* event_data = event->data.l;
-    Window target_win = None;
-    jint action = java_awt_dnd_DnDConstants_ACTION_NONE;
-
-    DTRACE_PRINTLN4("%s:%d XdndStatus target_window=%ld target_protocol=%d.",
-                    __FILE__, __LINE__, target_window, target_protocol);
-
-    if (target_protocol != XDND_PROTOCOL) {
-        DTRACE_PRINTLN2("%s:%d XdndStatus rejected - invalid state.",
-                        __FILE__, __LINE__);
-        return True;
-    }
-
-    target_win = event_data[0];
-
-    /* Ignore XDnD messages from all other windows. */
-    if (target_window != target_win) {
-        DTRACE_PRINTLN4("%s:%d XdndStatus rejected - invalid target window cur=%ld this=%ld.",
-                        __FILE__, __LINE__, target_window, target_win);
-        return True;
-    }
-
-    if (event_data[1] & XDND_ACCEPT_DROP_FLAG) {
-        /* This feature is new in XDnD version 2, but we can use it as XDnD
-           compliance only requires supporting version 3 and up. */
-        action = xdnd_to_java_action(event_data[4]);
-    }
-
-    if (action == java_awt_dnd_DnDConstants_ACTION_NONE &&
-        target_action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-        ds_postDragSourceEvent(env, x_root, y_root);
-    } else if (action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-        jint type = 0;
-
-        if (target_action == java_awt_dnd_DnDConstants_ACTION_NONE) {
-            type = sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_ENTER;
-        } else {
-            type = sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_MOTION;
-        }
-
-        ds_postDragSourceDragEvent(env, action, event_state,
-                                   x_root, y_root, type);
-    }
-
-    target_action = action;
-
-    return True;
-}
-
-static Boolean
-handle_xdnd_finished(XClientMessageEvent* event) {
-    JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-    long* event_data = event->data.l;
-    Window target_win = None;
-    jboolean success = JNI_TRUE;
-    jint action = java_awt_dnd_DnDConstants_ACTION_NONE;
-
-    if (target_protocol != XDND_PROTOCOL) {
-        DTRACE_PRINTLN2("%s:%d XdndStatus rejected - invalid state.",
-                        __FILE__, __LINE__);
-        return True;
-    }
-
-    target_win = event_data[0];
-
-    /* Ignore XDnD messages from all other windows. */
-    if (target_window != target_win) {
-        DTRACE_PRINTLN4("%s:%d XdndStatus rejected - invalid target window cur=%ld this=%ld.",
-                        __FILE__, __LINE__, target_window, target_win);
-        return True;
-    }
-
-    if (target_protocol_version >= 5) {
-        success = (event_data[1] & XDND_ACCEPT_DROP_FLAG) != 0 ?
-            JNI_TRUE : JNI_FALSE;
-        action = xdnd_to_java_action(event_data[2]);
-    } else {
-        /* Assume that the drop was successful and the performed drop action is
-           the drop action accepted with the latest XdndStatus message. */
-        success = JNI_TRUE;
-        action = target_action;
-    }
-
-    ds_postDragSourceDropEvent(env, success, action, x_root, y_root);
-
-    dnd_in_progress = False;
-
-    XSelectInput(event->display, target_win, target_window_mask);
-
-    cleanup_drag(event->display, CurrentTime);
-
-    return True;
-}
-
-static Boolean
-handle_motif_client_message(XClientMessageEvent* event) {
-    JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-    int reason = (int)(event->data.b[0] & MOTIF_MESSAGE_REASON_MASK);
-    int origin = (int)(event->data.b[0] & MOTIF_MESSAGE_SENDER_MASK);
-    unsigned char byte_order = event->data.b[1];
-    jint action = java_awt_dnd_DnDConstants_ACTION_NONE;
-    Time time = CurrentTime;
-    int x = 0, y = 0;
-
-    /* Only receiver messages should be handled. */
-    if (origin != MOTIF_MESSAGE_FROM_RECEIVER) {
-        return False;
-    }
-
-    if (target_protocol != MOTIF_DND_PROTOCOL) {
-        DTRACE_PRINTLN2("%s:%d _MOTIF_DRAG_AND_DROP_MESSAGE rejected - invalid state.",
-                        __FILE__, __LINE__);
-        return True;
-    }
-
-    switch (reason) {
-    case DROP_SITE_ENTER:
-    case DROP_SITE_LEAVE:
-    case DRAG_MOTION:
-    case OPERATION_CHANGED:
-        break;
-    default:
-        return False;
-    }
-
-    time = read_card32(event->data.b, 4, byte_order);
-
-    /* Discard events from the previous receiver. */
-    if (target_enter_server_time == CurrentTime ||
-        time < target_enter_server_time) {
-        DTRACE_PRINTLN2("%s:%d _MOTIF_DRAG_AND_DROP_MESSAGE rejected - invalid time.",
-                        __FILE__, __LINE__);
-        return True;
-    }
-
-    if (reason != DROP_SITE_LEAVE) {
-        CARD16 flags = read_card16(event->data.b, 2, byte_order);
-        unsigned char status = (flags & MOTIF_DND_STATUS_MASK) >>
-            MOTIF_DND_STATUS_SHIFT;
-        unsigned char motif_action = (flags & MOTIF_DND_ACTION_MASK) >>
-            MOTIF_DND_ACTION_SHIFT;
-
-        if (status == MOTIF_VALID_DROP_SITE) {
-            action = motif_to_java_actions(motif_action);
-        } else {
-            action = java_awt_dnd_DnDConstants_ACTION_NONE;
-        }
-
-        x = read_card16(event->data.b, 8, byte_order);
-        y = read_card16(event->data.b, 10, byte_order);
-    }
-
-    /*
-     * We should derive the type of java event to post not from the message
-     * reason, but from the combination of the current and previous target
-     * actions:
-     * Even if the reason is DROP_SITE_LEAVE we shouldn't post dragExit
-     * if the drag was rejected earlier.
-     * Even if the reason is DROP_SITE_ENTER we shouldn't post dragEnter
-     * if the drag is not accepted.
-     */
-    if (target_action != java_awt_dnd_DnDConstants_ACTION_NONE &&
-        action == java_awt_dnd_DnDConstants_ACTION_NONE) {
-
-        ds_postDragSourceEvent(env, x, y);
-    } else if (action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-        jint type = 0;
-
-        if (target_action == java_awt_dnd_DnDConstants_ACTION_NONE) {
-            type = sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_ENTER;
-        } else {
-            type = sun_awt_dnd_SunDragSourceContextPeer_DISPATCH_MOTION;
-        }
-
-        ds_postDragSourceDragEvent(env, action, event_state, x, y, type);
-    }
-
-    target_action = action;
-
-    return True;
-}
-
-/*
- * Handles client messages.
- * Returns True if the event is processed, False otherwise.
- */
-static Boolean
-handle_client_message(XClientMessageEvent* event) {
-    if (event->message_type == XA_XdndStatus) {
-        return handle_xdnd_status(event);
-    } else if (event->message_type == XA_XdndFinished) {
-        return handle_xdnd_finished(event);
-    } else if (event->message_type == _XA_MOTIF_DRAG_AND_DROP_MESSAGE) {
-        return handle_motif_client_message(event);
-    }
-    return False;
-}
-
-/*
- * Similar to XtLastTimestampProcessed(). We cannot use Xt time stamp, as it is
- * updated in XtDispatchEvent that may not be called if a java event is
- * consumed. This can make Xt time stamp out-of-date and cause XGrab* failures
- * with GrabInvalidTime reason.
- */
-static Time
-get_latest_time_stamp() {
-    return latest_time_stamp;
-}
-
-static void
-update_latest_time_stamp(XEvent* event) {
-    Time time = latest_time_stamp;
-
-    switch (event->type) {
-    case KeyPress:
-    case KeyRelease:     time = event->xkey.time;            break;
-    case ButtonPress:
-    case ButtonRelease:  time = event->xbutton.time;         break;
-    case MotionNotify:   time = event->xmotion.time;         break;
-    case EnterNotify:
-    case LeaveNotify:    time = event->xcrossing.time;       break;
-    case PropertyNotify: time = event->xproperty.time;       break;
-    case SelectionClear: time = event->xselectionclear.time; break;
-    }
-
-    latest_time_stamp = time;
-}
-
-Boolean
-awt_dnd_ds_process_event(XEvent* event) {
-    Display* dpy = event->xany.display;
-
-    update_latest_time_stamp(event);
-
-    if (process_proxy_mode_event(event)) {
-        return True;
-    }
-
-    if (!dnd_in_progress) {
-        return False;
-    }
-
-    /* Process drag and drop messages. */
-    switch (event->type) {
-    case ClientMessage:
-        return handle_client_message(&event->xclient);
-    case DestroyNotify:
-        /* Target crashed during drop processing - cleanup. */
-        if (!drag_in_progress &&
-            event->xdestroywindow.window == target_window) {
-            cleanup_drag(dpy, CurrentTime);
-            return True;
-        }
-        /* Pass along */
-        return False;
-    }
-
-    if (!drag_in_progress) {
-        return False;
-    }
-
-    /* Process drag-only messages. */
-    switch (event->type) {
-    case KeyRelease:
-    case KeyPress: {
-        KeySym keysym = XKeycodeToKeysym(dpy, event->xkey.keycode, 0);
-        switch (keysym) {
-        case XK_Escape: {
-            if (keysym == XK_Escape) {
-                remove_dnd_grab(dpy, event->xkey.time);
-                cleanup_drag(dpy, event->xkey.time);
-            }
-            break;
-        }
-        case XK_Control_R:
-        case XK_Control_L:
-        case XK_Shift_R:
-        case XK_Shift_L: {
-            Window subwindow;
-            int xw, yw, xr, yr;
-            unsigned int modifiers;
-            XQueryPointer(event->xkey.display, event->xkey.root, &event->xkey.root, &subwindow,
-                          &xr, &yr, &xw, &yw, &modifiers);
-            event->xkey.state = modifiers;
-            //It's safe to use key event as motion event since we use only their common fields.
-            handle_mouse_move(&event->xmotion);
-            break;
-        }
-        }
-        return True;
-    }
-    case ButtonPress:
-        return True;
-    case MotionNotify:
-        handle_mouse_move(&event->xmotion);
-        return True;
-    case ButtonRelease:
-        /*
-         * On some X servers it could happen that ButtonRelease coordinates
-         * differ from the latest MotionNotify coordinates, so we need to
-         * process it as a mouse motion.
-         * MotionNotify differs from ButtonRelease only in is_hint member, but
-         * we never use it, so it is safe to cast to MotionNotify.
-         */
-        handle_mouse_move(&event->xmotion);
-        if (event->xbutton.button == Button1 || event->xbutton.button == Button2) {
-            // drag is initiated with Button1 or Button2 pressed and
-            // ended on release of either of these buttons (as the same
-            // behavior was with our old Motif DnD-based implementation)
-            remove_dnd_grab(dpy, event->xbutton.time);
-            drag_in_progress = False;
-            if (target_window != None && target_action != java_awt_dnd_DnDConstants_ACTION_NONE) {
-                /*
-                 * ACTION_NONE indicates that either the drop target rejects the
-                 * drop or it haven't responded yet. The latter could happen in
-                 * case of fast drag, slow target-server connection or slow
-                 * drag notifications processing on the target side.
-                 */
-                process_drop(&event->xbutton);
-            } else {
-                cleanup_drag(dpy, event->xbutton.time);
-            }
-        }
-        return True;
-    default:
-        return False;
-    }
-}
-
-static Boolean
-motif_convert_proc(Widget w, Atom* selection, Atom* target, Atom* type,
-                   XtPointer* value, unsigned long* length, int32_t* format) {
-
-    if (*target == XA_XmTRANSFER_SUCCESS ||
-        *target == XA_XmTRANSFER_FAILURE) {
-
-        JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-        jboolean success =
-            (*target == XA_XmTRANSFER_SUCCESS) ? JNI_TRUE : JNI_FALSE;
-
-        ds_postDragSourceDropEvent(env, success, target_action,
-                                   x_root, y_root);
-
-        dnd_in_progress = False;
-
-        XSelectInput(XtDisplay(w), target_window, target_window_mask);
-
-        cleanup_drag(XtDisplay(w), CurrentTime);
-
-        *type = *target;
-        *length = 0;
-        *format = 32;
-        *value = NULL;
-
-        return True;
-    } else {
-        return awt_convertData(w, selection, target, type, value, length,
-                               format);
-    }
-}
-
-static Boolean
-set_convert_data_context(JNIEnv* env, Display* dpy, XID xid, jobject component,
-                         jobject transferable, jobject formatMap,
-                         jlongArray formats) {
-    awt_convertDataCallbackStruct* structPtr = NULL;
-
-    if (XFindContext(awt_display, xid, awt_convertDataContext,
-                     (XPointer*)&structPtr) == XCNOMEM || structPtr != NULL) {
-        return False;
-    }
-
-    structPtr = calloc(1, sizeof(awt_convertDataCallbackStruct));
-    if (structPtr == NULL) {
-        return False;
-    }
-
-    structPtr->source              = (*env)->NewGlobalRef(env, component);
-    structPtr->transferable        = (*env)->NewGlobalRef(env, transferable);
-    structPtr->formatMap           = (*env)->NewGlobalRef(env, formatMap);
-    structPtr->formats             = (*env)->NewGlobalRef(env, formats);
-
-    if (JNU_IsNull(env, structPtr->source) ||
-        JNU_IsNull(env, structPtr->transferable) ||
-        JNU_IsNull(env, structPtr->formatMap) ||
-        JNU_IsNull(env, structPtr->formats)) {
-
-        if (!JNU_IsNull(env, structPtr->source)) {
-            (*env)->DeleteGlobalRef(env, structPtr->source);
-        }
-        if (!JNU_IsNull(env, structPtr->transferable)) {
-            (*env)->DeleteGlobalRef(env, structPtr->transferable);
-        }
-        if (!JNU_IsNull(env, structPtr->formatMap)) {
-            (*env)->DeleteGlobalRef(env, structPtr->formatMap);
-        }
-        if (!JNU_IsNull(env, structPtr->formats)) {
-            (*env)->DeleteGlobalRef(env, structPtr->formats);
-        }
-        free(structPtr);
-        return False;
-    }
-
-    if (XSaveContext(dpy, xid, awt_convertDataContext,
-                     (XPointer)structPtr) == XCNOMEM) {
-        free(structPtr);
-        return False;
-    }
-
-    return True;
-}
-
-/*
- * Convenience routine. Constructs an appropriate exception message based on the
- * specified prefix and the return code of XGrab* function and throws an
- * InvalidDnDOperationException with the constructed message.
- */
-static void
-throw_grab_failure_exception(JNIEnv* env, int ret_code, char* msg_prefix) {
-    char msg[200];
-    char* msg_cause = "";
-
-    switch (ret_code) {
-    case GrabNotViewable:  msg_cause = "not viewable";    break;
-    case AlreadyGrabbed:   msg_cause = "already grabbed"; break;
-    case GrabInvalidTime:  msg_cause = "invalid time";    break;
-    case GrabFrozen:       msg_cause = "grab frozen";     break;
-    default:               msg_cause = "unknown failure"; break;
-    }
-
-    sprintf(msg, "%s: %s.", msg_prefix, msg_cause);
-    JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                    msg);
-}
-
-/*
- * Sets the proxy mode source window - the source window which the drag
- * notifications from an XEmbed client should be forwarded to.
- * If the window is not None and there is a drag operation in progress,
- * throws InvalidDnDOperationException and doesn't change
- * proxy_mode_source_window.
- * The caller mush hold AWT_LOCK.
- */
-void
-set_proxy_mode_source_window(Window window) {
-    if (window != None && dnd_in_progress) {
-        JNIEnv *env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "Drag and drop is already in progress.");
-        return;
-    }
-
-    proxy_mode_source_window = window;
-}
-
-/*
- * Checks if the event is a drag notification from an XEmbed client.
- * If it is, forwards this event back to the current source and returns True.
- * Otherwise, returns False.
- * Currently only XDnD protocol notifications are recognized.
- * The caller must hold AWT_LOCK.
- */
-static Boolean
-process_proxy_mode_event(XEvent* event) {
-    if (proxy_mode_source_window == None) {
-        return False;
-    }
-
-    if (event->type == ClientMessage) {
-        XClientMessageEvent* xclient = &event->xclient;
-        if (xclient->message_type == XA_XdndStatus ||
-            xclient->message_type == XA_XdndFinished) {
-            Window source = proxy_mode_source_window;
-
-            xclient->data.l[0] = xclient->window;
-            xclient->window = source;
-
-            XSendEvent(xclient->display, source, False, NoEventMask,
-                       (XEvent*)xclient);
-
-            if (xclient->message_type == XA_XdndFinished) {
-                proxy_mode_source_window = None;
-            }
-
-            return True;
-        }
-    }
-
-    return False;
-}
-
-/*
- * Class:     sun_awt_motif_X11DragSourceContextPeer
- * Method:    startDrag
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_awt_motif_X11DragSourceContextPeer_startDrag(JNIEnv *env,
-                                                      jobject this,
-                                                      jobject component,
-                                                      jobject wpeer,
-                                                      jobject transferable,
-                                                      jobject trigger,
-                                                      jobject cursor,
-                                                      jint ctype,
-                                                      jint actions,
-                                                      jlongArray formats,
-                                                      jobject formatMap) {
-    Time time_stamp = CurrentTime;
-    Cursor xcursor = None;
-    Window root_window = None;
-    Atom* targets = NULL;
-    jsize num_targets = 0;
-
-    AWT_LOCK();
-
-    if (dnd_in_progress) {
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "Drag and drop is already in progress.");
-        AWT_UNLOCK();
-        return;
-    }
-
-    if (proxy_mode_source_window != None) {
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "Proxy drag is in progress.");
-        AWT_UNLOCK();
-        return;
-    }
-
-    if (!awt_dnd_init(awt_display)) {
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "DnD subsystem initialization failed.");
-        AWT_UNLOCK();
-        return;
-    }
-
-    if (!JNU_IsNull(env, cursor)) {
-        xcursor = getCursor(env, cursor);
-
-        if (xcursor == None) {
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Invalid drag cursor");
-            AWT_UNLOCK();
-        }
-    }
-
-    /* Determine the root window for the drag operation. */
-    {
-        struct FrameData* wdata = (struct FrameData*)
-            JNU_GetLongFieldAsPtr(env, wpeer, mComponentPeerIDs.pData);
-
-        if (wdata == NULL) {
-            JNU_ThrowNullPointerException(env, "Null component data");
-            AWT_UNLOCK();
-            return;
-        }
-
-        if (wdata->winData.shell == NULL) {
-            JNU_ThrowNullPointerException(env, "Null shell widget");
-            AWT_UNLOCK();
-            return;
-        }
-
-        root_window = RootWindowOfScreen(XtScreen(wdata->winData.shell));
-
-        if (root_window == None) {
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot get the root window for the drag operation.");
-            AWT_UNLOCK();
-            return;
-        }
-    }
-
-    time_stamp = get_latest_time_stamp();
-
-    /* Extract the targets from java array. */
-    {
-        targets = NULL;
-        num_targets = (*env)->GetArrayLength(env, formats);
-
-        /*
-         * In debug build GetLongArrayElements aborts with assertion on an empty
-         * array.
-         */
-        if (num_targets > 0) {
-            jboolean isCopy = JNI_TRUE;
-            jlong* java_targets = (*env)->GetLongArrayElements(env, formats,
-                                                               &isCopy);
-
-            if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-                AWT_UNLOCK();
-                return;
-            }
-
-            if (java_targets != NULL) {
-                targets = (Atom*)malloc(num_targets * sizeof(Atom));
-                if (targets != NULL) {
-#ifdef _LP64
-                    memcpy(targets, java_targets, num_targets * sizeof(Atom));
-#else
-                    jsize i;
-
-                    for (i = 0; i < num_targets; i++) {
-                        targets[i] = (Atom)java_targets[i];
-                    }
-#endif
-                }
-                (*env)->ReleaseLongArrayElements(env, formats, java_targets,
-                                                 JNI_ABORT);
-            }
-        }
-        if (targets == NULL) {
-            num_targets = 0;
-        }
-    }
-
-    /* Write the XDnD initiator info on the awt_root_shell. */
-    {
-        unsigned char ret;
-        Atom action_atoms[3];
-        unsigned int action_count = 0;
-
-        if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {
-            action_atoms[action_count] = XA_XdndActionCopy;
-            action_count++;
-        }
-        if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {
-            action_atoms[action_count] = XA_XdndActionMove;
-            action_count++;
-        }
-        if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {
-            action_atoms[action_count] = XA_XdndActionLink;
-            action_count++;
-        }
-
-        ret = checked_XChangeProperty(awt_display, awt_dnd_ds_get_source_window(),
-                                      XA_XdndActionList, XA_ATOM, 32,
-                                      PropModeReplace, (unsigned char*)action_atoms,
-                                      action_count * sizeof(Atom));
-
-        if (ret != Success) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot write XdndActionList property");
-            AWT_UNLOCK();
-            return;
-        }
-
-        ret = checked_XChangeProperty(awt_display, awt_dnd_ds_get_source_window(),
-                                      XA_XdndTypeList, XA_ATOM, 32,
-                                      PropModeReplace, (unsigned char*)targets,
-                                      num_targets);
-
-        if (ret != Success) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot write XdndTypeList property");
-            AWT_UNLOCK();
-            return;
-        }
-    }
-
-    /* Write the Motif DnD initiator info on the awt_root_shell. */
-    {
-        InitiatorInfo info;
-        unsigned char ret;
-        int target_list_index =
-            get_index_for_target_list(awt_display, targets, num_targets);
-
-        if (target_list_index == -1) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot determine the target list index.");
-            AWT_UNLOCK();
-            return;
-        }
-
-        info.byte_order = MOTIF_BYTE_ORDER;
-        info.protocol_version = MOTIF_DND_PROTOCOL_VERSION;
-        info.index = target_list_index;
-        info.selection_atom = _XA_MOTIF_ATOM_0;
-
-        ret = checked_XChangeProperty(awt_display, awt_dnd_ds_get_source_window(),
-                                      _XA_MOTIF_ATOM_0,
-                                      _XA_MOTIF_DRAG_INITIATOR_INFO, 8,
-                                      PropModeReplace, (unsigned char*)&info,
-                                      sizeof(InitiatorInfo));
-
-        if (ret != Success) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot write the Motif DnD initiator info");
-            AWT_UNLOCK();
-            return;
-        }
-    }
-
-    /* Acquire XDnD selection ownership. */
-    if (XtOwnSelection(awt_root_shell, XA_XdndSelection, time_stamp,
-                       awt_convertData, NULL, NULL) != True) {
-        cleanup_drag(awt_display, time_stamp);
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "Cannot acquire XdndSelection ownership.");
-        AWT_UNLOCK();
-        return;
-    }
-
-    /* Acquire Motif DnD selection ownership. */
-    if (XtOwnSelection(awt_root_shell, _XA_MOTIF_ATOM_0, time_stamp,
-                       motif_convert_proc, NULL, NULL) != True) {
-        cleanup_drag(awt_display, time_stamp);
-        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                        "Cannot acquire Motif DnD selection ownership.");
-        AWT_UNLOCK();
-        return;
-    }
-
-    /*
-     * Store the information needed to convert data for both selections
-     * in awt_convertDataContext.
-     */
-    {
-        if (!set_convert_data_context(env, awt_display, XA_XdndSelection,
-                                      component, transferable, formatMap,
-                                      formats)) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot save context for XDnD selection data conversion.");
-            AWT_UNLOCK();
-            return;
-        }
-
-        if (!set_convert_data_context(env, awt_display, _XA_MOTIF_ATOM_0,
-                                      component, transferable, formatMap,
-                                      formats)) {
-            cleanup_drag(awt_display, time_stamp);
-            JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
-                            "Cannot save context for Motif DnD selection data conversion.");
-            AWT_UNLOCK();
-            return;
-        }
-    }
-
-    /* Install X grabs. */
-    {
-        XWindowAttributes xwa;
-        int ret;
-
-        XGetWindowAttributes(awt_display, root_window, &xwa);
-
-        your_root_event_mask = xwa.your_event_mask;
-
-        XSelectInput(awt_display, root_window,
-                     your_root_event_mask | ROOT_EVENT_MASK);
-
-        ret = XGrabPointer(awt_display,
-                           root_window,
-                           False,
-                           GRAB_EVENT_MASK,
-                           GrabModeAsync,
-                           GrabModeAsync,
-                           None,
-                           xcursor,
-                           time_stamp);
-
-        if (ret != GrabSuccess) {
-            cleanup_drag(awt_display, time_stamp);
-            throw_grab_failure_exception(env, ret, "Cannot grab pointer");
-            AWT_UNLOCK();
-            return;
-        }
-
-        ret = XGrabKeyboard(awt_display,
-                            root_window,
-                            False,
-                            GrabModeAsync,
-                            GrabModeAsync,
-                            time_stamp);
-
-        if (ret != GrabSuccess) {
-            cleanup_drag(awt_display, time_stamp);
-            throw_grab_failure_exception(env, ret, "Cannot grab keyboard");
-            AWT_UNLOCK();
-            return;
-        }
-    }
-
-    /* Update the global state. */
-    source_peer = (*env)->NewGlobalRef(env, this);
-    dnd_in_progress = True;
-    drag_in_progress = True;
-    data_types = targets;
-    data_types_count = num_targets;
-    source_actions = actions;
-    drag_root_window = root_window;
-
-    AWT_UNLOCK();
-}
-
-/*
- * Class:     sun_awt_motif_X11DragSourceContextPeer
- * Method:    setNativeCursor
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_awt_motif_X11DragSourceContextPeer_setNativeCursor(JNIEnv *env,
-                                                            jobject this,
-                                                            jlong nativeCtxt,
-                                                            jobject cursor,
-                                                            jint type) {
-    if (JNU_IsNull(env, cursor)) {
-        return;
-    }
-
-    XChangeActivePointerGrab(awt_display,
-                             GRAB_EVENT_MASK,
-                             getCursor(env, cursor),
-                             CurrentTime);
-}