jdk/src/solaris/native/sun/awt/awt_DataTransferer.c
changeset 1211 b659a7cee935
parent 1210 7798f9e88bf9
parent 1203 3e5496df0d2b
child 1212 d718a4419361
--- a/jdk/src/solaris/native/sun/awt/awt_DataTransferer.c	Fri Sep 12 14:35:51 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1068 +0,0 @@
-/*
- * Copyright 2000-2005 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_p.h"
-#include <X11/Intrinsic.h>
-#include <X11/Xutil.h>
-
-#include <sys/utsname.h>
-
-#include <jni.h>
-#include <jni_util.h>
-
-#include "sun_awt_datatransfer_DataTransferer.h"
-#include "sun_awt_motif_MDataTransferer.h"
-
-#include "awt_XmDnD.h"
-#include "awt_DataTransferer.h"
-
-static jclass string;
-
-XContext awt_convertDataContext = 0;
-
-Atom XA_TARGETS;
-
-extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
-
-typedef enum {
-    SelectionPending,
-    SelectionSuccess,
-    SelectionFailure,
-    SelectionOwnerTimedOut
-} SelectionStatus;
-
-/* Should only be accessed by the current owner of AWT_LOCK. */
-static SelectionStatus globalSelectionStatus = SelectionPending;
-
-static SelectionStatus get_selection_status() {
-    return globalSelectionStatus;
-}
-
-static void set_selection_status(SelectionStatus status) {
-    globalSelectionStatus = status;
-}
-
-static void
-selection_request_filter(Widget widget, XtPointer closure, XEvent *event,
-                         Boolean *cont) {
-    if (event->type == SelectionRequest) {
-        Window awt_root_window = XtWindow(awt_root_shell);
-        Atom selection = event->xselectionrequest.selection;
-        Window owner = XGetSelectionOwner(event->xany.display, selection);
-
-        if (owner != awt_root_window) {
-            XSelectionEvent notify;
-
-            notify.type = SelectionNotify;
-            notify.display = event->xselectionrequest.display;
-            notify.requestor = event->xselectionrequest.requestor;
-            notify.selection = event->xselectionrequest.selection;
-            notify.time = event->xselectionrequest.time;
-            notify.target = event->xselectionrequest.target;
-            notify.property = None;
-
-            XSendEvent(notify.display, notify.requestor, False,
-                       (unsigned long)0, (XEvent*)&notify);
-            *cont = False;
-        }
-    }
-}
-
-/**
- * global function to initialize this client as a Dynamic-only app.
- *
- * gets called once during toolkit initialization.
- */
-
-void awt_initialize_DataTransferer() {
-    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    jclass stringClassLocal = NULL;
-
-    DASSERT(string == NULL);
-
-    stringClassLocal = (*env)->FindClass(env, "java/lang/String");
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        DASSERT(False);
-    }
-
-    if (JNU_IsNull(env, stringClassLocal)) return;
-
-    string = (*env)->NewGlobalRef(env, stringClassLocal); /* never freed! */
-    (*env)->DeleteLocalRef(env, stringClassLocal);
-
-    if (JNU_IsNull(env, string)) {
-        JNU_ThrowOutOfMemoryError(env, "");
-        return;
-    }
-
-    DASSERT(awt_convertDataContext == 0);
-    awt_convertDataContext = XUniqueContext();
-    DASSERT(awt_convertDataContext != 0);
-
-    /*
-     * Fixes for 4513976 and 4818143.
-     */
-    XtAppSetSelectionTimeout(awt_appContext,
-            JNU_CallStaticMethodByName(env, NULL, "sun/awt/UNIXToolkit",
-                                       "getDatatransferTimeout", "()I").i);
-
-    /*
-     * Xt selection machinery doesn't respond to SelectionRequests if the
-     * event arrives on a widget that is not the current selection owner.
-     * This can happen if XtDisownSelection was called when SelectionRequest was
-     * already on the native queue.
-     * If the requestor is another JVM, it hangs for the selection timeout
-     * as SelectionNotify is never sent.
-     * We install an event handler that filters out SelectionRequests if the
-     * awt_root_shell is not the current selection owner.
-     */
-    XtAddEventHandler(awt_root_shell, (EventMask)0, True,
-                      selection_request_filter, NULL);
-
-    XA_TARGETS = XInternAtom(awt_display, "TARGETS", False);
-}
-
-/*
- * Single routine to convert to target FILE_NAME or _DT_FILENAME
- */
-Boolean
-convertFileType(jbyteArray data, Atom * type, XtPointer * value,
-                unsigned long *length, int32_t *format)
-{
-    /*
-     * Convert the internal representation to an File Name.
-     * The data passed is an array of
-     * null separated bytes. Each series of bytes is a string
-     * that is then converted to an XString which are then put
-     * into an XStringList and put into an XTextProperty for
-     * usage in other programs.
-     *
-     * It would be desireable to have dataConvert to this conversion
-     * but it isn't possible to return a byte array that represents
-     * the XTextProperty.
-     */
-
-    JNIEnv*       env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    jboolean      isCopy=JNI_FALSE;
-    XTextProperty tp;
-    jsize         len;
-    jsize         strings = 0;
-    jsize         i;
-    char**        stringList;
-    Status        s;
-    jbyte*        bytes;
-    char*         start;
-    size_t        slen;
-    char*         utf;
-
-    if ((*env)->PushLocalFrame(env, 16) < 0) {
-        return False;
-    }
-
-    /* convert the data to an Array of Byte Elements */
-    bytes = (*env)->GetByteArrayElements(env, data, &isCopy);
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        (*env)->PopLocalFrame(env, NULL);
-        return False;
-    }
-
-    if (JNU_IsNull(env, bytes)) {
-        (*env)->PopLocalFrame(env, NULL);
-        return False;
-    }
-
-    /* Get the length of the area */
-    len = (*env)->GetArrayLength(env, data);
-    if (len == 0) {
-        (*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT);
-        (*env)->PopLocalFrame(env, NULL);
-        return False;
-    }
-
-    /*
-     * determine the number of lists. The byteArray is null separated list of
-     * strings.
-     */
-    for (i = 0; i < len; i++) {
-        if (bytes[i] == '\0') {
-            strings++;
-        }
-    }
-
-    /* Allocate an X11 string list */
-    stringList = (char **)XtCalloc(strings, sizeof(char *));
-    if (stringList == (char**)NULL) {
-        (*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT);
-        (*env)->PopLocalFrame(env, NULL);
-        return False;
-    }
-
-    for (i = 0; i < strings; i++) {
-        if (i == 0) {
-            start = (char*)bytes;
-        } else {
-            start = (char*)&bytes[slen];
-        }
-
-        /*
-         * if start is a NULL we're at the end of the list
-         * We'll just a have null entry on the end of the list
-         */
-        if (start[0] == '\0') {
-            stringList[i] = NULL;
-            continue;
-        }
-        slen = strlen(start) + 1;
-
-        stringList[i] = (char*)XtCalloc(slen, sizeof(char));
-
-        if (stringList[i] == (char *)NULL) {
-            jsize j;
-
-            (*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT);
-
-            for (j = 0; j < i; j++) {
-                XtFree((void *)stringList[j]);
-            }
-
-            (*env)->PopLocalFrame(env, NULL);
-
-            return False;
-        }
-
-        memcpy((void *)stringList[i], (const void*)start, slen);
-    }
-
-    (*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT);
-    s = XStringListToTextProperty(stringList, strings, &tp);
-
-    /* free the strings that were created */
-    for (i = 0; i < strings; i++) {
-        if (stringList[i] != NULL) {
-            XtFree((void*)stringList[i]);
-        }
-    }
-
-    XtFree((void*)stringList);
-
-    if (s == 0) {
-        (*env)->PopLocalFrame(env, NULL);
-        return False;
-    }
-
-    *value = (XtPointer)XtCalloc(tp.nitems, sizeof(char));
-
-    if (*value == (XtPointer)NULL) {
-        XFree((void*)tp.value);
-
-        (*env)->PopLocalFrame(env, NULL);
-
-        return False;
-    }
-
-    memcpy((void *)(*value), (const void *)tp.value, tp.nitems);
-
-    XFree((void*)tp.value);
-
-    *length = tp.nitems;
-    *type   = tp.encoding;
-    *format = tp.format;
-    (*env)->PopLocalFrame(env, NULL);
-    return True;
-}
-
-/*
- * Class:     sun_awt_motif_MDataTransferer
- * Method:    getAtomForTarget
- * Signature: (Ljava/lang/String;)J
- */
-
-JNIEXPORT jlong JNICALL
-Java_sun_awt_motif_MDataTransferer_getAtomForTarget(JNIEnv *env,
-                                                    jclass cls,
-                                                    jstring targetString)
-{
-    Atom target;
-    char *target_str;
-
-    if (JNU_IsNull(env, targetString)) {
-        JNU_ThrowNullPointerException(env, "NullPointerException");
-        return -1;
-    }
-    target_str = (char *) JNU_GetStringPlatformChars(env, targetString, NULL);
-
-    AWT_LOCK();
-
-    target = XInternAtom(awt_display, target_str, False);
-
-    AWT_UNLOCK();
-
-    JNU_ReleaseStringPlatformChars(env, targetString,
-                                   (const char *) target_str);
-    return target;
-}
-
-/*
- * Class:     sun_awt_motif_MDataTransferer
- * Method:    getTargetNameForAtom
- * Signature: (J)Ljava/lang/String;
- */
-
-JNIEXPORT jstring JNICALL
-Java_sun_awt_motif_MDataTransferer_getTargetNameForAtom(JNIEnv *env,
-                                                        jclass cls,
-                                                        jlong atom)
-{
-    jstring targetString;
-    char *name;
-
-    AWT_LOCK();
-
-    name = XGetAtomName(awt_display, (Atom) atom);
-
-    if (name == NULL) {
-        JNU_ThrowNullPointerException(env, "Failed to retrieve atom name.");
-        AWT_UNLOCK();
-        return NULL;
-    }
-
-    targetString = (*env)->NewStringUTF(env, (const char *)name);
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        XFree (name);
-        AWT_UNLOCK();
-        return NULL;
-    }
-
-    if (JNU_IsNull(env, targetString)) {
-        JNU_ThrowNullPointerException(env, "Failed to create a string.");
-        XFree (name);
-        AWT_UNLOCK();
-        return NULL;
-    }
-
-    XFree (name);
-
-    AWT_UNLOCK();
-    return targetString;
-}
-
-/*
- * Class:     sun_awt_datatransfer_DataTransferer
- * Method:    dragQueryFile
- * Signature: ([B)[Ljava/lang/String;
- *
- * This method converts a byte array that came from File most likely from a
- * drag operation into a String array.
- */
-
-JNIEXPORT jobjectArray JNICALL
-Java_sun_awt_motif_MDataTransferer_dragQueryFile
-    (JNIEnv *env, jobject this, jbyteArray bytes)
-{
-    XTextProperty tp;
-    jbyte         *value;
-
-    char**        strings  = (char **)NULL;
-    int32_t       nstrings = 0;
-    jobject       filenames;
-    jobject       ret = NULL;
-    int32_t       i;
-    jsize         len;
-    jboolean      isCopy=JNI_FALSE;
-
-    /*
-     * If the length of the byte array is 0 just return a null
-     */
-    len = (*env)->GetArrayLength(env, bytes);
-    if (len == 0) {
-        return NULL;
-    }
-
-    value = (*env)->GetByteArrayElements(env, bytes, &isCopy);
-    if (JNU_IsNull(env, value)) {
-        return NULL;
-    }
-
-    AWT_LOCK();
-
-    tp.encoding = XInternAtom(awt_display, "STRING", False);
-    tp.value    = (unsigned char *)value;
-    tp.nitems   = len;
-    tp.format   = 8;
-
-    /*
-     * Convert the byte stream into a list of X11 strings
-     */
-    if (XTextPropertyToStringList(&tp, &strings, &nstrings) == 0 ||
-        nstrings == 0)
-        {
-            (*env)->ReleaseByteArrayElements(env, bytes, value, JNI_ABORT);
-            AWT_UNLOCK();
-            return NULL;
-        }
-
-    (*env)->ReleaseByteArrayElements(env, bytes, value, JNI_ABORT);
-
-    filenames = (*env)->NewObjectArray(env, nstrings, string, NULL);
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        goto wayout;
-    }
-
-    if (JNU_IsNull(env, filenames)) {
-        goto wayout;
-    }
-
-    /*
-     * Actuall conversion code per X11 String
-     */
-    for (i = 0; i < nstrings; i++) {
-        jstring string = (*env)->NewStringUTF(env,
-                                              (const char *)strings[i]);
-        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-            (*env)->ExceptionDescribe(env);
-            (*env)->ExceptionClear(env);
-            goto wayout;
-        }
-
-        if (JNU_IsNull(env, string)) {
-            goto wayout;
-        }
-
-        (*env)->SetObjectArrayElement(env, filenames, i, string);
-
-        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-            (*env)->ExceptionDescribe(env);
-            (*env)->ExceptionClear(env);
-            goto wayout;
-        }
-
-        (*env)->DeleteLocalRef(env, string);
-    }
-
-    ret = filenames;
- wayout:
-    /*
-     * Clean up and return
-     */
-    XFreeStringList(strings);
-    AWT_UNLOCK();
-    return ret;
-}
-
-DECLARE_JAVA_CLASS(dataTransfererClazz, "sun/awt/datatransfer/DataTransferer")
-
-/**
- * Returns a local reference to the singleton DataTransferer instance.
- * The caller should delete the reference when done.
- */
-static jobject
-get_data_transferer(JNIEnv* env) {
-    jobject transferer = NULL;
-
-    DECLARE_STATIC_OBJECT_JAVA_METHOD(getInstanceMethodID, dataTransfererClazz,
-                                     "getInstance",
-                                     "()Lsun/awt/datatransfer/DataTransferer;");
-
-    transferer = (*env)->CallStaticObjectMethod(env, clazz, getInstanceMethodID);
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    }
-
-    DASSERT(!JNU_IsNull(env, transferer));
-
-    return transferer;
-}
-
-static jobject
-call_convertData(JNIEnv* env, jobject source, jobject contents, jlong format,
-                 jobject formatMap) {
-    jobject transferer = get_data_transferer(env);
-    jobject ret = NULL;
-    DECLARE_OBJECT_JAVA_METHOD(convertDataMethodID, dataTransfererClazz,
-                               "convertData",
-                               "(Ljava/lang/Object;Ljava/awt/datatransfer/Transferable;JLjava/util/Map;Z)[B");
-
-    ret = (*env)->CallObjectMethod(env, transferer, convertDataMethodID,
-                                   source, contents, format, formatMap,
-                                   awt_currentThreadIsPrivileged(env));
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    }
-
-    (*env)->DeleteLocalRef(env, transferer);
-
-    return ret;
-}
-
-static void
-process_convert_data_requests() {
-    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_4);
-    jobject transferer = get_data_transferer(env);
-
-    DECLARE_VOID_JAVA_METHOD(processDataConversionRequestsMethodID,
-                             dataTransfererClazz,
-                             "processDataConversionRequests",
-                             "()V");
-
-    (*env)->CallVoidMethod(env, transferer,
-                           processDataConversionRequestsMethodID);
-
-    if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    }
-
-    (*env)->DeleteLocalRef(env, transferer);
-}
-
-Boolean
-awt_convertData(Widget w, Atom * selection, Atom * target, Atom * type,
-                XtPointer * value, unsigned long *length, int32_t *format) {
-    JNIEnv*  env  = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    Display* dpy = XtDisplay(w);
-    awt_convertDataCallbackStruct* structPtr = NULL;
-
-    if (XFindContext(dpy, *selection, awt_convertDataContext,
-                     (XPointer*)&structPtr) == XCNOMEM || structPtr == NULL) {
-        return False;
-    }
-
-    if ((*env)->PushLocalFrame(env, 2) < 0) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        return False;
-    }
-
-    if (*target == XA_TARGETS) {
-        jlongArray formats = structPtr->formats;
-        jsize      count;
-        jlong*     targets;
-        jboolean   isCopy;
-
-#ifndef _LP64 /* Atom and jlong are different sizes in the 32-bit build */
-        Atom*      aValue;
-        jlong*     saveTargets;
-        jsize      i;
-#endif
-
-        if (JNU_IsNull(env, formats)) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-
-        count = (*env)->GetArrayLength(env, formats);
-        if (count == 0) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-
-        targets = (*env)->GetLongArrayElements(env, formats, &isCopy);
-
-        *type = XA_ATOM;
-        *format = 32;
-
-#ifdef _LP64
-        *value = XtMalloc(count * sizeof(Atom));
-        memcpy((void *)*value, (void *)targets, count * sizeof(Atom));
-#else
-        *value = aValue = (Atom *)XtMalloc(count * sizeof(Atom));
-        saveTargets = targets;
-        for (i = 0; i < count; i++, aValue++, targets++) {
-            *aValue = (Atom)*targets;
-        }
-        targets = saveTargets;
-#endif
-        (*env)->ReleaseLongArrayElements(env, formats, targets, JNI_ABORT);
-
-        *length = count;
-
-    } else if (*target == XInternAtom(dpy, _XA_DELETE, False)) {
-
-        /*
-         * acknowledge the DELETE target here ... the "delete" semantic
-         * of move will take place after the drop is complete.
-         */
-
-        *type   = XInternAtom(dpy, _XA_NULL, False);
-        *length = 0;
-        *value  = (XtPointer)NULL;
-        /* Uninitialized format can cause crash in Xt conversion code. */
-        *format = 8;
-    } else if (*target == XInternAtom(dpy, _XA_HOSTNAME, False)) {
-        struct utsname name;
-        XTextProperty  tp;
-
-        uname(&name);
-
-        if (!XStringListToTextProperty((char **)&name.nodename, 1, &tp)) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-
-        *value = (XtPointer)XtCalloc(tp.nitems, sizeof(char));
-
-        memcpy((void *)*value, (const void *)tp.value, tp.nitems);
-
-        XFree((void *)tp.value);
-
-        *type   = tp.encoding;
-        *length = tp.nitems + 1;
-        *format = tp.format;
-    } else if (*target == XInternAtom(dpy, _XA_FILENAME, False) ||
-               *target == XInternAtom(dpy, _DT_FILENAME, False)) {
-
-        /*
-         * Convert the internal representation to an File Name.
-         * The data returned from dataConvert is a an array of
-         * null separated bytes. Each series of bytes is a string
-         * that is then converted to an XString which are then put
-         * into an XStringList and put into an XTextProperty for
-         * usage in other programs.
-         *
-         * It would be desireable to have dataConvert to this conversion
-         * but it isn't possible to return a byte array that represents
-         * the XTextProperty.
-         */
-        jbyteArray    data;
-
-        /*
-         * Fix for 4513976.
-         * Type None should be used instead of XT_CONVERT_FAIL
-         * to report conversion failure.
-         */
-        /*  assume forthcoming error */
-        *type   = None;
-        *value  = (XtPointer)NULL;
-        *length = 0;
-        *format = 8;
-
-        data = call_convertData(env, structPtr->source, structPtr->transferable,
-                                (jlong)*target, structPtr->formatMap);
-
-        /* error test */
-        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-            (*env)->ExceptionDescribe(env);
-            (*env)->ExceptionClear(env);
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-        if (JNU_IsNull(env, data)) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-
-        if (convertFileType(data, type, value, length, format) == False) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-    } else {
-        jbyteArray bytes = NULL;
-        jbyte*     copy = NULL;
-
-        /*
-         * Fix for 4513976.
-         * Type None should be used instead of XT_CONVERT_FAIL
-         * to report conversion failure.
-         */
-        *type   = None; /* assume forthcoming error */
-        *value  = (XtPointer)NULL;
-        *length = 0;
-        *format = 8;
-
-        bytes = call_convertData(env, structPtr->source, structPtr->transferable,
-                                 (jlong)*target, structPtr->formatMap);
-
-        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-            (*env)->ExceptionDescribe(env);
-            (*env)->ExceptionClear(env);
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        }
-
-        if (bytes == NULL) {
-            (*env)->PopLocalFrame(env, NULL);
-            return False;
-        } else {
-            jsize len = (*env)->GetArrayLength(env, bytes);
-
-            if (len == 0) {
-                *type   = *target;
-                *format = 8;
-                (*env)->PopLocalFrame(env, NULL);
-                return True;
-            }
-
-            copy = (jbyte*)XtCalloc(1, len * sizeof(jbyte));
-            if (copy == (jbyte*)NULL) {
-                JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
-                (*env)->PopLocalFrame(env, NULL);
-                return False;
-            }
-
-            (*env)->GetByteArrayRegion(env, (jbyteArray)bytes, 0, len, copy);
-
-            if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-                (*env)->ExceptionDescribe(env);
-                (*env)->ExceptionClear(env);
-                XtFree((void *)copy);
-                (*env)->PopLocalFrame(env, NULL);
-                return False;
-            }
-
-            *value  = (XtPointer)copy;
-            *type   = *target;
-            *length = len;
-            *format = 8;
-        }
-    }
-
-    (*env)->PopLocalFrame(env, NULL);
-    return True;
-}
-
-
-jlongArray
-getSelectionTargetsHelper(JNIEnv* env, XtPointer value, unsigned long length)
-{
-    Atom* targets = (Atom*)value;
-    jlongArray targetArray = NULL;
-    jlong* checkedTargets = NULL;
-    size_t count = 0, i = 0, j = 0;
-
-    /* Get rid of zero atoms if there are any. */
-    for (; i < length; i++) {
-        if (targets[i] != 0) {
-            count++;
-        }
-    }
-    checkedTargets = calloc(count, sizeof(jlong));
-    if (checkedTargets == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    } else {
-        for (i = 0; i < length; i++) {
-            if (targets[i] != 0) {
-                checkedTargets[j++] = targets[i];
-            }
-        }
-
-        DASSERT(j == count);
-
-        if ((*env)->EnsureLocalCapacity(env, 1) >= 0) {
-
-            targetArray = (*env)->NewLongArray(env, count);
-
-            if (!JNU_IsNull(env, targetArray)) {
-                (*env)->SetLongArrayRegion(env, targetArray, 0, count,
-                                           checkedTargets);
-
-                if ((*env)->ExceptionCheck(env)) {
-                    (*env)->ExceptionDescribe(env);
-                    (*env)->ExceptionClear(env);
-
-                    (*env)->DeleteLocalRef(env, targetArray);
-                    targetArray = NULL;
-                }
-            }
-        }
-        free(checkedTargets);
-    }
-
-    return targetArray;
-}
-
-static void
-get_selection_targets_callback(Widget w, XtPointer client_data, Atom* selection,
-                               Atom* type, XtPointer value,
-                               unsigned long* length, int32_t* format) {
-    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    jobject* pReturnArray = (jobject*)client_data;
-    SelectionStatus status = SelectionFailure;
-
-    /*
-     * It is highly unlikely that TARGETS will ever be passed even though that
-     * was what was requested. However, XA_ATOM ("ATOM") is likely.
-     * Actually they are the same so treat them as such. See XToolKit
-     * Intrinsic Manual on XtSelectionCallbackProc for more details on type.
-     */
-    if (*type == XA_TARGETS || *type == XA_ATOM) {
-        jlongArray targetArray = getSelectionTargetsHelper(env, value, *length);
-        if (!JNU_IsNull(env, targetArray)) {
-            *pReturnArray = (*env)->NewGlobalRef(env, targetArray);
-            status = SelectionSuccess;
-            (*env)->DeleteLocalRef(env, targetArray);
-        }
-    } else if (*type == XT_CONVERT_FAIL) {
-        status = SelectionOwnerTimedOut;
-    } else {
-        /*
-         * A part of the fix for 4259272.
-         * Actually Xt Intrinsics says about XtSelectionCallback that
-         * "if there is no owner for the specified selection, or that owner
-         * cannot convert the selected data to the requested type, then this
-         * callback is called with value NULL and length zero".
-         * But we report success if type is not TARGETS, XA_ATOM or XT_CONVERT_FAIL,
-         * and we should not change this behaviour. We just return zero-length
-         * array instead of null, because null denotes that we could not get
-         * selection targets at the time of tracking changes of available on
-         * the selection data flavors.
-         */
-        jlongArray targetArray = (*env)->NewLongArray(env, 0);
-        *pReturnArray = (*env)->NewGlobalRef(env, targetArray);
-        /*
-         * Fix for 4655996.
-         * Report success if there is no owner for this selection or the owner
-         * fails to provide target types.
-         */
-        status = SelectionSuccess;
-        (*env)->DeleteLocalRef(env, targetArray);
-    }
-
-    if (value != NULL) {
-        XtFree(value);
-        value = NULL;
-    }
-
-    set_selection_status(status);
-}
-
-static void
-get_selection_data_callback(Widget w, XtPointer client_data, Atom * selection,
-                            Atom * type, XtPointer value, unsigned long *length,
-                            int32_t *format) {
-    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    jobject* pData = (jobject*)client_data;
-    SelectionStatus status = SelectionFailure;
-
-    if (*type == XT_CONVERT_FAIL) {
-        status = SelectionOwnerTimedOut;
-    } else if (*type != None) {
-        if ((*env)->EnsureLocalCapacity(env, 1) >= 0) {
-            jsize size = (*length <= INT_MAX) ? *length : INT_MAX;
-            jbyteArray array = (*env)->NewByteArray(env, size);
-
-            if (!JNU_IsNull(env, array)) {
-                (*env)->SetByteArrayRegion(env, array, 0, size, (jbyte*)value);
-                if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
-                    (*env)->ExceptionDescribe(env);
-                    (*env)->ExceptionClear(env);
-                } else {
-                    *pData = (*env)->NewGlobalRef(env, array);
-                    status = SelectionSuccess;
-                }
-
-                (*env)->DeleteLocalRef(env, array);
-            }
-        }
-    }
-
-    if (value != NULL) {
-        XtFree(value);
-        value = NULL;
-    }
-
-    set_selection_status(status);
-}
-
-static int32_t
-wait_for_selection_event(void *data) {
-    process_convert_data_requests();
-    return get_selection_status() != SelectionPending;
-}
-
-jlongArray
-get_selection_targets(JNIEnv *env, Atom selection, Time time_stamp) {
-    jlongArray ret     = NULL;
-    jlongArray targets = NULL;
-    SelectionStatus status = SelectionPending;
-
-    AWT_LOCK();
-
-    XtAppSetSelectionTimeout(awt_appContext,
-            JNU_CallStaticMethodByName(env, NULL, "sun/awt/UNIXToolkit",
-                                       "getDatatransferTimeout", "()I").i);
-
-    set_selection_status(SelectionPending);
-    XtGetSelectionValue(awt_root_shell, selection, XA_TARGETS,
-                        get_selection_targets_callback, (XtPointer)&targets,
-                        time_stamp);
-
-    awt_MToolkit_modalWait(wait_for_selection_event, NULL);
-    status = get_selection_status();
-
-    AWT_FLUSH_UNLOCK();
-
-    if (!JNU_IsNull(env, targets)) {
-        ret = (*env)->NewLocalRef(env, targets);
-        (*env)->DeleteGlobalRef(env, targets);
-    }
-
-    switch (status) {
-    case SelectionSuccess:
-        break;
-    case SelectionFailure:
-        JNU_ThrowByName(env, "java/lang/IllegalStateException",
-                        "Failed to get selection targets");
-        break;
-    case SelectionOwnerTimedOut:
-        // return an empty array of targets if the selection owner timed out
-        ret = (*env)->NewLongArray(env, 0);
-        break;
-    default:
-        JNU_ThrowByName(env, "java/lang/IllegalStateException",
-                        "Unexpected selection status");
-        break;
-    }
-
-    return ret;
-}
-
-jbyteArray
-get_selection_data(JNIEnv *env, Atom selection, Atom target, Time time_stamp) {
-    jbyteArray ret    = NULL;
-    jbyteArray data   = NULL;
-    SelectionStatus status = SelectionPending;
-
-    AWT_LOCK();
-
-    XtAppSetSelectionTimeout(awt_appContext,
-            JNU_CallStaticMethodByName(env, NULL, "sun/awt/UNIXToolkit",
-                                       "getDatatransferTimeout", "()I").i);
-
-    set_selection_status(SelectionPending);
-    XtGetSelectionValue(awt_root_shell, selection, target,
-                        get_selection_data_callback,
-                        (XtPointer)&data, time_stamp);
-
-    awt_MToolkit_modalWait(wait_for_selection_event, NULL);
-    status = get_selection_status();
-
-    AWT_FLUSH_UNLOCK();
-
-    if (!JNU_IsNull(env, data)) {
-        ret = (*env)->NewLocalRef(env, data);
-        (*env)->DeleteGlobalRef(env, data);
-    }
-
-    switch (status) {
-    case SelectionSuccess:
-        break;
-    case SelectionFailure:
-        JNU_ThrowIOException(env, "Failed to get selection data");
-        break;
-    case SelectionOwnerTimedOut:
-        JNU_ThrowIOException(env, "Selection owner timed out");
-        break;
-    default:
-        JNU_ThrowIOException(env, "Unexpected selection status");
-        break;
-    }
-
-    return ret;
-}
-
-void
-awt_cleanupConvertDataContext(JNIEnv *env, Atom selectionAtom) {
-    awt_convertDataCallbackStruct* structPtr = NULL;
-
-    if (XFindContext(awt_display, selectionAtom, awt_convertDataContext,
-                     (XPointer*)&structPtr) == 0 && structPtr != NULL) {
-
-        (*env)->DeleteGlobalRef(env, structPtr->source);
-        (*env)->DeleteGlobalRef(env, structPtr->transferable);
-        (*env)->DeleteGlobalRef(env, structPtr->formatMap);
-        (*env)->DeleteGlobalRef(env, structPtr->formats);
-        free(structPtr);
-    }
-    /*
-     * Xlib Programming Manual says that it is better to erase
-     * the current entry with XDeleteContext() before XSaveContext().
-     */
-    XDeleteContext(awt_display, selectionAtom, awt_convertDataContext);
-    if (XSaveContext(awt_display, selectionAtom, awt_convertDataContext,
-                     (XPointer)NULL) == XCNOMEM) {
-        JNU_ThrowInternalError(env, "XError");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    }
-}
-
-static Bool exitSecondaryLoop = True;
-
-/*
- * This predicate procedure allows the Toolkit thread to process specific events
- * while it is blocked waiting for the event dispatch thread to process
- * a SunDropTargetEvent. We need this to prevent deadlock when the client code
- * processing SunDropTargetEvent sets or gets the contents of the system
- * clipboard/selection. In this case the event dispatch thread waits for the
- * Toolkit thread to process PropertyNotify or SelectionNotify events.
- */
-static Bool
-secondary_loop_event(Display* dpy, XEvent* event, char* arg) {
-    return (event->type == SelectionNotify ||
-            event->type == SelectionClear  ||
-            event->type == PropertyNotify) ? True : False;
-}
-
-
-JNIEXPORT void JNICALL
-Java_sun_awt_motif_MToolkitThreadBlockedHandler_enter(JNIEnv *env, jobject this) {
-    DASSERT(exitSecondaryLoop && awt_currentThreadIsPrivileged(env));
-    exitSecondaryLoop = False;
-    while (!exitSecondaryLoop) {
-        XEvent event;
-        while (XCheckIfEvent(awt_display, &event, secondary_loop_event, NULL)) {
-            XtDispatchEvent(&event);
-        }
-        AWT_WAIT(AWT_DND_POLL_INTERVAL);
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_awt_motif_MToolkitThreadBlockedHandler_exit(JNIEnv *env, jobject this) {
-    DASSERT(!exitSecondaryLoop && !awt_currentThreadIsPrivileged(env));
-    exitSecondaryLoop = True;
-    AWT_NOTIFY_ALL();
-}