/*
 * Copyright (c) 1997, 2005, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifdef HEADLESS
    #error This file should not be included in headless library
#endif

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#ifdef XAWT
#include <sys/time.h>
#else /* !XAWT */
#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <Xm/MwmUtil.h>
#include <Xm/MenuShell.h>
#endif /* XAWT */

#include "awt.h"
#include "awt_p.h"

#include <sun_awt_X11InputMethod.h>
#ifdef XAWT
#include <sun_awt_X11_XComponentPeer.h>
#include <sun_awt_X11_XInputMethod.h>

#define XtWindow(w)     (w)
#else /* !XAWT */
#include <sun_awt_motif_MComponentPeer.h>
#include <sun_awt_motif_MInputMethod.h>

#define MCOMPONENTPEER_CLASS_NAME       "sun/awt/motif/MComponentPeer"
#endif /* XAWT */

#define THROW_OUT_OF_MEMORY_ERROR() \
        JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
#define SETARG(name, value)     XtSetArg(args[argc], name, value); argc++

struct X11InputMethodIDs {
  jfieldID pData;
} x11InputMethodIDs;

static void PreeditStartCallback(XIC, XPointer, XPointer);
static void PreeditDoneCallback(XIC, XPointer, XPointer);
static void PreeditDrawCallback(XIC, XPointer,
                                XIMPreeditDrawCallbackStruct *);
static void PreeditCaretCallback(XIC, XPointer,
                                 XIMPreeditCaretCallbackStruct *);
#ifdef __linux__
static void StatusStartCallback(XIC, XPointer, XPointer);
static void StatusDoneCallback(XIC, XPointer, XPointer);
static void StatusDrawCallback(XIC, XPointer,
                               XIMStatusDrawCallbackStruct *);
#endif

#define ROOT_WINDOW_STYLES      (XIMPreeditNothing | XIMStatusNothing)
#define NO_STYLES               (XIMPreeditNone | XIMStatusNone)

#define PreeditStartIndex       0
#define PreeditDoneIndex        1
#define PreeditDrawIndex        2
#define PreeditCaretIndex       3
#ifdef __linux__
#define StatusStartIndex        4
#define StatusDoneIndex         5
#define StatusDrawIndex         6
#define NCALLBACKS              7
#else
#define NCALLBACKS              4
#endif

/*
 * Callback function pointers: the order has to match the *Index
 * values above.
 */
static XIMProc callback_funcs[NCALLBACKS] = {
    (XIMProc)PreeditStartCallback,
    (XIMProc)PreeditDoneCallback,
    (XIMProc)PreeditDrawCallback,
    (XIMProc)PreeditCaretCallback,
#ifdef __linux__
    (XIMProc)StatusStartCallback,
    (XIMProc)StatusDoneCallback,
    (XIMProc)StatusDrawCallback,
#endif
};

#ifdef __linux__
#define MAX_STATUS_LEN  100
typedef struct {
    Window   w;                /*status window id        */
    Window   root;             /*the root window id      */
#ifdef XAWT
    Window   parent;           /*parent shell window     */
#else
    Widget   parent;           /*parent shell window     */
#endif
    int      x, y;             /*parent's upperleft position */
    int      width, height;    /*parent's width, height  */
    GC       lightGC;          /*gc for light border     */
    GC       dimGC;            /*gc for dim border       */
    GC       bgGC;             /*normal painting         */
    GC       fgGC;             /*normal painting         */
    int      statusW, statusH; /*status window's w, h    */
    int      rootW, rootH;     /*root window's w, h    */
    int      bWidth;           /*border width            */
    char     status[MAX_STATUS_LEN]; /*status text       */
    XFontSet fontset;           /*fontset for drawing    */
    int      off_x, off_y;
    Bool     on;                /*if the status window on*/
} StatusWindow;
#endif

/*
 * X11InputMethodData keeps per X11InputMethod instance information. A pointer
 * to this data structure is kept in an X11InputMethod object (pData).
 */
typedef struct _X11InputMethodData {
    XIC         current_ic;     /* current X Input Context */
    XIC         ic_active;      /* X Input Context for active clients */
    XIC         ic_passive;     /* X Input Context for passive clients */
    XIMCallback *callbacks;     /* callback parameters */
#ifndef XAWT
    jobject     peer;           /* MComponentPeer of client Window */
#endif /* XAWT */
    jobject     x11inputmethod; /* global ref to X11InputMethod instance */
                                /* associated with the XIC */
#ifdef __linux__
    StatusWindow *statusWindow; /* our own status window  */
#else
#ifndef XAWT
    Widget      statusWidget;   /* IM status window widget */
#endif /* XAWT */
#endif
    char        *lookup_buf;    /* buffer used for XmbLookupString */
    int         lookup_buf_len; /* lookup buffer size in bytes */
} X11InputMethodData;

/*
 * When XIC is created, a global reference is created for
 * sun.awt.X11InputMethod object so that it could be used by the XIM callback
 * functions. This could be a dangerous thing to do when the original
 * X11InputMethod object is garbage collected and as a result,
 * destroyX11InputMethodData is called to delete the global reference.
 * If any XIM callback function still holds and uses the "already deleted"
 * global reference, disaster is going to happen. So we have to maintain
 * a list for these global references which is consulted first when the
 * callback functions or any function tries to use "currentX11InputMethodObject"
 * which always refers to the global reference try to use it.
 *
 */
typedef struct _X11InputMethodGRefNode {
    jobject inputMethodGRef;
    struct _X11InputMethodGRefNode* next;
} X11InputMethodGRefNode;

X11InputMethodGRefNode *x11InputMethodGRefListHead = NULL;

/* reference to the current X11InputMethod instance, it is always
   point to the global reference to the X11InputMethodObject since
   it could be referenced by different threads. */
jobject currentX11InputMethodInstance = NULL;

Window  currentFocusWindow = 0;  /* current window that has focus for input
                                       method. (the best place to put this
                                       information should be
                                       currentX11InputMethodInstance's pData) */
static XIM X11im = NULL;
Display * dpy = NULL;

#define GetJNIEnv() (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)

#ifndef XAWT
static jobject  mcompClass = NULL;
static jobject  awteventClass = NULL;
static jfieldID mcompPDataID = NULL;
#endif /* XAWT */

static void DestroyXIMCallback(XIM, XPointer, XPointer);
static void OpenXIMCallback(Display *, XPointer, XPointer);
/* Solaris XIM Extention */
#define XNCommitStringCallback "commitStringCallback"
static void CommitStringCallback(XIC, XPointer, XPointer);

static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);

#ifdef __solaris__
/* Prototype for this function is missing in Solaris X11R6 Xlib.h */
extern char *XSetIMValues(
#if NeedVarargsPrototypes
    XIM /* im */, ...
#endif
);
#endif

#ifdef XAWT_HACK
/*
 * This function is stolen from /src/solaris/hpi/src/system_md.c
 * It is used in setting the time in Java-level InputEvents
 */
jlong
awt_util_nowMillisUTC()
{
    struct timeval t;
    gettimeofday(&t, NULL);
    return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
}
#endif /* XAWT_HACK */

