8201429: Support AIX Input Method Editor (IME) for AWT Input Method Framework (IMF)
authorclanger
Wed, 30 May 2018 08:19:59 +0200
changeset 50350 668463f93ec0
parent 50349 b3a654c6fbcc
child 50351 9289c4214a35
8201429: Support AIX Input Method Editor (IME) for AWT Input Method Framework (IMF) Reviewed-by: prr Contributed-by: takiguc@linux.vnet.ibm.com, christoph.langer@sap.com
make/lib/Awt2dLibraries.gmk
src/java.desktop/aix/classes/sun/awt/X11InputMethod.java
src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c
src/java.desktop/unix/classes/sun/awt/X11InputMethod.java
src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java
src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
--- a/make/lib/Awt2dLibraries.gmk	Tue May 29 11:22:21 2018 -0700
+++ b/make/lib/Awt2dLibraries.gmk	Wed May 30 08:19:59 2018 +0200
@@ -269,6 +269,7 @@
   ifeq ($(ENABLE_HEADLESS_ONLY), false)
 
     LIBAWT_XAWT_DIRS := \
+        $(wildcard $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS)/native/libawt_xawt) \
         $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt_xawt \
         $(TOPDIR)/src/java.desktop/share/native/common/awt/debug \
         $(TOPDIR)/src/java.desktop/share/native/common/awt/utility \
@@ -329,7 +330,7 @@
       BUILD_LIBAWT_XAWT_awt_Font.c_CFLAGS := -w
       # initializing a declared 'extern'
       BUILD_LIBAWT_XAWT_debug_mem.c_CFLAGS := -w
