8213232: Unix/X11 setCompositionEnableNative issue

Reviewed-by: serb
This commit is contained in:
Ichiroh Takiguchi 2019-04-30 14:30:17 -07:00
parent dfc6e4b49e
commit 3a894521eb
4 changed files with 128 additions and 14 deletions

View File

@ -88,7 +88,7 @@ static void StatusDrawCallback(XIC, XPointer,
* values above. * values above.
*/ */
static XIMProc callback_funcs[NCALLBACKS] = { static XIMProc callback_funcs[NCALLBACKS] = {
(XIMProc)PreeditStartCallback, (XIMProc)(void *)&PreeditStartCallback,
(XIMProc)PreeditDoneCallback, (XIMProc)PreeditDoneCallback,
(XIMProc)PreeditDrawCallback, (XIMProc)PreeditDrawCallback,
(XIMProc)PreeditCaretCallback, (XIMProc)PreeditCaretCallback,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -547,6 +547,8 @@ public class InputContext extends java.awt.im.InputContext
if (inputMethod instanceof InputMethodAdapter) { if (inputMethod instanceof InputMethodAdapter) {
((InputMethodAdapter) inputMethod).setClientComponent(null); ((InputMethodAdapter) inputMethod).setClientComponent(null);
} }
if (null == currentClientComponent.getInputMethodRequests())
wasCompositionEnabledSupported = false;
} }
savedLocale = inputMethod.getLocale(); savedLocale = inputMethod.getLocale();
@ -563,6 +565,7 @@ public class InputContext extends java.awt.im.InputContext
enableClientWindowNotification(inputMethod, false); enableClientWindowNotification(inputMethod, false);
if (this == inputMethodWindowContext) { if (this == inputMethodWindowContext) {
inputMethod.hideWindows(); inputMethod.hideWindows();
inputMethod.removeNotify();
inputMethodWindowContext = null; inputMethodWindowContext = null;
} }
inputMethodLocator = null; inputMethodLocator = null;

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -55,7 +55,7 @@ public abstract class X11InputMethod extends X11InputMethodBase {
* Reset the composition state to the current composition state. * Reset the composition state to the current composition state.
*/ */
protected void resetCompositionState() { protected void resetCompositionState() {
if (compositionEnableSupported) { if (compositionEnableSupported && haveActiveClient()) {
try { try {
/* Restore the composition mode to the last saved composition /* Restore the composition mode to the last saved composition
mode. */ mode. */

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,7 +46,7 @@ struct X11InputMethodIDs {
jfieldID pData; jfieldID pData;
} x11InputMethodIDs; } x11InputMethodIDs;
static void PreeditStartCallback(XIC, XPointer, XPointer); static int PreeditStartCallback(XIC, XPointer, XPointer);
static void PreeditDoneCallback(XIC, XPointer, XPointer); static void PreeditDoneCallback(XIC, XPointer, XPointer);
static void PreeditDrawCallback(XIC, XPointer, static void PreeditDrawCallback(XIC, XPointer,
XIMPreeditDrawCallbackStruct *); XIMPreeditDrawCallbackStruct *);
@ -80,7 +80,7 @@ static void StatusDrawCallback(XIC, XPointer,
* values above. * values above.
*/ */
static XIMProc callback_funcs[NCALLBACKS] = { static XIMProc callback_funcs[NCALLBACKS] = {
(XIMProc)PreeditStartCallback, (XIMProc)(void *)&PreeditStartCallback,
(XIMProc)PreeditDoneCallback, (XIMProc)PreeditDoneCallback,
(XIMProc)PreeditDrawCallback, (XIMProc)PreeditDrawCallback,
(XIMProc)PreeditCaretCallback, (XIMProc)PreeditCaretCallback,
@ -175,6 +175,9 @@ static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *); static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *); static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *); static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
#if defined(__linux__) || defined(MACOSX)
static Window getParentWindow(Window);
#endif
#ifdef __solaris__ #ifdef __solaris__
/* Prototype for this function is missing in Solaris X11R6 Xlib.h */ /* Prototype for this function is missing in Solaris X11R6 Xlib.h */
@ -1019,9 +1022,28 @@ createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
} }
} }
// 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. */ /* Add the global reference object to X11InputMethod to the list. */
addToX11InputMethodGRefList(pX11IMData->x11inputmethod); 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; return True;
err: err:
@ -1031,11 +1053,12 @@ createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
return False; return False;
} }
static void static int
PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data) PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{ {
/*ARGSUSED*/ /*ARGSUSED*/
/* printf("Native: PreeditStartCallback\n"); */ /* printf("Native: PreeditStartCallback\n"); */
return -1;
} }
static void static void
@ -1163,6 +1186,29 @@ StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
{ {
/*ARGSUSED*/ /*ARGSUSED*/
/*printf("StatusDoneCallback:\n"); */ /*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 static void
@ -1552,6 +1598,10 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabled
{ {
X11InputMethodData *pX11IMData; X11InputMethodData *pX11IMData;
char * ret = NULL; char * ret = NULL;
XVaNestedList pr_atrb;
#if defined(__linux__) || defined(MACOSX)
Boolean calledXSetICFocus = False;
#endif
AWT_LOCK(); AWT_LOCK();
pX11IMData = getX11InputMethodData(env, this); pX11IMData = getX11InputMethodData(env, this);
@ -1561,11 +1611,44 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabled
return JNI_FALSE; return JNI_FALSE;
} }
ret = XSetICValues(pX11IMData->current_ic, XNPreeditState, #if defined(__linux__) || defined(MACOSX)
(enable ? XIMPreeditEnable : XIMPreeditDisable), NULL); 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(); 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", ""); JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
} }
@ -1588,7 +1671,14 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledN
{ {
X11InputMethodData *pX11IMData = NULL; X11InputMethodData *pX11IMData = NULL;
char * ret = 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(); AWT_LOCK();
pX11IMData = getX11InputMethodData(env, this); pX11IMData = getX11InputMethodData(env, this);
@ -1598,10 +1688,14 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledN
return JNI_FALSE; 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(); 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", ""); JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
return JNI_FALSE; return JNI_FALSE;
} }
@ -1618,3 +1712,20 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
AWT_UNLOCK(); AWT_UNLOCK();
#endif #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