/*
 * Converts the wchar_t string to a multi-byte string calling wcstombs(). A
 * buffer is allocated by malloc() to store the multi-byte string. NULL is
 * returned if the given wchar_t string pointer is NULL or buffer allocation is
 * failed.
 */
static char *
wcstombsdmp(wchar_t *wcs, int len)
{
    size_t n;
    char *mbs;

    if (wcs == NULL)
        return NULL;

    n = len*MB_CUR_MAX + 1;

    mbs = (char *) malloc(n * sizeof(char));
    if (mbs == NULL) {
        THROW_OUT_OF_MEMORY_ERROR();
        return NULL;
    }

    /* TODO: check return values... Handle invalid characters properly...  */
    if (wcstombs(mbs, wcs, n) == (size_t)-1)
        return NULL;

    return mbs;
}

#ifndef XAWT
/*
 * Find a class for the given class name and return a global reference to the
 * class.
 */
static jobject
findClass(const char *className)
{
    JNIEnv *env = GetJNIEnv();
    jclass classClass;
    jobject objectClass;

    classClass = (*env)->FindClass(env, className);
    objectClass = (*env)->NewGlobalRef(env,classClass);

    if (JNU_IsNull(env, objectClass)) {
        JNU_ThrowClassNotFoundException(env, className);
    }
    return objectClass;
}
#endif /* XAWT */

/*
 * Returns True if the global reference is still in the list,
 * otherwise False.
 */
static Bool isX11InputMethodGRefInList(jobject imGRef) {
    X11InputMethodGRefNode *pX11InputMethodGRef = x11InputMethodGRefListHead;

    if (imGRef == NULL) {
        return False;
    }

    while (pX11InputMethodGRef != NULL) {
        if (pX11InputMethodGRef->inputMethodGRef == imGRef) {
            return True;
        }
        pX11InputMethodGRef = pX11InputMethodGRef->next;
    }

    return False;
}

/*
 * Add the new created global reference to the list.
 */
static void addToX11InputMethodGRefList(jobject newX11InputMethodGRef) {
    X11InputMethodGRefNode *newNode = NULL;

    if (newX11InputMethodGRef == NULL ||
        isX11InputMethodGRefInList(newX11InputMethodGRef)) {
        return;
    }

    newNode = (X11InputMethodGRefNode *)malloc(sizeof(X11InputMethodGRefNode));

    if (newNode == NULL) {
        return;
    } else {
        newNode->inputMethodGRef = newX11InputMethodGRef;
        newNode->next = x11InputMethodGRefListHead;
        x11InputMethodGRefListHead = newNode;
    }
}

/*
 * Remove the global reference from the list.
 */
static void removeX11InputMethodGRefFromList(jobject x11InputMethodGRef) {
     X11InputMethodGRefNode *pX11InputMethodGRef = NULL;
     X11InputMethodGRefNode *cX11InputMethodGRef = x11InputMethodGRefListHead;

     if (x11InputMethodGRefListHead == NULL ||
         x11InputMethodGRef == NULL) {
         return;
     }

     /* cX11InputMethodGRef always refers to the current node while
        pX11InputMethodGRef refers to the previous node.
     */
     while (cX11InputMethodGRef != NULL) {
         if (cX11InputMethodGRef->inputMethodGRef == x11InputMethodGRef) {
             break;
         }
         pX11InputMethodGRef = cX11InputMethodGRef;
         cX11InputMethodGRef = cX11InputMethodGRef->next;
     }

     if (cX11InputMethodGRef == NULL) {
         return; /* Not found. */
     }

     if (cX11InputMethodGRef == x11InputMethodGRefListHead) {
         x11InputMethodGRefListHead = x11InputMethodGRefListHead->next;
     } else {
         pX11InputMethodGRef->next = cX11InputMethodGRef->next;
     }
     free(cX11InputMethodGRef);

     return;
}


static X11InputMethodData * getX11InputMethodData(JNIEnv * env, jobject imInstance) {
    X11InputMethodData *pX11IMData =
        (X11InputMethodData *)JNU_GetLongFieldAsPtr(env, imInstance, x11InputMethodIDs.pData);

    /*
     * In case the XIM server was killed somehow, reset X11InputMethodData.
     */
    if (X11im == NULL && pX11IMData != NULL) {
        JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
                             "flushText",
                             "()V");
        /* IMPORTANT:
           The order of the following calls is critical since "imInstance" may
           point to the global reference itself, if "freeX11InputMethodData" is called
           first, the global reference will be destroyed and "setX11InputMethodData"
           will in fact fail silently. So pX11IMData will not be set to NULL.
           This could make the original java object refers to a deleted pX11IMData
           object.
        */
        setX11InputMethodData(env, imInstance, NULL);
        freeX11InputMethodData(env, pX11IMData);
        pX11IMData = NULL;
    }

    return pX11IMData;
}

static void setX11InputMethodData(JNIEnv * env, jobject imInstance, X11InputMethodData *pX11IMData) {
    JNU_SetLongFieldFromPtr(env, imInstance, x11InputMethodIDs.pData, pX11IMData);
}

/* this function should be called within AWT_LOCK() */
static void
destroyX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
{
    /*
     * Destroy XICs
     */
    if (pX11IMData == NULL) {
        return;
    }

    if (pX11IMData->ic_active != (XIC)0) {
        XUnsetICFocus(pX11IMData->ic_active);
        XDestroyIC(pX11IMData->ic_active);
        if (pX11IMData->ic_active != pX11IMData->ic_passive) {
            if (pX11IMData->ic_passive != (XIC)0) {
                XUnsetICFocus(pX11IMData->ic_passive);
                XDestroyIC(pX11IMData->ic_passive);
            }
            pX11IMData->ic_passive = (XIC)0;
            pX11IMData->current_ic = (XIC)0;
        }
    }

    freeX11InputMethodData(env, pX11IMData);
}

static void
freeX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
{
#ifdef __linux__
    if (pX11IMData->statusWindow != NULL){
        StatusWindow *sw = pX11IMData->statusWindow;
        XFreeGC(awt_display, sw->lightGC);
        XFreeGC(awt_display, sw->dimGC);
        XFreeGC(awt_display, sw->bgGC);
        XFreeGC(awt_display, sw->fgGC);
        if (sw->fontset != NULL) {
            XFreeFontSet(awt_display, sw->fontset);
        }
        XDestroyWindow(awt_display, sw->w);
        free((void*)sw);
    }
#endif

    if (pX11IMData->callbacks)
        free((void *)pX11IMData->callbacks);

    if (env) {
#ifndef XAWT
        (*env)->DeleteGlobalRef(env, pX11IMData->peer);
#endif /* XAWT */
        /* Remove the global reference from the list, so that
           the callback function or whoever refers to it could know.
        */
        removeX11InputMethodGRefFromList(pX11IMData->x11inputmethod);
        (*env)->DeleteGlobalRef(env, pX11IMData->x11inputmethod);
    }

    if (pX11IMData->lookup_buf) {
        free((void *)pX11IMData->lookup_buf);
    }

    free((void *)pX11IMData);
}

/*
 * Sets or unsets the focus to the given XIC.
 */
