/*
 * Copyright 2002-2007 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.
 */

#include "sun_awt_X11_XlibWrapper.h"
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xdbe.h>
#include <X11/extensions/shape.h>
#include <string.h>
#include <stdlib.h>

#include <jni.h>
#include <jni_util.h>
#include <jlong.h>

#include <awt.h>
#include <jvm.h>

#include <Region.h>

#if defined(DEBUG) || defined(INTERNAL_BUILD)
static jmethodID lockIsHeldMID = NULL;

static void
CheckHaveAWTLock(JNIEnv *env)
{
    if (lockIsHeldMID == NULL) {
        if (tkClass == NULL) return;
        lockIsHeldMID =
            (*env)->GetStaticMethodID(env, tkClass,
                                      "isAWTLockHeldByCurrentThread", "()Z");
    }
    if (!(*env)->CallStaticBooleanMethod(env, tkClass, lockIsHeldMID)) {
        JNU_ThrowInternalError(env, "Current thread does not hold AWT_LOCK!");
    }
}

#define AWT_CHECK_HAVE_LOCK() CheckHaveAWTLock(env)
#else
#define AWT_CHECK_HAVE_LOCK()
#endif


/*
 * Class:     XlibWrapper
 * Method:    XOpenDisplay
 * Signature: (J)J
 */

JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XOpenDisplay
(JNIEnv *env, jclass clazz, jlong display_name)
{
    Display *dp;
    AWT_CHECK_HAVE_LOCK();
    dp  =  XOpenDisplay((char *) jlong_to_ptr(display_name));

    return ptr_to_jlong(dp);
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XCloseDisplay(JNIEnv *env, jclass clazz,
                       jlong display) {
    AWT_CHECK_HAVE_LOCK();
    XCloseDisplay((Display*) jlong_to_ptr(display));
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XDisplayString(JNIEnv *env, jclass clazz,
                        jlong display) {
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XDisplayString((Display*) jlong_to_ptr(display)));
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XSetCloseDownMode(JNIEnv *env, jclass clazz,
                           jlong display, jint mode) {
    AWT_CHECK_HAVE_LOCK();
    XSetCloseDownMode((Display*) jlong_to_ptr(display), (int)mode);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DefaultScreen
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DefaultScreen (JNIEnv *env, jclass clazz, jlong display) {

    AWT_CHECK_HAVE_LOCK();
    return (jlong) DefaultScreen((Display *) jlong_to_ptr(display));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    ScreenOfDisplay
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_ScreenOfDisplay(JNIEnv *env, jclass clazz, jlong display, jlong screen_number) {
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(ScreenOfDisplay((Display *) jlong_to_ptr(display),
                                        screen_number));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DoesBackingStore
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_DoesBackingStore(JNIEnv *env, jclass clazz, jlong screen) {
    AWT_CHECK_HAVE_LOCK();
    return (jint) DoesBackingStore((Screen*) jlong_to_ptr(screen));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DisplayWidth
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidth
(JNIEnv *env, jclass clazz, jlong display, jlong screen) {

    AWT_CHECK_HAVE_LOCK();
    return (jlong) DisplayWidth((Display *) jlong_to_ptr(display),screen);

}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DisplayWidthMM
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidthMM
(JNIEnv *env, jclass clazz, jlong display, jlong screen) {
    AWT_CHECK_HAVE_LOCK();
    return (jlong) DisplayWidthMM((Display *) jlong_to_ptr(display),screen);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DisplayHeight
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeight
(JNIEnv *env, jclass clazz, jlong display, jlong screen) {

    AWT_CHECK_HAVE_LOCK();
    return (jlong) DisplayHeight((Display *) jlong_to_ptr(display),screen);
}
/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    DisplayHeightMM
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeightMM
(JNIEnv *env, jclass clazz, jlong display, jlong screen) {
    AWT_CHECK_HAVE_LOCK();
    return (jlong) DisplayHeightMM((Display *) jlong_to_ptr(display),screen);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    RootWindow
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_RootWindow
(JNIEnv *env , jclass clazz, jlong display, jlong screen_number) {
    AWT_CHECK_HAVE_LOCK();
    return (jlong) RootWindow((Display *) jlong_to_ptr(display), screen_number);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    ScreenCount
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_ScreenCount
(JNIEnv *env , jclass clazz, jlong display) {
    AWT_CHECK_HAVE_LOCK();
    return ScreenCount((Display *) jlong_to_ptr(display));
}


/*
 * Class:     XlibWrapper
 * Method:    XCreateWindow
 * Signature: (JJIIIIIIJJJJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreateWindow
  (JNIEnv *env, jclass clazz, jlong display, jlong window,
   jint x, jint y, jint w, jint h , jint border_width, jint depth,
   jlong wclass, jlong visual, jlong valuemask, jlong attributes)
{
    AWT_CHECK_HAVE_LOCK();
    return  XCreateWindow((Display *) jlong_to_ptr(display),(Window) window, x, y, w, h,
              border_width, depth, wclass, (Visual *) jlong_to_ptr(visual),
              valuemask, (XSetWindowAttributes *) jlong_to_ptr(attributes));

}

/*
 * Class:     XlibWrapper
 * Method:    XConvertCase
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XConvertCase
  (JNIEnv *env, jclass clazz, jlong keysym,
   jlong keysym_lowercase, jlong keysym_uppercase)
{
    AWT_CHECK_HAVE_LOCK();
    XConvertCase(keysym, (jlong_to_ptr(keysym_lowercase)),
                         (jlong_to_ptr(keysym_uppercase)));
}


/*
 * Class:     XlibWrapper
 * Method:    XMapWindow
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XMapWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
    AWT_CHECK_HAVE_LOCK();
    XMapWindow( (Display *)jlong_to_ptr(display),(Window) window);

}

/*
 * Class:     XlibWrapper
 * Method:    XMapRaised
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XMapRaised
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
    AWT_CHECK_HAVE_LOCK();
    XMapRaised( (Display *)jlong_to_ptr(display),(Window) window);

}

/*
 * Class:     XlibWrapper
 * Method:    XRaiseWindow
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRaiseWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{

    AWT_CHECK_HAVE_LOCK();
    XRaiseWindow( (Display *)jlong_to_ptr(display),(Window) window);

}

/*
 * Class:     XlibWrapper
 * Method:    XLowerWindow
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XLowerWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{

    AWT_CHECK_HAVE_LOCK();
    XLowerWindow( (Display *)jlong_to_ptr(display),(Window) window);

}

/*
 * Class:     XlibWrapper
 * Method:    XRestackWindows
 * Signature: (JJI)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRestackWindows
(JNIEnv *env, jclass clazz, jlong display, jlong windows, jint length)
{

    AWT_CHECK_HAVE_LOCK();
    XRestackWindows( (Display *) jlong_to_ptr(display), (Window *) jlong_to_ptr(windows), length);

}

/*
 * Class:     XlibWrapper
 * Method:    XSetInputFocus
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetInputFocus
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{

    AWT_CHECK_HAVE_LOCK();
    XSetInputFocus( (Display *)jlong_to_ptr(display),(Window) window, RevertToPointerRoot, CurrentTime);

}
/*
 * Class:     XlibWrapper
 * Method:    XSetInputFocus2
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetInputFocus2
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong time)
{

    AWT_CHECK_HAVE_LOCK();
    XSetInputFocus( (Display *)jlong_to_ptr(display),(Window) window, RevertToPointerRoot, time);

}

/*
 * Class:     XlibWrapper
 * Method:    XGetInputFocus
 * Signature: (JJ)V
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetInputFocus
(JNIEnv *env, jclass clazz, jlong display)
{

    Window focusOwner;
    int revert_to;
    AWT_CHECK_HAVE_LOCK();
    XGetInputFocus( (Display *)jlong_to_ptr(display), &focusOwner, &revert_to);
    return focusOwner;
}


/*
 * Class:     XlibWrapper
 * Method:    XDestroyWindow
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XDestroyWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
    AWT_CHECK_HAVE_LOCK();
    XDestroyWindow( (Display *)jlong_to_ptr(display),(Window) window);
}

JNIEXPORT int JNICALL Java_sun_awt_X11_XlibWrapper_XGrabPointer
(JNIEnv *env, jclass clazz, jlong display, jlong window,
 jint owner_events, jint event_mask, jint pointer_mode,
 jint keyboard_mode, jlong confine_to, jlong cursor, jlong time)
{
    AWT_CHECK_HAVE_LOCK();
    return XGrabPointer( (Display *)jlong_to_ptr(display), (Window) window,
             (Bool) owner_events, (unsigned int) event_mask, (int) pointer_mode,
             (int) keyboard_mode, (Window) confine_to, (Cursor) cursor, (Time) time);
}

JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XUngrabPointer
(JNIEnv *env, jclass clazz, jlong display, jlong time)
{
    AWT_CHECK_HAVE_LOCK();
    XUngrabPointer( (Display *)jlong_to_ptr(display), (Time) time);
}

JNIEXPORT int JNICALL Java_sun_awt_X11_XlibWrapper_XGrabKeyboard
(JNIEnv *env, jclass clazz, jlong display, jlong window,
 jint owner_events, jint pointer_mode,
 jint keyboard_mode, jlong time)
{
    AWT_CHECK_HAVE_LOCK();
    return XGrabKeyboard( (Display *)jlong_to_ptr(display), (Window) window,
              (Bool) owner_events, (int) pointer_mode,
              (int) keyboard_mode, (Time) time);
}

JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XUngrabKeyboard
(JNIEnv *env, jclass clazz, jlong display, jlong time)
{
    AWT_CHECK_HAVE_LOCK();
    XUngrabKeyboard( (Display *)jlong_to_ptr(display), (Time) time);
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XGrabServer(JNIEnv *env, jclass clazz,
                                         jlong display) {
     AWT_CHECK_HAVE_LOCK();
     XGrabServer((Display*)jlong_to_ptr(display));
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XUngrabServer(JNIEnv *env, jclass clazz,
                                           jlong display) {
     AWT_CHECK_HAVE_LOCK();
     XUngrabServer((Display*)jlong_to_ptr(display));
     /* Workaround for bug 5039226 */
     XSync((Display*)jlong_to_ptr(display), False);
}

/*
 * Class:     XlibWrapper
 * Method:    XUnmapWindow
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XUnmapWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{

    AWT_CHECK_HAVE_LOCK();
    XUnmapWindow( (Display *)jlong_to_ptr(display),(Window) window);

}



JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSelectInput
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong mask)
{
    AWT_CHECK_HAVE_LOCK();
    XSelectInput((Display *) jlong_to_ptr(display), (Window) window, mask);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XNextEvent
 * Signature: (JJ)V
 */


JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XNextEvent
(JNIEnv *env, jclass clazz, jlong display, jlong ptr)
{
    AWT_CHECK_HAVE_LOCK();
    XNextEvent( (Display *) jlong_to_ptr(display), jlong_to_ptr(ptr));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XMaskEvent
 * Signature: (JJJ)V
 */

JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XMaskEvent
  (JNIEnv *env, jclass clazz, jlong display, jlong event_mask, jlong event_return)
{
    AWT_CHECK_HAVE_LOCK();
    XMaskEvent( (Display *) jlong_to_ptr(display), event_mask, (XEvent *) jlong_to_ptr(event_return));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XWindowEvent
 * Signature: (JJJJ)V
 */

JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XWindowEvent
  (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong event_mask, jlong event_return)
{
    AWT_CHECK_HAVE_LOCK();
    XWindowEvent( (Display *) jlong_to_ptr(display), (Window)window, event_mask, (XEvent *) jlong_to_ptr(event_return));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFilterEvent
 * Signature: (JJ)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XFilterEvent
(JNIEnv *env, jclass clazz, jlong ptr, jlong window)
{
    AWT_CHECK_HAVE_LOCK();
    return (jboolean) XFilterEvent((XEvent *) jlong_to_ptr(ptr), (Window) window);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSupportsLocale
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XSupportsLocale
(JNIEnv *env, jclass clazz)
{
    AWT_CHECK_HAVE_LOCK();
    return (jboolean)XSupportsLocale();
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetLocaleModifiers
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_XSetLocaleModifiers
(JNIEnv *env, jclass clazz, jstring jstr)
{
    char * modifier_list = NULL;
    char * ret = NULL;

    if (!JNU_IsNull(env, jstr)) {
        modifier_list = (char *)JNU_GetStringPlatformChars(env, jstr, NULL);
    }

    AWT_CHECK_HAVE_LOCK();
    if (modifier_list) {
        ret = XSetLocaleModifiers(modifier_list);
        JNU_ReleaseStringPlatformChars(env, jstr, (const char *) modifier_list);
    } else {
        ret = XSetLocaleModifiers("");
    }

    return (ret != NULL ? JNU_NewStringPlatform(env, ret): NULL);
}


/*
 * Class:     sun_awt_X11_wrappers_XlibWrapper
 * Method:    XPeekEvent
 * Signature: (JJ)V
 */


JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XPeekEvent
(JNIEnv *env, jclass clazz, jlong display, jlong ptr)
{
    AWT_CHECK_HAVE_LOCK();
    XPeekEvent((Display *) jlong_to_ptr(display),jlong_to_ptr(ptr));
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XMoveResizeWindow
 * Signature: (JJIIII)V
 */

JNIEXPORT void JNICALL  Java_sun_awt_X11_XlibWrapper_XMoveResizeWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint x , jint y , jint width, jint height) {

    AWT_CHECK_HAVE_LOCK();
    XMoveResizeWindow( (Display *) jlong_to_ptr(display), (Window) window, x, y, width, height);

}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XResizeWindow
 * Signature: (JJII)V
 */

JNIEXPORT void JNICALL  Java_sun_awt_X11_XlibWrapper_XResizeWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint width, jint height)
{
    AWT_CHECK_HAVE_LOCK();
    XResizeWindow( (Display *) jlong_to_ptr(display),(Window) window,width,height);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XMoveWindow
 * Signature: (JJII)V
 */

JNIEXPORT void JNICALL  Java_sun_awt_X11_XlibWrapper_XMoveWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint width, jint height)
{
    AWT_CHECK_HAVE_LOCK();
    XMoveWindow( (Display *) jlong_to_ptr(display),(Window) window,width,height);
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetWindowBackground
 * Signature: (JJJ)V
 */

JNIEXPORT void JNICALL  Java_sun_awt_X11_XlibWrapper_XSetWindowBackground
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong background_pixel) {

    AWT_CHECK_HAVE_LOCK();
    XSetWindowBackground((Display *) jlong_to_ptr(display),window,background_pixel);

}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFlush
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XFlush
(JNIEnv *env, jclass clazz, jlong display) {

    AWT_CHECK_HAVE_LOCK();
    XFlush((Display *)jlong_to_ptr(display));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSync
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSync
(JNIEnv *env, jclass clazz, jlong display, jint discard) {

    AWT_CHECK_HAVE_LOCK();
    XSync((Display *) jlong_to_ptr(display), discard);

}

JNIEXPORT int JNICALL Java_sun_awt_X11_XlibWrapper_XTranslateCoordinates
(JNIEnv *env, jclass clazz, jlong display, jlong src_w, jlong dest_w,
 jlong src_x, jlong src_y, jlong dest_x_return, jlong dest_y_return,
 jlong child_return)
{
    AWT_CHECK_HAVE_LOCK();
    return XTranslateCoordinates( (Display *) jlong_to_ptr(display), src_w, dest_w,
                  src_x, src_y,
                  (int *) jlong_to_ptr(dest_x_return),
                  (int *) jlong_to_ptr(dest_y_return),
                  (Window *) jlong_to_ptr(child_return));
}

JNIEXPORT int JNICALL Java_sun_awt_X11_XlibWrapper_XEventsQueued
(JNIEnv *env, jclass clazz, jlong display, jint mode) {

    AWT_CHECK_HAVE_LOCK();
    return XEventsQueued((Display *) jlong_to_ptr(display), mode);

}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    SetProperty
 * Signature: (JJJLjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_SetProperty
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong atom, jstring jstr) {
    char *cname;
    XTextProperty tp;
    int32_t status;

    /*
       In case there are direct support of UTF-8 declared, use UTF-8 strings.
    */
    if (!JNU_IsNull(env, jstr)) {
#ifdef X_HAVE_UTF8_STRING
        cname = (char *) (*env)->GetStringUTFChars(env, jstr, JNI_FALSE);
#else
        cname = (char *) JNU_GetStringPlatformChars(env, jstr, NULL);
#endif
    } else {
        cname = "";
    }


    AWT_CHECK_HAVE_LOCK();

#ifdef X_HAVE_UTF8_STRING
    status = Xutf8TextListToTextProperty((Display *)jlong_to_ptr(display), &cname, 1,
                                       XStdICCTextStyle, &tp);
#else
    status = XmbTextListToTextProperty((Display *)jlong_to_ptr(display), &cname, 1,
                                       XStdICCTextStyle, &tp);
#endif


    if (status == Success || status > 0) {
        XChangeProperty((Display *)jlong_to_ptr(display), window, atom, tp.encoding, tp.format, PropModeReplace, tp.value, tp.nitems);
        if (tp.value != NULL) {
            XFree(tp.value);
        }
    }

    if (!JNU_IsNull(env, jstr)) {
#ifdef X_HAVE_UTF8_STRING
        (*env)->ReleaseStringUTFChars(env, jstr, (const char *) cname);
#else
        JNU_ReleaseStringPlatformChars(env, jstr, (const char *) cname);
#endif
    }
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XChangeProperty
 * Signature: (JJJJJJJJJJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XChangePropertyImpl(
    JNIEnv *env, jclass clazz, jlong display, jlong window, jlong property,
    jlong type, jint format, jint mode, jlong data, jint nelements)
{
    AWT_CHECK_HAVE_LOCK();
    XChangeProperty((Display*) jlong_to_ptr(display), (Window) window, (Atom) property,
            (Atom) type, format, mode, (unsigned char*) jlong_to_ptr(data),
            nelements);
}
/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XChangePropertyS
 * Signature: (JJJJJJJJJLjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XChangePropertyS(
    JNIEnv *env, jclass clazz, jlong display, jlong window, jlong property,
    jlong type, jint format, jint mode, jstring value)
{
    jboolean iscopy;
    const char * chars = JNU_GetStringPlatformChars(env, value, &iscopy);
    AWT_CHECK_HAVE_LOCK();
    XChangeProperty((Display*)jlong_to_ptr(display), window, (Atom)property,
                    (Atom)type, format, mode, (unsigned char*)chars, strlen(chars));
    if (iscopy) {
        JNU_ReleaseStringPlatformChars(env, value, chars);
    }
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetWindowProperty
 * Signature: (JJJJJJJJJJJ)J;
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWindowProperty
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong property, jlong long_offset,
 jlong long_length, jlong delete, jlong req_type, jlong actual_type,
 jlong actual_format, jlong nitems_ptr, jlong bytes_after, jlong data_ptr)
{
    AWT_CHECK_HAVE_LOCK();
    return XGetWindowProperty((Display*) jlong_to_ptr(display), window, property, long_offset, long_length,
                  delete, (Atom) req_type, (Atom*) jlong_to_ptr(actual_type),
                  (int *) jlong_to_ptr(actual_format), (unsigned long *) jlong_to_ptr(nitems_ptr),
                  (unsigned long*) jlong_to_ptr(bytes_after), (unsigned char**) jlong_to_ptr(data_ptr));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    GetProperty
 * Signature: (JJJ)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_GetProperty
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong atom)
{
    /* Request status */
    int status;

    /* Returns of XGetWindowProperty */
    Atom actual_type;
    int actual_format;
    unsigned long nitems;
    unsigned long bytes_after;
    unsigned char * string;
    jstring res;
    AWT_CHECK_HAVE_LOCK();
    status = XGetWindowProperty((Display*)jlong_to_ptr(display), window,
                                atom, 0, 0xFFFF, False, XA_STRING,
                                &actual_type, &actual_format, &nitems, &bytes_after,
                                &string);
    if (status != Success || string == NULL) {
    return NULL;
    }

    if (actual_type != XA_STRING || actual_format != 8) {
    XFree(string);
    return NULL;
    }

    // Memory leak???
    return JNU_NewStringPlatform(env,(char*) string);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    InternAtom
 * Signature: (JLjava/lang/String;I)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_InternAtom
(JNIEnv *env, jclass clazz, jlong display, jstring jstr, jint ife) {

    char *cname;
    unsigned long atom;

    if (!JNU_IsNull(env, jstr)) {
        cname = (char *)JNU_GetStringPlatformChars(env, jstr, NULL);
    } else {
        cname = "";
    }

    AWT_CHECK_HAVE_LOCK();
    atom = XInternAtom((Display *) jlong_to_ptr(display), cname, ife);

    if (!JNU_IsNull(env, jstr)) {
        JNU_ReleaseStringPlatformChars(env, jstr, (const char *) cname);
    }

    return (jlong) atom;

}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XCreateFontCursor
(JNIEnv *env, jclass clazz, jlong display, jint shape) {
    AWT_CHECK_HAVE_LOCK();
    return XCreateFontCursor((Display *) jlong_to_ptr(display), (int) shape);
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XCreatePixmapCursor
 * Signature: (JJJJJII)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreatePixmapCursor
(JNIEnv *env , jclass clazz, jlong display, jlong source, jlong mask, jlong fore, jlong back, jint x , jint y) {

    AWT_CHECK_HAVE_LOCK();
    return (jlong) XCreatePixmapCursor((Display *) jlong_to_ptr(display), (Pixmap) source, (Pixmap) mask,
                                       (XColor *) jlong_to_ptr(fore), (XColor *) jlong_to_ptr(back), x, y);
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XQueryBestCursor
 * Signature: (JJIIJJ)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryBestCursor
(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jint width, jint height, jlong width_return, jlong height_return) {

    Status status;

    AWT_CHECK_HAVE_LOCK();
    status  =  XQueryBestCursor((Display *) jlong_to_ptr(display), (Drawable) drawable, width,height,
                                (unsigned int *) jlong_to_ptr(width_return), (unsigned int *) jlong_to_ptr(height_return));

    if (status == 0) return JNI_FALSE;
    else return JNI_TRUE;
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFreeCursor
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XFreeCursor
(JNIEnv *env, jclass clazz, jlong display, jlong cursor) {

    AWT_CHECK_HAVE_LOCK();
    XFreeCursor( (Display *) jlong_to_ptr(display), (Cursor) cursor);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XQueryPointer
 * Signature: (JJJJJJJJJ)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryPointer
(JNIEnv *env, jclass clazz, jlong display, jlong w, jlong root_return, jlong child_return, jlong root_x_return , jlong root_y_return, jlong win_x_return, jlong win_y_return, jlong mask_return) {

    Bool b;

    AWT_CHECK_HAVE_LOCK();
    b = XQueryPointer((Display *) jlong_to_ptr(display),
                      (Window) w, (Window *) jlong_to_ptr(root_return), (Window *) jlong_to_ptr(child_return),
                      (int *) jlong_to_ptr(root_x_return), (int *) jlong_to_ptr(root_y_return),
                      (int *) jlong_to_ptr(win_x_return), (int *) jlong_to_ptr(win_y_return),
                      (unsigned int *) jlong_to_ptr(mask_return));
    if (b == True) return JNI_TRUE;
    else return JNI_FALSE;

}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XChangeWindowAttributes
 * Signature: (JJJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XChangeWindowAttributes
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong valuemask, jlong attributes) {

    AWT_CHECK_HAVE_LOCK();
    XChangeWindowAttributes((Display *) jlong_to_ptr(display), (Window) window, (unsigned long) valuemask,
                            (XSetWindowAttributes *) jlong_to_ptr(attributes));
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetTransientFor
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetTransientFor
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong transient_for_window)
{
    AWT_CHECK_HAVE_LOCK();
    XSetTransientForHint((Display *) jlong_to_ptr(display), window, transient_for_window);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetWMHints
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetWMHints
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong hints)
{
    AWT_CHECK_HAVE_LOCK();
    XSetWMHints((Display *) jlong_to_ptr(display), window, (XWMHints *) jlong_to_ptr(hints));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetWMHints
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XGetWMHints
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong hints)
{
    XWMHints * get_hints;
    AWT_CHECK_HAVE_LOCK();
    get_hints = XGetWMHints((Display*)jlong_to_ptr(display), window);
    if (get_hints != NULL) {
        memcpy(jlong_to_ptr(hints), get_hints, sizeof(XWMHints));
        XFree(get_hints);
    } else {
        memset(jlong_to_ptr(hints), 0, sizeof(XWMHints));
    }
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetPointerMapping
 * Signature: (JJI)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetPointerMapping
(JNIEnv *env, jclass clazz, jlong display, jlong map, jint buttonNumber)
{
    AWT_CHECK_HAVE_LOCK();
    return XGetPointerMapping((Display*)jlong_to_ptr(display), (unsigned char*) jlong_to_ptr(map), buttonNumber);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetDefault
 * Signature: (JJI)I
 */
JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_XGetDefault
(JNIEnv *env, jclass clazz, jlong display, jstring program, jstring option)
{
    char * c_program = NULL;
    char * c_option = NULL;
    char * c_res = NULL;

    if (!JNU_IsNull(env, program)) {
        c_program = (char *)JNU_GetStringPlatformChars(env, program, NULL);
    }
    if (!JNU_IsNull(env, option)) {
        c_option = (char *)JNU_GetStringPlatformChars(env, option, NULL);
    }

    if (c_program == NULL || c_option == NULL) {
        if (!JNU_IsNull(env, program)) {
            JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program);
        }
        if (!JNU_IsNull(env, option)) {
            JNU_ReleaseStringPlatformChars(env, option, (const char *) c_option);
        }
        return NULL;
    }
    AWT_CHECK_HAVE_LOCK();
    c_res = XGetDefault((Display*)jlong_to_ptr(display), c_program, c_option);

    if (!JNU_IsNull(env, program)) {
        JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program);
    }
    if (!JNU_IsNull(env, option)) {
        JNU_ReleaseStringPlatformChars(env, option, (const char *) c_option);
    }

    if (c_res != NULL) {
        // Memory leak???
        return JNU_NewStringPlatform(env, c_res);
    } else {
        return NULL;
    }
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    getScreenOfWindow
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_getScreenOfWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
    XWindowAttributes attrs;
    memset(&attrs, 0, sizeof(attrs));
    AWT_CHECK_HAVE_LOCK();
    XGetWindowAttributes((Display *) jlong_to_ptr(display), window, &attrs);
    return ptr_to_jlong(attrs.screen);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XScreenNumberOfScreen
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XScreenNumberOfScreen
(JNIEnv *env, jclass clazz, jlong screen)
{
    AWT_CHECK_HAVE_LOCK();
    if(jlong_to_ptr(screen) == NULL) {
        return -1;
    }
    return XScreenNumberOfScreen((Screen*) jlong_to_ptr(screen));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XIconifyWindow
 * Signature: (JJJ)V
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XIconifyWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong screenNumber)
{
    AWT_CHECK_HAVE_LOCK();
    return XIconifyWindow((Display*) jlong_to_ptr(display), window, screenNumber);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFree
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XFree
(JNIEnv *env, jclass clazz, jlong ptr)
{
    AWT_CHECK_HAVE_LOCK();
    XFree(jlong_to_ptr(ptr));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFree
 * Signature: (J)V
 */
JNIEXPORT jbyteArray JNICALL Java_sun_awt_X11_XlibWrapper_getStringBytes
(JNIEnv *env, jclass clazz, jlong str_ptr)
{
    unsigned char * str = (unsigned char*) jlong_to_ptr(str_ptr);
    long length = strlen((char*)str);
    jbyteArray res = (*env)->NewByteArray(env, length);
    void * storage = malloc(length+1);
    memcpy(storage, str, length+1);
    (*env)->SetByteArrayRegion(env, res, 0, length,
                   (const signed char*) storage);
    return res;
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    ServerVendor
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_ServerVendor
(JNIEnv *env, jclass clazz, jlong display)
{
    AWT_CHECK_HAVE_LOCK();
    return JNU_NewStringPlatform(env, ServerVendor((Display*)jlong_to_ptr(display)));
}
/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    VendorRelease
 * Signature: (J)I;
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_VendorRelease
(JNIEnv *env, jclass clazz, jlong display)
{
    AWT_CHECK_HAVE_LOCK();
    return VendorRelease((Display*)jlong_to_ptr(display));
}

JavaVM* jvm = NULL;
static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
    if (jvm != NULL) {
        JNIEnv * env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
        return JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "GlobalErrorHandler", "(JJ)I",
                                          ptr_to_jlong(dpy), ptr_to_jlong(event)).i;
    } else {
        return 0;
    }
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    SetToolkitErrorHandler
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler
(JNIEnv *env, jclass clazz)
{
    (*env)->GetJavaVM(env, &jvm);
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XSetErrorHandler(ToolkitErrorHandler));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetErrorHandler
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetErrorHandler
(JNIEnv *env, jclass clazz, jlong handler)
{
    AWT_CHECK_HAVE_LOCK();
    XSetErrorHandler((XErrorHandler) jlong_to_ptr(handler));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    CallErrorHandler
 * Signature: (JJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_CallErrorHandler
(JNIEnv *env, jclass clazz, jlong handler, jlong display, jlong event_ptr)
{
    return (*(XErrorHandler)jlong_to_ptr(handler))((Display*) jlong_to_ptr(display), (XErrorEvent*) jlong_to_ptr(event_ptr));
}



/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XInternAtoms
 * Signature: (J[Ljava/lang/String;ZJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XInternAtoms
(JNIEnv *env, jclass clazz, jlong display, jobjectArray names_arr, jboolean only_if_exists, jlong atoms)
{

    int length = (*env)->GetArrayLength(env, names_arr);
    char ** names = (char**)malloc(length*sizeof(char*));
    jboolean copy;
    int index, name_index = 0;
    int status;
    for (index = 0; index < length; index++) {
        jstring str = (*env)->GetObjectArrayElement(env, names_arr, index);
        if (!JNU_IsNull(env, str)) {
            const char * str_char = JNU_GetStringPlatformChars(env, str, NULL);
            names[name_index++] = strdup(str_char);
            JNU_ReleaseStringPlatformChars(env, str, str_char);
            (*env)->DeleteLocalRef(env, str);
        }
    }
    AWT_CHECK_HAVE_LOCK();
    status = XInternAtoms((Display*)jlong_to_ptr(display), names, name_index, only_if_exists, (Atom*) jlong_to_ptr(atoms));
    for (index = 0; index < length; index++) {
        free(names[index]);
    }
    free(names);
    return status;
}



/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetWindowAttributes
 * Signature: (JJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWindowAttributes
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong attr_ptr)
{
    jint status;
    AWT_CHECK_HAVE_LOCK();
    memset((XWindowAttributes*) jlong_to_ptr(attr_ptr), 0, sizeof(XWindowAttributes));
    status =  XGetWindowAttributes((Display*)jlong_to_ptr(display), window, (XWindowAttributes*) jlong_to_ptr(attr_ptr));
    return status;
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetGeometry
 * Signature: (JJJJJJJJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetGeometry
(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jlong root_return,
     jlong x_return, jlong y_return, jlong width_return, jlong height_return,
     jlong border_width_return, jlong depth_return)
{
    jint status;
    AWT_CHECK_HAVE_LOCK();
    status = XGetGeometry((Display *)jlong_to_ptr(display),
                          (Drawable)drawable, (Window *)jlong_to_ptr(root_return),
                          (int *)jlong_to_ptr(x_return), (int *)jlong_to_ptr(y_return),
                          (unsigned int *)jlong_to_ptr(width_return), (unsigned int *)jlong_to_ptr(height_return),
                          (unsigned int *)jlong_to_ptr(border_width_return),
                          (unsigned int *)jlong_to_ptr(depth_return));
    return status;
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetWMNormalHints
 * Signature: (JJJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWMNormalHints
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong hints, jlong supplied_return)
{
    AWT_CHECK_HAVE_LOCK();
    return XGetWMNormalHints((Display*) jlong_to_ptr(display),
                             window,
                             (XSizeHints*) jlong_to_ptr(hints),
                             (long*) jlong_to_ptr(supplied_return));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetWMNormalHints
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetWMNormalHints
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong hints)
{
    AWT_CHECK_HAVE_LOCK();
    XSetWMNormalHints((Display*) jlong_to_ptr(display), window, (XSizeHints*) jlong_to_ptr(hints));
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XDeleteProperty
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XDeleteProperty
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong atom)
{
    AWT_CHECK_HAVE_LOCK();
    XDeleteProperty((Display*) jlong_to_ptr(display), window, (Atom)atom);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSendEvent
 * Signature: (JJZJJ)V
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XSendEvent
(JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean propagate, jlong event_mask, jlong event)
{
    AWT_CHECK_HAVE_LOCK();
    return XSendEvent((Display*) jlong_to_ptr(display),
                      window,
                      propagate==JNI_TRUE?True:False,
                      (long) event_mask,
                      (XEvent*) jlong_to_ptr(event));
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XQueryTree
 * Signature: (JJJJJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XQueryTree
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong root_return, jlong parent_return, jlong children_return, jlong nchildren_return)
{
    AWT_CHECK_HAVE_LOCK();
    return XQueryTree((Display*) jlong_to_ptr(display),
                      window,
                      (Window *) jlong_to_ptr(root_return),
                      (Window*) jlong_to_ptr(parent_return),
                      (Window**) jlong_to_ptr(children_return),
                      (unsigned int*) jlong_to_ptr(nchildren_return));
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    memcpy
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_memcpy
(JNIEnv *env, jclass clazz, jlong dest_ptr, jlong src_ptr, jlong length)
{
    memcpy(jlong_to_ptr(dest_ptr), jlong_to_ptr(src_ptr), length);
}


JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSetMinMaxHints
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint x, jint y, jint width, jint height, jlong flags) {
    XSizeHints * hints;
    AWT_CHECK_HAVE_LOCK();
    hints = XAllocSizeHints();
    hints->flags = flags;
    hints->width = width;
    hints->min_width = width;
    hints->max_width = width;
    hints->height = height;
    hints->min_height = height;
    hints->max_height = height;
    hints->x = x;
    hints->y = y;
    XSetWMNormalHints((Display*) jlong_to_ptr(display), window, hints);
    XFree(hints);
}


JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetVisualInfo
(JNIEnv *env, jclass clazz, jlong display, jlong vinfo_mask, jlong vinfo_template,
 jlong nitems_return)
{
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XGetVisualInfo((Display*) jlong_to_ptr(display),
                                       (long) vinfo_mask,
                                       (XVisualInfo*) jlong_to_ptr(vinfo_template),
                                       (int*) jlong_to_ptr(nitems_return)));
}

JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XAllocSizeHints
  (JNIEnv *env, jclass clazz)
{
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XAllocSizeHints());
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XIconifyWindow
 * Signature: (JJJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XBell
(JNIEnv *env, jclass clazz, jlong display, jint percent)
{
    AWT_CHECK_HAVE_LOCK();
    XBell((Display*)jlong_to_ptr(display), percent);
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XAllocColor
 * Signature: (JJJ)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XAllocColor
(JNIEnv *env, jclass clazz, jlong display , jlong colormap, jlong xcolor) {

    Status status;
    AWT_CHECK_HAVE_LOCK();
    status = XAllocColor((Display *) jlong_to_ptr(display), (Colormap) colormap, (XColor *) jlong_to_ptr(xcolor));

    if (status == 0) return JNI_FALSE;
    else return JNI_TRUE;
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XCreateBitmapFromData
 * Signature: (JJJII)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreateBitmapFromData
(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jlong data, jint width, jint height) {
    AWT_CHECK_HAVE_LOCK();

    return (jlong) XCreateBitmapFromData((Display *) jlong_to_ptr(display), (Drawable) drawable,
                                         (char *) jlong_to_ptr(data), width, height);
}


/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XFreePixmap
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XFreePixmap
(JNIEnv *env, jclass clazz, jlong display, jlong pixmap) {
    AWT_CHECK_HAVE_LOCK();
    XFreePixmap((Display *)jlong_to_ptr(display), (Pixmap) pixmap);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XReparentWindow
 * Signature: (JJJII)V
 */
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XReparentWindow
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong parent, jint x, jint y) {
    AWT_CHECK_HAVE_LOCK();
    XReparentWindow((Display*)jlong_to_ptr(display), window, parent, x, y);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XConvertSelection
 * Signature: (JJJJJJ)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XConvertSelection(JNIEnv *env, jclass clazz,
                           jlong display, jlong selection,
                           jlong target, jlong property,
                           jlong requestor, jlong time) {
    AWT_CHECK_HAVE_LOCK();
    XConvertSelection((Display*)jlong_to_ptr(display), selection, target, property, requestor,
              time);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XSetSelectionOwner
 * Signature: (JJJJ)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XSetSelectionOwner(JNIEnv *env, jclass clazz,
                        jlong display, jlong selection,
                        jlong owner, jlong time) {
    AWT_CHECK_HAVE_LOCK();
    XSetSelectionOwner((Display*)jlong_to_ptr(display), selection, owner, time);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetSelectionOwner
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XGetSelectionOwner(JNIEnv *env, jclass clazz,
                        jlong display, jlong selection) {
    AWT_CHECK_HAVE_LOCK();
    return (jlong)XGetSelectionOwner((Display*)jlong_to_ptr(display), selection);
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XGetAtomName
 * Signature: (JJ)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL
Java_sun_awt_X11_XlibWrapper_XGetAtomName(JNIEnv *env, jclass clazz,
                      jlong display, jlong atom)
{
    jstring string = NULL;
    char* name;
    AWT_CHECK_HAVE_LOCK();
    name = (char*) XGetAtomName((Display*)jlong_to_ptr(display), atom);

    if (name == NULL) {
        fprintf(stderr, "Atom was %d\n", (int)atom);
        JNU_ThrowNullPointerException(env, "Failed to retrieve atom name.");
        return NULL;
    }

    string = (*env)->NewStringUTF(env, (const char *)name);

    XFree(name);

    return string;
}

/*
 * Class:     sun_awt_X11_XlibWrapper
 * Method:    XMaxRequestSize
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XMaxRequestSize(JNIEnv *env, jclass clazz,
                         jlong display) {
    AWT_CHECK_HAVE_LOCK();
    return XMaxRequestSize((Display*) jlong_to_ptr(display));
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XAllocWMHints(JNIEnv *env, jclass clazz)
{
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XAllocWMHints());
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XCreatePixmap(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jint width, jint height, jint depth)
{
    AWT_CHECK_HAVE_LOCK();
    return XCreatePixmap((Display*)jlong_to_ptr(display), (Drawable)drawable, width, height, depth);
}
JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XCreateImage
  (JNIEnv *env, jclass clazz, jlong display, jlong visual_ptr,
   jint depth, jint format, jint offset, jlong data, jint width,
   jint height, jint bitmap_pad, jint bytes_per_line)
{
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XCreateImage((Display*) jlong_to_ptr(display), (Visual*) jlong_to_ptr(visual_ptr),
                depth, format, offset, (char*) jlong_to_ptr(data),
                width, height, bitmap_pad, bytes_per_line));
}
JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XCreateGC
  (JNIEnv *env, jclass clazz, jlong display, jlong drawable,
   jlong valuemask, jlong values)
{
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XCreateGC((Display*) jlong_to_ptr(display), (Drawable)drawable, valuemask, (XGCValues*) jlong_to_ptr(values)));
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XDestroyImage(JNIEnv *env, jclass clazz, jlong image)
{
    XImage *img = (XImage*) jlong_to_ptr(image);
    AWT_CHECK_HAVE_LOCK();

    // Fix for bug 4903671 :
    // We should be careful to not double free the memory pointed to data
    // Since we use unsafe to allocate it, we should use unsafe to free it.
    // So we should NULL the data pointer before calling XDestroyImage so
    // that X does not free the pointer for us.
    img->data = NULL;
    XDestroyImage(img);
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XPutImage(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jlong gc, jlong image, jint src_x, jint src_y, jint dest_x, jint dest_y, jint width, jint height)
{
    AWT_CHECK_HAVE_LOCK();
    XPutImage((Display*)jlong_to_ptr(display), (Drawable)drawable, (GC) jlong_to_ptr(gc), (XImage*) jlong_to_ptr(image), src_x, src_y,
              dest_x, dest_y, width, height);
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XFreeGC(JNIEnv *env, jclass clazz, jlong display, jlong gc)
{
    AWT_CHECK_HAVE_LOCK();
    XFreeGC((Display*) jlong_to_ptr(display), (GC) jlong_to_ptr(gc));
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XSetWindowBackgroundPixmap(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong pixmap)
{
    AWT_CHECK_HAVE_LOCK();
    XSetWindowBackgroundPixmap((Display*) jlong_to_ptr(display), (Window)window, (Pixmap)pixmap);
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XClearWindow(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
    AWT_CHECK_HAVE_LOCK();
    XClearWindow((Display*) jlong_to_ptr(display), (Window)window);
}

JNIEXPORT jint JNICALL
Java_sun_awt_X11_XlibWrapper_XGetIconSizes(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong ret_sizes, jlong ret_count)
{
    XIconSize** psize = (XIconSize**) jlong_to_ptr(ret_sizes);
    int * pcount = (int *) jlong_to_ptr(ret_count);
    Status res;
    AWT_CHECK_HAVE_LOCK();
    res = XGetIconSizes((Display*) jlong_to_ptr(display), (Window)window, psize, pcount);
    return res;
}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeQueryExtension
  (JNIEnv *env, jclass clazz, jlong display, jlong major_version_return,
   jlong minor_version_return)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeQueryExtension((Display*) jlong_to_ptr(display), (int *) jlong_to_ptr(major_version_return),
                  (int *) jlong_to_ptr(minor_version_return));
}

JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryExtension
  (JNIEnv *env, jclass clazz, jlong display, jstring jstr, jlong mop_return,
   jlong feve_return, jlong err_return)
{
    char *cname;
    Boolean bu;
    if (!JNU_IsNull(env, jstr)) {
        cname = (char *)JNU_GetStringPlatformChars(env, jstr, NULL);
    } else {
        cname = "";
    }

    AWT_CHECK_HAVE_LOCK();
    bu = XQueryExtension((Display*) jlong_to_ptr(display), cname, (int *) jlong_to_ptr(mop_return),
                (int *) jlong_to_ptr(feve_return),  (int *) jlong_to_ptr(err_return));
    if (!JNU_IsNull(env, jstr)) {
        JNU_ReleaseStringPlatformChars(env, jstr, (const char *) cname);
    }
    return bu ? JNI_TRUE : JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKeypadKey
  (JNIEnv *env, jclass clazz, jlong keysym)
{
    AWT_CHECK_HAVE_LOCK();
    if(IsKeypadKey(keysym)) {
        return JNI_TRUE;
    }
    return JNI_FALSE;
}

JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XdbeAllocateBackBufferName
  (JNIEnv *env, jclass clazz, jlong display, jlong window, jint swap_action)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeAllocateBackBufferName((Display*) jlong_to_ptr(display), (Window) window,
                      (XdbeSwapAction) swap_action);
}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeDeallocateBackBufferName
  (JNIEnv *env, jclass clazz, jlong display, jlong buffer)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeDeallocateBackBufferName((Display*) jlong_to_ptr(display), (XdbeBackBuffer) buffer);
}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeBeginIdiom
  (JNIEnv *env, jclass clazz, jlong display)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeBeginIdiom((Display*) jlong_to_ptr(display));
}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeEndIdiom
  (JNIEnv *env, jclass clazz, jlong display)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeEndIdiom((Display*) jlong_to_ptr(display));
}

JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeSwapBuffers
  (JNIEnv *env, jclass clazz, jlong display, jlong swap_info, jint num_windows)
{
    AWT_CHECK_HAVE_LOCK();
    return XdbeSwapBuffers((Display*) jlong_to_ptr(display), (XdbeSwapInfo *) jlong_to_ptr(swap_info), num_windows);
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz,
                                              jlong display, jint keycode,
                                              jint index) {
    AWT_CHECK_HAVE_LOCK();
    return XKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (int)index);
}

JNIEXPORT jint JNICALL
Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode(JNIEnv *env, jclass clazz,
                                              jlong display, jlong keysym) {
    AWT_CHECK_HAVE_LOCK();
    return XKeysymToKeycode((Display*) jlong_to_ptr(display), (KeySym)keysym);
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XGetModifierMapping(JNIEnv *env, jclass clazz,
                                              jlong display) {
    AWT_CHECK_HAVE_LOCK();
    return ptr_to_jlong(XGetModifierMapping((Display*) jlong_to_ptr(display)));
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XFreeModifiermap(JNIEnv *env, jclass clazz,
                                              jlong keymap) {
    AWT_CHECK_HAVE_LOCK();
    XFreeModifiermap((XModifierKeymap*) jlong_to_ptr(keymap));
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab(JNIEnv *env, jclass clazz,
                                                      jlong display, jint mask,
                                                      jlong cursor, jlong time) {
    AWT_CHECK_HAVE_LOCK();
    XChangeActivePointerGrab((Display*)jlong_to_ptr(display), (unsigned int)mask,
                             (Cursor)cursor, (Time)time);
}

/******************* Secondary loop support ************************************/
#define AWT_SECONDARY_LOOP_TIMEOUT 250

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 jboolean JNICALL
Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent(JNIEnv *env, jclass clazz,
                                                     jlong display, jlong ptr) {
    AWT_CHECK_HAVE_LOCK();
    exitSecondaryLoop = False;
    while (!exitSecondaryLoop) {
        if (XCheckIfEvent((Display*) jlong_to_ptr(display), (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, NULL)) {
            return JNI_TRUE;
        }
        AWT_WAIT(AWT_SECONDARY_LOOP_TIMEOUT);
    }
    return JNI_FALSE;
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop(JNIEnv *env, jclass clazz) {
    DASSERT(!exitSecondaryLoop);
    AWT_CHECK_HAVE_LOCK();
    exitSecondaryLoop = True;
    AWT_NOTIFY_ALL();
}
/*******************************************************************************/

JNIEXPORT jobjectArray JNICALL
Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList(JNIEnv *env,
                                                       jclass clazz,
                                                       jbyteArray bytes,
                                                       jlong encodingAtom) {
    XTextProperty tp;
    jbyte         *value;

    char**        strings  = (char **)NULL;
    int32_t       nstrings = 0;
    jobjectArray  ret = NULL;
    int32_t       i;
    jsize         len;
    jboolean      isCopy = JNI_FALSE;
    static jclass stringClass = NULL;
    jclass        stringClassLocal = NULL;

    AWT_CHECK_HAVE_LOCK();

    if (JNU_IsNull(env, stringClass)) {
        stringClassLocal = (*env)->FindClass(env, "java/lang/String");

        if ((*env)->ExceptionCheck(env)) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
            DASSERT(False);
        }

        if (JNU_IsNull(env, stringClassLocal)) {
            return NULL;
        }

        stringClass = (*env)->NewGlobalRef(env, stringClassLocal); /* never freed! */
        (*env)->DeleteLocalRef(env, stringClassLocal);

        if (JNU_IsNull(env, stringClass)) {
            JNU_ThrowOutOfMemoryError(env, "");
            return NULL;
        }
    }

    /*
     * If the length of the byte array is 0 just return a null
     */
    len = (*env)->GetArrayLength(env, bytes);
    if (len == 0) {
        return (*env)->NewObjectArray(env, 0, stringClass, NULL);
    }

    value = (*env)->GetByteArrayElements(env, bytes, &isCopy);
    if (JNU_IsNull(env, value)) {
        return NULL;
    }

    tp.encoding = encodingAtom;
    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) {
        (*env)->ReleaseByteArrayElements(env, bytes, value, JNI_ABORT);
        return NULL;
    }

    (*env)->ReleaseByteArrayElements(env, bytes, value, JNI_ABORT);

    if (nstrings == 0) {
        return (*env)->NewObjectArray(env, 0, stringClass, NULL);
    }

    ret = (*env)->NewObjectArray(env, nstrings, stringClass, NULL);

    if ((*env)->ExceptionCheck(env)) {
        (*env)->ExceptionDescribe(env);
        (*env)->ExceptionClear(env);
        goto wayout;
    }

    if (JNU_IsNull(env, ret)) {
        goto wayout;
    }

    for (i = 0; i < nstrings; i++) {
        jstring string = (*env)->NewStringUTF(env,
                                              (const char *)strings[i]);
        if ((*env)->ExceptionCheck(env)) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
            goto wayout;
        }

        if (JNU_IsNull(env, string)) {
            goto wayout;
        }

        (*env)->SetObjectArrayElement(env, ret, i, string);

        if ((*env)->ExceptionCheck(env)) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
            goto wayout;
        }

        (*env)->DeleteLocalRef(env, string);
    }

 wayout:
    /*
     * Clean up and return
     */
    XFreeStringList(strings);
    return ret;
}


JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_XPutBackEvent(JNIEnv *env,
                                           jclass clazz,
                                           jlong display,
                                           jlong event) {
    XPutBackEvent((Display*)jlong_to_ptr(display), (XEvent*) jlong_to_ptr(event));
}

JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_getAddress(JNIEnv *env,
                                           jclass clazz,
                                           jobject o) {
    return ptr_to_jlong(o);
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_copyIntArray(JNIEnv *env,
                                           jclass clazz,
                                           jlong dest, jobject array, jint size) {
    jboolean isCopy = JNI_FALSE;
    jint * ints = (*env)->GetIntArrayElements(env, array, &isCopy);
    memcpy(jlong_to_ptr(dest), ints, size);
    if (isCopy) {
        (*env)->ReleaseIntArrayElements(env, array, ints, JNI_ABORT);
    }
}

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_copyLongArray(JNIEnv *env,
                                           jclass clazz,
                                           jlong dest, jobject array, jint size) {
    jboolean isCopy = JNI_FALSE;
    jlong * longs = (*env)->GetLongArrayElements(env, array, &isCopy);
    memcpy(jlong_to_ptr(dest), longs, size);
    if (isCopy) {
        (*env)->ReleaseLongArrayElements(env, array, longs, JNI_ABORT);
    }
}

JNIEXPORT jint JNICALL
Java_sun_awt_X11_XlibWrapper_XSynchronize(JNIEnv *env, jclass clazz, jlong display, jboolean onoff)
{
    return (jint) XSynchronize((Display*)jlong_to_ptr(display), (onoff == JNI_TRUE ? True : False));
}

JNIEXPORT jboolean JNICALL
Java_sun_awt_X11_XlibWrapper_XShapeQueryExtension
(JNIEnv *env, jclass clazz, jlong display, jlong event_base_return, jlong error_base_return)
{
    jboolean status;

    AWT_CHECK_HAVE_LOCK();

    status = XShapeQueryExtension((Display *)jlong_to_ptr(display),
            (int *)jlong_to_ptr(event_base_return), (int *)jlong_to_ptr(error_base_return));
    return status;
}

/*
 * Class:     XlibWrapper
 * Method:    SetRectangularShape
 */

JNIEXPORT void JNICALL
Java_sun_awt_X11_XlibWrapper_SetRectangularShape
(JNIEnv *env, jclass clazz, jlong display, jlong window,
 jint x1, jint y1, jint x2, jint y2,
 jobject region)
{
    XRectangle rects[256];
    XRectangle *pRect = rects;
    int numrects;

    AWT_CHECK_HAVE_LOCK();

    numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region,
            &pRect, 256);

    XShapeCombineRectangles((Display *)jlong_to_ptr(display), (Window)jlong_to_ptr(window),
                ShapeBounding, 0, 0, pRect, numrects, ShapeSet, YXBanded);

    if (pRect != rects) {
        free(pRect);
    }
}