-   endif
+    endif
 
     $(eval $(call SetupJdkLibrary, BUILD_LIBAWT_XAWT, \
         NAME := awt_xawt, \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/aix/classes/sun/awt/X11InputMethod.java	Wed May 30 08:19:59 2018 +0200
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 1997, 2018, 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.
+ */
+
+package sun.awt;
+
+import java.awt.AWTException;
+import java.awt.EventQueue;
+import java.awt.event.InputMethodEvent;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextHitInfo;
+import java.awt.peer.ComponentPeer;
+import java.text.AttributedString;
+
+import sun.util.logging.PlatformLogger;
+
+/**
+ * Input Method Adapter for XIM for AIX
+ *
+ * @author JavaSoft International
+ */
+public abstract class X11InputMethod extends X11InputMethodBase {
+
+    // to keep the instance of activating if IM resumed
+    static protected X11InputMethod activatedInstance = null;
+
+    /**
+     * Constructs an X11InputMethod instance. It initializes the XIM
+     * environment if it's not done yet.
+     *
+     * @exception AWTException if XOpenIM() failed.
+     */
+    public X11InputMethod() throws AWTException {
+        super();
+    }
+
+    /**
+     * Reset the composition state to the current composition state.
+     */
+    protected void resetCompositionState() {
+        if (compositionEnableSupported && haveActiveClient()) {
+            try {
+                /* Restore the composition mode to the last saved composition
+                   mode. */
+                setCompositionEnabled(savedCompositionState);
+            } catch (UnsupportedOperationException e) {
+                compositionEnableSupported = false;
+            }
+        }
+    }
+
+    /**
+     * Activate input method.
+     */
+    public synchronized void activate() {
+        activatedInstance = this;
+        clientComponentWindow = getClientComponentWindow();
+        if (clientComponentWindow == null)
+            return;
+
+        if (lastXICFocussedComponent != null) {
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine("XICFocused {0}, AWTFocused {1}",
+                         lastXICFocussedComponent, awtFocussedComponent);
+            }
+            if (lastXICFocussedComponent != awtFocussedComponent) {
+                ComponentPeer lastXICFocussedComponentPeer = getPeer(lastXICFocussedComponent);
+                if (lastXICFocussedComponentPeer != null) {
+                    setXICFocus(lastXICFocussedComponentPeer, false, isLastXICActive);
+                }
+            }
+            lastXICFocussedComponent = null;
+        }
+
+        if (pData == 0) {
+            if (!createXIC()) {
+                return;
+            }
+            disposed = false;
+        }
+
+        /*  reset input context if necessary and set the XIC focus
+        */
+        resetXICifneeded();
+        ComponentPeer awtFocussedComponentPeer = getPeer(awtFocussedComponent);
+        setStatusAreaVisible(true, pData);
+
+        if (awtFocussedComponentPeer != null) {
+            setXICFocus(awtFocussedComponentPeer, true, haveActiveClient());
+        }
+        lastXICFocussedComponent = awtFocussedComponent;
+        isLastXICActive = haveActiveClient();
+        isActive = true;
+        if (savedCompositionState) {
+            resetCompositionState();
+        }
+    }
+
+    /**
+     * Deactivate input method.
+     */
+    public synchronized void deactivate(boolean isTemporary) {
+        boolean   isAc =  haveActiveClient();
+        /* Usually as the client component, let's call it component A,
+           loses the focus, this method is called. Then when another client
+           component, let's call it component B,  gets the focus, activate is first called on
+           the previous focused compoent which is A, then endComposition is called on A,
+           deactivate is called on A again. And finally activate is called on the newly
+           focused component B. Here is the call sequence.
+
+           A loses focus               B gains focus
+           -------------> deactivate A -------------> activate A -> endComposition A ->
+           deactivate A -> activate B ----....
+
+           So in order to carry the composition mode across the components sharing the same
+           input context, we save it when deactivate is called so that when activate is
+           called, it can be restored correctly till activate is called on the newly focused
+           component. (See also sun/awt/im/InputContext and bug 6184471).
+           Last note, getCompositionState should be called before setXICFocus since
+           setXICFocus here sets the XIC to 0.
+        */
+        activatedInstance = null;
+        savedCompositionState = getCompositionState();
+
+        if (isTemporary) {
+            //turn the status window off...
+            turnoffStatusWindow();
+            /* Delay resetting the XIC focus until activate is called and the newly
+             * Focused component has a different peer as the last focused component.
+             */
+            lastXICFocussedComponent = awtFocussedComponent;
+        } else {
+            if (awtFocussedComponent != null ) {
+                ComponentPeer awtFocussedComponentPeer = getPeer(awtFocussedComponent);
+                if (awtFocussedComponentPeer != null) {
+                    setXICFocus(awtFocussedComponentPeer, false, isAc);
+                }
+            }
+            lastXICFocussedComponent = null;
+        }
+
+        isLastXICActive = isAc;
+        isLastTemporary = isTemporary;
+        isActive = false;
+        setStatusAreaVisible(false, pData);
+    }
+
+    // implements java.awt.im.spi.InputMethod.hideWindows
+    public void hideWindows() {
+        if (pData != 0) {
+            setStatusAreaVisible(false, pData);
+            turnoffStatusWindow();
+        }
+    }
+
+    /**
+     * Updates composed text with XIM preedit information and
+     * posts composed text to the awt event queue. The args of
+     * this method correspond to the XIM preedit callback
+     * information. The XIM highlight attributes are translated via
+     * fixed mapping (i.e., independent from any underlying input
+     * method engine). This method is invoked in the AWT Toolkit
+     * (X event loop) thread context and thus inside the AWT Lock.
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       This functionality is implemented in a package-private method
+    //       to insure that it cannot be overridden by client subclasses.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    void dispatchComposedText(String chgText,
+                                           int chgStyles[],
+                                           int chgOffset,
+                                           int chgLength,
+                                           int caretPosition,
+                                           long when) {
+        if (disposed) {
+            return;
+        }
+
+        // Workaround for deadlock bug on solaris2.6_zh bug#4170760
+        if (chgText == null
+            && chgStyles == null
+            && chgOffset == 0
+            && chgLength == 0
+            && caretPosition == 0
+            && composedText == null
+            && committedText == null)
+            return;
+
+        // Recalculate chgOffset and chgLength for supplementary char
+        if (composedText != null) {
+            int tmpChgOffset=chgOffset;
+            int tmpChgLength=chgLength;
+            int index = 0;
+            for (int i=0;i < tmpChgOffset; i++,index++){
+                if (index < composedText.length()
+                    && Character.charCount(composedText.codePointAt(index))==2){
+                    index++;
+                    chgOffset++;
+                }
+            }
+            // The index keeps value
+            for (int i=0;i < tmpChgLength; i++,index++){
+                if (index < composedText.length()
+                    && Character.charCount(composedText.codePointAt(index))==2){
+                    index++;
+                    chgLength++;
+                }
+            }
+        }
+
+        // Replace control character with a square box
+        if (chgText != null) {
+            StringBuffer newChgText = new StringBuffer();
+            for (int i=0; i < chgText.length(); i++){
+                char c = chgText.charAt(i);
+                if (Character.isISOControl(c)){
+                    c = '\u25A1';
+                }
+                newChgText.append(c);
+            }
+            chgText = new String(newChgText);
+        }
+
+        if (composedText == null) {
+            // TODO: avoid reallocation of those buffers
+            composedText = new StringBuffer(INITIAL_SIZE);
+            rawFeedbacks = new IntBuffer(INITIAL_SIZE);
+        }
+        if (chgLength > 0) {
+            if (chgText == null && chgStyles != null) {
+                rawFeedbacks.replace(chgOffset, chgStyles);
+            } else {
+                if (chgLength == composedText.length()) {
+                    // optimization for the special case to replace the
+                    // entire previous text
+                    composedText = new StringBuffer(INITIAL_SIZE);
+                    rawFeedbacks = new IntBuffer(INITIAL_SIZE);
+                } else {
+                    if (composedText.length() > 0) {
+                        if (chgOffset+chgLength < composedText.length()) {
+                            String text;
+                            text = composedText.toString().substring(chgOffset+chgLength,
+                                                                     composedText.length());
+                            composedText.setLength(chgOffset);
+                            composedText.append(text);
+                        } else {
+                            // in case to remove substring from chgOffset
+                            // to the end
+                            composedText.setLength(chgOffset);
+                        }
+                        rawFeedbacks.remove(chgOffset, chgLength);
+                    }
+                }
+            }
+        }
+        if (chgText != null) {
+            composedText.insert(chgOffset, chgText);
+            if (chgStyles != null) {
+                // Recalculate chgStyles for supplementary char
+                if (chgText.length() > chgStyles.length){
+                    int index=0;
+                    int[] newStyles = new int[chgText.length()];
+                    for (int i=0; i < chgStyles.length; i++, index++){
+                        newStyles[index]=chgStyles[i];
+                        if (index < chgText.length()
+                            && Character.charCount(chgText.codePointAt(index))==2){
+                            newStyles[++index]=chgStyles[i];
+                        }
+                    }
+                    chgStyles=newStyles;
+                }
+                rawFeedbacks.insert(chgOffset, chgStyles);
+            }
+
+        }
+
+        else if (chgStyles != null) {
+            // Recalculate chgStyles to support supplementary char
+            int count=0;
+            for (int i=0; i < chgStyles.length; i++){
+                if (composedText.length() > chgOffset+i+count
+                    && Character.charCount(composedText.codePointAt(chgOffset+i+count))==2){
+                    count++;
+                }
+            }
+            if (count>0){
+                int index=0;
+                int[] newStyles = new int[chgStyles.length+count];
+                for (int i=0; i < chgStyles.length; i++, index++){
+                    newStyles[index]=chgStyles[i];
+                    if (composedText.length() > chgOffset+index
+                        && Character.charCount(composedText.codePointAt(chgOffset+index))==2){
+                        newStyles[++index]=chgStyles[i];
+                    }
+                }
+                chgStyles=newStyles;
+            }
+            rawFeedbacks.replace(chgOffset, chgStyles);
+        }
+
+        if (composedText.length() == 0) {
+            composedText = null;
+            rawFeedbacks = null;
+
+            // if there is any outstanding committed text stored by
+            // dispatchCommittedText(), it has to be sent to the
+            // client component.
+            if (committedText != null) {
+                dispatchCommittedText(committedText, when);
+                committedText = null;
+                return;
+            }
+
+            // otherwise, send null text to delete client's composed
+            // text.
+            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                                 null,
+                                 0,
+                                 null,
+                                 null,
+                                 when);
+
+            return;
+        }
+
+        // Adjust caretPosition for supplementary char
+        for (int i=0; i< caretPosition; i++){
+            if (i < composedText.length()
+                && Character.charCount(composedText.codePointAt(i))==2){
+                caretPosition++;
+                i++;
+            }
+        }
+
+        // Now sending the composed text to the client
+        int composedOffset;
+        AttributedString inputText;
+
+        // if there is any partially committed text, concatenate it to
+        // the composed text.
+        if (committedText != null) {
+            composedOffset = committedText.length();
+            inputText = new AttributedString(committedText + composedText);
+            committedText = null;
+        } else {
+            composedOffset = 0;
+            inputText = new AttributedString(composedText.toString());
+        }
+
+        int currentFeedback;
+        int nextFeedback;
+        int startOffset = 0;
+        int currentOffset;
+        int visiblePosition = 0;
+        TextHitInfo visiblePositionInfo = null;
+
+        rawFeedbacks.rewind();
+        currentFeedback = rawFeedbacks.getNext();
+        rawFeedbacks.unget();
+        while ((nextFeedback = rawFeedbacks.getNext()) != -1) {
+            if (visiblePosition == 0) {
+                visiblePosition = nextFeedback & XIMVisibleMask;
+                if (visiblePosition != 0) {
+                    int index = rawFeedbacks.getOffset() - 1;
+
+                    if (visiblePosition == XIMVisibleToBackward)
+                        visiblePositionInfo = TextHitInfo.leading(index);
+                    else
+                        visiblePositionInfo = TextHitInfo.trailing(index);
+                }
+            }
+            nextFeedback &= ~XIMVisibleMask;
+            if (currentFeedback != nextFeedback) {
+                rawFeedbacks.unget();
+                currentOffset = rawFeedbacks.getOffset();
+                inputText.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT,
+                                       convertVisualFeedbackToHighlight(currentFeedback),
+                                       composedOffset + startOffset,
+                                       composedOffset + currentOffset);
+                startOffset = currentOffset;
+                currentFeedback = nextFeedback;
+            }
+        }
+        currentOffset = rawFeedbacks.getOffset();
+        if (currentOffset >= 0) {
+            inputText.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT,
+                                   convertVisualFeedbackToHighlight(currentFeedback),
+                                   composedOffset + startOffset,
+                                   composedOffset + currentOffset);
+        }
+
+        postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                             inputText.getIterator(),
+                             composedOffset,
+                             TextHitInfo.leading(caretPosition),
+                             visiblePositionInfo,
+                             when);
+    }
+
+    /* Some IMs need forced Text clear */
+    void clearComposedText(long when) {
+        composedText = null;
+        postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                             null, 0, null, null,
+                             when);
+        if (committedText != null && committedText.length() > 0) {
+            dispatchCommittedText(committedText, when);
+        }
+        committedText = null;
+        rawFeedbacks = null;
+    }
+
+    void clearComposedText() {
+        if (EventQueue.isDispatchThread()) {
+            clearComposedText(EventQueue.getMostRecentEventTime());
+        }
+    }
+
+    /*
+     * Subclasses should override disposeImpl() instead of dispose(). Client
+     * code should always invoke dispose(), never disposeImpl().
+     */
+    protected synchronized void disposeImpl() {
+        disposeXIC();
+        awtLock();
+        try {
+            clearComposedText();
+        } finally {
+            // Put awtUnlock into finally block in case an exception is thrown in clearComposedText.
+            awtUnlock();
+        }
+        awtFocussedComponent = null;
+        lastXICFocussedComponent = null;
+        needResetXIC = false;
+        savedCompositionState = false;
+        compositionEnableSupported = true;
+    }
+
+    /**
+     * @see java.awt.im.spi.InputMethod#setCompositionEnabled(boolean)
+     */
+    public void setCompositionEnabled(boolean enable) {
+        /* If the composition state is successfully changed, set
+           the savedCompositionState to 'enable'. Otherwise, simply
+           return.
+           setCompositionEnabledNative may throw UnsupportedOperationException.
+           Don't try to catch it since the method may be called by clients.
+           Use package private mthod 'resetCompositionState' if you want the
+           exception to be caught.
+        */
+        boolean pre, post;
+        pre=getCompositionState();
+
+        if (setCompositionEnabledNative(enable)) {
+            savedCompositionState = enable;
+        }
+
+        post=getCompositionState();
+        if (pre != post && post == enable){
+            if (enable == false) flushText();
+            if (awtFocussedComponent != null && isActive){
+                setXICFocus(getPeer(awtFocussedComponent),
+                            true, haveActiveClient());
+            }
+        }
+    }
+
+    private native void setStatusAreaVisible(boolean value, long data);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c	Wed May 30 08:19:59 2018 +0200
@@ -0,0 +1,2269 @@
+/*
+ * Copyright (c) 1997, 2018, 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 "awt.h"
+#include "awt_p.h"
+
+#include <sun_awt_X11InputMethodBase.h>
+#include <sun_awt_X11InputMethod.h>
+#include <sun_awt_X11_XInputMethod.h>
+
+#include <langinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <X11/Intrinsic.h>
+#include <X11/keysym.h>
+#include <X11/Xlib.h>
+
+#define THROW_OUT_OF_MEMORY_ERROR() \
+        JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
+
+struct X11InputMethodIDs {
+  jfieldID pData;
+} x11InputMethodIDs;
+
+static int PreeditStartCallback(XIC, XPointer, XPointer);
+static void PreeditDoneCallback(XIC, XPointer, XPointer);
+static void PreeditDrawCallback(XIC, XPointer,
+                                XIMPreeditDrawCallbackStruct *);
+static void PreeditCaretCallback(XIC, XPointer,
+                                 XIMPreeditCaretCallbackStruct *);
+static void StatusStartCallback(XIC, XPointer, XPointer);
+static void StatusDoneCallback(XIC, XPointer, XPointer);
+static void StatusDrawCallback(XIC, XPointer,
+                               XIMStatusDrawCallbackStruct *);
+
+#define ROOT_WINDOW_STYLES      (XIMPreeditNothing | XIMStatusNothing)
+#define NO_STYLES               (XIMPreeditNone | XIMStatusNone)
+/* added style to allow for in-place composition, such as "dead" keys for accents */
+#define IN_PLACE_STYLES         (XIMPreeditNothing | XIMStatusNone)
+
+#define PreeditStartIndex       0
+#define PreeditDoneIndex        1
+#define PreeditDrawIndex        2
+#define PreeditCaretIndex       3
+#define StatusStartIndex        4
+#define StatusDoneIndex         5
+#define StatusDrawIndex         6
+#define NCALLBACKS              7
+
+#define STATUS_BORDER 2         /* Status Border width */
+#define CARET_OFFSET 1          /* Offset of caret position (pixel) */
+#define BORDER_MARGIN 3         /* BORDER MARGIN width */
+#define STATUS_MARGIN 7         /* Margin between the status window and its parent window */
+#define PREEDIT_ATTR_MASK (XIMReverse|XIMUnderline)
+          /* Preedit attribute which host adapter can handle */
+
+/*
+ * 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,
+    (XIMProc)StatusStartCallback,
+    (XIMProc)StatusDoneCallback,
+    (XIMProc)StatusDrawCallback,
+};
+
+#define MAX_STATUS_LEN  100
+typedef struct {
+    Window   w;                /*status window id        */
+    Window   root;             /*the root window id      */
+    Window   parent;           /*parent shell window     */
+    Window   grandParent;      /*window has WM frame     */
+    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            */
+    wchar_t  status[MAX_STATUS_LEN + 1]; /*status text       */
+    XFontSet fontset;           /*fontset for drawing    */
+    int      off_x, off_y;
+    Bool     on;                /*if the status window on*/
+    int      fOff;              /* font base line(in pixel) from top */
+    int      fBot;              /* font bottom line(in pixel) from top */
+    int      peTextW;           /* Composition text width in pixel */
+    wchar_t* peText;            /* Composed string (wide char.) */
+    XIMFeedback* peAttr;        /* Composed text attribute */
+    int      peCaret;           /* Caret position in number of character */
+    Bool     status_ready;      /* Not draw Status at XCreateIC */
+} StatusWindow;
+
+/*
+ * 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 */
+    jobject     x11inputmethod; /* global ref to X11InputMethod instance */
+                                /* associated with the XIC */
+    StatusWindow *statusWindow; /* our own status window  */
+    Bool        passiveStatusWindow;/* Passive Client uses StatusWindow */
+    Bool        isActiveClient;     /* True:clinet is active */
+    Bool        forceReset;     /* True: call resetXIC before UnsetICFocus */
+} X11InputMethodData;
+
+/* 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)
+
+static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
+static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
+static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
+static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
+
+/* Prototype for this function is missing in AIX Xlib.h */
+extern char *XSetIMValues(
+#if NeedVarargsPrototypes
+    XIM /* im */, ...
+#endif
+);
+
+static int st_wcslen(wchar_t *string);
+static Bool isPreeditStateActive(XIC ic);
+static void * buf_insert(void * src, void * insert, int size,
+                         int src_len, int ins_len, int offset);
+static void * handle_buffer(void * source, void * insert,
+                            int size, int src_len, int ins_len,
+                            int del_len, int offset);
+static void preedit_draw_passive(X11InputMethodData *pX11IMData,
+                                 XIMPreeditDrawCallbackStruct *pre_draw);
+static void resetPassivePreeditText(StatusWindow *statusWindow);
+static void draw_caret(StatusWindow *statusWindow, GC gc, int pos);
+static int  get_next_attr(int len, unsigned long *attr);
+static void draw_preedit(StatusWindow *statusWindow);
+static void align_status(StatusWindow *statusWindow);
+static void shrink_status(StatusWindow *statusWindow);
+static GC create_gc(Window win, Bool isReverse);
+static XFontSet create_fontset(void);
+static Bool is_text_available(XIMText * text);
+static Bool isNativeIm();
+static Window getGrandParent(Window parent);
+static void moveStatusWindow(StatusWindow *statusWindow);
+static void arrange_window_stack(StatusWindow* statusWindow);
+static Window get_current_focus(XIC ic);
+
+/*
+ * 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);
+}
+
+/*
+ * 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) {
+        free(mbs);
+        return NULL;
+    }
+
+    return mbs;
+}
+
+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");
+        JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+        /* 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)
+{
+    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);
+        if (pX11IMData->statusWindow->peText){
+            free((void *)pX11IMData->statusWindow->peText);
+            pX11IMData->statusWindow->peText = NULL;
+        }
+        if (pX11IMData->statusWindow->peAttr){
+            free((void *)pX11IMData->statusWindow->peAttr);
+            pX11IMData->statusWindow->peAttr = NULL;
+        }
+        free((void*)sw);
+    }
+
+    if (pX11IMData->callbacks)
+        free((void *)pX11IMData->callbacks);
+
+    if (env) {
+        (*env)->DeleteGlobalRef(env, pX11IMData->x11inputmethod);
+    }
+
+    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
+
+Boolean
+awt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
+{
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData = NULL;
+    int buf_len = INITIAL_LOOKUP_BUF_SIZE;
+    char mbbuf[INITIAL_LOOKUP_BUF_SIZE];
+    char *buf;
+    KeySym keysym = NoSymbol;
+    Status status;
+    int mblen;
+    jstring javastr;
+    XIC ic;
+    Boolean result = True;
+    static Boolean composing = False;
+
+    /*
+      printf("lookupString: entering...\n");
+     */
+
+    pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
+
+    if (pX11IMData == NULL) {
+        return False;
+    }
+
+    if ((ic = pX11IMData->current_ic) == (XIC)0){
+        return False;
+    }
+
+    buf = mbbuf;
+    mblen = XmbLookupString(ic, event, buf,
+                            buf_len - 1, &keysym, &status);
+
+    /*
+     * In case of overflow, a buffer is allocated and it retries
+     * XmbLookupString().
+     */
+    if (status == XBufferOverflow) {
+        buf_len = mblen + 1;
+        buf = (char *)malloc(buf_len);
+        if (buf == NULL) {
+            THROW_OUT_OF_MEMORY_ERROR();
+            return result;
+        }
+        mblen = XmbLookupString(ic, event, buf, buf_len, &keysym, &status);
+    }
+    buf[mblen] = 0;
+
+    /* Get keysym without taking modifiers into account first to map
+     * to AWT keyCode table.
+     */
+    switch (status) {
+    case XLookupBoth:
+        if (!composing) {
+            if (event->keycode != 0) {
+                *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 *)buf);
+        if (javastr != NULL) {
+            JNU_CallMethodByName(env, NULL,
+                                 currentX11InputMethodInstance,
+                                 "dispatchCommittedText",
+                                 "(Ljava/lang/String;J)V",
+                                 javastr,
+                                 event->time);
+            if ((*env)->ExceptionOccurred(env)) {
+                (*env)->ExceptionDescribe(env);
+                (*env)->ExceptionClear(env);
+            }
+        }
+        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;
+    }
+
+    if (buf != mbbuf) {
+        free(buf);
+    }
+    return result;
+}
+
+static StatusWindow *createStatusWindow(Window parent) {
+    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;
+    unsigned long bg, fg, light, dim;
+    int x, y, off_x, off_y, xx, yy;
+    unsigned int w, h, bw, depth;
+    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;
+    Window grandParent;
+    Window target;
+    XFontSet fontset;
+
+    fontset = create_fontset();
+    if (NULL == fontset) {
+        return NULL;
+    }
+
+    XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
+
+    attrib.override_redirect = True;
+    attribmask = CWOverrideRedirect;
+    for (i = 0; i < awt_numScreens; i++) {
+        if (RootWindow(dpy, i) == rootWindow) {
+            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);
+
+    grandParent = getGrandParent(parent);
+    target = (grandParent == 0) ? parent : grandParent;
+    XGetWindowAttributes(dpy, target, &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,
+                target,
+                &rootWindow,
+                &containerWindow,
+                &ignoreWindowPtr,
+                &ignoreUnit);
+    XGetWindowAttributes(dpy, containerWindow, &xxwa);
+
+    XTranslateCoordinates(dpy,
+                          target, xwa.root,
+                          0, 0,
+                          &x, &y, &child);
+
+    if (containerWindow == rootWindow) {
+        off_x = 0; off_y = STATUS_MARGIN;
+    } else {
+        XGetWindowAttributes(dpy, containerWindow, &xxwa);
+        off_x = (xxwa.width - xwa.width) / 2;
+        /* off_y = xxwa.height - xwa.height - off_x;*/ /*it's magic:-) */
+        {
+            int cx, cy;
+            XTranslateCoordinates(dpy,
+                                  containerWindow, xxwa.root,
+                                  0, 0,
+                                  &cx, &cy,
+                                  &child);
+            off_y = (xxwa.height + cy) - (xwa.height + y);
+        }
+    }
+
+    /*get the size of root window*/
+    XGetWindowAttributes(dpy, rootWindow, &xxwa);
+
+    XTranslateCoordinates(dpy,
+                          target, 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;
+    }
+
+    if ((DefaultVisual(dpy,screen))->class != adata->awt_visInfo.visual->class &&
+        adata->awt_visInfo.visual->class == TrueColor) {
+        attrib.colormap = XCreateColormap(dpy, xwa.root,
+            adata->awt_visInfo.visual, AllocNone );
+        attrib.border_pixel = BlackPixel(dpy, screen) ;
+        attribmask |= CWColormap | CWBorderPixel;
+    }
+
+    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);
+    if (grandParent != 0){
+        long mask;
+        XGetWindowAttributes(dpy, grandParent, &xwa);
+        mask = xwa.your_event_mask | StructureNotifyMask |
+               VisibilityChangeMask | PropertyChangeMask;
+        XSelectInput(dpy, grandParent,mask);
+    }
+
+    statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
+    if (statusWindow == NULL){
+        THROW_OUT_OF_MEMORY_ERROR();
+        return NULL;
+    }
+    statusWindow->w = status;
+    statusWindow->fontset = fontset;
+    statusWindow->parent = parent;
+    statusWindow->grandParent = grandParent;
+    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->peTextW = 0;
+    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 = create_gc(status, FALSE);
+    XSetForeground(dpy, statusWindow->fgGC, fg);
+    statusWindow->bgGC = create_gc(status, TRUE);
+    XSetForeground(dpy, statusWindow->bgGC, bg);
+    statusWindow->status_ready = False;
+    wcscpy(statusWindow->status, L"");
+    return statusWindow;
+}
+
+/* This method is to turn off or turn on the status window. */
+static void onoffStatusWindow(X11InputMethodData* pX11IMData,
+                                Window parent,
+                                Bool ON){
+    XWindowAttributes xwa;
+    Window child;
+    int x, y;
+    StatusWindow *statusWindow = NULL;
+
+    if (NULL == pX11IMData ||
+        NULL == (statusWindow =  pX11IMData->statusWindow)){
+        return;
+    }
+
+    if (ON == False) {
+        XUnmapWindow(dpy, statusWindow->w);
+        return;
+    }
+    if (NULL == currentX11InputMethodInstance){
+        return;
+    }
+    {
+        JNIEnv *env = GetJNIEnv();
+        parent = JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
+                                      "getCurrentParentWindow",
+                                      "()J").j;
+        if ((*env)->ExceptionOccurred(env)) {
+            (*env)->ExceptionDescribe(env);
+            (*env)->ExceptionClear(env);
+        }
+    }
+    if (statusWindow->parent != parent) {
+        statusWindow->parent = parent;
+    }
+    if (st_wcslen(statusWindow->status) > 0 ||
+        (statusWindow->peText != NULL && st_wcslen(statusWindow->peText) > 0 )) {
+        moveStatusWindow(statusWindow);
+        XMapRaised(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;
+    int len;
+    XRectangle logical, ink;
+
+    if (NULL == statusWindow) return;
+    if ((len = st_wcslen(statusWindow->status)) == 0) {
+        return;
+    }
+    XwcTextExtents(statusWindow->fontset, statusWindow->status,
+                   len, &ink, &logical);
+    width = logical.width;
+    height = logical.height;
+
+    XFillRectangle(dpy, win, bggc, 0, 0, width+2, height+2);
+
+    XDrawLine(dpy, win, fggc, 0, 0, width+2, 0);
+    XDrawLine(dpy, win, fggc, 0, height+2, width+2, height+2);
+    XDrawLine(dpy, win, fggc, 0, 0, 0, height+2);
+    XDrawLine(dpy, win, fggc, width+2, 0, width+2, height+2);
+
+    if (statusWindow->fontset) {
+        XwcDrawString(dpy, win, statusWindow->fontset, fggc,
+                      -logical.x + 1, -logical.y + 1,
+                      statusWindow->status,
+                      st_wcslen(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]"));
+    }
+}
+
+Bool statusWindowEventHandler(XEvent event) {
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData = NULL;
+    StatusWindow *statusWindow;
+
+    if (NULL == currentX11InputMethodInstance ||
+        NULL == (pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance)) ||
+        NULL == (statusWindow = pX11IMData->statusWindow))
+    {
+        return False;
+    }
+
+    if (statusWindow->w == event.xany.window) {
+        switch (event.type) {
+        case Expose:
+            paintStatusWindow(statusWindow);
+            if (statusWindow->peText)
+                draw_preedit(statusWindow);
+            arrange_window_stack(statusWindow);
+            break;
+        case ConfigureNotify:
+        case VisibilityNotify:
+            arrange_window_stack(statusWindow);
+            break;
+        /*
+        case UnmapNotify:
+        case VisibilityNotify:
+            break;
+        */
+        default:
+            break;
+        }
+        return True;
+    } else if ((statusWindow->parent == event.xany.window) ||
+               (statusWindow->grandParent && statusWindow->grandParent == event.xany.window)) {
+        switch (event.type) {
+        case MapNotify:
+            if (statusWindow->on) {
+                onoffStatusWindow(pX11IMData, statusWindow->parent, True);
+            }
+            break;
+        case UnmapNotify:
+            onoffStatusWindow(pX11IMData, 0, False);
+            break;
+        case VisibilityNotify:
+            if (statusWindow->on) {
+                arrange_window_stack(statusWindow);
+            }
+            break;
+        case ConfigureNotify:
+            if (statusWindow->grandParent && statusWindow->on) {
+                moveStatusWindow(statusWindow);
+            }
+        case PropertyNotify:
+            if (statusWindow->on) {
+                arrange_window_stack(statusWindow);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    return False;
+}
+
+static void adjustStatusWindow(Window shell) {
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData = NULL;
+    StatusWindow *statusWindow;
+
+    if (NULL == currentX11InputMethodInstance
+        || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
+        || NULL == (statusWindow = pX11IMData->statusWindow)
+        || !statusWindow->on)
+    {
+        return;
+    }
+
+    moveStatusWindow(statusWindow);
+}
+
+/*
+ * 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
+createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
+{
+    XVaNestedList preedit = NULL;
+    XVaNestedList status = NULL;
+    XIMStyle on_the_spot_styles = XIMPreeditCallbacks,
+             in_place_styles = 0,
+             active_styles = 0,
+             passive_styles = 0,
+             no_styles = 0;
+    XIMCallback *callbacks;
+    unsigned short i;
+    XIMStyles *im_styles;
+    char *ret = NULL;
+    Bool passiveStatusWindow = False;
+    pX11IMData->statusWindow = NULL;
+
+    if (X11im == NULL) {
+        return False;
+    }
+    if (!w) {
+        return False;
+    }
+
+    if (getenv("IBMJAVA_PASSIVE") == NULL) {
+        passiveStatusWindow = False;
+    } else {
+        passiveStatusWindow = True;
+    }
+
+    if (isNativeIm()) { passiveStatusWindow = True; }
+
+    ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);
+
+    if (ret != NULL) {
+        jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
+        return FALSE ;
+    }
+
+    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;
+        }
+    }
+
+    for (i = 0; i < im_styles->count_styles; i++) {
+        if (im_styles->supported_styles[i] == on_the_spot_styles)
+            active_styles = im_styles->supported_styles[i];
+        if (im_styles->supported_styles[i] == ROOT_WINDOW_STYLES)
+            passive_styles = im_styles->supported_styles[i];
+        if (im_styles->supported_styles[i] == IN_PLACE_STYLES) {
+            in_place_styles = im_styles->supported_styles[i];
+        }
+        if (im_styles->supported_styles[i] == NO_STYLES) {
+            no_styles = im_styles->supported_styles[i];
+        }
+    }
+
+    XFree(im_styles);
+
+    if (active_styles != on_the_spot_styles) {
+        if (passive_styles == ROOT_WINDOW_STYLES)
+            active_styles = passive_styles;
+        else {
+          if (in_place_styles == IN_PLACE_STYLES){
+              active_styles = passive_styles = IN_PLACE_STYLES;
+          } else {
+            if (no_styles == NO_STYLES)
+                active_styles = passive_styles = NO_STYLES;
+            else
+                active_styles = passive_styles = 0;
+          }
+        }
+    } else {
+      if (!passiveStatusWindow) {
+        if (passive_styles != ROOT_WINDOW_STYLES) {
+            if (no_styles == NO_STYLES)
+                active_styles = passive_styles = NO_STYLES;
+            else
+                active_styles = passive_styles = 0;
+        }
+      } else
+          passive_styles = active_styles;
+    }
+
+    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;
+        /*always try XIMStatusCallbacks for active client...*/
+        {
+        if (on_the_spot_styles & XIMStatusCallbacks) {
+            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, w,
+                                              XNFocusWindow, w,
+                                              XNInputStyle, active_styles,
+                                              XNPreeditAttributes, preedit,
+                                              XNStatusAttributes, status,
+                                              NULL);
+            if (NULL != pX11IMData->statusWindow) {
+                pX11IMData->statusWindow->status_ready = True;
+            }
+            XFree((void *)status);
+            XFree((void *)preedit);
+        }
+        if (passiveStatusWindow) {
+            pX11IMData->ic_passive = pX11IMData->ic_active;
+        } else {
+            pX11IMData->ic_passive = XCreateIC(X11im,
+                                               XNClientWindow, w,
+                                               XNFocusWindow, w,
+                                               XNInputStyle, passive_styles,
+                                               NULL);
+        }
+    } else {
+        pX11IMData->ic_active = XCreateIC(X11im,
+                                          XNClientWindow, w,
+                                          XNFocusWindow, w,
+                                          XNInputStyle, active_styles,
+                                          NULL);
+        pX11IMData->ic_passive = pX11IMData->ic_active;
+    }
+
+    // The code set the IC mode that the preedit state is not initialied
+    // at XmbResetIC.  This attribute can be set at XCreateIC.  I separately
+    // set the attribute to avoid the failure of XCreateIC at some platform
+    // which does not support the attribute.
+    if (pX11IMData->ic_active != 0)
+        XSetICValues(pX11IMData->ic_active,
+                        XNResetState, XIMPreserveState, NULL);
+    if (pX11IMData->ic_passive != 0 &&
+        pX11IMData->ic_active != pX11IMData->ic_passive)
+            XSetICValues(pX11IMData->ic_passive,
+             XNResetState, XIMInitialState, NULL);
+
+    pX11IMData->passiveStatusWindow = passiveStatusWindow;
+
+    if (pX11IMData->ic_active == (XIC)0
+        || pX11IMData->ic_passive == (XIC)0) {
+        return False;
+    }
+
+    /* Unset focus to avoid unexpected IM on */
+    setXICFocus(pX11IMData->ic_active, False);
+    if (pX11IMData->ic_active != pX11IMData->ic_passive)
+        setXICFocus(pX11IMData->ic_passive, False);
+
+    return True;
+
+ err:
+    if (preedit)
+        XFree((void *)preedit);
+    THROW_OUT_OF_MEMORY_ERROR();
+    return False;
+}
+
+static int
+PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
+{
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData;
+
+    pX11IMData = getX11InputMethodData(env, (jobject)client_data);
+    if (pX11IMData == NULL || pX11IMData->statusWindow == NULL) {
+        return 0;
+    }
+    resetPassivePreeditText(pX11IMData->statusWindow);
+
+    return -1;  /* unlimited length for preedit text  */
+}
+
+static void
+PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
+{
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData;
+
+    pX11IMData = getX11InputMethodData(env, (jobject)client_data);
+    if (pX11IMData == NULL) {
+        return;
+    }
+
+    if (!pX11IMData->isActiveClient) {
+        resetPassivePreeditText(pX11IMData->statusWindow);
+        shrink_status(pX11IMData->statusWindow);
+    }
+    else{
+            JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
+                                 "clearComposedText",
+                                 "(J)V",
+                                 awt_util_nowMillisUTC());
+            if ((*env)->ExceptionOccurred(env)) {
+                (*env)->ExceptionDescribe(env);
+                (*env)->ExceptionClear(env);
+            }
+    }
+}
+
+/*
+ * 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 ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
+        goto finally;
+    }
+
+    if (!pX11IMData->isActiveClient){
+        if (ic == pX11IMData->ic_passive) {
+            preedit_draw_passive(pX11IMData, pre_draw);
+        }
+        goto finally;
+    }
+
+    if ((text = pre_draw->text) != NULL) {
+        if (is_text_available(text)) {
+            if (text->string.multi_byte != NULL) {
+                if (pre_draw->text->encoding_is_wchar == False) {
+                    javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
+                    if (javastr == NULL) {
+                        goto finally;
+                    }
+                } 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) {
+                        goto finally;
+                    }
+                }
+            }
+        }
+        if (text->feedback != NULL) {
+            int cnt;
+            jint *tmpstyle;
+
+            style = (*env)->NewIntArray(env, text->length);
+            if (JNU_IsNull(env, style)) {
+                (*env)->ExceptionClear(env);
+                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());
+
+    if ((*env)->ExceptionOccurred(env)) {
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+    }
+
+finally:
+    AWT_UNLOCK();
+    return;
+}
+
+static void
+PreeditCaretCallback(XIC ic, XPointer client_data,
+                     XIMPreeditCaretCallbackStruct *pre_caret)
+{
+    XIMPreeditDrawCallbackStruct pre_draw;
+
+    if (pre_caret != NULL && pre_caret->direction == XIMAbsolutePosition) {
+        pre_draw.caret = pre_caret->position;
+        pre_draw.chg_first = 0;
+        pre_draw.chg_length = 0;
+        pre_draw.text = NULL;
+        PreeditDrawCallback(ic, client_data, &pre_draw);
+    }
+}
+
+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;
+    int value_make = CWX|CWWidth|CWHeight;
+    XRectangle logical, ink;
+    XWindowChanges xwc;
+    int len;
+
+    AWT_LOCK();
+
+    if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
+        || NULL == (statusWindow = pX11IMData->statusWindow)){
+        goto finally;
+    }
+
+    if (status_draw->type == XIMTextType) {
+        XIMText *text = (status_draw->data).text;
+        if (text != NULL) {
+            if (text->string.multi_byte != NULL) {
+                if(!strcmp(text->string.multi_byte," ")){
+                    wcscpy(statusWindow->status, L"");
+                    onoffStatusWindow(pX11IMData, 0, False);
+                    goto finally;
+                }
+                mbstowcs(statusWindow->status,
+                         (const char *)text->string.multi_byte,
+                         (size_t)MAX_STATUS_LEN);
+            } else {
+                if (0 == st_wcslen(text->string.wide_char)){
+                    wcscpy(statusWindow->status, L"");
+                    onoffStatusWindow(pX11IMData, 0, False);
+                    goto finally;
+                }
+                wcsncpy(statusWindow->status,
+                        text->string.wide_char,
+                        MAX_STATUS_LEN);
+            }
+            XwcTextExtents(statusWindow->fontset, statusWindow->status,
+                           st_wcslen(statusWindow->status), &ink, &logical);
+            statusWindow->statusW = logical.width + BORDER_MARGIN;
+            statusWindow->statusH = logical.height + BORDER_MARGIN;
+            xwc.x = statusWindow->x - statusWindow->off_x;
+            if (xwc.x < 0 ) xwc.x = 0;
+            xwc.width = statusWindow->statusW;
+            xwc.height = statusWindow->statusH;
+            if (xwc.x + xwc.width > statusWindow->rootW){
+                xwc.x = statusWindow->rootW - xwc.width;
+            }
+            XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
+          if (statusWindow->status_ready && statusWindow->on == True){
+            onoffStatusWindow(pX11IMData, statusWindow->parent, True);
+          }
+            paintStatusWindow(statusWindow);
+            if (statusWindow->peText)
+                draw_preedit(statusWindow);
+        }
+        else {
+            wcscpy(statusWindow->status, L"");
+            /*just turnoff the status window
+            paintStatusWindow(statusWindow);
+            */
+            onoffStatusWindow(pX11IMData, 0, False);
+        }
+    }
+
+ finally:
+    AWT_UNLOCK();
+}
+
+/* return the string length without trailing spaces    */
+/* work around code for Japanese AIXIM is implemented. */
+static int st_wcslen(wchar_t *string)
+{
+    int len = (int32_t)wcslen(string);
+    if (len == 0)
+        return 0;
+   for (len--;len >= 0; len--) {
+        if (!iswspace((wint_t) string[len])) break;
+    }
+    return len+1;
+}
+
+/*
+ * Checks whether given XIMText contains a string data.
+ */
+static Bool is_text_available(XIMText * text)
+{
+    if (text == NULL || text->length==0)
+        return False;
+    if (text->encoding_is_wchar) {
+        if(text->string.wide_char[0] == L'\0')
+            return False;
+    } else {
+        if (text->string.multi_byte[0] == '\0')
+            return False;
+    }
+    return True;
+}
+
+/*
+ * check if preedit status is active
+*/
+static Bool isPreeditStateActive(XIC ic)
+{
+    XIMPreeditState state = XIMPreeditUnKnown;
+    XVaNestedList pr_atrb;
+    char* nosupportAttr;
+
+    if (ic == NULL) return False;
+
+    pr_atrb = XVaCreateNestedList(0,XNPreeditState,&state,NULL);
+    nosupportAttr=XGetICValues(ic,XNPreeditAttributes,pr_atrb,NULL);
+    XFree(pr_atrb);
+    if (nosupportAttr==NULL && state & XIMPreeditDisable)
+        return False;
+    else
+        return True;
+}
+
+static void * buf_insert(void * src, void * insert, int size,
+                         int src_len, int ins_len, int offset)
+{
+    char *temp;
+
+    temp = realloc(src, size*(src_len+ins_len+1));
+    if (temp == NULL) {
+        THROW_OUT_OF_MEMORY_ERROR();
+        return src;
+    }
+    if (offset != src_len) {
+        memmove(&temp[size*(offset+ins_len)],
+                &((char *)temp)[size*offset],
+                size*(src_len-offset));
+    }
+    memcpy(&temp[size*offset], insert, size*ins_len);
+
+    return (void *)temp;
+}
+
+static void * handle_buffer(void * source, void * insert,
+                            int size,int src_len, int ins_len,
+                            int del_len, int offset)
+{
+    void * temp = source;
+
+    if (del_len > 0) {
+        if (del_len == ins_len) {
+            memcpy(&((char *)source)[size*offset], insert, size*ins_len);
+            return source;
+        }
+        else if (src_len > offset+del_len) {
+            memmove(&((char *)source)[size*offset],
+                    &((char *)source)[size*(offset+del_len)],
+                    size*(src_len-offset-del_len));
+        }
+    }
+    if (ins_len > 0) {
+        temp = buf_insert(source, insert, size, src_len,
+                          ins_len, offset);
+    }
+    return temp;
+}
+/*
+ * Display the given preedit text to the root window which is ownd by
+ * myself. All of the character is converted to wide char.
+ * this function is used for the passive client.
+ */
+static void preedit_draw_passive(X11InputMethodData *pX11IMData,
+                    XIMPreeditDrawCallbackStruct *pre_draw)
+{
+    XIMText *text;
+    wchar_t *tempbuf = NULL;
+    StatusWindow *statusWindow;
+    wchar_t *cur_text;
+    unsigned long *cur_attr;
+    int     cur_len = 0;
+    int     chg_len = pre_draw->chg_length;
+    int     chg_1st = pre_draw->chg_first;
+
+    if (NULL == (statusWindow = pX11IMData->statusWindow))
+        return;
+    cur_text = statusWindow->peText;
+    cur_attr = statusWindow->peAttr;
+    if (cur_text == NULL && pre_draw->text == NULL)
+        return;
+
+    if (cur_text != NULL)
+        cur_len = (int32_t)wcslen(cur_text);
+    text = pre_draw->text;
+    if (text == NULL) {
+        /* delete only */
+        if (cur_len >  chg_1st+chg_len) {
+            memmove(&cur_text[chg_1st],
+                    &cur_text[chg_1st+chg_len],
+                    sizeof(wchar_t)*(cur_len-chg_1st-chg_len));
+            memmove(&cur_attr[chg_1st],
+                    &cur_attr[chg_1st+chg_len],
+                    sizeof(long)*(cur_len-chg_1st-chg_len));
+        }
+        if ((pre_draw->chg_length <= cur_len ) && (pre_draw->chg_length >0))
+            cur_text[cur_len-pre_draw->chg_length] =L'\0';
+    } else {
+        /* insert or replace */
+        int     ins_len = 0;
+        void *  ins_text = NULL;
+
+        /* if invalid offset is specified, do nothing. */
+        /* this fix is for aixim for eucTW             */
+        if (cur_len < chg_1st)
+            return;
+        if(is_text_available(text)) {
+            /* insert or replace the text */
+            if (text->encoding_is_wchar == False) {
+                /* convert the text to wide chars.
+                   allocate enough size buffer
+                */
+                tempbuf = (wchar_t *)malloc(sizeof(wchar_t)*(text->length+1));
+                if (tempbuf == NULL) {
+                    THROW_OUT_OF_MEMORY_ERROR();
+                    return;
+                }
+                ins_len = (int32_t)mbstowcs(tempbuf, text->string.multi_byte,
+                                   text->length);
+                if (ins_len == -1) {
+                        free(tempbuf);
+                        return;
+                }
+                ins_text = (void *)tempbuf;
+            }
+            else {
+                ins_len = text->length;
+                ins_text = text->string.wide_char;
+            }
+            /* finish prepare the data to be inserted */
+
+            statusWindow->peText =
+                    handle_buffer(cur_text, ins_text, sizeof(wchar_t),
+                                  cur_len, ins_len, chg_len, chg_1st);
+            statusWindow->peAttr =
+                    handle_buffer(cur_attr, text->feedback, sizeof(long),
+                                  cur_len, ins_len, chg_len, chg_1st);
+            statusWindow->peText[cur_len-chg_len+ins_len] =L'\0';
+
+            if (tempbuf != NULL)
+                free(tempbuf);
+        } /* endof insert or replace text */
+        else {
+            /* change attribute only */
+            memcpy(&cur_attr[chg_1st], text->feedback,
+                    sizeof(long)*text->length);
+        }
+    }
+    statusWindow->peCaret= pre_draw->caret;
+    draw_preedit(statusWindow);
+    if (statusWindow->on && wcslen(statusWindow->peText) > 0)
+        onoffStatusWindow(pX11IMData, statusWindow->parent, True);
+    else if (wcslen(statusWindow->status) == 0)
+        onoffStatusWindow(pX11IMData, 0, False);
+}
+
+/*
+ * reset predit test of passive mode
+ */
+static void
+resetPassivePreeditText(StatusWindow *statusWindow)
+{
+    if (NULL == statusWindow) return;
+    if(statusWindow->peText != NULL) {
+        free(statusWindow->peText);
+        statusWindow->peText = NULL;
+    }
+    if(statusWindow->peAttr != NULL) {
+        free(statusWindow->peAttr);
+        statusWindow->peAttr = NULL;
+    }
+    statusWindow->peCaret= 0;
+}
+
+static void draw_caret(StatusWindow *statusWindow, GC gc, int pos)
+{
+    if (NULL == statusWindow) return;
+    XSetFunction(dpy, gc, GXinvert);
+    XDrawLine(dpy, statusWindow->w,
+              gc, pos, STATUS_BORDER/2,
+              pos, STATUS_BORDER/2+statusWindow->fOff);
+    XSetFunction(dpy, gc, GXcopy);
+}
+
+static int  get_next_attr(int len, unsigned long *attr)
+{
+    int count;
+
+    for (count = 1; count < len; count++)  {
+        if ((attr[count-1] & PREEDIT_ATTR_MASK)
+            != (attr[count] & PREEDIT_ATTR_MASK))
+            break;
+    }
+    return count;
+}
+
+static void draw_preedit(StatusWindow *statusWindow)
+{
+    unsigned long *attr;
+    int x_pos,x_caret;
+    unsigned int  len;
+    int len_disp, pos;
+    wchar_t *str;
+    GC  gc;
+    XRectangle ink, rect, rect_c;
+    Bool caret_done = False;
+
+    if (NULL == statusWindow) return;
+    align_status(statusWindow);
+    XFillRectangle(dpy, statusWindow->w,
+                   statusWindow->bgGC,
+                   statusWindow->statusW,0,
+                   statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN,
+                   statusWindow->fBot+2);
+
+
+    XDrawLine(dpy, statusWindow->w, statusWindow->fgGC,
+              statusWindow->statusW, 0,
+              statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN, 0);
+    XDrawLine(dpy, statusWindow->w, statusWindow->fgGC,
+              statusWindow->statusW, statusWindow->fBot+2,
+              statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN,
+              statusWindow->fBot+2);
+    XDrawLine(dpy, statusWindow->w, statusWindow->fgGC,
+              statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN, 0,
+              statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN,
+              statusWindow->fBot+2);
+    if (0 == statusWindow->statusW)
+        XDrawLine(dpy, statusWindow->w, statusWindow->fgGC,
+                  0, 0, 0, statusWindow->fBot+2);
+
+    str =  statusWindow->peText;
+
+    if (str != NULL &&  (len = (int32_t)wcslen(str)) != 0) {
+        pos = 0;
+        attr = statusWindow->peAttr;
+        x_pos = x_caret = statusWindow->statusW + STATUS_BORDER;
+        while((int)len-1 >= pos) {
+            len_disp = get_next_attr(len - pos, &attr[pos]);
+            if (attr[pos] & XIMReverse) {
+                gc = statusWindow->bgGC;
+            }
+            else {
+                gc = statusWindow->fgGC;
+            }
+            XwcTextExtents(statusWindow->fontset,
+                           &str[pos],
+                           len_disp, &ink, &rect);
+            XwcDrawImageString(dpy, statusWindow->w,
+                               statusWindow->fontset, gc,
+                               x_pos, statusWindow->fOff+1, &str[pos], len_disp);
+            if (attr[pos] & XIMUnderline) {
+                XDrawLine(dpy, statusWindow->w,
+                          gc, x_pos, statusWindow->fBot,
+                          x_pos+rect.width, statusWindow->fBot);
+            }
+            if (!caret_done) {
+                if( statusWindow->peCaret >= pos &&
+                    statusWindow->peCaret <= pos+len_disp) {
+                    if (statusWindow->peCaret == 0)
+                        x_caret = x_pos;
+                    else if (statusWindow->peCaret == pos+len_disp)
+                        x_caret = x_pos+rect.width;
+                    else {
+                        XwcTextExtents(statusWindow->fontset,
+                                        &str[pos],
+                                        statusWindow->peCaret-pos,
+                                        &ink, &rect_c);
+                        x_caret = x_pos+ rect_c.width;
+                    }
+                    x_caret-=CARET_OFFSET;
+                    caret_done = True;
+                }
+            }
+            pos += len_disp;
+            x_pos += rect.width;
+        }
+        if (caret_done)
+            draw_caret(statusWindow, statusWindow->fgGC, x_caret);
+    }
+}
+
+/* calc required status window size and resize the window */
+static void align_status(StatusWindow *statusWindow)
+{
+    int len_st, len_pe = 0;
+    XRectangle rect_st, rect_pe, ink;
+    Dimension cur_w;
+    int value_make = CWX|CWWidth|CWHeight;
+    XWindowChanges xwc;
+
+    if (NULL == statusWindow) return;
+    if ((len_st = st_wcslen(statusWindow->status)) == 0
+        && (statusWindow->peText == NULL || st_wcslen(statusWindow->peText) == 0 ))
+        return;
+
+    rect_pe.x = rect_pe.y = rect_pe.width = rect_pe.height = 0;
+
+    XwcTextExtents(statusWindow->fontset,
+                   statusWindow->status,
+                   len_st, &ink, &rect_st);
+    if (statusWindow->peText != NULL
+        && (len_pe = (int32_t)wcslen(statusWindow->peText)) > 0) {
+        XwcTextExtents(statusWindow->fontset,
+                       statusWindow->peText,
+                       len_pe, &ink, &rect_pe);
+    }
+    statusWindow->fOff = max(-rect_st.y, -rect_pe.y);
+    statusWindow->fBot = max(rect_st.height, rect_pe.height);
+    statusWindow->statusW =rect_st.width;
+    if (rect_st.width > 0) statusWindow->statusW += BORDER_MARGIN;
+    statusWindow->peTextW = rect_pe.width;
+
+    xwc.x = statusWindow->x - statusWindow->off_x;
+    if (xwc.x < 0 ) xwc.x = 0;
+
+    if (len_pe > 0) {
+        xwc.width = statusWindow->statusW
+                    + statusWindow->peTextW + BORDER_MARGIN + 1;
+        xwc.height = statusWindow->fBot + BORDER_MARGIN;
+    } else {
+        xwc.width = statusWindow->statusW;
+        xwc.height = statusWindow->fBot + BORDER_MARGIN;
+    }
+    if (xwc.x + xwc.width > statusWindow->rootW){
+      xwc.x = statusWindow->rootW - xwc.width;
+    }
+    XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
+}
+
+static void shrink_status(StatusWindow *statusWindow)
+{
+    int value_make = CWX|CWWidth|CWHeight;
+    XWindowChanges xwc;
+
+    if (NULL == statusWindow) return;
+    xwc.width  = statusWindow->statusW;
+    xwc.height = statusWindow->statusH;
+    statusWindow->peTextW = 0;
+    xwc.x = statusWindow->x - statusWindow->off_x;
+    if (xwc.x < 0 ) xwc.x = 0;
+    if (xwc.x + xwc.width > statusWindow->rootW){
+      xwc.x = statusWindow->rootW - xwc.width;
+    }
+    XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
+}
+
+static GC create_gc(Window win, Bool isReverse)
+{
+    XGCValues xgcv;
+    unsigned long mask;
+    AwtScreenDataPtr defaultScreen;
+
+    defaultScreen = getScreenData(DefaultScreen(dpy));
+
+    mask = (GCForeground | GCBackground );
+    if (isReverse) {
+        xgcv.foreground = defaultScreen->whitepixel;
+        xgcv.background = defaultScreen->blackpixel;
+    } else {
+        xgcv.foreground = defaultScreen->blackpixel;
+        xgcv.background = defaultScreen->whitepixel;
+    }
+    return XCreateGC(dpy, win, mask, &xgcv);
+}
+
+static Bool isNativeIm()
+{
+#define XIMMODIFIER          "@im="
+#define XIM_SERVER_CATEGORY  "@server="
+    char *immodifiers;
+    char *imserver, *imserverPtr;
+    Atom imserverAtom;
+
+    if (!(immodifiers = getenv("XMODIFIERS"))) return True;
+    if (!(imserver = calloc(1,strlen(immodifiers)+strlen(XIM_SERVER_CATEGORY)+1))) return True;
+    if (!(immodifiers = strstr(immodifiers,XIMMODIFIER))) return True;
+    immodifiers += strlen(XIMMODIFIER);
+    strcpy(imserver,XIM_SERVER_CATEGORY);
+    imserverPtr = imserver + strlen(imserver);
+    while(*immodifiers != '@' && *immodifiers != '\0') {
+        *imserverPtr = *immodifiers;
+        imserverPtr++;
+        immodifiers++;
+    }
+    imserverAtom = XInternAtom(awt_display, imserver, True);
+    free(imserver);
+    if (imserverAtom > 0)
+        return False;
+    else
+        return True;
+}
+
+static Window getGrandParent(Window parent)
+{
+    Window containerWindow,rootWindow,tmp;
+    Window *ignoreWindowPtr;
+    unsigned int ignoreUnit;
+    Window grandParent=0;
+    XWindowAttributes xwa;
+    Atom WM_STATE;
+    Atom type = None;
+    int32_t format;
+    unsigned long nitems, after;
+    unsigned char * data;
+
+    if (parent == 0) return grandParent;
+    WM_STATE = XInternAtom(dpy, "WM_STATE", True);
+    if (WM_STATE == None) return grandParent;
+
+    tmp=parent;
+    while(XQueryTree(dpy, tmp,
+                     &rootWindow, &containerWindow,
+                     &ignoreWindowPtr, &ignoreUnit)){
+        XFree(ignoreWindowPtr);
+        if (containerWindow == rootWindow) break;
+        if (XGetWindowProperty(dpy, containerWindow, WM_STATE,
+                    0, 0, False, AnyPropertyType,
+                    &type, &format, &nitems, &after, &data) == Success) {
+            XFree(data);
+            if (type) {
+                XGetWindowAttributes(dpy, containerWindow, &xwa);
+                if (FALSE == xwa.override_redirect){
+                    grandParent=containerWindow;
+                }
+            }
+        }
+        tmp=containerWindow;
+    }
+    return grandParent;
+}
+
+static void moveStatusWindow(StatusWindow *statusWindow)
+{
+    XWindowAttributes xwa;
+    Window child;
+    int x, y, width;
+    Window target;
+
+    if (NULL == statusWindow) return;
+    if (statusWindow->grandParent) {
+        target = statusWindow->grandParent;
+    } else {
+        target = statusWindow->parent;
+    }
+    XGetWindowAttributes(dpy, target, &xwa);
+    XTranslateCoordinates(dpy,
+                          target, xwa.root,
+                          0, 0,
+                          &x, &y,
+                          &child);
+    if (statusWindow->x != x
+        || statusWindow->y != y
+        || statusWindow->width != xwa.width
+        || statusWindow->height != xwa.height){
+        statusWindow->x = x;
+        statusWindow->y = y;
+        statusWindow->height = xwa.height;
+        statusWindow->width = xwa.width;
+        x = statusWindow->x - statusWindow->off_x;
+        y = statusWindow->y + statusWindow->height + statusWindow->off_y;
+        if (x < 0 ){
+            x = 0;
+        }
+        if (statusWindow->peTextW > 0) {
+            width = statusWindow->statusW + statusWindow->peTextW + BORDER_MARGIN + 1;
+            if (x + width > statusWindow->rootW){
+                x = statusWindow->rootW - width;
+            }
+        } else {
+            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);
+    }
+}
+
+static void arrange_window_stack(StatusWindow* statusWindow)
+{
+    XWindowChanges xwc;
+    int value_make = CWSibling|CWStackMode;
+    Window root, parent, *children;
+    unsigned int nchildren;
+
+    if (NULL == statusWindow) return;
+    if (XQueryTree(dpy, statusWindow->parent,
+                       &root, &parent, &children, &nchildren)){
+        XFree(children);
+        xwc.sibling = parent;
+        while(XQueryTree(dpy, xwc.sibling, &root, &parent, &children, &nchildren)) {
+            XFree(children);
+            if (root != parent) {
+                xwc.sibling = parent;
+            } else {
+                break;
+            }
+        }
+        xwc.stack_mode = Above;
+        XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
+    }
+}
+
+static int count_missing_fonts(char **charset_list, int charset_count)
+{
+    int i,j;
+    if (charset_count > 0) {
+        j=charset_count;
+        for(i=0; i < charset_count; i++) {
+            if ((strstr(charset_list[i], "IBM-udc")) ||
+                (strstr(charset_list[i], "IBM-sbd")) ||
+                (strstr(charset_list[i], "IBM-ucdTW")))
+                j--;
+        }
+        return j;
+    }
+    else
+        return 0;
+}
+
+static XFontSet create_fontset_name(char * font_name, Bool force)
+{
+    XFontSet fontset = NULL;
+    char **charset_list;
+    int charset_count;
+    char *def_string;
+    int missing_fonts;
+
+    fontset = XCreateFontSet(dpy, font_name,
+                &charset_list, &charset_count, &def_string);
+    if (charset_count > 0) {
+        missing_fonts = count_missing_fonts(charset_list,
+                                            charset_count);
+        XFreeStringList(charset_list);
+        if (fontset && (missing_fonts > 0)) {
+            if (!force) {
+                XFreeFontSet(dpy, fontset);
+                fontset = NULL;
+            }
+        }
+    }
+    return fontset;
+}
+
+static XFontSet create_fontset()
+{
+    XFontSet fontset = NULL;
+    int i;
+    static char * fontlist[] = {
+        "-dt-interface user-medium-r-normal-S*-*-*-*-*-*-*-*-*",
+        "-*-*-medium-r-normal-*-14-*-*-*-c-*-*-*",
+        "-*-*-medium-r-normal-*-14-*-*-*-m-*-*-*",
+        "-*-*-medium-r-normal--14-0-0-0-m-*-*-*",
+        "-monotype-sansmonowt-medium-r-normal--14-*-*-*-m-*-*-*",
+        "-*--14-*",
+        "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*",
+        "-*--16-*",
+        "-*--17-*",
+        "-*--18-*",
+        "-*--19-*",
+        "-*--20-*",
+        "-*--24-*",
+        NULL};
+
+    for (i=0; fontlist[i] != NULL && fontset==NULL; i++)
+        fontset = create_fontset_name(fontlist[i], False);
+
+    if (!fontset)
+        fprintf(stdout, "Cannot load fonts for IMF.\n");
+    return  fontset;
+}
+
+static Window get_current_focus(XIC ic) {
+    Window w = 0;
+    if (ic != NULL)
+        XGetICValues(ic, XNFocusWindow, &w, NULL);
+    return w;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
+                                            jobject this,
+                                            jlong display)
+{
+    Bool registered;
+
+    AWT_LOCK();
+
+    dpy = (Display *)jlong_to_ptr(display);
+
+    if (X11im == NULL) {
+        X11im = XOpenIM(dpy, NULL, NULL, NULL);
+    }
+
+    AWT_UNLOCK();
+
+    return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
+                                              jobject this,
+                                              jlong window)
+{
+    X11InputMethodData *pX11IMData;
+    jobject globalRef;
+    XIC ic;
+
+    AWT_LOCK();
+
+    if (!window) {
+        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;
+    }
+
+    globalRef = (*env)->NewGlobalRef(env, this);
+    pX11IMData->x11inputmethod = globalRef;
+    pX11IMData->statusWindow = NULL;
+
+    setX11InputMethodData(env, this, pX11IMData);
+
+    if (createXIC(env, pX11IMData, (Window)window) == False) {
+        destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
+        pX11IMData = (X11InputMethodData *) NULL;
+        setX11InputMethodData(env, this, pX11IMData);
+        if ((*env)->ExceptionCheck(env)) {
+            goto finally;
+        }
+    }
+
+finally:
+    AWT_UNLOCK();
+    return (pX11IMData != NULL);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
+                                                jobject this,
+                                                jlong w,
+                                                jboolean req,
+                                                jboolean active)
+{
+    X11InputMethodData *pX11IMData;
+    AWT_LOCK();
+    pX11IMData = getX11InputMethodData(env, this);
+    if (pX11IMData == NULL) {
+        AWT_UNLOCK();
+        return;
+    }
+
+    if (req) {
+        if (!w) {
+            AWT_UNLOCK();
+            return;
+        }
+        pX11IMData->isActiveClient = active;
+        pX11IMData->current_ic = active ?
+                        pX11IMData->ic_active : pX11IMData->ic_passive;
+        /*
+         * On Solaris2.6, setXICWindowFocus() has to be invoked
+         * before setting focus.
+         */
+        get_current_focus(pX11IMData->current_ic); /* workaround for kinput2 and SCIM */
+        if (currentFocusWindow != w) {
+            setXICWindowFocus(pX11IMData->current_ic, w);
+            setXICFocus(pX11IMData->current_ic, req);
+            currentX11InputMethodInstance = pX11IMData->x11inputmethod;
+            currentFocusWindow =  w;
+        } else {
+            setXICFocus(pX11IMData->current_ic, req);
+        }
+        if ((active || pX11IMData->passiveStatusWindow)
+            && (pX11IMData->statusWindow && pX11IMData->statusWindow->on))
+            onoffStatusWindow(pX11IMData, w, True);
+    } else {
+        currentX11InputMethodInstance = NULL;
+        currentFocusWindow = 0;
+        onoffStatusWindow(pX11IMData, 0, False);
+        if (pX11IMData->current_ic != NULL)
+        setXICFocus(pX11IMData->current_ic, req);
+
+        pX11IMData->current_ic = (XIC)0;
+    }
+
+    XFlush(dpy);
+    AWT_UNLOCK();
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * 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_X11InputMethodBase_initIDs
+  (JNIEnv *env, jclass cls)
+{
+    x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    turnoffStatusWindow
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_turnoffStatusWindow
+  (JNIEnv *env, jobject this)
+{
+    X11InputMethodData *pX11IMData;
+    StatusWindow *statusWindow;
+
+    AWT_LOCK();
+
+    if (NULL == currentX11InputMethodInstance
+        || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
+        || NULL == (statusWindow = pX11IMData->statusWindow)
+        || !statusWindow->on ){
+        AWT_UNLOCK();
+        return;
+    }
+    onoffStatusWindow(pX11IMData, 0, False);
+    statusWindow->on = False;
+
+    AWT_UNLOCK();
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    disposeXIC
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_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();
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    resetXIC
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_awt_X11InputMethodBase_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) {
+        if (!isPreeditStateActive(pX11IMData->current_ic)) {
+            xText = NULL;
+        } else {
+            if (!(pX11IMData->forceReset))
+                setXICFocus(pX11IMData->current_ic, FALSE);
+            xText = XmbResetIC(pX11IMData->current_ic);
+            if (!(pX11IMData->forceReset))
+                setXICFocus(pX11IMData->current_ic, TRUE);
+        }
+    } else {
+        /*
+         * If there is no reference to the current XIC, try to reset both XICs.
+         */
+        if (!isPreeditStateActive(pX11IMData->ic_active))
+            xText = NULL;
+        else
+        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;
+            if (!isPreeditStateActive(pX11IMData->ic_passive))
+                tmpText = NULL;
+            else
+                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);
+    }
+
+    /* workaround
+     * Some IME do not call PreeditDoneCallback routine even
+     * when XmbResetIC is called. I force to reset the preedit string.
+     */
+    if (!pX11IMData->isActiveClient) {
+        resetPassivePreeditText(pX11IMData->statusWindow);
+        shrink_status(pX11IMData->statusWindow);
+    } else {
+        JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
+                             "clearComposedText",
+                             "()V");
+        if ((*env)->ExceptionOccurred(env)) {
+            (*env)->ExceptionDescribe(env);
+            (*env)->ExceptionClear(env);
+        }
+    }
+
+    AWT_UNLOCK();
+    return jText;
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    setCompositionEnabledNative
+ * Signature: (Z)Z
+ *
+ * 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_X11InputMethodBase_setCompositionEnabledNative
+  (JNIEnv *env, jobject this, jboolean enable)
+{
+    X11InputMethodData *pX11IMData;
+    char * ret = NULL;
+    XVaNestedList pr_atrb;
+
+    AWT_LOCK();
+    pX11IMData = getX11InputMethodData(env, this);
+
+    if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
+        AWT_UNLOCK();
+        return JNI_FALSE;
+    }
+
+    pr_atrb = XVaCreateNestedList(0, XNPreeditState,
+                  (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
+    ret = XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL);
+    XFree((void *)pr_atrb);
+    AWT_UNLOCK();
+
+    if ((ret != 0) &&
+        ((strcmp(ret, XNPreeditAttributes) == 0)
+         || (strcmp(ret, XNPreeditState) == 0))) {
+        JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+    }
+
+    return (jboolean)(ret == 0);
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    isCompositionEnabledNative
+ * Signature: ()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_X11InputMethodBase_isCompositionEnabledNative
+  (JNIEnv *env, jobject this)
+{
+    X11InputMethodData *pX11IMData = NULL;
+    char * ret = NULL;
+    XIMPreeditState state = XIMPreeditUnKnown;
+    XVaNestedList   pr_atrb;
+
+    AWT_LOCK();
+    pX11IMData = getX11InputMethodData(env, this);
+
+    if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
+        AWT_UNLOCK();
+        return JNI_FALSE;
+    }
+
+    pr_atrb = XVaCreateNestedList(0, XNPreeditState, &state, NULL);
+    ret = XGetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL);
+    XFree((void *)pr_atrb);
+    AWT_UNLOCK();
+
+    if ((ret != 0) &&
+        ((strcmp(ret, XNPreeditAttributes) == 0)
+         || (strcmp(ret, XNPreeditState) == 0))) {
+        JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
+        return JNI_FALSE;
+    }
+
+    return (jboolean)(state == XIMPreeditEnable);
+}
+
+JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
+  (JNIEnv *env, jobject this, jlong window)
+{
+
+}
+
+/*
+ * Class:     sun_awt_X11InputMethod
+ * Method:    setStatusAreaVisible
+ * Signature: (ZJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11InputMethod_setStatusAreaVisible
+  (JNIEnv *env, jobject this, jboolean value, jlong data)
+{
+    X11InputMethodData *pX11IMData;
+
+    pX11IMData = getX11InputMethodData(env, this);
+    if (NULL == pX11IMData) return;
+    if (NULL == pX11IMData->statusWindow) return;
+
+    if ((int)value){
+        pX11IMData->statusWindow->on = True;
+    }else{
+        pX11IMData->statusWindow->on = False;
+    }
+    return;
+}
--- a/src/java.desktop/unix/classes/sun/awt/X11InputMethod.java	Tue May 29 11:22:21 2018 -0700
+++ b/src/java.desktop/unix/classes/sun/awt/X11InputMethod.java	Wed May 30 08:19:59 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -25,147 +25,21 @@
 
 package sun.awt;
 
-import java.util.Collections;
-import java.util.Locale;
-import java.util.Map;
-import java.util.HashMap;
-import java.awt.AWTEvent;
 import java.awt.AWTException;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.EventQueue;
-import java.awt.Window;
-import java.awt.im.InputMethodHighlight;
-import java.awt.im.spi.InputMethodContext;
-import sun.awt.im.InputMethodAdapter;
 import java.awt.event.InputMethodEvent;
 import java.awt.font.TextAttribute;
 import java.awt.font.TextHitInfo;
 import java.awt.peer.ComponentPeer;
-import java.lang.Character.Subset;
 import java.text.AttributedString;
-import java.text.AttributedCharacterIterator;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
 import sun.util.logging.PlatformLogger;
-import java.util.StringTokenizer;
-import java.util.regex.Pattern;
-
 
 /**
  * Input Method Adapter for XIM
  *
  * @author JavaSoft International
  */