static void
setXICFocus(XIC ic, unsigned short req)
{
    if (ic == NULL) {
        (void)fprintf(stderr, "Couldn't find X Input Context\n");
        return;
    }
    if (req == 1)
        XSetICFocus(ic);
    else
        XUnsetICFocus(ic);
}

/*
 * Sets the focus window to the given XIC.
 */
static void
setXICWindowFocus(XIC ic, Window w)
{
    if (ic == NULL) {
        (void)fprintf(stderr, "Couldn't find X Input Context\n");
        return;
    }
    (void) XSetICValues(ic, XNFocusWindow, w, NULL);
}

/*
 * Invokes XmbLookupString() to get something from the XIM. It invokes
 * X11InputMethod.dispatchCommittedText() if XmbLookupString() returns
 * committed text.  This function is called from handleKeyEvent in canvas.c and
 * it's under the Motif event loop thread context.
 *
 * Buffer usage: There is a bug in XFree86-4.3.0 XmbLookupString implementation,
 * where it never returns XBufferOverflow.  We need to allocate the initial lookup buffer
 * big enough, so that the possibility that user encounters this problem is relatively
 * small.  When this bug gets fixed, we can make the initial buffer size smaller.
 * Note that XmbLookupString() sometimes produces a non-null-terminated string.
 *
 * Returns True when there is a keysym value to be handled.
 */
#define INITIAL_LOOKUP_BUF_SIZE 512

Bool
awt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
{
    JNIEnv *env = GetJNIEnv();
    X11InputMethodData *pX11IMData = NULL;
    KeySym keysym = NoSymbol;
    Status status;
    int mblen;
    jstring javastr;
    XIC ic;
    Bool result = True;
    static Bool composing = False;

    /*
      printf("lookupString: entering...\n");
     */

    if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
        currentX11InputMethodInstance = NULL;
        return False;
    }

    pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);

    if (pX11IMData == NULL) {
#ifdef __linux__
        return False;
#else
        return result;
#endif
    }

    if ((ic = pX11IMData->current_ic) == (XIC)0){
#ifdef __linux__
        return False;
#else
        return result;
#endif
    }

    /* allocate the lookup buffer at the first invocation */
    if (pX11IMData->lookup_buf_len == 0) {
        pX11IMData->lookup_buf = (char *)malloc(INITIAL_LOOKUP_BUF_SIZE);
        if (pX11IMData->lookup_buf == NULL) {
            THROW_OUT_OF_MEMORY_ERROR();
            return result;
        }
        pX11IMData->lookup_buf_len = INITIAL_LOOKUP_BUF_SIZE;
    }

    mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
                            pX11IMData->lookup_buf_len - 1, &keysym, &status);

    /*
     * In case of overflow, a buffer is allocated and it retries
     * XmbLookupString().
     */
    if (status == XBufferOverflow) {
        free((void *)pX11IMData->lookup_buf);
        pX11IMData->lookup_buf_len = 0;
        pX11IMData->lookup_buf = (char *)malloc(mblen + 1);
        if (pX11IMData->lookup_buf == NULL) {
            THROW_OUT_OF_MEMORY_ERROR();
            return result;
        }
        pX11IMData->lookup_buf_len = mblen + 1;
        mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
                            pX11IMData->lookup_buf_len - 1, &keysym, &status);
    }
    pX11IMData->lookup_buf[mblen] = 0;

    /* Get keysym without taking modifiers into account first to map
     * to AWT keyCode table.
     */
#ifndef XAWT
    if (((event->state & ShiftMask) ||
        (event->state & LockMask)) &&
         keysym >= 'A' && keysym <= 'Z')
    {
        keysym = XLookupKeysym(event, 0);
    }
#endif

    switch (status) {
    case XLookupBoth:
        if (!composing) {
#ifdef XAWT
            if (event->keycode != 0) {
#else
            if (keysym < 128 || ((keysym & 0xff00) == 0xff00)) {
#endif
                *keysymp = keysym;
                result = False;
                break;
            }
        }
        composing = False;
        /*FALLTHRU*/
    case XLookupChars:
    /*
     printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
       event->type, event->state, event->keycode, keysym);
    */
        javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
        if (javastr != NULL) {
            JNU_CallMethodByName(env, NULL,
                                 currentX11InputMethodInstance,
                                 "dispatchCommittedText",
                                 "(Ljava/lang/String;J)V",
                                 javastr,
#ifndef XAWT_HACK
                                 awt_util_nowMillisUTC_offset(event->time));
#else
                                 event->time);
#endif
        }
        break;

    case XLookupKeySym:
    /*
     printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
       event->type, event->state, event->keycode, keysym);
    */
        if (keysym == XK_Multi_key)
            composing = True;
        if (! composing) {
            *keysymp = keysym;
            result = False;
        }
        break;

    case XLookupNone:
    /*
     printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
        event->type, event->state, event->keycode, keysym);
    */
        break;
    }

    return result;
}

