< prev index next >

src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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

@@ -44,11 +44,11 @@
 
 struct X11InputMethodIDs {
   jfieldID pData;
 } x11InputMethodIDs;
 
-static void PreeditStartCallback(XIC, XPointer, XPointer);
+static int PreeditStartCallback(XIC, XPointer, XPointer);
 static void PreeditDoneCallback(XIC, XPointer, XPointer);
 static void PreeditDrawCallback(XIC, XPointer,
                                 XIMPreeditDrawCallbackStruct *);
 static void PreeditCaretCallback(XIC, XPointer,
                                  XIMPreeditCaretCallbackStruct *);

@@ -173,10 +173,13 @@
 
 static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
 static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
 static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
 static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
+#if defined(__linux__) || defined(MACOSX)
+static Window getParentWindow(Window);
+#endif
 
 #ifdef __solaris__
 /* Prototype for this function is missing in Solaris X11R6 Xlib.h */
 extern char *XSetIMValues(
 #if NeedVarargsPrototypes

@@ -1017,27 +1020,47 @@
         if (pX11IMData->ic_active != pX11IMData->ic_passive) {
             XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
         }
     }
 
+    // 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, XIMInitialState,
+                     NULL);
+    if (pX11IMData->ic_passive != 0
+            && pX11IMData->ic_active != pX11IMData->ic_passive)
+        XSetICValues(pX11IMData->ic_passive,
+                     XNResetState, XIMInitialState,
+                     NULL);
+
     /* Add the global reference object to X11InputMethod to the list. */
     addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
 
+    /* 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 void
+static int
 PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
 {
     /*ARGSUSED*/
     /* printf("Native: PreeditStartCallback\n"); */
+    return -1;
 }
 
 static void
 PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
 {

@@ -1161,10 +1184,33 @@
 static void
 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
 {
     /*ARGSUSED*/
     /*printf("StatusDoneCallback:\n"); */
+    JNIEnv *env = GetJNIEnv();
+    X11InputMethodData *pX11IMData = NULL;
+    StatusWindow *statusWindow;
+
+    AWT_LOCK();
+
+    if (!isX11InputMethodGRefInList((jobject)client_data)) {
+        if ((jobject)client_data == currentX11InputMethodInstance) {
+            currentX11InputMethodInstance = NULL;
+        }
+        goto finally;
+    }
+
+    if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
+        || NULL == (statusWindow = pX11IMData->statusWindow)){
+        goto finally;
+    }
+    currentX11InputMethodInstance = (jobject)client_data;
+
+    onoffStatusWindow(pX11IMData, 0, False);
+
+ finally:
+    AWT_UNLOCK();
 }
 
 static void
 StatusDrawCallback(XIC ic, XPointer client_data,
                      XIMStatusDrawCallbackStruct *status_draw)

@@ -1550,24 +1596,61 @@
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative
   (JNIEnv *env, jobject this, jboolean enable)
 {
     X11InputMethodData *pX11IMData;
     char * ret = NULL;
+    XVaNestedList   pr_atrb;
+#if defined(__linux__) || defined(MACOSX)
+    Boolean calledXSetICFocus = False;
+#endif
 
     AWT_LOCK();
     pX11IMData = getX11InputMethodData(env, this);
 
     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
         AWT_UNLOCK();
         return JNI_FALSE;
     }
 
-    ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
-                       (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
+#if defined(__linux__) || defined(MACOSX)
+    if (NULL != pX11IMData->statusWindow) {
+        Window focus = 0;
+        int revert_to;
+#if defined(_LP64) && !defined(_LITTLE_ENDIAN)
+        // The Window value which is used for XGetICValues must be 32bit on BigEndian XOrg's xlib
+        unsigned int w = 0;
+#else
+        Window w = 0;
+#endif
+        XGetInputFocus(awt_display, &focus, &revert_to);
+        XGetICValues(pX11IMData->current_ic, XNFocusWindow, &w, NULL);
+        if (RevertToPointerRoot == revert_to
+                && pX11IMData->ic_active != pX11IMData->ic_passive) {
+            if (pX11IMData->current_ic == pX11IMData->ic_active) {
+                if (getParentWindow(focus) == getParentWindow(w)) {
+                    XUnsetICFocus(pX11IMData->ic_active);
+                    calledXSetICFocus = True;
+                }
+            }
+        }
+    }
+#endif
+    pr_atrb = XVaCreateNestedList(0,
+                  XNPreeditState, (enable ? XIMPreeditEnable : XIMPreeditDisable),
+                  NULL);
+    ret = XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL);
+    XFree((void *)pr_atrb);
+#if defined(__linux__) || defined(MACOSX)
+    if (calledXSetICFocus) {
+        XSetICFocus(pX11IMData->ic_active);
+    }
+#endif
     AWT_UNLOCK();
 
-    if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
+    if ((ret != 0) 
+            && ((strcmp(ret, XNPreeditAttributes) == 0)
+            || (strcmp(ret, XNPreeditState) == 0))) {
         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
     }
 
     return (jboolean)(ret == 0);
 }

@@ -1586,24 +1669,35 @@
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative
   (JNIEnv *env, jobject this)
 {
     X11InputMethodData *pX11IMData = NULL;
     char * ret = NULL;
-    XIMPreeditState state;
+#if defined(_LP64) && !defined(_LITTLE_ENDIAN)
+    // XIMPreeditState value which is used for XGetICValues must be 32bit on BigEndian XOrg's xlib
+    unsigned int state = XIMPreeditUnKnown;
+#else
+    XIMPreeditState state = XIMPreeditUnKnown;
+#endif
+
+    XVaNestedList   pr_atrb;
 
     AWT_LOCK();
     pX11IMData = getX11InputMethodData(env, this);
 
     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
         AWT_UNLOCK();
         return JNI_FALSE;
     }
 
-    ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
+    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, XNPreeditState) == 0)) {
+    if ((ret != 0)
+            && ((strcmp(ret, XNPreeditAttributes) == 0)
+            || (strcmp(ret, XNPreeditState) == 0))) {
         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
         return JNI_FALSE;
     }
 
     return (jboolean)(state == XIMPreeditEnable);

@@ -1616,5 +1710,22 @@
     AWT_LOCK();
     adjustStatusWindow(window);
     AWT_UNLOCK();
 #endif
 }
+
+#if defined(__linux__) || defined(MACOSX)
+static Window getParentWindow(Window w)
+{
+    Window root=None, parent=None, *ignore_children=NULL;
+    unsigned int ignore_uint=0;
+    Status status = 0;
+
+    if (w == None)
+        return None;
+    status = XQueryTree(dpy, w, &root, &parent, &ignore_children, &ignore_uint);
+    XFree(ignore_children);
+    if (status == 0)
+        return None;
+    return parent;
+}
+#endif
< prev index next >