-public abstract class X11InputMethod extends InputMethodAdapter {
-    private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11InputMethod");
-    /*
-     * The following XIM* values must be the same as those defined in
-     * Xlib.h
-     */
-    private static final int XIMReverse = (1<<0);
-    private static final int XIMUnderline = (1<<1);
-    private static final int XIMHighlight = (1<<2);
-    private static final int XIMPrimary = (1<<5);
-    private static final int XIMSecondary = (1<<6);
-    private static final int XIMTertiary = (1<<7);
-
-    /*
-     * visible position values
-     */
-    private static final int XIMVisibleToForward = (1<<8);
-    private static final int XIMVisibleToBackward = (1<<9);
-    private static final int XIMVisibleCenter = (1<<10);
-    private static final int XIMVisibleMask = (XIMVisibleToForward|
-                                               XIMVisibleToBackward|
-                                               XIMVisibleCenter);
-
-    private Locale locale;
-    private static boolean isXIMOpened = false;
-    protected Container clientComponentWindow = null;
-    private Component awtFocussedComponent = null;
-    private Component lastXICFocussedComponent = null;
-    private boolean   isLastXICActive = false;
-    private boolean   isLastTemporary = false;
-    private boolean   isActive = false;
-    private boolean   isActiveClient = false;
-    private static Map<TextAttribute, ?>[] highlightStyles;
-    private boolean disposed = false;
-
-    //reset the XIC if necessary
-    private boolean   needResetXIC = false;
-    private WeakReference<Component> needResetXICClient = new WeakReference<>(null);
-
-    // The use of compositionEnableSupported is to reduce unnecessary
-    // native calls if set/isCompositionEnabled
-    // throws UnsupportedOperationException.
-    // It is set to false if that exception is thrown first time
-    // either of the two methods are called.
-    private boolean compositionEnableSupported = true;
-    // The savedCompositionState indicates the composition mode when
-    // endComposition or setCompositionEnabled is called. It doesn't always
-    // reflect the actual composition state because it doesn't get updated
-    // when the user changes the composition state through direct interaction
-    // with the input method. It is used to save the composition mode when
-    // focus is traversed across different client components sharing the
-    // same java input context. Also if set/isCompositionEnabled are not
-    // supported, it remains false.
-    private boolean savedCompositionState = false;
-
-    // variables to keep track of preedit context.
-    // these variables need to be accessed within AWT_LOCK/UNLOCK
-    private String committedText = null;
-    private StringBuffer composedText = null;
-    private IntBuffer rawFeedbacks;
-
-    // private data (X11InputMethodData structure defined in
-    // awt_InputMethod.c) for native methods
-    // this structure needs to be accessed within AWT_LOCK/UNLOCK
-    private transient long pData = 0; // accessed by native
-
-    // Initialize highlight mapping table
-    static {
-        @SuppressWarnings({"unchecked", "rawtypes"})
-        Map<TextAttribute, ?> styles[] = new Map[4];
-        HashMap<TextAttribute, Object> map;
-
-        // UNSELECTED_RAW_TEXT_HIGHLIGHT
-        map = new HashMap<>(1);
-        map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-        styles[0] = Collections.unmodifiableMap(map);
-
-        // SELECTED_RAW_TEXT_HIGHLIGHT
-        map = new HashMap<>(1);
-        map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
-        styles[1] = Collections.unmodifiableMap(map);
-
-        // UNSELECTED_CONVERTED_TEXT_HIGHLIGHT
-        map = new HashMap<>(1);
-        map.put(TextAttribute.INPUT_METHOD_UNDERLINE,
-                TextAttribute.UNDERLINE_LOW_ONE_PIXEL);
-        styles[2] = Collections.unmodifiableMap(map);
-
-        // SELECTED_CONVERTED_TEXT_HIGHLIGHT
-        map = new HashMap<>(1);
-        map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
-        styles[3] = Collections.unmodifiableMap(map);
-
-        highlightStyles = styles;
-    }
-
-    static {
-        initIDs();
-    }
-
-    /**
-     * Initialize JNI field and method IDs for fields that may be
-       accessed from C.
-     */
-    private static native void initIDs();
+public abstract class X11InputMethod extends X11InputMethodBase {
 
     /**
      * Constructs an X11InputMethod instance. It initializes the XIM
@@ -174,113 +48,13 @@
      * @exception AWTException if XOpenIM() failed.
      */
     public X11InputMethod() throws AWTException {
-        // supports only the locale in which the VM is started
-        locale = X11InputMethodDescriptor.getSupportedLocale();
-        if (initXIM() == false) {
-            throw new AWTException("Cannot open X Input Method");
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void finalize() throws Throwable {
-        dispose();
-        super.finalize();
-    }
-
-    /**
-     * Invokes openIM() that invokes XOpenIM() if it's not opened yet.
-     * @return  true if openXIM() is successful or it's already been opened.
-     */
-    private synchronized boolean initXIM() {
-        if (isXIMOpened == false)
-            isXIMOpened = openXIM();
-        return isXIMOpened;
-    }
-
-    protected abstract boolean openXIM();
-
-    protected boolean isDisposed() {
-        return disposed;
-    }
-
-    protected abstract void setXICFocus(ComponentPeer peer,
-                                    boolean value, boolean active);
-
-    /**
-     * Does nothing - this adapter doesn't use the input method context.
-     *
-     * @see java.awt.im.spi.InputMethod#setInputMethodContext
-     */
-    public void setInputMethodContext(InputMethodContext context) {
-    }
-
-    /**
-     * Set locale to input. If input method doesn't support specified locale,
-     * false will be returned and its behavior is not changed.
-     *
-     * @param lang locale to input
-     * @return the true is returned when specified locale is supported.
-     */
-    public boolean setLocale(Locale lang) {
-        if (lang.equals(locale)) {
-            return true;
-        }
-        // special compatibility rule for Japanese and Korean
-        if (locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
-                locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns current input locale.
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Does nothing - XIM doesn't let you specify which characters you expect.
-     *
-     * @see java.awt.im.spi.InputMethod#setCharacterSubsets
-     */
-    public void setCharacterSubsets(Subset[] subsets) {
-    }
-
-    /**
-     * Dispatch event to input method. InputContext dispatch event with this
-     * method. Input method set consume flag if event is consumed in
-     * input method.
-     *
-     * @param e event
-     */
-    public void dispatchEvent(AWTEvent e) {
-    }
-
-
-    protected final void resetXICifneeded(){
-        /* needResetXIC is used to indicate whether to call
-           resetXIC on the active client. resetXIC will always be
-           called on the passive client when endComposition is called.
-        */
-        if (needResetXIC && haveActiveClient() &&
-            getClientComponent() != needResetXICClient.get()){
-            resetXIC();
-
-            // needs to reset the last xic focussed component.
-            lastXICFocussedComponent = null;
-            isLastXICActive = false;
-
-            needResetXICClient.clear();
-            needResetXIC = false;
-        }
+        super();
     }
 
     /**
      * Reset the composition state to the current composition state.
      */
-    private void resetCompositionState() {
+    protected void resetCompositionState() {
         if (compositionEnableSupported) {
             try {
                 /* Restore the composition mode to the last saved composition
@@ -293,23 +67,6 @@
     }
 
     /**
-     * Query and then return the current composition state.
-     * @return the composition state if isCompositionEnabled call
-     * is successful. Otherwise, it returns false.
-     */
-    private boolean getCompositionState() {
-        boolean compositionState = false;
-        if (compositionEnableSupported) {
-            try {
-                compositionState = isCompositionEnabled();
-            } catch (UnsupportedOperationException e) {
-                compositionEnableSupported = false;
-            }
-        }
-        return compositionState;
-    }
-
-    /**
      * Activate input method.
      */
     public synchronized void activate() {
@@ -317,7 +74,7 @@
         if (clientComponentWindow == null)
             return;
 
-        if (lastXICFocussedComponent != null){
+        if (lastXICFocussedComponent != null) {
             if (log.isLoggable(PlatformLogger.Level.FINE)) {
                 log.fine("XICFocused {0}, AWTFocused {1}",
                          lastXICFocussedComponent, awtFocussedComponent);
@@ -360,8 +117,6 @@
         isActive = true;
     }
 
-    protected abstract boolean createXIC();
-
     /**
      * Deactivate input method.
      */
@@ -387,198 +142,26 @@
         */
         savedCompositionState = getCompositionState();
 
-        if (isTemporary){
+        if (isTemporary) {
             //turn the status window off...
             turnoffStatusWindow();
         }
 
         /* Delay resetting the XIC focus until activate is called and the newly
-           focussed component has a different peer as the last focussed component.
-        */
+         * Focused component has a different peer as the last focused component.
+         */
         lastXICFocussedComponent = awtFocussedComponent;
         isLastXICActive = isAc;
         isLastTemporary = isTemporary;
         isActive = false;
     }
 
-    /**
-     * Explicitly disable the native IME. Native IME is not disabled when
-     * deactivate is called.
-     */
-    public void disableInputMethod() {
-        if (lastXICFocussedComponent != null) {
-            setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
-            lastXICFocussedComponent = null;
-            isLastXICActive = false;
-
-            resetXIC();
-            needResetXICClient.clear();
-            needResetXIC = false;
-        }
-    }
-
     // implements java.awt.im.spi.InputMethod.hideWindows
     public void hideWindows() {
         // ??? need real implementation
     }
 
     /**
-     * @see java.awt.Toolkit#mapInputMethodHighlight
-     */
-    public static Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) {
-        int index;
-        int state = highlight.getState();
-        if (state == InputMethodHighlight.RAW_TEXT) {
-            index = 0;
-        } else if (state == InputMethodHighlight.CONVERTED_TEXT) {
-            index = 2;
-        } else {
-            return null;
-        }
-        if (highlight.isSelected()) {
-            index += 1;
-        }
-        return highlightStyles[index];
-    }
-
-    /**
-     * @see sun.awt.im.InputMethodAdapter#setAWTFocussedComponent
-     */
-    protected void setAWTFocussedComponent(Component component) {
-        if (component == null) {
-            return;
-        }
-        if (isActive) {
-            // deactivate/activate are being suppressed during a focus change -
-            // this may happen when an input method window is made visible
-            boolean ac = haveActiveClient();
-            setXICFocus(getPeer(awtFocussedComponent), false, ac);
-            setXICFocus(getPeer(component), true, ac);
-        }
-        awtFocussedComponent = component;
-    }
-
-    /**
-     * @see sun.awt.im.InputMethodAdapter#stopListening
-     */
-    protected void stopListening() {
-        // It is desirable to disable XIM by calling XSetICValues with
-        // XNPreeditState == XIMPreeditDisable.  But Solaris 2.6 and
-        // Solaris 7 do not implement this correctly without a patch,
-        // so just call resetXIC here.  Prior endComposition call commits
-        // the existing composed text.
-        endComposition();
-        // disable the native input method so that the other input
-        // method could get the input focus.
-        disableInputMethod();
-        if (needResetXIC) {
-            resetXIC();
-            needResetXICClient.clear();
-            needResetXIC = false;
-        }
-    }
-
-    /**
-     * Returns the Window instance in which the client component is
-     * contained. If not found, null is returned. (IS THIS POSSIBLE?)
-     */
-    // NOTE: This method may be called by privileged threads.
-    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
-    private Window getClientComponentWindow() {
-        Component client = getClientComponent();
-        Container container;
-
-        if (client instanceof Container) {
-            container = (Container) client;
-        } else {
-            container = getParent(client);
-        }
-
-        while (container != null && !(container instanceof java.awt.Window)) {
-            container = getParent(container);
-        }
-        return (Window) container;
-    }
-
-    protected abstract Container getParent(Component client);
-
-    /**
-     * Returns peer of the given client component. If the given client component
-     * doesn't have peer, peer of the native container of the client is returned.
-     */
-    protected abstract ComponentPeer getPeer(Component client);
-
-    /**
-     * Used to protect preedit data
-     */
-    protected abstract void awtLock();
-    protected abstract void awtUnlock();
-
-    /**
-     * Creates an input method event from the arguments given
-     * and posts it on the AWT event queue. For arguments,
-     * see InputMethodEvent. Called by input method.
-     *
-     * @see java.awt.event.InputMethodEvent#InputMethodEvent
-     */
-    private void postInputMethodEvent(int id,
-                                      AttributedCharacterIterator text,
-                                      int committedCharacterCount,
-                                      TextHitInfo caret,
-                                      TextHitInfo visiblePosition,
-                                      long when) {
-        Component source = getClientComponent();
-        if (source != null) {
-            InputMethodEvent event = new InputMethodEvent(source,
-                id, when, text, committedCharacterCount, caret, visiblePosition);
-            SunToolkit.postEvent(SunToolkit.targetToAppContext(source), (AWTEvent)event);
-        }
-    }
-
-    private void postInputMethodEvent(int id,
-                                      AttributedCharacterIterator text,
-                                      int committedCharacterCount,
-                                      TextHitInfo caret,
-                                      TextHitInfo visiblePosition) {
-        postInputMethodEvent(id, text, committedCharacterCount,
-                             caret, visiblePosition, EventQueue.getMostRecentEventTime());
-    }
-
-    /**
-     * Dispatches committed text from XIM to the awt event queue. This
-     * method is invoked from the event handler in canvas.c in the
-     * AWT Toolkit thread context and thus inside the AWT Lock.
-     * @param   str     committed text
-     * @param   when    when
-     */
-    // NOTE: This method may be called by privileged threads.
-    //       This functionality is implemented in a package-private method
-    //       to insure that it cannot be overridden by client subclasses.
-    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
-    void dispatchCommittedText(String str, long when) {
-        if (str == null)
-            return;
-
-        if (composedText == null) {
-            AttributedString attrstr = new AttributedString(str);
-            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
-                                 attrstr.getIterator(),
-                                 str.length(),
-                                 null,
-                                 null,
-                                 when);
-        } else {
-            // if there is composed text, wait until the preedit
-            // callback is invoked.
-            committedText = str;
-        }
-    }
-
-    private void dispatchCommittedText(String str) {
-        dispatchCommittedText(str, EventQueue.getMostRecentEventTime());
-    }
-
-    /**
      * Updates composed text with XIM preedit information and
      * posts composed text to the awt event queue. The args of
      * this method correspond to the XIM preedit callback
@@ -601,7 +184,7 @@
             return;
         }
 
-        //Workaround for deadlock bug on solaris2.6_zh bug#4170760
+        // Workaround for deadlock bug on solaris2.6_zh bug#4170760
         if (chgText == null
             && chgStyles == null
             && chgOffset == 0
@@ -739,34 +322,6 @@
                              when);
     }
 
-    /**
-     * Flushes composed and committed text held in this context.
-     * This method is invoked in the AWT Toolkit (X event loop) thread context
-     * and thus inside the AWT Lock.
-     */
-    // NOTE: This method may be called by privileged threads.
-    //       This functionality is implemented in a package-private method
-    //       to insure that it cannot be overridden by client subclasses.
-    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
-    void flushText() {
-        String flush = (committedText != null ? committedText : "");
-        if (composedText != null) {
-            flush += composedText.toString();
-        }
-
-        if (!flush.equals("")) {
-            AttributedString attrstr = new AttributedString(flush);
-            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
-                                 attrstr.getIterator(),
-                                 flush.length(),
-                                 null,
-                                 null,
-                                 EventQueue.getMostRecentEventTime());
-            composedText = null;
-            committedText = null;
-        }
-    }
-
     /*
      * Subclasses should override disposeImpl() instead of dispose(). Client
      * code should always invoke dispose(), never disposeImpl().
@@ -783,43 +338,6 @@
     }
 
     /**
-     * Frees all X Window resources associated with this object.
-     *
-     * @see java.awt.im.spi.InputMethod#dispose
-     */
-    public final void dispose() {
-        boolean call_disposeImpl = false;
-
-        if (!disposed) {
-            synchronized (this) {
-                if (!disposed) {
-                    disposed = call_disposeImpl = true;
-                }
-            }
-        }
-
-        if (call_disposeImpl) {
-            disposeImpl();
-        }
-    }
-
-    /**
-     * Returns null.
-     *
-     * @see java.awt.im.spi.InputMethod#getControlObject
-     */
-    public Object getControlObject() {
-        return null;
-    }
-
-    /**
-     * @see java.awt.im.spi.InputMethod#removeNotify
-     */
-    public synchronized void removeNotify() {
-        dispose();
-    }
-
-    /**
      * @see java.awt.im.spi.InputMethod#setCompositionEnabled(boolean)
      */
     public void setCompositionEnabled(boolean enable) {
@@ -835,263 +353,4 @@
             savedCompositionState = enable;
         }
     }
-
-    /**
-     * @see java.awt.im.spi.InputMethod#isCompositionEnabled
-     */
-    public boolean isCompositionEnabled() {
-        /* isCompositionEnabledNative may throw UnsupportedOperationException.
-           Don't try to catch it since this method may be called by clients.
-           Use package private method 'getCompositionState' if you want the
-           exception to be caught.
-        */
-        return isCompositionEnabledNative();
-    }
-
-    /**
-     * Ends any input composition that may currently be going on in this
-     * context. Depending on the platform and possibly user preferences,
-     * this may commit or delete uncommitted text. Any changes to the text
-     * are communicated to the active component using an input method event.
-     *
-     * <p>
-     * A text editing component may call this in a variety of situations,
-     * for example, when the user moves the insertion point within the text
-     * (but outside the composed text), or when the component's text is
-     * saved to a file or copied to the clipboard.
-     *
-     */
-    public void endComposition() {
-        if (disposed) {
-            return;
-        }
-
-        /* Before calling resetXIC, record the current composition mode
-           so that it can be restored later. */
-        savedCompositionState = getCompositionState();
-        boolean active = haveActiveClient();
-        if (active && composedText == null && committedText == null){
-            needResetXIC = true;
-            needResetXICClient = new WeakReference<>(getClientComponent());
-            return;
-        }
-
-        String text = resetXIC();
-        /* needResetXIC is only set to true for active client. So passive
-           client should not reset the flag to false. */
-        if (active) {
-            needResetXIC = false;
-        }
-
-        // Remove any existing composed text by posting an InputMethodEvent
-        // with null composed text.  It would be desirable to wait for a
-        // dispatchComposedText call from X input method engine, but some
-        // input method does not conform to the XIM specification and does
-        // not call the preedit callback to erase preedit text on calling
-        // XmbResetIC.  To work around this problem, do it here by ourselves.
-        awtLock();
-        composedText = null;
-        postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
-                             null,
-                             0,
-                             null,
-                             null);
-
-        if (text != null && text.length() > 0) {
-            dispatchCommittedText(text);
-        }
-        awtUnlock();
-
-        // Restore the preedit state if it was enabled
-        if (savedCompositionState) {
-            resetCompositionState();
-        }
-    }
-
-    /**
-     * Returns a string with information about the current input method server, or null.
-     * On both Linux & SunOS, the value of environment variable XMODIFIERS is
-     * returned if set. Otherwise, on SunOS, $HOME/.dtprofile will be parsed
-     * to find out the language service engine (atok or wnn) since there is
-     * no API in Xlib which returns the information of native
-     * IM server or language service and we want to try our best to return as much
-     * information as possible.
-     *
-     * Note: This method could return null on Linux if XMODIFIERS is not set properly or
-     * if any IOException is thrown.
-     * See man page of XSetLocaleModifiers(3X11) for the usgae of XMODIFIERS,
-     * atok12setup(1) and wnn6setup(1) for the information written to
-     * $HOME/.dtprofile when you run these two commands.
-     *
-     */
-    public String getNativeInputMethodInfo() {
-        String xmodifiers = System.getenv("XMODIFIERS");
-        String imInfo = null;
-
-        // If XMODIFIERS is set, return the value
-        if (xmodifiers != null) {
-            int imIndex = xmodifiers.indexOf("@im=");
-            if (imIndex != -1) {
-                imInfo = xmodifiers.substring(imIndex + 4);
-            }
-        } else if (System.getProperty("os.name").startsWith("SunOS")) {
-            File dtprofile = new File(System.getProperty("user.home") +
-                                      "/.dtprofile");
-            String languageEngineInfo = null;
-            try {
-                BufferedReader br = new BufferedReader(new FileReader(dtprofile));
-                String line = null;
-
-                while ( languageEngineInfo == null && (line = br.readLine()) != null) {
-                    if (line.contains("atok") || line.contains("wnn")) {
-                        StringTokenizer tokens =  new StringTokenizer(line);
-                        while (tokens.hasMoreTokens()) {
-                            String token = tokens.nextToken();
-                            if (Pattern.matches("atok.*setup", token) ||
-                                Pattern.matches("wnn.*setup", token)){
-                                languageEngineInfo = token.substring(0, token.indexOf("setup"));
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                br.close();
-            } catch(IOException ioex) {
-                // Since this method is provided for internal testing only,
-                // we dump the stack trace for the ease of debugging.
-                ioex.printStackTrace();
-            }
-
-            imInfo = "htt " + languageEngineInfo;
-        }
-
-        return imInfo;
-    }
-
-
-    /**
-     * Performs mapping from an XIM visible feedback value to Java IM highlight.
-     * @return Java input method highlight
-     */
-    private InputMethodHighlight convertVisualFeedbackToHighlight(int feedback) {
-        InputMethodHighlight highlight;
-
-        switch (feedback) {
-        case XIMUnderline:
-            highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
-            break;
-        case XIMReverse:
-            highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
-            break;
-        case XIMHighlight:
-            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
-            break;
-        case XIMPrimary:
-            highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
-            break;
-        case XIMSecondary:
-            highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
-            break;
-        case XIMTertiary:
-            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
-            break;
-        default:
-            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
-            break;
-        }
-        return highlight;
-    }
-
-    // initial capacity size for string buffer, etc.
-    private static final int INITIAL_SIZE = 64;
-
-    /**
-     * IntBuffer is an inner class that manipulates an int array and
-     * provides UNIX file io stream-like programming interfaces to
-     * access it. (An alternative would be to use ArrayList which may
-     * be too expensive for the work.)
-     */
-    private final class IntBuffer {
-        private int[] intArray;
-        private int size;
-        private int index;
-
-        IntBuffer(int initialCapacity) {
-            intArray = new int[initialCapacity];
-            size = 0;
-            index = 0;
-        }
-
-        void insert(int offset, int[] values) {
-            int newSize = size + values.length;
-            if (intArray.length < newSize) {
-                int[] newIntArray = new int[newSize * 2];
-                System.arraycopy(intArray, 0, newIntArray, 0, size);
-                intArray = newIntArray;
-            }
-            System.arraycopy(intArray, offset, intArray, offset+values.length,
-                             size - offset);
-            System.arraycopy(values, 0, intArray, offset, values.length);
-            size += values.length;
-            if (index > offset)
-                index = offset;
-        }
-
-        void remove(int offset, int length) {
-            if (offset + length != size)
-                System.arraycopy(intArray, offset+length, intArray, offset,
-                                 size - offset - length);
-            size -= length;
-            if (index > offset)
-                index = offset;
-        }
-
-        void replace(int offset, int[] values) {
-            System.arraycopy(values, 0, intArray, offset, values.length);
-        }
-
-        void removeAll() {
-            size = 0;
-            index = 0;
-        }
-
-        void rewind() {
-            index = 0;
-        }
-
-        int getNext() {
-            if (index == size)
-                return -1;
-            return intArray[index++];
-        }
-
-        void unget() {
-            if (index != 0)
-                index--;
-        }
-
-        int getOffset() {
-            return index;
-        }
-
-        public String toString() {
-            StringBuffer s = new StringBuffer();
-            for (int i = 0; i < size;) {
-                s.append(intArray[i++]);
-                if (i < size)
-                    s.append(",");
-            }
-            return s.toString();
-        }
-    }
-
-    /*
-     * Native methods
-     */
-    private native String resetXIC();
-    private native void disposeXIC();
-    private native boolean setCompositionEnabledNative(boolean enable);
-    private native boolean isCompositionEnabledNative();
-    private native void turnoffStatusWindow();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java	Wed May 30 08:19:59 2018 +0200
@@ -0,0 +1,849 @@
+/*
+ * Copyright (c) 1997, 2018, 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.
+ */
+
+package sun.awt;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.EventQueue;
+import java.awt.Window;
+import java.awt.event.InputMethodEvent;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodHighlight;
+import java.awt.im.spi.InputMethodContext;
+import java.awt.peer.ComponentPeer;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.Character.Subset;
+import java.lang.ref.WeakReference;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+
+import sun.awt.im.InputMethodAdapter;
+import sun.util.logging.PlatformLogger;
+
+/**
+ * Input Method Adapter for XIM
+ *
+ * @author JavaSoft International
+ */
+public abstract class X11InputMethodBase extends InputMethodAdapter {
+    protected static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11InputMethod");
+    /*
+     * The following XIM* values must be the same as those defined in
+     * Xlib.h
+     */
+    private static final int XIMReverse = (1<<0);
+    private static final int XIMUnderline = (1<<1);
+    private static final int XIMHighlight = (1<<2);
+    private static final int XIMPrimary = (1<<5);
+    private static final int XIMSecondary = (1<<6);
+    private static final int XIMTertiary = (1<<7);
+
+    /*
+     * visible position values
+     */
+    protected static final int XIMVisibleToForward = (1<<8);
+    protected static final int XIMVisibleToBackward = (1<<9);
+    protected static final int XIMVisibleCenter = (1<<10);
+    protected static final int XIMVisibleMask =
+        (XIMVisibleToForward | XIMVisibleToBackward | XIMVisibleCenter);
+
+    private Locale locale;
+    private static boolean isXIMOpened = false;
+    protected Container clientComponentWindow = null;
+    protected Component awtFocussedComponent = null;
+    protected Component lastXICFocussedComponent = null;
+    protected boolean   isLastXICActive = false;
+    protected boolean   isLastTemporary = false;
+    protected boolean   isActive = false;
+    private static Map<TextAttribute, ?>[] highlightStyles;
+    protected boolean disposed = false;
+
+    //reset the XIC if necessary
+    protected boolean   needResetXIC = false;
+    private WeakReference<Component> needResetXICClient = new WeakReference<>(null);
+
+    // The use of compositionEnableSupported is to reduce unnecessary
+    // native calls if set/isCompositionEnabled
+    // throws UnsupportedOperationException.
+    // It is set to false if that exception is thrown first time
+    // either of the two methods are called.
+    protected boolean compositionEnableSupported = true;
+    // The savedCompositionState indicates the composition mode when
+    // endComposition or setCompositionEnabled is called. It doesn't always
+    // reflect the actual composition state because it doesn't get updated
+    // when the user changes the composition state through direct interaction
+    // with the input method. It is used to save the composition mode when
+    // focus is traversed across different client components sharing the
+    // same java input context. Also if set/isCompositionEnabled are not
+    // supported, it remains false.
+    protected boolean savedCompositionState = false;
+
+    // variables to keep track of preedit context.
+    // these variables need to be accessed within AWT_LOCK/UNLOCK
+    protected String committedText = null;
+    protected StringBuffer composedText = null;
+    protected IntBuffer rawFeedbacks;
+
+    // private data (X11InputMethodData structure defined in
+    // awt_InputMethod.c) for native methods
+    // this structure needs to be accessed within AWT_LOCK/UNLOCK
+    protected transient long pData = 0; // accessed by native
+
+    // Initialize highlight mapping table
+    static {
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        Map<TextAttribute, ?> styles[] = new Map[4];
+        HashMap<TextAttribute, Object> map;
+
+        // UNSELECTED_RAW_TEXT_HIGHLIGHT
+        map = new HashMap<>(1);
+        map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+        styles[0] = Collections.unmodifiableMap(map);
+
+        // SELECTED_RAW_TEXT_HIGHLIGHT
+        map = new HashMap<>(1);
+        map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
+        styles[1] = Collections.unmodifiableMap(map);
+
+        // UNSELECTED_CONVERTED_TEXT_HIGHLIGHT
+        map = new HashMap<>(1);
+        map.put(TextAttribute.INPUT_METHOD_UNDERLINE,
+                TextAttribute.UNDERLINE_LOW_ONE_PIXEL);
+        styles[2] = Collections.unmodifiableMap(map);
+
+        // SELECTED_CONVERTED_TEXT_HIGHLIGHT
+        map = new HashMap<>(1);
+        map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
+        styles[3] = Collections.unmodifiableMap(map);
+
+        highlightStyles = styles;
+    }
+
+    static {
+        initIDs();
+    }
+
+    /**
+     * Constructs an X11InputMethod instance. It initializes the XIM
+     * environment if it's not done yet.
+     *
+     * @exception AWTException if XOpenIM() failed.
+     */
+    public X11InputMethodBase() throws AWTException {
+        // supports only the locale in which the VM is started
+        locale = X11InputMethodDescriptor.getSupportedLocale();
+        if (initXIM() == false) {
+            throw new AWTException("Cannot open X Input Method");
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void finalize() throws Throwable {
+        dispose();
+        super.finalize();
+    }
+
+    /**
+     * Invokes openIM() that invokes XOpenIM() if it's not opened yet.
+     * @return  true if openXIM() is successful or it's already been opened.
+     */
+    private synchronized boolean initXIM() {
+        if (isXIMOpened == false)
+            isXIMOpened = openXIM();
+        return isXIMOpened;
+    }
+
+    protected abstract boolean openXIM();
+
+    protected boolean isDisposed() {
+        return disposed;
+    }
+
+    protected abstract void setXICFocus(ComponentPeer peer,
+                                    boolean value, boolean active);
+
+    /**
+     * Does nothing - this adapter doesn't use the input method context.
+     *
+     * @see java.awt.im.spi.InputMethod#setInputMethodContext
+     */
+    public void setInputMethodContext(InputMethodContext context) {
+    }
+
+    /**
+     * Set locale to input. If input method doesn't support specified locale,
+     * false will be returned and its behavior is not changed.
+     *
+     * @param lang locale to input
+     * @return the true is returned when specified locale is supported.
+     */
+    public boolean setLocale(Locale lang) {
+        if (lang.equals(locale)) {
+            return true;
+        }
+        // special compatibility rule for Japanese and Korean
+        if (locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
+                locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns current input locale.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Does nothing - XIM doesn't let you specify which characters you expect.
+     *
+     * @see java.awt.im.spi.InputMethod#setCharacterSubsets
+     */
+    public void setCharacterSubsets(Subset[] subsets) {
+    }
+
+    /**
+     * Dispatch event to input method. InputContext dispatch event with this
+     * method. Input method set consume flag if event is consumed in
+     * input method.
+     *
+     * @param e event
+     */
+    public void dispatchEvent(AWTEvent e) {
+    }
+
+    protected final void resetXICifneeded(){
+        /* needResetXIC is used to indicate whether to call
+           resetXIC on the active client. resetXIC will always be
+           called on the passive client when endComposition is called.
+        */
+        if (needResetXIC && haveActiveClient() &&
+            getClientComponent() != needResetXICClient.get()){
+            resetXIC();
+
+            // needs to reset the last xic focussed component.
+            lastXICFocussedComponent = null;
+            isLastXICActive = false;
+
+            needResetXICClient.clear();
+            needResetXIC = false;
+        }
+    }
+
+    /**
+     * Reset the composition state to the current composition state.
+     */
+    protected abstract void resetCompositionState();
+
+    /**
+     * Query and then return the current composition state.
+     * @return the composition state if isCompositionEnabled call
+     * is successful. Otherwise, it returns false.
+     */
+    protected boolean getCompositionState() {
+        boolean compositionState = false;
+        if (compositionEnableSupported) {
+            try {
+                compositionState = isCompositionEnabled();
+            } catch (UnsupportedOperationException e) {
+                compositionEnableSupported = false;
+            }
+        }
+        return compositionState;
+    }
+
+    /**
+     * Activate input method.
+     */
+    public abstract void activate();
+
+    protected abstract boolean createXIC();
+
+    /**
+     * Deactivate input method.
+     */
+    public abstract void deactivate(boolean isTemporary);
+
+    /**
+     * Explicitly disable the native IME. Native IME is not disabled when
+     * deactivate is called.
+     */
+    public void disableInputMethod() {
+        if (lastXICFocussedComponent != null) {
+            setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
+            lastXICFocussedComponent = null;
+            isLastXICActive = false;
+
+            resetXIC();
+            needResetXICClient.clear();
+            needResetXIC = false;
+        }
+    }
+
+    // implements java.awt.im.spi.InputMethod.hideWindows
+    public abstract void hideWindows();
+
+    /**
+     * @see java.awt.Toolkit#mapInputMethodHighlight
+     */
+    public static Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) {
+        int index;
+        int state = highlight.getState();
+        if (state == InputMethodHighlight.RAW_TEXT) {
+            index = 0;
+        } else if (state == InputMethodHighlight.CONVERTED_TEXT) {
+            index = 2;
+        } else {
+            return null;
+        }
+        if (highlight.isSelected()) {
+            index += 1;
+        }
+        return highlightStyles[index];
+    }
+
+    /**
+     * @see sun.awt.im.InputMethodAdapter#setAWTFocussedComponent
+     */
+    protected void setAWTFocussedComponent(Component component) {
+        if (component == null) {
+            return;
+        }
+        if (isActive) {
+            // deactivate/activate are being suppressed during a focus change -
+            // this may happen when an input method window is made visible
+            boolean ac = haveActiveClient();
+            setXICFocus(getPeer(awtFocussedComponent), false, ac);
+            setXICFocus(getPeer(component), true, ac);
+        }
+        awtFocussedComponent = component;
+    }
+
+    /**
+     * @see sun.awt.im.InputMethodAdapter#stopListening
+     */
+    protected void stopListening() {
+        // It is desirable to disable XIM by calling XSetICValues with
+        // XNPreeditState == XIMPreeditDisable.  But Solaris 2.6 and
+        // Solaris 7 do not implement this correctly without a patch,
+        // so just call resetXIC here.  Prior endComposition call commits
+        // the existing composed text.
+        endComposition();
+        // disable the native input method so that the other input
+        // method could get the input focus.
+        disableInputMethod();
+        if (needResetXIC) {
+            resetXIC();
+            needResetXICClient.clear();
+            needResetXIC = false;
+        }
+    }
+
+    /**
+     * Returns the Window instance in which the client component is
+     * contained. If not found, null is returned. (IS THIS POSSIBLE?)
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    protected Window getClientComponentWindow() {
+        Component client = getClientComponent();
+        Container container;
+
+        if (client instanceof Container) {
+            container = (Container) client;
+        } else {
+            container = getParent(client);
+        }
+
+        while (container != null && !(container instanceof java.awt.Window)) {
+            container = getParent(container);
+        }
+        return (Window) container;
+    }
+
+    protected abstract Container getParent(Component client);
+
+    /**
+     * Returns peer of the given client component. If the given client component
+     * doesn't have peer, peer of the native container of the client is returned.
+     */
+    protected abstract ComponentPeer getPeer(Component client);
+
+    /**
+     * Used to protect preedit data
+     */
+    protected abstract void awtLock();
+    protected abstract void awtUnlock();
+
+    /**
+     * Creates an input method event from the arguments given
+     * and posts it on the AWT event queue. For arguments,
+     * see InputMethodEvent. Called by input method.
+     *
+     * @see java.awt.event.InputMethodEvent#InputMethodEvent
+     */
+    protected void postInputMethodEvent(int id,
+                                      AttributedCharacterIterator text,
+                                      int committedCharacterCount,
+                                      TextHitInfo caret,
+                                      TextHitInfo visiblePosition,
+                                      long when) {
+        Component source = getClientComponent();
+        if (source != null) {
+            InputMethodEvent event = new InputMethodEvent(source,
+                id, when, text, committedCharacterCount, caret, visiblePosition);
+            SunToolkit.postEvent(SunToolkit.targetToAppContext(source), (AWTEvent)event);
+        }
+    }
+
+    private void postInputMethodEvent(int id,
+                                      AttributedCharacterIterator text,
+                                      int committedCharacterCount,
+                                      TextHitInfo caret,
+                                      TextHitInfo visiblePosition) {
+        postInputMethodEvent(id, text, committedCharacterCount,
+                             caret, visiblePosition, EventQueue.getMostRecentEventTime());
+    }
+
+    /**
+     * Dispatches committed text from XIM to the awt event queue. This
+     * method is invoked from the event handler in canvas.c in the
+     * AWT Toolkit thread context and thus inside the AWT Lock.
+     * @param   str     committed text
+     * @param   when    when
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       This functionality is implemented in a package-private method
+    //       to insure that it cannot be overridden by client subclasses.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    void dispatchCommittedText(String str, long when) {
+        if (str == null)
+            return;
+
+        if (composedText == null) {
+            AttributedString attrstr = new AttributedString(str);
+            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                                 attrstr.getIterator(),
+                                 str.length(),
+                                 null,
+                                 null,
+                                 when);
+        } else {
+            // if there is composed text, wait until the preedit
+            // callback is invoked.
+            committedText = str;
+        }
+    }
+
+    private void dispatchCommittedText(String str) {
+        dispatchCommittedText(str, EventQueue.getMostRecentEventTime());
+    }
+
+    /**
+     * Updates composed text with XIM preedit information and
+     * posts composed text to the awt event queue. The args of
+     * this method correspond to the XIM preedit callback
+     * information. The XIM highlight attributes are translated via
+     * fixed mapping (i.e., independent from any underlying input
+     * method engine). This method is invoked in the AWT Toolkit
+     * (X event loop) thread context and thus inside the AWT Lock.
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       This functionality is implemented in a package-private method
+    //       to insure that it cannot be overridden by client subclasses.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    abstract void dispatchComposedText(String chgText,
+                                           int chgStyles[],
+                                           int chgOffset,
+                                           int chgLength,
+                                           int caretPosition,
+                                           long when);
+
+    /**
+     * Flushes composed and committed text held in this context.
+     * This method is invoked in the AWT Toolkit (X event loop) thread context
+     * and thus inside the AWT Lock.
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       This functionality is implemented in a package-private method
+    //       to insure that it cannot be overridden by client subclasses.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    void flushText() {
+        String flush = (committedText != null ? committedText : "");
+        if (composedText != null) {
+            flush += composedText.toString();
+        }
+
+        if (!flush.equals("")) {
+            AttributedString attrstr = new AttributedString(flush);
+            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                                 attrstr.getIterator(),
+                                 flush.length(),
+                                 null,
+                                 null,
+                                 EventQueue.getMostRecentEventTime());
+            composedText = null;
+            committedText = null;
+        }
+    }
+
+    /*
+     * Subclasses should override disposeImpl() instead of dispose(). Client
+     * code should always invoke dispose(), never disposeImpl().
+     */
+    protected abstract void disposeImpl();
+
+    /**
+     * Frees all X Window resources associated with this object.
+     *
+     * @see java.awt.im.spi.InputMethod#dispose
+     */
+    public final void dispose() {
+        boolean call_disposeImpl = false;
+
+        if (!disposed) {
+            synchronized (this) {
+                if (!disposed) {
+                    disposed = call_disposeImpl = true;
+                }
+            }
+        }
+
+        if (call_disposeImpl) {
+            disposeImpl();
+        }
+    }
+
+    /**
+     * Returns null.
+     *
+     * @see java.awt.im.spi.InputMethod#getControlObject
+     */
+    public Object getControlObject() {
+        return null;
+    }
+
+    /**
+     * @see java.awt.im.spi.InputMethod#removeNotify
+     */
+    public synchronized void removeNotify() {
+        dispose();
+    }
+
+    /**
+     * @see java.awt.im.spi.InputMethod#setCompositionEnabled(boolean)
+     */
+    public abstract void setCompositionEnabled(boolean enable);
+
+    /**
+     * @see java.awt.im.spi.InputMethod#isCompositionEnabled
+     */
+    public boolean isCompositionEnabled() {
+        /* isCompositionEnabledNative may throw UnsupportedOperationException.
+           Don't try to catch it since this method may be called by clients.
+           Use package private method 'getCompositionState' if you want the
+           exception to be caught.
+        */
+        return isCompositionEnabledNative();
+    }
+
+    /**
+     * Ends any input composition that may currently be going on in this
+     * context. Depending on the platform and possibly user preferences,
+     * this may commit or delete uncommitted text. Any changes to the text
+     * are communicated to the active component using an input method event.
+     *
+     * <p>
+     * A text editing component may call this in a variety of situations,
+     * for example, when the user moves the insertion point within the text
+     * (but outside the composed text), or when the component's text is
+     * saved to a file or copied to the clipboard.
+     *
+     */
+    public void endComposition() {
+        if (disposed) {
+            return;
+        }
+
+        /* Before calling resetXIC, record the current composition mode
+           so that it can be restored later. */
+        savedCompositionState = getCompositionState();
+        boolean active = haveActiveClient();
+        if (active && composedText == null && committedText == null){
+            needResetXIC = true;
+            needResetXICClient = new WeakReference<>(getClientComponent());
+            return;
+        }
+
+        String text = resetXIC();
+        /* needResetXIC is only set to true for active client. So passive
+           client should not reset the flag to false. */
+        if (active) {
+            needResetXIC = false;
+        }
+
+        // Remove any existing composed text by posting an InputMethodEvent
+        // with null composed text.  It would be desirable to wait for a
+        // dispatchComposedText call from X input method engine, but some
+        // input method does not conform to the XIM specification and does
+        // not call the preedit callback to erase preedit text on calling
+        // XmbResetIC.  To work around this problem, do it here by ourselves.
+        awtLock();
+        try {
+            composedText = null;
+            postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+                                 null,
+                                 0,
+                                 null,
+                                 null);
+
+            if (text != null && text.length() > 0) {
+                dispatchCommittedText(text);
+            }
+        } finally {
+            // Put awtUnlock into finally block in case an exception is thrown.
+            awtUnlock();
+        }
+
+        // Restore the preedit state if it was enabled
+        if (savedCompositionState) {
+            resetCompositionState();
+        }
+    }
+
+    /**
+     * Returns a string with information about the current input method server, or null.
+     * On both Linux & SunOS, the value of environment variable XMODIFIERS is
+     * returned if set. Otherwise, on SunOS, $HOME/.dtprofile will be parsed
+     * to find out the language service engine (atok or wnn) since there is
+     * no API in Xlib which returns the information of native
+     * IM server or language service and we want to try our best to return as much
+     * information as possible.
+     *
+     * Note: This method could return null on Linux if XMODIFIERS is not set properly or
+     * if any IOException is thrown.
+     * See man page of XSetLocaleModifiers(3X11) for the usgae of XMODIFIERS,
+     * atok12setup(1) and wnn6setup(1) for the information written to
+     * $HOME/.dtprofile when you run these two commands.
+     *
+     */
+    public String getNativeInputMethodInfo() {
+        String xmodifiers = System.getenv("XMODIFIERS");
+        String imInfo = null;
+
+        // If XMODIFIERS is set, return the value
+        if (xmodifiers != null) {
+            int imIndex = xmodifiers.indexOf("@im=");
+            if (imIndex != -1) {
+                imInfo = xmodifiers.substring(imIndex + 4);
+            }
+        } else if (System.getProperty("os.name").startsWith("SunOS")) {
+            File dtprofile = new File(System.getProperty("user.home") +
+                                      "/.dtprofile");
+            String languageEngineInfo = null;
+            try {
+                BufferedReader br = new BufferedReader(new FileReader(dtprofile));
+                String line = null;
+
+                while ( languageEngineInfo == null && (line = br.readLine()) != null) {
+                    if (line.contains("atok") || line.contains("wnn")) {
+                        StringTokenizer tokens =  new StringTokenizer(line);
+                        while (tokens.hasMoreTokens()) {
+                            String token = tokens.nextToken();
+                            if (Pattern.matches("atok.*setup", token) ||
+                                Pattern.matches("wnn.*setup", token)){
+                                languageEngineInfo = token.substring(0, token.indexOf("setup"));
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                br.close();
+            } catch(IOException ioex) {
+                // Since this method is provided for internal testing only,
+                // we dump the stack trace for the ease of debugging.
+                ioex.printStackTrace();
+            }
+
+            imInfo = "htt " + languageEngineInfo;
+        }
+
+        return imInfo;
+    }
+
+
+    /**
+     * Performs mapping from an XIM visible feedback value to Java IM highlight.
+     * @return Java input method highlight
+     */
+    protected InputMethodHighlight convertVisualFeedbackToHighlight(int feedback) {
+        InputMethodHighlight highlight;
+
+        switch (feedback) {
+        case XIMUnderline:
+            highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
+            break;
+        case XIMReverse:
+            highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
+            break;
+        case XIMHighlight:
+            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
+            break;
+        case 0: //None of the values are set by Wnn
+        case XIMPrimary:
+            highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
+            break;
+        case XIMSecondary:
+            highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
+            break;
+        case XIMTertiary:
+            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
+            break;
+        default:
+            highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
+            break;
+        }
+        return highlight;
+    }
+
+    // initial capacity size for string buffer, etc.
+    protected static final int INITIAL_SIZE = 64;
+
+    /**
+     * IntBuffer is an inner class that manipulates an int array and
+     * provides UNIX file io stream-like programming interfaces to
+     * access it. (An alternative would be to use ArrayList which may
+     * be too expensive for the work.)
+     */
+    protected final class IntBuffer {
+        private int[] intArray;
+        private int size;
+        private int index;
+
+        IntBuffer(int initialCapacity) {
+            intArray = new int[initialCapacity];
+            size = 0;
+            index = 0;
+        }
+
+        void insert(int offset, int[] values) {
+            int newSize = size + values.length;
+            if (intArray.length < newSize) {
+                int[] newIntArray = new int[newSize * 2];
+                System.arraycopy(intArray, 0, newIntArray, 0, size);
+                intArray = newIntArray;
+            }
+            System.arraycopy(intArray, offset, intArray, offset+values.length,
+                             size - offset);
+            System.arraycopy(values, 0, intArray, offset, values.length);
+            size += values.length;
+            if (index > offset)
+                index = offset;
+        }
+
+        void remove(int offset, int length) {
+            if (offset + length != size)
+                System.arraycopy(intArray, offset+length, intArray, offset,
+                                 size - offset - length);
+            size -= length;
+            if (index > offset)
+                index = offset;
+        }
+
+        void replace(int offset, int[] values) {
+            System.arraycopy(values, 0, intArray, offset, values.length);
+        }
+
+        void removeAll() {
+            size = 0;
+            index = 0;
+        }
+
+        void rewind() {
+            index = 0;
+        }
+
+        int getNext() {
+            if (index == size)
+                return -1;
+            return intArray[index++];
+        }
+
+        void unget() {
+            if (index != 0)
+                index--;
+        }
+
+        int getOffset() {
+            return index;
+        }
+
+        public String toString() {
+            StringBuffer s = new StringBuffer();
+            for (int i = 0; i < size;) {
+                s.append(intArray[i++]);
+                if (i < size)
+                    s.append(",");
+            }
+            return s.toString();
+        }
+    }
+
+    /*
+     * Native methods
+     */
+
+    /**
+     * Initialize JNI field and method IDs for fields that may be
+     * accessed from C.
+     */
+    private static native void initIDs();
+
+    protected native void turnoffStatusWindow();
+
+    protected native void disposeXIC();
+
+    private native String resetXIC();
+
+    protected native boolean setCompositionEnabledNative(boolean enable);
+
+    private native boolean isCompositionEnabledNative();
+}
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Tue May 29 11:22:21 2018 -0700
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Wed May 30 08:19:59 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,18 +27,18 @@
     #error This file should not be included in headless library
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <sys/time.h>
-
 #include "awt.h"
 #include "awt_p.h"
 
-#include <sun_awt_X11InputMethod.h>
+#include <sun_awt_X11InputMethodBase.h>
 #include <sun_awt_X11_XInputMethod.h>
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <X11/keysym.h>
+#include <X11/Xlib.h>
+
 #define THROW_OUT_OF_MEMORY_ERROR() \
         JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
 
@@ -536,10 +536,10 @@
         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);
-    */
+        /*
+        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,
@@ -552,10 +552,10 @@
         break;
 
     case XLookupKeySym:
-    /*
-     printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
-       event->type, event->state, event->keycode, keysym);
-    */
+        /*
+        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) {
@@ -565,10 +565,10 @@
         break;
 
     case XLookupNone:
-    /*
-     printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
-        event->type, event->state, event->keycode, keysym);
-    */
+        /*
+        printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
+               event->type, event->state, event->keycode, keysym);
+        */
         break;
     }
 
@@ -576,8 +576,7 @@
 }
 
 #if defined(__linux__) || defined(MACOSX)
-static StatusWindow *createStatusWindow(
-                                Window parent) {
+static StatusWindow *createStatusWindow(Window parent) {
     StatusWindow *statusWindow;
     XSetWindowAttributes attrib;
     unsigned long attribmask;
@@ -600,7 +599,7 @@
     AwtGraphicsConfigDataPtr adata;
     extern int awt_numScreens;
     /*hardcode the size right now, should get the size base on font*/
-    int   width=80, height=22;
+    int width=80, height=22;
     Window rootWindow;
     Window *ignoreWindowPtr;
     unsigned int ignoreUnit;
@@ -652,10 +651,10 @@
     if (xx < 0 ){
         xx = 0;
     }
-    if (xx + width > xxwa.width){
+    if (xx + width > xxwa.width) {
         xx = xxwa.width - width;
     }
-    if (yy + height > xxwa.height){
+    if (yy + height > xxwa.height) {
         yy = xxwa.height - height;
     }
 
@@ -724,7 +723,7 @@
         return;
     }
 
-    if (ON == False){
+    if (ON == False) {
         XUnmapWindow(dpy, statusWindow->w);
         statusWindow->on = False;
         return;
@@ -732,7 +731,7 @@
     parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
                                   "getCurrentParentWindow",
                                   "()J").j;
-    if (statusWindow->parent != parent){
+    if (statusWindow->parent != parent) {
         statusWindow->parent = parent;
     }
     XGetWindowAttributes(dpy, parent, &xwa);
@@ -741,21 +740,22 @@
                           xwa.x, xwa.y,
                           &x, &y,
                           &child);
-    if (statusWindow->x != x
-        || statusWindow->y != y
-        || statusWindow->height != xwa.height){
+    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 ){
+        if (x < 0 ) {
             x = 0;
         }
-        if (x + statusWindow->statusW > statusWindow->rootW){
+        if (x + statusWindow->statusW > statusWindow->rootW) {
             x = statusWindow->rootW - statusWindow->statusW;
         }
-        if (y + statusWindow->statusH > statusWindow->rootH){
+        if (y + statusWindow->statusH > statusWindow->rootH) {
             y = statusWindow->rootH - statusWindow->statusH;
         }
         XMoveWindow(dpy, statusWindow->w, x, y);
@@ -790,61 +790,19 @@
     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){
+    if (statusWindow->fontset) {
         XmbDrawString(dpy, win, statusWindow->fontset, fggc,
                       bwidth + 2, height - bwidth - 4,
                       statusWindow->status,
                       strlen(statusWindow->status));
-    }
-    else{
+    } 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;
-  }
-}
-
-static void adjustStatusWindow(Window shell){
+static void adjustStatusWindow(Window shell) {
     JNIEnv *env = GetJNIEnv();
     X11InputMethodData *pX11IMData = NULL;
     StatusWindow *statusWindow;
@@ -853,9 +811,11 @@
         || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
         || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
         || NULL == (statusWindow = pX11IMData->statusWindow)
-        || !statusWindow->on) {
+        || !statusWindow->on)
+    {
         return;
     }
+
     {
         XWindowAttributes xwa;
         int x, y;
@@ -875,7 +835,7 @@
 
           x = statusWindow->x - statusWindow->off_x;
           y = statusWindow->y + statusWindow->height - statusWindow->off_y;
-          if (x < 0 ){
+          if (x < 0 ) {
               x = 0;
           }
           if (x + statusWindow->statusW > statusWindow->rootW){
@@ -889,6 +849,7 @@
     }
 }
 #endif  /* __linux__ || MACOSX */
+
 /*
  * Creates two XICs, one for active clients and the other for passive
  * clients. All information on those XICs are stored in the
@@ -931,9 +892,9 @@
         return FALSE ;
     }
 
-#if defined(__linux__) || defined(MACOSX)
     on_the_spot_styles |= XIMStatusNothing;
 
+#if defined(__linux__) || defined(MACOSX)
     /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
       at the same time, so use StatusCallback to draw the status
       ourself
@@ -944,8 +905,6 @@
             break;
         }
     }
-#else /*! __linux__ && !MACOSX */
-    on_the_spot_styles |= XIMStatusNothing;
 #endif /* __linux__ || MACOSX */
 
     for (i = 0; i < im_styles->count_styles; i++) {
@@ -1023,12 +982,12 @@
             XFree((void *)preedit);
         }
 #else /* !__linux__ && !MACOSX */
-            pX11IMData->ic_active = XCreateIC(X11im,
-                                              XNClientWindow, w,
-                                              XNFocusWindow, w,
-                                              XNInputStyle, active_styles,
-                                              XNPreeditAttributes, preedit,
-                                              NULL);
+        pX11IMData->ic_active = XCreateIC(X11im,
+                                          XNClientWindow, w,
+                                          XNFocusWindow, w,
+                                          XNInputStyle, active_styles,
+                                          XNPreeditAttributes, preedit,
+                                          NULL);
         XFree((void *)preedit);
 #endif /* __linux__ || MACOSX */
     } else {
@@ -1075,14 +1034,14 @@
 PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
 {
     /*ARGSUSED*/
-    /* printf("Native: PreeditCaretCallback\n"); */
+    /* printf("Native: PreeditStartCallback\n"); */
 }
 
 static void
 PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
 {
     /*ARGSUSED*/
-    /* printf("Native: StatusStartCallback\n"); */
+    /* printf("Native: PreeditDoneCallback\n"); */
 }
 
 /*
@@ -1187,7 +1146,6 @@
 {
     /*ARGSUSED*/
     /* printf("Native: PreeditCaretCallback\n"); */
-
 }
 
 #if defined(__linux__) || defined(MACOSX)
@@ -1196,7 +1154,6 @@
 {
     /*ARGSUSED*/
     /*printf("StatusStartCallback:\n");  */
-
 }
 
 static void
@@ -1204,7 +1161,6 @@
 {
     /*ARGSUSED*/
     /*printf("StatusDoneCallback:\n"); */
-
 }
 
 static void
@@ -1230,25 +1186,23 @@
         || NULL == (statusWindow = pX11IMData->statusWindow)){
         goto finally;
     }
-   currentX11InputMethodInstance = (jobject)client_data;
+    currentX11InputMethodInstance = (jobject)client_data;
 
-    if (status_draw->type == XIMTextType){
+    if (status_draw->type == XIMTextType) {
         XIMText *text = (status_draw->data).text;
-        if (text != NULL){
-          if (text->string.multi_byte != NULL) {
-              strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN);
-              statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
-          }
-          else {
-              char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
-              strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
-              statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
-          }
-          statusWindow->on = True;
-          onoffStatusWindow(pX11IMData, statusWindow->parent, True);
-          paintStatusWindow(statusWindow);
-        }
-        else {
+        if (text != NULL) {
+            if (text->string.multi_byte != NULL) {
+                strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN);
+                statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
+            } else {
+                char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
+                strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
+                statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
+            }
+            statusWindow->on = True;
+            onoffStatusWindow(pX11IMData, statusWindow->parent, True);
+            paintStatusWindow(statusWindow);
+        } else {
             statusWindow->on = False;
             /*just turnoff the status window
             paintStatusWindow(statusWindow);
@@ -1327,26 +1281,10 @@
     X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
 }
 
-/*
- * Class:     sun_awt_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
 Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
-                                          jobject this,
-                                          jlong display)
+                                            jobject this,
+                                            jlong display)
 {
     Bool registered;
 
@@ -1375,8 +1313,8 @@
 
 JNIEXPORT jboolean JNICALL
 Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
-                                                  jobject this,
-                                                  jlong window)
+                                              jobject this,
+                                              jlong window)
 {
     X11InputMethodData *pX11IMData;
     jobject globalRef;
@@ -1423,10 +1361,10 @@
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
-                                              jobject this,
-                                              jlong w,
-                                              jboolean req,
-                                              jboolean active)
+                                                jobject this,
+                                                jlong w,
+                                                jboolean req,
+                                                jboolean active)
 {
     X11InputMethodData *pX11IMData;
     AWT_LOCK();
@@ -1471,9 +1409,27 @@
     AWT_UNLOCK();
 }
 
-JNIEXPORT void JNICALL
-Java_sun_awt_X11InputMethod_turnoffStatusWindow(JNIEnv *env,
-                                                jobject this)
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * 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_X11InputMethodBase_initIDs
+  (JNIEnv *env, jclass cls)
+{
+    x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
+}
+
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    turnoffStatusWindow
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_turnoffStatusWindow
+  (JNIEnv *env, jobject this)
 {
 #if defined(__linux__) || defined(MACOSX)
     X11InputMethodData *pX11IMData;
@@ -1495,9 +1451,13 @@
 #endif
 }
 
-JNIEXPORT void JNICALL
-Java_sun_awt_X11InputMethod_disposeXIC(JNIEnv *env,
-                                             jobject this)
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    disposeXIC
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_disposeXIC
+  (JNIEnv *env, jobject this)
 {
     X11InputMethodData *pX11IMData = NULL;
 
@@ -1518,9 +1478,13 @@
     AWT_UNLOCK();
 }
 
-JNIEXPORT jstring JNICALL
-Java_sun_awt_X11InputMethod_resetXIC(JNIEnv *env,
-                                           jobject this)
+/*
+ * Class:     sun_awt_X11InputMethodBase
+ * Method:    resetXIC
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_awt_X11InputMethodBase_resetXIC
+  (JNIEnv *env, jobject this)
 {
     X11InputMethodData *pX11IMData;
     char *xText = NULL;
@@ -1564,9 +1528,9 @@
 }
 
 /*
- * Class:     sun_awt_X11InputMethod
+ * Class:     sun_awt_X11InputMethodBase
  * Method:    setCompositionEnabledNative
- * Signature: (ZJ)V
+ * Signature: (Z)Z
  *
  * This method tries to set the XNPreeditState attribute associated with the current
  * XIC to the passed in 'enable' state.
@@ -1575,9 +1539,8 @@
  * '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
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative
   (JNIEnv *env, jobject this, jboolean enable)
 {
     X11InputMethodData *pX11IMData;
@@ -1603,18 +1566,17 @@
 }
 
 /*
- * Class:     sun_awt_X11InputMethod
+ * Class:     sun_awt_X11InputMethodBase
  * Method:    isCompositionEnabledNative
- * Signature: (J)Z
+ * Signature: ()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
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative
   (JNIEnv *env, jobject this)
 {
     X11InputMethodData *pX11IMData = NULL;
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	Tue May 29 11:22:21 2018 -0700
+++ b/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	Wed May 30 08:19:59 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -23,31 +23,32 @@
  * questions.
  */
 
+#include "awt.h"
+#include "awt_util.h"
+#include "jni.h"
+#include "jlong.h"
+#include "Region.h"
+#include "sizecalc.h"
+#include "utility/rect.h"
+
 #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 <stdlib.h>
+#include <string.h>
 #include <X11/extensions/Xdbe.h>
 #include <X11/extensions/shape.h>
-#include <string.h>
-#include <stdlib.h>
+#include <X11/keysym.h>
 #include <X11/Sunkeysym.h>
-
-#include <jni.h>
-#include <jni_util.h>
-#include <jlong.h>
-#include <sizecalc.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/XKBlib.h>
+#include <X11/Xos.h>
+#include <X11/Xutil.h>
 
-#include <awt.h>
-#include <awt_util.h>
-#include <jvm.h>
-
-#include <Region.h>
-#include "utility/rect.h"
-
-#include <X11/XKBlib.h>
+#if defined(AIX)
+#undef X_HAVE_UTF8_STRING
+extern Bool statusWindowEventHandler(XEvent event);
+#endif
 
 // From XWindow.c
 extern KeySym keycodeToKeysym(Display *display, KeyCode keycode, int index);
@@ -288,7 +289,6 @@
     return ScreenCount((Display *) jlong_to_ptr(display));
 }
 
-
 /*
  * Class:     XlibWrapper
  * Method:    XCreateWindow
@@ -303,7 +303,6 @@
     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));
-
 }
 
 /*
@@ -320,7 +319,6 @@
                          (jlong_to_ptr(keysym_uppercase)));
 }
 
-
 /*
  * Class:     XlibWrapper
  * Method:    XMapWindow
@@ -331,7 +329,6 @@
 {
     AWT_CHECK_HAVE_LOCK();
     XMapWindow( (Display *)jlong_to_ptr(display),(Window) window);
-
 }
 
 /*
@@ -344,7 +341,6 @@
 {
     AWT_CHECK_HAVE_LOCK();
     XMapRaised( (Display *)jlong_to_ptr(display),(Window) window);
-
 }
 
 /*
@@ -355,10 +351,8 @@
 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);
-
 }
 
 /*
@@ -369,10 +363,8 @@
 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);
-
 }
 
 /*
@@ -383,10 +375,8 @@
 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);
-
 }
 
 /*
@@ -411,11 +401,10 @@
 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
@@ -424,10 +413,8 @@
 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);
-
 }
 
 /*
@@ -438,7 +425,6 @@
 JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetInputFocus
 (JNIEnv *env, jclass clazz, jlong display)
 {
-
     Window focusOwner;
     int revert_to;
     AWT_CHECK_HAVE_LOCK_RETURN(0);
@@ -446,7 +432,6 @@
     return focusOwner;
 }
 
-
 /*
  * Class:     XlibWrapper
  * Method:    XDestroyWindow
@@ -525,8 +510,6 @@
 
 }
 
-
-
 JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSelectInput
 (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong mask)
 {
@@ -543,6 +526,7 @@
                    (unsigned long)bits_to_change,
                    (unsigned long)values_for_bits);
 }
+
 JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails
 (JNIEnv *env, jclass clazz, jlong display, jlong device, jlong event_type,
               jlong bits_to_change, jlong values_for_bits)
@@ -553,6 +537,7 @@
                    (unsigned long)bits_to_change,
                    (unsigned long)values_for_bits);
 }
+
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension
 (JNIEnv *env, jclass clazz, jlong display, jlong opcode_rtrn, jlong event_rtrn,
               jlong error_rtrn, jlong major_in_out, jlong minor_in_out)
@@ -567,6 +552,7 @@
                                (int *) jlong_to_ptr(minor_in_out));
     return status ? JNI_TRUE : JNI_FALSE;
 }
+
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion
 (JNIEnv *env, jclass clazz, jlong lib_major_in_out, jlong lib_minor_in_out)
 {
@@ -587,6 +573,7 @@
                               (unsigned int) which,
                               (unsigned int) device_spec);
 }
+
 JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap
 (JNIEnv *env, jclass clazz, jlong display, jlong which, jlong xkb)
 {
@@ -626,8 +613,6 @@
  * Method:    XNextEvent
  * Signature: (JJ)V
  */
-
-
 JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XNextEvent
 (JNIEnv *env, jclass clazz, jlong display, jlong ptr)
 {
@@ -640,7 +625,6 @@
  * 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)
 {
@@ -653,7 +637,6 @@
  * 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)
 {
@@ -670,6 +653,11 @@
 (JNIEnv *env, jclass clazz, jlong ptr, jlong window)
 {
     AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE);
+#if defined(AIX)
+    if (True == statusWindowEventHandler(*((XEvent *)(uintptr_t)ptr))) {
+        return (jboolean)True;
+    }
+#endif
     return (jboolean) XFilterEvent((XEvent *) jlong_to_ptr(ptr), (Window) window);
 }
 
@@ -727,19 +715,15 @@
     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);
-
 }
 
 /*
@@ -747,10 +731,8 @@
  * 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)
-{
+(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);
 }
@@ -760,10 +742,8 @@
  * 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)
-{
+(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);
 }
@@ -774,13 +754,10 @@
  * 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);
-
 }
 
 
@@ -803,10 +780,8 @@
  */
 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 jint JNICALL Java_sun_awt_X11_XlibWrapper_XTranslateCoordinates
@@ -855,7 +830,6 @@
         cname = "";
     }
 
-
     AWT_CHECK_HAVE_LOCK();
 
 #ifdef X_HAVE_UTF8_STRING
@@ -866,7 +840,6 @@
                                        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) {
@@ -1005,7 +978,6 @@
     return XCreateFontCursor((Display *) jlong_to_ptr(display), (int) shape);
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XCreatePixmapCursor
@@ -1019,7 +991,6 @@
                                        (XColor *) jlong_to_ptr(fore), (XColor *) jlong_to_ptr(back), x, y);
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XQueryBestCursor
@@ -1038,7 +1009,6 @@
     else return JNI_TRUE;
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XFreeCursor
@@ -1084,7 +1054,6 @@
                             (XSetWindowAttributes *) jlong_to_ptr(attributes));
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XSetTransientFor
@@ -1181,7 +1150,6 @@
     }
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    getScreenOfWindow
@@ -1253,7 +1221,6 @@
     return res;
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    ServerVendor
@@ -1265,6 +1232,7 @@
     AWT_CHECK_HAVE_LOCK_RETURN(NULL);
     return JNU_NewStringPlatform(env, ServerVendor((Display*)jlong_to_ptr(display)));
 }
+
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    VendorRelease
@@ -1276,6 +1244,7 @@
     AWT_CHECK_HAVE_LOCK_RETURN(0);
     return VendorRelease((Display*)jlong_to_ptr(display));
 }
+
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    IsXsunKPBehavior
@@ -1309,7 +1278,6 @@
     }
 }
 
-
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsSunKeyboard
 (JNIEnv *env, jclass clazz, jlong display)
 {
@@ -1407,7 +1375,6 @@
     return (*(XErrorHandler)jlong_to_ptr(handler))((Display*) jlong_to_ptr(display), (XErrorEvent*) jlong_to_ptr(event_ptr));
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    PrintXErrorEvent
@@ -1431,7 +1398,6 @@
     }
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XInternAtoms
@@ -1451,8 +1417,6 @@
     return status;
 }
 
-
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XGetWindowAttributes
@@ -1468,7 +1432,6 @@
     return status;
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XGetGeometry
@@ -1490,7 +1453,6 @@
     return status;
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XGetWMNormalHints
@@ -1546,7 +1508,6 @@
                       (XEvent*) jlong_to_ptr(event));
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XQueryTree
@@ -1564,7 +1525,6 @@
                       (unsigned int*) jlong_to_ptr(nchildren_return));
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    memcpy
@@ -1576,7 +1536,6 @@
     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;
@@ -1595,7 +1554,6 @@
     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)
@@ -1626,7 +1584,6 @@
     XBell((Display*)jlong_to_ptr(display), percent);
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XAllocColor
@@ -1643,7 +1600,6 @@
     else return JNI_TRUE;
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XCreateBitmapFromData
@@ -1657,7 +1613,6 @@
                                          (char *) jlong_to_ptr(data), width, height);
 }
 
-
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XFreePixmap
@@ -1772,6 +1727,7 @@
     AWT_CHECK_HAVE_LOCK_RETURN(0);
     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,
@@ -1783,6 +1739,7 @@
                 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,
@@ -1806,6 +1763,7 @@
     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)
 {
@@ -1813,18 +1771,21 @@
     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)
 {
@@ -1922,7 +1883,6 @@
 JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XQueryKeymap
 (JNIEnv *env, jclass clazz, jlong display, jlong vector)
 {
-
     AWT_CHECK_HAVE_LOCK();
     XQueryKeymap( (Display *) jlong_to_ptr(display), (char *) jlong_to_ptr(vector));
 }
@@ -1961,6 +1921,7 @@
 //    printf("-------------------------------------^^^^\n");
     return (jint)(sr.group);
 }
+
 JNIEXPORT jlong JNICALL
 Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym(JNIEnv *env, jclass clazz,
                                               jlong display, jint keycode,
@@ -1989,6 +1950,7 @@
     AWT_CHECK_HAVE_LOCK();
     XFreeModifiermap((XModifierKeymap*) jlong_to_ptr(keymap));
 }
+
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XRefreshKeyboardMapping
@@ -2034,7 +1996,6 @@
             ) ? True : False;
 }
 
-
 JNIEXPORT jboolean JNICALL
 Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent(JNIEnv *env, jclass clazz,
                                                      jlong display, jlong ptr) {
@@ -2062,7 +2023,6 @@
     exitSecondaryLoop = True;
     AWT_NOTIFY_ALL();
 }
-/*******************************************************************************/
 
 JNIEXPORT jobjectArray JNICALL
 Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList(JNIEnv *env,
@@ -2181,7 +2141,6 @@
     return ret;
 }
 
-
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XlibWrapper_XPutBackEvent(JNIEnv *env,
                                            jclass clazz,