#ifdef __linux__
static StatusWindow *createStatusWindow(
#ifdef XAWT
                                Window parent) {
#else
                                Widget parent) {
#endif
    StatusWindow *statusWindow;
    XSetWindowAttributes attrib;
    unsigned long attribmask;
    Window containerWindow;
    Window status;
    Window child;
    XWindowAttributes xwa;
    XWindowAttributes xxwa;
    /* Variable for XCreateFontSet()*/
    char **mclr;
    int  mccr = 0;
    char *dsr;
    Pixel bg, fg, light, dim;
    int x, y, w, h, bw, depth, off_x, off_y, xx, yy;
    XGCValues values;
    unsigned long valuemask = 0;  /*ignore XGCvalue and use defaults*/
    int screen = 0;
    int i;
    AwtGraphicsConfigDataPtr adata;
    extern int awt_numScreens;
    /*hardcode the size right now, should get the size base on font*/
    int   width=80, height=22;
    Window rootWindow;
    Window *ignoreWindowPtr;
    unsigned int ignoreUnit;

#ifdef XAWT
    XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
#else
    while (!XtIsShell(parent)){
        parent = XtParent(parent);
    }
#endif

    attrib.override_redirect = True;
    attribmask = CWOverrideRedirect;
    for (i = 0; i < awt_numScreens; i++) {
#ifdef XAWT
        if (RootWindow(dpy, i) == rootWindow) {
#else
        if (ScreenOfDisplay(dpy, i) == XtScreen(parent)) {
#endif
            screen = i;
            break;
        }
    }
    adata = getDefaultConfig(screen);
    bg    = adata->AwtColorMatch(255, 255, 255, adata);
    fg    = adata->AwtColorMatch(0, 0, 0, adata);
    light = adata->AwtColorMatch(195, 195, 195, adata);
    dim   = adata->AwtColorMatch(128, 128, 128, adata);

    XGetWindowAttributes(dpy, XtWindow(parent), &xwa);
    bw = 2; /*xwa.border_width does not have the correct value*/

    /*compare the size difference between parent container
      and shell widget, the diff should be the border frame
      and title bar height (?)*/

    XQueryTree( dpy,
                XtWindow(parent),
                &rootWindow,
                &containerWindow,
                &ignoreWindowPtr,
                &ignoreUnit);
    XGetWindowAttributes(dpy, containerWindow, &xxwa);

    off_x = (xxwa.width - xwa.width) / 2;
    off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */

    /*get the size of root window*/
    XGetWindowAttributes(dpy, rootWindow, &xxwa);

    XTranslateCoordinates(dpy,
                          XtWindow(parent), xwa.root,
                          xwa.x, xwa.y,
                          &x, &y,
                          &child);
    xx = x - off_x;
    yy = y + xwa.height - off_y;
    if (xx < 0 ){
        xx = 0;
    }
    if (xx + width > xxwa.width){
        xx = xxwa.width - width;
    }
    if (yy + height > xxwa.height){
        yy = xxwa.height - height;
    }

    status =  XCreateWindow(dpy,
                            xwa.root,
                            xx, yy,
                            width, height,
                            0,
                            xwa.depth,
                            InputOutput,
                            adata->awt_visInfo.visual,
                            attribmask, &attrib);
    XSelectInput(dpy, status,
                 ExposureMask | StructureNotifyMask | EnterWindowMask |
                 LeaveWindowMask | VisibilityChangeMask);
    statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
    if (statusWindow == NULL){
        THROW_OUT_OF_MEMORY_ERROR();
        return NULL;
    }
    statusWindow->w = status;
    //12-point font
    statusWindow->fontset = XCreateFontSet(dpy,
                                           "-*-*-medium-r-normal-*-*-120-*-*-*-*",
                                           &mclr, &mccr, &dsr);
    /* In case we didn't find the font set, release the list of missing characters */
    if (mccr > 0) {
        XFreeStringList(mclr);
    }
    statusWindow->parent = parent;
    statusWindow->on  = False;
    statusWindow->x = x;
    statusWindow->y = y;
    statusWindow->width = xwa.width;
    statusWindow->height = xwa.height;
    statusWindow->off_x = off_x;
    statusWindow->off_y = off_y;
    statusWindow->bWidth  = bw;
    statusWindow->statusH = height;
    statusWindow->statusW = width;
    statusWindow->rootH = xxwa.height;
    statusWindow->rootW = xxwa.width;
    statusWindow->lightGC = XCreateGC(dpy, status, valuemask, &values);
    XSetForeground(dpy, statusWindow->lightGC, light);
    statusWindow->dimGC = XCreateGC(dpy, status, valuemask, &values);
    XSetForeground(dpy, statusWindow->dimGC, dim);
    statusWindow->fgGC = XCreateGC(dpy, status, valuemask, &values);
    XSetForeground(dpy, statusWindow->fgGC, fg);
    statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
    XSetForeground(dpy, statusWindow->bgGC, bg);
    return statusWindow;
}

/* This method is to turn off or turn on the status window. */
static void onoffStatusWindow(X11InputMethodData* pX11IMData,
#ifdef XAWT
                                Window parent,
#else
                                Widget parent,
#endif
                                Bool ON){
    XWindowAttributes xwa;
    Window child;
    int x, y;
    StatusWindow *statusWindow = NULL;

    if (NULL == currentX11InputMethodInstance ||
        NULL == pX11IMData ||
        NULL == (statusWindow =  pX11IMData->statusWindow)){
        return;
    }

    if (ON == False){
        XUnmapWindow(dpy, statusWindow->w);
        statusWindow->on = False;
        return;
    }
#ifdef XAWT
    parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
                                  "getCurrentParentWindow",
                                  "()J").j;
#else
    while (!XtIsShell(parent)){
        parent = XtParent(parent);
    }
#endif
    if (statusWindow->parent != parent){
        statusWindow->parent = parent;
    }
    XGetWindowAttributes(dpy, XtWindow(parent), &xwa);
    XTranslateCoordinates(dpy,
                          XtWindow(parent), xwa.root,
                          xwa.x, xwa.y,
                          &x, &y,
                          &child);
    if (statusWindow->x != x
        || statusWindow->y != y
        || statusWindow->height != xwa.height){
        statusWindow->x = x;
        statusWindow->y = y;
        statusWindow->height = xwa.height;
        x = statusWindow->x - statusWindow->off_x;
        y = statusWindow->y + statusWindow->height - statusWindow->off_y;
        if (x < 0 ){
            x = 0;
        }
        if (x + statusWindow->statusW > statusWindow->rootW){
            x = statusWindow->rootW - statusWindow->statusW;
        }
        if (y + statusWindow->statusH > statusWindow->rootH){
            y = statusWindow->rootH - statusWindow->statusH;
        }
        XMoveWindow(dpy, statusWindow->w, x, y);
    }
    statusWindow->on = True;
    XMapWindow(dpy, statusWindow->w);
}

void paintStatusWindow(StatusWindow *statusWindow){
    Window  win  = statusWindow->w;
    GC  lightgc = statusWindow->lightGC;
    GC  dimgc = statusWindow->dimGC;
    GC  bggc = statusWindow->bgGC;
    GC  fggc = statusWindow->fgGC;

    int width = statusWindow->statusW;
    int height = statusWindow->statusH;
    int bwidth = statusWindow->bWidth;
    XFillRectangle(dpy, win, bggc, 0, 0, width, height);
    /* draw border */
    XDrawLine(dpy, win, fggc, 0, 0, width, 0);
    XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
    XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
    XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);

    XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
    XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
    XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
    XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);

    XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
    XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
    XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
    XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
    if (statusWindow->fontset){
        XmbDrawString(dpy, win, statusWindow->fontset, fggc,
                      bwidth + 2, height - bwidth - 4,
                      statusWindow->status,
                      strlen(statusWindow->status));
    }
    else{
        /*too bad we failed to create a fontset for this locale*/
        XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
                    "[InputMethod ON]", strlen("[InputMethod ON]"));
    }
}

void statusWindowEventHandler(XEvent event){
    JNIEnv *env = GetJNIEnv();
    X11InputMethodData *pX11IMData = NULL;
    StatusWindow *statusWindow;

    if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
        currentX11InputMethodInstance = NULL;
        return;
    }

    if (NULL == currentX11InputMethodInstance
        || NULL == (pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance))
        || NULL == (statusWindow = pX11IMData->statusWindow)
        || statusWindow->w != event.xany.window){
        return;
    }

    switch (event.type){
    case Expose:
        paintStatusWindow(statusWindow);
        break;
    case MapNotify:
    case ConfigureNotify:
        {
          /*need to reset the stackMode...*/
            XWindowChanges xwc;
            int value_make = CWStackMode;
            xwc.stack_mode = TopIf;
            XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
        }
        break;
        /*
    case UnmapNotify:
    case VisibilityNotify:
        break;
        */
    default:
        break;
  }
}

#ifdef XAWT
static void adjustStatusWindow(Window shell){
#else
void adjustStatusWindow(Widget shell){
#endif
    JNIEnv *env = GetJNIEnv();
    X11InputMethodData *pX11IMData = NULL;
    StatusWindow *statusWindow;

    if (NULL == currentX11InputMethodInstance
        || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
        || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
        || NULL == (statusWindow = pX11IMData->statusWindow)
        || !statusWindow->on) {
        return;
    }
#ifdef XAWT
    {
#else
    if (statusWindow->parent == shell) {
#endif
        XWindowAttributes xwa;
        int x, y;
        Window child;
        XGetWindowAttributes(dpy, XtWindow(shell), &xwa);
        XTranslateCoordinates(dpy,
                              XtWindow(shell), xwa.root,
                              xwa.x, xwa.y,
                              &x, &y,
                              &child);
        if (statusWindow->x != x
            || statusWindow->y != y
            || statusWindow->height != xwa.height){
          statusWindow->x = x;
          statusWindow->y = y;
          statusWindow->height = xwa.height;

          x = statusWindow->x - statusWindow->off_x;
          y = statusWindow->y + statusWindow->height - statusWindow->off_y;
          if (x < 0 ){
              x = 0;
          }
          if (x + statusWindow->statusW > statusWindow->rootW){
              x = statusWindow->rootW - statusWindow->statusW;
          }
          if (y + statusWindow->statusH > statusWindow->rootH){
              y = statusWindow->rootH - statusWindow->statusH;
          }
          XMoveWindow(dpy, statusWindow->w, x, y);
        }
    }
}
#endif  /*__linux__*/
/*
 * Creates two XICs, one for active clients and the other for passive
 * clients. All information on those XICs are stored in the
 * X11InputMethodData given by the pX11IMData parameter.
 *
 * For active clients: Try to use preedit callback to support
 * on-the-spot. If tc is not null, the XIC to be created will
 * share the Status Area with Motif widgets (TextComponents). If the
 * preferable styles can't be used, fallback to root-window styles. If
 * root-window styles failed, fallback to None styles.
 *
 * For passive clients: Try to use root-window styles. If failed,
 * fallback to None styles.
 */
static Bool
#ifdef XAWT
createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
#else /* !XAWT */
createXIC(Widget w, X11InputMethodData *pX11IMData,
          jobject tc, jobject peer)
#endif /* XAWT */
{
    XIC active_ic, passive_ic;
    XVaNestedList preedit = NULL;
    XVaNestedList status = NULL;
    XIMStyle on_the_spot_styles = XIMPreeditCallbacks,
             active_styles = 0,
             passive_styles = 0,
             no_styles = 0;
    XIMCallback *callbacks;
    unsigned short i;
    XIMStyles *im_styles;
    char *ret = NULL;

    if (X11im == NULL) {
        return False;
    }
#ifdef XAWT
    if (w == NULL) {
        return False;
    }
#else /* !XAWT */
    /*
     * If the parent window has one or more TextComponents, the status
     * area of Motif will be shared with the created XIC. Otherwise,
     * root-window style status is used.
     */
#endif /* XAWT */

    ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);

    if (ret != NULL) {
        jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
        return FALSE ;
    }

#ifdef __linux__
    on_the_spot_styles |= XIMStatusNothing;

    /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
      at the same time, so use StatusCallback to draw the status
      ourself
    */
    for (i = 0; i < im_styles->count_styles; i++) {
        if (im_styles->supported_styles[i] == (XIMPreeditCallbacks | XIMStatusCallbacks)) {
            on_the_spot_styles = (XIMPreeditCallbacks | XIMStatusCallbacks);
            break;
        }
    }
#else /*! __linux__ */
#ifdef XAWT
    on_the_spot_styles |= XIMStatusNothing;
#else /* !XAWT */
    /*
     * If the parent window has one or more TextComponents, the status
     * area of Motif will be shared with the created XIC. Otherwise,
     * root-window style status is used.
     */
    if (tc != NULL){
        XVaNestedList status = NULL;
        status = awt_motif_getXICStatusAreaList(w, tc);
        if (status != NULL){
            on_the_spot_styles |=  XIMStatusArea;
            XFree(status);
        }
        else
            on_the_spot_styles |= XIMStatusNothing;
    }
    else
        on_the_spot_styles |= XIMStatusNothing;

#endif /* XAWT */
#endif /* __linux__ */

    for (i = 0; i < im_styles->count_styles; i++) {
        active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
        passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES;
        no_styles |= im_styles->supported_styles[i] & NO_STYLES;
    }

    XFree(im_styles);

    if (active_styles != on_the_spot_styles) {
        if (passive_styles == ROOT_WINDOW_STYLES)
            active_styles = passive_styles;
        else {
            if (no_styles == NO_STYLES)
                active_styles = passive_styles = NO_STYLES;
            else
                active_styles = passive_styles = 0;
        }
    } else {
        if (passive_styles != ROOT_WINDOW_STYLES) {
            if (no_styles == NO_STYLES)
                active_styles = passive_styles = NO_STYLES;
            else
                active_styles = passive_styles = 0;
        }
    }

    if (active_styles == on_the_spot_styles) {
        callbacks = (XIMCallback *)malloc(sizeof(XIMCallback) * NCALLBACKS);
        if (callbacks == (XIMCallback *)NULL)
            return False;
        pX11IMData->callbacks = callbacks;

        for (i = 0; i < NCALLBACKS; i++, callbacks++) {
            callbacks->client_data = (XPointer) pX11IMData->x11inputmethod;
            callbacks->callback = callback_funcs[i];
        }

        callbacks = pX11IMData->callbacks;
        preedit = (XVaNestedList)XVaCreateNestedList(0,
                        XNPreeditStartCallback, &callbacks[PreeditStartIndex],
                        XNPreeditDoneCallback,  &callbacks[PreeditDoneIndex],
                        XNPreeditDrawCallback,  &callbacks[PreeditDrawIndex],
                        XNPreeditCaretCallback, &callbacks[PreeditCaretIndex],
                        NULL);
        if (preedit == (XVaNestedList)NULL)
            goto err;
#ifdef __linux__
        /*always try XIMStatusCallbacks for active client...*/
        {
            status = (XVaNestedList)XVaCreateNestedList(0,
                        XNStatusStartCallback, &callbacks[StatusStartIndex],
                        XNStatusDoneCallback,  &callbacks[StatusDoneIndex],
                        XNStatusDrawCallback, &callbacks[StatusDrawIndex],
                        NULL);

            if (status == NULL)
                goto err;
            pX11IMData->statusWindow = createStatusWindow(w);
            pX11IMData->ic_active = XCreateIC(X11im,
                                              XNClientWindow, XtWindow(w),
                                              XNFocusWindow, XtWindow(w),
                                              XNInputStyle, active_styles,
                                              XNPreeditAttributes, preedit,
                                              XNStatusAttributes, status,
                                              NULL);
            XFree((void *)status);
            XFree((void *)preedit);
        }
#else /* !__linux__ */
#ifndef XAWT
        if (on_the_spot_styles & XIMStatusArea) {
            Widget parent;
            status = awt_motif_getXICStatusAreaList(w, tc);
            if (status == NULL)
                goto err;
            pX11IMData->statusWidget = awt_util_getXICStatusAreaWindow(w);
            pX11IMData->ic_active = XCreateIC(X11im,
                                              XNClientWindow, XtWindow(pX11IMData->statusWidget),
                                              XNFocusWindow, XtWindow(w),
                                              XNInputStyle, active_styles,
                                              XNPreeditAttributes, preedit,
                                              XNStatusAttributes, status,
                                              NULL);
            XFree((void *)status);
        } else {
#endif /* XAWT */
            pX11IMData->ic_active = XCreateIC(X11im,
                                              XNClientWindow, XtWindow(w),
                                              XNFocusWindow, XtWindow(w),
                                              XNInputStyle, active_styles,
                                              XNPreeditAttributes, preedit,
                                              NULL);
#ifndef XAWT
        }
#endif /* XAWT */
        XFree((void *)preedit);
#endif /* __linux__ */
        pX11IMData->ic_passive = XCreateIC(X11im,
                                           XNClientWindow, XtWindow(w),
                                           XNFocusWindow, XtWindow(w),
                                           XNInputStyle, passive_styles,
                                           NULL);

    } else {
        pX11IMData->ic_active = XCreateIC(X11im,
                                          XNClientWindow, XtWindow(w),
                                          XNFocusWindow, XtWindow(w),
                                          XNInputStyle, active_styles,
                                          NULL);
        pX11IMData->ic_passive = pX11IMData->ic_active;
    }

    if (pX11IMData->ic_active == (XIC)0
        || pX11IMData->ic_passive == (XIC)0) {
        return False;
    }

    /*
     * Use commit string call back if possible.
     * This will ensure the correct order of preedit text and commit text
     */
    {
        XIMCallback cb;
        cb.client_data = (XPointer) pX11IMData->x11inputmethod;
        cb.callback = CommitStringCallback;
        XSetICValues (pX11IMData->ic_active, XNCommitStringCallback, &cb, NULL);
        if (pX11IMData->ic_active != pX11IMData->ic_passive) {
            XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
        }
    }

    /* Add the global reference object to X11InputMethod to the list. */
    addToX11InputMethodGRefList(pX11IMData->x11inputmethod);

    return True;

 err:
    if (preedit)
        XFree((void *)preedit);
    THROW_OUT_OF_MEMORY_ERROR();
    return False;
}

static void
PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{
    /*ARGSUSED*/
    /* printf("Native: PreeditCaretCallback\n"); */
}

static void
PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
{
    /*ARGSUSED*/
    /* printf("Native: StatusStartCallback\n"); */
}

/*
 * Translate the preedit draw callback items to Java values and invoke
 * X11InputMethod.dispatchComposedText().
 *
 * client_data: X11InputMethod object
 */
static void
PreeditDrawCallback(XIC ic, XPointer client_data,
                    XIMPreeditDrawCallbackStruct *pre_draw)
{
    JNIEnv *env = GetJNIEnv();
    X11InputMethodData *pX11IMData = NULL;
    jmethodID x11imMethodID;

    XIMText *text;
    jstring javastr = NULL;
    jintArray style = NULL;

    /* printf("Native: PreeditDrawCallback() \n"); */
    if (pre_draw == NULL) {
        return;
    }
    AWT_LOCK();
    if (!isX11InputMethodGRefInList((jobject)client_data)) {
        if ((jobject)client_data == currentX11InputMethodInstance) {
            currentX11InputMethodInstance = NULL;
        }
        goto finally;
    }
    if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
        goto finally;
    }

    if ((text = pre_draw->text) != NULL) {
        if (text->string.multi_byte != NULL) {
            if (pre_draw->text->encoding_is_wchar == False) {
                javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
            } else {
                char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
                if (mbstr == NULL) {
                    goto finally;
                }
                javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
                free(mbstr);
            }
        }
        if (text->feedback != NULL) {
            int cnt;
            jint *tmpstyle;

            style = (*env)->NewIntArray(env, text->length);
            if (JNU_IsNull(env, style)) {
                THROW_OUT_OF_MEMORY_ERROR();
                goto finally;
            }

            if (sizeof(XIMFeedback) == sizeof(jint)) {
                /*
                 * Optimization to avoid copying the array
                 */
                (*env)->SetIntArrayRegion(env, style, 0,
                                          text->length, (jint *)text->feedback);
            } else {
                tmpstyle  = (jint *)malloc(sizeof(jint)*(text->length));
                if (tmpstyle == (jint *) NULL) {
                    THROW_OUT_OF_MEMORY_ERROR();
                    goto finally;
                }
                for (cnt = 0; cnt < (int)text->length; cnt++)
                        tmpstyle[cnt] = text->feedback[cnt];
                (*env)->SetIntArrayRegion(env, style, 0,
                                          text->length, (jint *)tmpstyle);
            }
        }
    }
    JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
                         "dispatchComposedText",
                         "(Ljava/lang/String;[IIIIJ)V",
                         javastr,
                         style,
                         (jint)pre_draw->chg_first,
                         (jint)pre_draw->chg_length,
                         (jint)pre_draw->caret,
                         awt_util_nowMillisUTC());
finally:
    AWT_UNLOCK();
    return;
}

static void
PreeditCaretCallback(XIC ic, XPointer client_data,
                     XIMPreeditCaretCallbackStruct *pre_caret)
{
    /*ARGSUSED*/
    /* printf("Native: PreeditCaretCallback\n"); */

}

#ifdef __linux__
static void
StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{
    /*ARGSUSED*/
    /*printf("StatusStartCallback:\n");  */

}

static void
StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
{
    /*ARGSUSED*/
    /*printf("StatusDoneCallback:\n"); */

}

static void
StatusDrawCallback(XIC ic, XPointer client_data,
                     XIMStatusDrawCallbackStruct *status_draw)
{
    /*ARGSUSED*/
    /*printf("StatusDrawCallback:\n"); */
    JNIEnv *env = GetJNIEnv();
    X11InputMethodData *pX11IMData = NULL;
    StatusWindow *statusWindow;

    AWT_LOCK();

    if (!isX11InputMethodGRefInList((jobject)client_data)) {
        if ((jobject)client_data == currentX11InputMethodInstance) {
            currentX11InputMethodInstance = NULL;
        }
        goto finally;
    }

    if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
        || NULL == (statusWindow = pX11IMData->statusWindow)){
        goto finally;
    }
   currentX11InputMethodInstance = (jobject)client_data;

    if (status_draw->type == XIMTextType){
        XIMText *text = (status_draw->data).text;
        if (text != NULL){
          if (text->string.multi_byte != NULL){
              strcpy(statusWindow->status, text->string.multi_byte);
          }
          else{
              char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
              strcpy(statusWindow->status, mbstr);
          }
          statusWindow->on = True;
          onoffStatusWindow(pX11IMData, statusWindow->parent, True);
          paintStatusWindow(statusWindow);
        }
        else {
            statusWindow->on = False;
            /*just turnoff the status window
            paintStatusWindow(statusWindow);
            */
            onoffStatusWindow(pX11IMData, 0, False);
        }
    }

 finally:
    AWT_UNLOCK();
}
#endif /*__linux__*/

static void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
    JNIEnv *env = GetJNIEnv();
    XIMText * text = (XIMText *)call_data;
    X11InputMethodData *pX11IMData = NULL;
    jstring javastr;

    AWT_LOCK();

    if (!isX11InputMethodGRefInList((jobject)client_data)) {
        if ((jobject)client_data == currentX11InputMethodInstance) {
            currentX11InputMethodInstance = NULL;
        }
        goto finally;
    }

    if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
        goto finally;
    }
    currentX11InputMethodInstance = (jobject)client_data;

    if (text->encoding_is_wchar == False) {
        javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
    } else {
        char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
        if (mbstr == NULL) {
            goto finally;
        }
        javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
        free(mbstr);
    }

    if (javastr != NULL) {
        JNU_CallMethodByName(env, NULL,
                                 pX11IMData->x11inputmethod,
                                 "dispatchCommittedText",
                                 "(Ljava/lang/String;J)V",
                                 javastr,
                                 awt_util_nowMillisUTC());
    }
 finally:
    AWT_UNLOCK();
}

static void OpenXIMCallback(Display *display, XPointer client_data, XPointer call_data) {
    XIMCallback ximCallback;

    X11im = XOpenIM(display, NULL, NULL, NULL);
    if (X11im == NULL) {
        return;
    }

    ximCallback.callback = (XIMProc)DestroyXIMCallback;
    ximCallback.client_data = NULL;
    XSetIMValues(X11im, XNDestroyCallback, &ximCallback, NULL);
}

static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
    /* mark that XIM server was destroyed */
    X11im = NULL;
}

/*
 * Class:     java_sun_awt_motif_X11InputMethod
 * Method:    initIDs
 * Signature: ()V
 */

/* This function gets called from the static initializer for
   X11InputMethod.java
   to initialize the fieldIDs for fields that may be accessed from C */
JNIEXPORT void JNICALL
Java_sun_awt_X11InputMethod_initIDs(JNIEnv *env, jclass cls)
{
    x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
}


JNIEXPORT jboolean JNICALL
#ifdef XAWT
Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
                                          jobject this,
                                          jlong display)
#else
Java_sun_awt_motif_MInputMethod_openXIMNative(JNIEnv *env,
                                          jobject this)
#endif
{
    Bool registered;

    AWT_LOCK();

#ifdef XAWT
    dpy = (Display *)display;
#else
    dpy = awt_display;
#endif

/* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
   (4768335)
*/
#ifdef __linux__
    registered = XRegisterIMInstantiateCallback(dpy, NULL, NULL,
                     NULL, (XIMProc)OpenXIMCallback, NULL);
    if (!registered) {
        /* directly call openXIM callback */
#endif
        OpenXIMCallback(dpy, NULL, NULL);
#ifdef __linux__
    }
#endif

    AWT_UNLOCK();

    return JNI_TRUE;
}

JNIEXPORT jboolean JNICALL
#ifdef XAWT
Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
                                                  jobject this,
                                                  jlong window)
{
#else /* !XAWT */
Java_sun_awt_motif_MInputMethod_createXICNative(JNIEnv *env,
                                                  jobject this,
                                                  jobject comp,
                                                  jobject tc)
{
    struct ComponentData *cdata;
#endif /* XAWT */
    X11InputMethodData *pX11IMData;
    jobject globalRef;
    XIC ic;

    AWT_LOCK();

#ifdef XAWT
    if (window == NULL) {
#else /* !XAWT */
    if (JNU_IsNull(env, comp)) {
#endif /* XAWT */
        JNU_ThrowNullPointerException(env, "NullPointerException");
        AWT_UNLOCK();
        return JNI_FALSE;
    }

    pX11IMData = (X11InputMethodData *) calloc(1, sizeof(X11InputMethodData));
    if (pX11IMData == NULL) {
        THROW_OUT_OF_MEMORY_ERROR();
        AWT_UNLOCK();
        return JNI_FALSE;
    }

#ifndef XAWT
    if (mcompClass == NULL) {
        mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
        mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
    }
    cdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,comp,mcompPDataID);

    if (cdata == 0) {
        free((void *)pX11IMData);
        JNU_ThrowNullPointerException(env, "createXIC");
        AWT_UNLOCK();
        return JNI_FALSE;
    }

    pX11IMData->peer = (*env)->NewGlobalRef(env, comp);
#endif /* XAWT */
    globalRef = (*env)->NewGlobalRef(env, this);
    pX11IMData->x11inputmethod = globalRef;
#ifdef __linux__
    pX11IMData->statusWindow = NULL;
#else /* __linux__ */
#ifndef XAWT
    pX11IMData->statusWidget = (Widget) NULL;
#endif /* XAWT */
#endif /* __linux__ */

    pX11IMData->lookup_buf = 0;
    pX11IMData->lookup_buf_len = 0;

#ifdef XAWT
    if (createXIC(env, pX11IMData, (Window)window)
#else /* !XAWT */
    if (createXIC(cdata->widget, pX11IMData, tc, comp)
#endif /* XAWT */
        == False) {
        destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
        pX11IMData = (X11InputMethodData *) NULL;
    }

    setX11InputMethodData(env, this, pX11IMData);

    AWT_UNLOCK();
    return (pX11IMData != NULL);
}

#ifndef XAWT
JNIEXPORT void JNICALL
Java_sun_awt_motif_MInputMethod_reconfigureXICNative(JNIEnv *env,
                                                       jobject this,
                                                       jobject comp,
                                                       jobject tc)
{
    X11InputMethodData *pX11IMData;

    AWT_LOCK();

    pX11IMData = getX11InputMethodData(env, this);
    if (pX11IMData == NULL) {
        AWT_UNLOCK();
        return;
    }

    if (pX11IMData->current_ic == (XIC)0) {
        destroyX11InputMethodData(env, pX11IMData);
        pX11IMData = (X11InputMethodData *)NULL;
    } else {
        Bool active;
        struct ComponentData *cdata;

        active = pX11IMData->current_ic == pX11IMData->ic_active;
        if (mcompClass == NULL) {
            mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
            mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
        }
        cdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,comp,mcompPDataID);
        if (cdata == 0) {
            JNU_ThrowNullPointerException(env, "reconfigureXICNative");
            destroyX11InputMethodData(env, pX11IMData);
            pX11IMData = (X11InputMethodData *)NULL;
        }
        XDestroyIC(pX11IMData->ic_active);
        if (pX11IMData->ic_active != pX11IMData->ic_passive)
            XDestroyIC(pX11IMData->ic_passive);
        pX11IMData->current_ic = (XIC)0;
        pX11IMData->ic_active = (XIC)0;
        pX11IMData->ic_passive = (XIC)0;
        if (createXIC(cdata->widget, pX11IMData, tc, comp)) {
            pX11IMData->current_ic = active ?
                        pX11IMData->ic_active : pX11IMData->ic_passive;
            /*
             * On Solaris2.6, setXICWindowFocus() has to be invoked
             * before setting focus.
             */
            setXICWindowFocus(pX11IMData->current_ic, XtWindow(cdata->widget));
            setXICFocus(pX11IMData->current_ic, True);
        } else {
            destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
            pX11IMData = (X11InputMethodData *)NULL;
        }
    }

    setX11InputMethodData(env, this, pX11IMData);

    AWT_UNLOCK();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MInputMethod_setXICFocusNative(JNIEnv *env,
                                              jobject this,
                                              jobject comp,
                                              jboolean req,
                                              jboolean active)
{
    struct ComponentData *cdata;
    Widget w;
#else /* !XAWT */
JNIEXPORT void JNICALL
Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
                                              jobject this,
                                              jlong w,
                                              jboolean req,
                                              jboolean active)
{
#endif /* XAWT */
    X11InputMethodData *pX11IMData;
    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);
    if (pX11IMData == NULL) {
        AWT_UNLOCK();
        return;
    }

    if (req) {
#ifdef XAWT
        if (w == NULL) {
            AWT_UNLOCK();
            return;
        }
#else /* !XAWT */
        struct ComponentData *cdata;

        if (JNU_IsNull(env, comp)) {
            AWT_UNLOCK();
            return;
        }
        if (mcompClass == NULL) {
            mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
            mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
        }
        cdata = (struct ComponentData *)JNU_GetLongFieldAsPtr(env, comp,
                                                              mcompPDataID);
        if (cdata == 0) {
            JNU_ThrowNullPointerException(env, "setXICFocus pData");
            AWT_UNLOCK();
            return;
        }
#endif /* XAWT */

        pX11IMData->current_ic = active ?
                        pX11IMData->ic_active : pX11IMData->ic_passive;
        /*
         * On Solaris2.6, setXICWindowFocus() has to be invoked
         * before setting focus.
         */
#ifndef XAWT
        w = cdata->widget;
#endif /* XAWT */
        setXICWindowFocus(pX11IMData->current_ic, XtWindow(w));
        setXICFocus(pX11IMData->current_ic, req);
        currentX11InputMethodInstance = pX11IMData->x11inputmethod;
        currentFocusWindow =  XtWindow(w);
#ifdef __linux__
        if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
            onoffStatusWindow(pX11IMData, w, True);
#endif
    } else {
        currentX11InputMethodInstance = NULL;
        currentFocusWindow = 0;
#ifdef __linux__
        onoffStatusWindow(pX11IMData, 0, False);
        if (pX11IMData->current_ic != NULL)
#endif
        setXICFocus(pX11IMData->current_ic, req);

        pX11IMData->current_ic = (XIC)0;
    }

    XFlush(dpy);
    AWT_UNLOCK();
}

JNIEXPORT void JNICALL
Java_sun_awt_X11InputMethod_turnoffStatusWindow(JNIEnv *env,
                                                jobject this)
{
#ifdef __linux__
    X11InputMethodData *pX11IMData;
    StatusWindow *statusWindow;

    AWT_LOCK();

    if (NULL == currentX11InputMethodInstance
        || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
        || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
        || NULL == (statusWindow = pX11IMData->statusWindow)
        || !statusWindow->on ){
        AWT_UNLOCK();
        return;
    }
    onoffStatusWindow(pX11IMData, 0, False);

    AWT_UNLOCK();
#endif
}

JNIEXPORT void JNICALL
Java_sun_awt_X11InputMethod_disposeXIC(JNIEnv *env,
                                             jobject this)
{
    X11InputMethodData *pX11IMData = NULL;

    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);
    if (pX11IMData == NULL) {
        AWT_UNLOCK();
        return;
    }

    setX11InputMethodData(env, this, NULL);

    if (pX11IMData->x11inputmethod == currentX11InputMethodInstance) {
        currentX11InputMethodInstance = NULL;
        currentFocusWindow = 0;
    }
    destroyX11InputMethodData(env, pX11IMData);
    AWT_UNLOCK();
}

JNIEXPORT jstring JNICALL
Java_sun_awt_X11InputMethod_resetXIC(JNIEnv *env,
                                           jobject this)
{
    X11InputMethodData *pX11IMData;
    char *xText = NULL;
    jstring jText = (jstring)0;

    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);
    if (pX11IMData == NULL) {
        AWT_UNLOCK();
        return jText;
    }

    if (pX11IMData->current_ic)
        xText = XmbResetIC(pX11IMData->current_ic);
    else {
        /*
         * If there is no reference to the current XIC, try to reset both XICs.
         */
        xText = XmbResetIC(pX11IMData->ic_active);
        /*it may also means that the real client component does
          not have focus -- has been deactivated... its xic should
          not have the focus, bug#4284651 showes reset XIC for htt
          may bring the focus back, so de-focus it again.
        */
        setXICFocus(pX11IMData->ic_active, FALSE);
        if (pX11IMData->ic_active != pX11IMData->ic_passive) {
            char *tmpText = XmbResetIC(pX11IMData->ic_passive);
            setXICFocus(pX11IMData->ic_passive, FALSE);
            if (xText == (char *)NULL && tmpText)
                xText = tmpText;
        }

    }
    if (xText != NULL) {
        jText = JNU_NewStringPlatform(env, (const char *)xText);
        XFree((void *)xText);
    }

    AWT_UNLOCK();
    return jText;
}

#ifndef XAWT
JNIEXPORT void JNICALL
Java_sun_awt_motif_MInputMethod_configureStatusAreaNative(JNIEnv *env,
                                                            jobject this,
                                                            jobject tc)
{
    X11InputMethodData *pX11IMData;
    XVaNestedList status;

#ifdef __linux__
      /*do nothing for linux? */
#else
    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);

    if ((pX11IMData == NULL) || (pX11IMData->ic_active == (XIC)0)) {
        AWT_UNLOCK();
        return;
    }

    if (pX11IMData->statusWidget) {
        status = awt_motif_getXICStatusAreaList(pX11IMData->statusWidget, tc);
        if (status != (XVaNestedList)NULL) {
            XSetICValues(pX11IMData->ic_active,
                         XNStatusAttributes, status,
                         NULL);
            XFree((void *)status);
        }
    }
    AWT_UNLOCK();
#endif
}
#endif /* XAWT */

/*
 * Class:     sun_awt_X11InputMethod
 * Method:    setCompositionEnabledNative
 * Signature: (ZJ)V
 *
 * This method tries to set the XNPreeditState attribute associated with the current
 * XIC to the passed in 'enable' state.
 *
 * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
 * 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
 * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
 * method fails due to other reasons.
 *
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_setCompositionEnabledNative
  (JNIEnv *env, jobject this, jboolean enable)
{
    X11InputMethodData *pX11IMData;
    char * ret = NULL;

    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);

    if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
        AWT_UNLOCK();
        return JNI_FALSE;
    }

    ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
                       (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
    AWT_UNLOCK();

    if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
        JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
    }

    return (jboolean)(ret == 0);
}

/*
 * Class:     sun_awt_X11InputMethod
 * Method:    isCompositionEnabledNative
 * Signature: (J)Z
 *
 * This method tries to get the XNPreeditState attribute associated with the current XIC.
 *
 * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
 * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
 * will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
 *
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_isCompositionEnabledNative
  (JNIEnv *env, jobject this)
{
    X11InputMethodData *pX11IMData = NULL;
    char * ret = NULL;
    XIMPreeditState state;

    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);

    if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
        AWT_UNLOCK();
        return JNI_FALSE;
    }

    ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
    AWT_UNLOCK();

    if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
        JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
        return JNI_FALSE;
    }

    return (jboolean)(state == XIMPreeditEnable);
}

#ifdef XAWT
JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
  (JNIEnv *env, jobject this, jlong window)
{
#ifdef __linux__
    AWT_LOCK();
    adjustStatusWindow(window);
    AWT_UNLOCK();
#endif
}
#endif
