< prev index next >
src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c
Print this page
rev 50285 : 8201429: Support AIX Input Method Editor (IME) for AWT Input Method Framework (IMF)
*** 1,7 ****
/*
! * Copyright (c) 1997, 2016, 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
--- 1,7 ----
/*
! * 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
*** 25,119 ****
#ifdef HEADLESS
#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_X11_XInputMethod.h>
#define THROW_OUT_OF_MEMORY_ERROR() \
JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
struct X11InputMethodIDs {
jfieldID pData;
} x11InputMethodIDs;
! static void PreeditStartCallback(XIC, XPointer, XPointer);
static void PreeditDoneCallback(XIC, XPointer, XPointer);
static void PreeditDrawCallback(XIC, XPointer,
XIMPreeditDrawCallbackStruct *);
static void PreeditCaretCallback(XIC, XPointer,
XIMPreeditCaretCallbackStruct *);
- #if defined(__linux__) || defined(MACOSX)
static void StatusStartCallback(XIC, XPointer, XPointer);
static void StatusDoneCallback(XIC, XPointer, XPointer);
static void StatusDrawCallback(XIC, XPointer,
XIMStatusDrawCallbackStruct *);
- #endif
#define ROOT_WINDOW_STYLES (XIMPreeditNothing | XIMStatusNothing)
#define NO_STYLES (XIMPreeditNone | XIMStatusNone)
#define PreeditStartIndex 0
#define PreeditDoneIndex 1
#define PreeditDrawIndex 2
#define PreeditCaretIndex 3
- #if defined(__linux__) || defined(MACOSX)
#define StatusStartIndex 4
#define StatusDoneIndex 5
#define StatusDrawIndex 6
#define NCALLBACKS 7
! #else
! #define NCALLBACKS 4
! #endif
/*
* Callback function pointers: the order has to match the *Index
* values above.
*/
static XIMProc callback_funcs[NCALLBACKS] = {
(XIMProc)PreeditStartCallback,
(XIMProc)PreeditDoneCallback,
(XIMProc)PreeditDrawCallback,
(XIMProc)PreeditCaretCallback,
- #if defined(__linux__) || defined(MACOSX)
(XIMProc)StatusStartCallback,
(XIMProc)StatusDoneCallback,
(XIMProc)StatusDrawCallback,
- #endif
};
- #if defined(__linux__) || defined(MACOSX)
#define MAX_STATUS_LEN 100
typedef struct {
Window w; /*status window id */
Window root; /*the root window id */
Window parent; /*parent shell window */
int x, y; /*parent's upperleft position */
int width, height; /*parent's width, height */
GC lightGC; /*gc for light border */
GC dimGC; /*gc for dim border */
GC bgGC; /*normal painting */
GC fgGC; /*normal painting */
int statusW, statusH; /*status window's w, h */
int rootW, rootH; /*root window's w, h */
int bWidth; /*border width */
! char status[MAX_STATUS_LEN]; /*status text */
XFontSet fontset; /*fontset for drawing */
int off_x, off_y;
Bool on; /*if the status window on*/
} StatusWindow;
- #endif
/*
* X11InputMethodData keeps per X11InputMethod instance information. A pointer
* to this data structure is kept in an X11InputMethod object (pData).
*/
--- 25,131 ----
#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).
*/
*** 122,158 ****
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 */
- #if defined(__linux__) || defined(MACOSX)
StatusWindow *statusWindow; /* our own status window */
! #endif
! char *lookup_buf; /* buffer used for XmbLookupString */
! int lookup_buf_len; /* lookup buffer size in bytes */
} X11InputMethodData;
- /*
- * When XIC is created, a global reference is created for
- * sun.awt.X11InputMethod object so that it could be used by the XIM callback
- * functions. This could be a dangerous thing to do when the original
- * X11InputMethod object is garbage collected and as a result,
- * destroyX11InputMethodData is called to delete the global reference.
- * If any XIM callback function still holds and uses the "already deleted"
- * global reference, disaster is going to happen. So we have to maintain
- * a list for these global references which is consulted first when the
- * callback functions or any function tries to use "currentX11InputMethodObject"
- * which always refers to the global reference try to use it.
- *
- */
- typedef struct _X11InputMethodGRefNode {
- jobject inputMethodGRef;
- struct _X11InputMethodGRefNode* next;
- } X11InputMethodGRefNode;
-
- X11InputMethodGRefNode *x11InputMethodGRefListHead = NULL;
-
/* reference to the current X11InputMethod instance, it is always
point to the global reference to the X11InputMethodObject since
it could be referenced by different threads. */
jobject currentX11InputMethodInstance = NULL;
--- 134,149 ----
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;
*** 163,191 ****
static XIM X11im = NULL;
Display * dpy = NULL;
#define GetJNIEnv() (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)
- static void DestroyXIMCallback(XIM, XPointer, XPointer);
- static void OpenXIMCallback(Display *, XPointer, XPointer);
- /* Solaris XIM Extention */
- #define XNCommitStringCallback "commitStringCallback"
- static void CommitStringCallback(XIC, XPointer, XPointer);
-
static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
! #ifdef __solaris__
! /* Prototype for this function is missing in Solaris X11R6 Xlib.h */
extern char *XSetIMValues(
#if NeedVarargsPrototypes
XIM /* im */, ...
#endif
);
! #endif
/*
* This function is stolen from /src/solaris/hpi/src/system_md.c
* It is used in setting the time in Java-level InputEvents
*/
--- 154,198 ----
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
*/
*** 227,317 ****
}
return mbs;
}
- /*
- * Returns True if the global reference is still in the list,
- * otherwise False.
- */
- static Bool isX11InputMethodGRefInList(jobject imGRef) {
- X11InputMethodGRefNode *pX11InputMethodGRef = x11InputMethodGRefListHead;
-
- if (imGRef == NULL) {
- return False;
- }
-
- while (pX11InputMethodGRef != NULL) {
- if (pX11InputMethodGRef->inputMethodGRef == imGRef) {
- return True;
- }
- pX11InputMethodGRef = pX11InputMethodGRef->next;
- }
-
- return False;
- }
-
- /*
- * Add the new created global reference to the list.
- */
- static void addToX11InputMethodGRefList(jobject newX11InputMethodGRef) {
- X11InputMethodGRefNode *newNode = NULL;
-
- if (newX11InputMethodGRef == NULL ||
- isX11InputMethodGRefInList(newX11InputMethodGRef)) {
- return;
- }
-
- newNode = (X11InputMethodGRefNode *)malloc(sizeof(X11InputMethodGRefNode));
-
- if (newNode == NULL) {
- return;
- } else {
- newNode->inputMethodGRef = newX11InputMethodGRef;
- newNode->next = x11InputMethodGRefListHead;
- x11InputMethodGRefListHead = newNode;
- }
- }
-
- /*
- * Remove the global reference from the list.
- */
- static void removeX11InputMethodGRefFromList(jobject x11InputMethodGRef) {
- X11InputMethodGRefNode *pX11InputMethodGRef = NULL;
- X11InputMethodGRefNode *cX11InputMethodGRef = x11InputMethodGRefListHead;
-
- if (x11InputMethodGRefListHead == NULL ||
- x11InputMethodGRef == NULL) {
- return;
- }
-
- /* cX11InputMethodGRef always refers to the current node while
- pX11InputMethodGRef refers to the previous node.
- */
- while (cX11InputMethodGRef != NULL) {
- if (cX11InputMethodGRef->inputMethodGRef == x11InputMethodGRef) {
- break;
- }
- pX11InputMethodGRef = cX11InputMethodGRef;
- cX11InputMethodGRef = cX11InputMethodGRef->next;
- }
-
- if (cX11InputMethodGRef == NULL) {
- return; /* Not found. */
- }
-
- if (cX11InputMethodGRef == x11InputMethodGRefListHead) {
- x11InputMethodGRefListHead = x11InputMethodGRefListHead->next;
- } else {
- pX11InputMethodGRef->next = cX11InputMethodGRef->next;
- }
- free(cX11InputMethodGRef);
-
- return;
- }
-
-
static X11InputMethodData * getX11InputMethodData(JNIEnv * env, jobject imInstance) {
X11InputMethodData *pX11IMData =
(X11InputMethodData *)JNU_GetLongFieldAsPtr(env, imInstance, x11InputMethodIDs.pData);
/*
--- 234,243 ----
*** 370,409 ****
}
static void
freeX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
{
- #if defined(__linux__) || defined(MACOSX)
if (pX11IMData->statusWindow != NULL){
StatusWindow *sw = pX11IMData->statusWindow;
XFreeGC(awt_display, sw->lightGC);
XFreeGC(awt_display, sw->dimGC);
XFreeGC(awt_display, sw->bgGC);
XFreeGC(awt_display, sw->fgGC);
if (sw->fontset != NULL) {
XFreeFontSet(awt_display, sw->fontset);
}
XDestroyWindow(awt_display, sw->w);
free((void*)sw);
}
- #endif
if (pX11IMData->callbacks)
free((void *)pX11IMData->callbacks);
if (env) {
- /* Remove the global reference from the list, so that
- the callback function or whoever refers to it could know.
- */
- removeX11InputMethodGRefFromList(pX11IMData->x11inputmethod);
(*env)->DeleteGlobalRef(env, pX11IMData->x11inputmethod);
}
- if (pX11IMData->lookup_buf) {
- free((void *)pX11IMData->lookup_buf);
- }
-
free((void *)pX11IMData);
}
/*
* Sets or unsets the focus to the given XIC.
--- 296,333 ----
}
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.
*** 453,462 ****
--- 377,389 ----
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;
*** 465,527 ****
/*
printf("lookupString: entering...\n");
*/
- if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
- currentX11InputMethodInstance = NULL;
- return False;
- }
-
pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
if (pX11IMData == NULL) {
- #if defined(__linux__) || defined(MACOSX)
return False;
- #else
- return result;
- #endif
}
if ((ic = pX11IMData->current_ic) == (XIC)0){
- #if defined(__linux__) || defined(MACOSX)
return False;
- #else
- return result;
- #endif
- }
-
- /* allocate the lookup buffer at the first invocation */
- if (pX11IMData->lookup_buf_len == 0) {
- pX11IMData->lookup_buf = (char *)malloc(INITIAL_LOOKUP_BUF_SIZE);
- if (pX11IMData->lookup_buf == NULL) {
- THROW_OUT_OF_MEMORY_ERROR();
- return result;
- }
- pX11IMData->lookup_buf_len = INITIAL_LOOKUP_BUF_SIZE;
}
! mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
! pX11IMData->lookup_buf_len - 1, &keysym, &status);
/*
* In case of overflow, a buffer is allocated and it retries
* XmbLookupString().
*/
if (status == XBufferOverflow) {
! free((void *)pX11IMData->lookup_buf);
! pX11IMData->lookup_buf_len = 0;
! pX11IMData->lookup_buf = (char *)malloc(mblen + 1);
! if (pX11IMData->lookup_buf == NULL) {
THROW_OUT_OF_MEMORY_ERROR();
return result;
}
! pX11IMData->lookup_buf_len = mblen + 1;
! mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
! pX11IMData->lookup_buf_len - 1, &keysym, &status);
}
! pX11IMData->lookup_buf[mblen] = 0;
/* Get keysym without taking modifiers into account first to map
* to AWT keyCode table.
*/
switch (status) {
--- 392,429 ----
/*
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) {
*** 534,585 ****
}
}
composing = False;
/*FALLTHRU*/
case XLookupChars:
! /*
! printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
! event->type, event->state, event->keycode, keysym);
! */
! javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
if (javastr != NULL) {
JNU_CallMethodByName(env, NULL,
currentX11InputMethodInstance,
"dispatchCommittedText",
"(Ljava/lang/String;J)V",
javastr,
event->time);
}
break;
case XLookupKeySym:
! /*
! printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
! event->type, event->state, event->keycode, keysym);
! */
if (keysym == XK_Multi_key)
composing = True;
if (! composing) {
*keysymp = keysym;
result = False;
}
break;
case XLookupNone:
! /*
! printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
! event->type, event->state, event->keycode, keysym);
! */
break;
}
return result;
}
! #if defined(__linux__) || defined(MACOSX)
! static StatusWindow *createStatusWindow(
! Window parent) {
StatusWindow *statusWindow;
XSetWindowAttributes attrib;
unsigned long attribmask;
Window containerWindow;
Window status;
--- 436,492 ----
}
}
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;
*** 598,611 ****
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;
XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
attrib.override_redirect = True;
attribmask = CWOverrideRedirect;
--- 505,526 ----
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;
*** 619,666 ****
bg = adata->AwtColorMatch(255, 255, 255, adata);
fg = adata->AwtColorMatch(0, 0, 0, adata);
light = adata->AwtColorMatch(195, 195, 195, adata);
dim = adata->AwtColorMatch(128, 128, 128, adata);
! XGetWindowAttributes(dpy, parent, &xwa);
bw = 2; /*xwa.border_width does not have the correct value*/
/*compare the size difference between parent container
and shell widget, the diff should be the border frame
and title bar height (?)*/
XQueryTree( dpy,
! parent,
&rootWindow,
&containerWindow,
&ignoreWindowPtr,
&ignoreUnit);
XGetWindowAttributes(dpy, containerWindow, &xxwa);
! off_x = (xxwa.width - xwa.width) / 2;
! off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */
/*get the size of root window*/
XGetWindowAttributes(dpy, rootWindow, &xxwa);
XTranslateCoordinates(dpy,
! parent, xwa.root,
xwa.x, xwa.y,
&x, &y,
&child);
xx = x - off_x;
yy = y + xwa.height - off_y;
if (xx < 0 ){
xx = 0;
}
! if (xx + width > xxwa.width){
xx = xxwa.width - width;
}
! if (yy + height > xxwa.height){
yy = xxwa.height - height;
}
status = XCreateWindow(dpy,
xwa.root,
xx, yy,
width, height,
0,
--- 534,610 ----
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,
*** 669,713 ****
adata->awt_visInfo.visual,
attribmask, &attrib);
XSelectInput(dpy, status,
ExposureMask | StructureNotifyMask | EnterWindowMask |
LeaveWindowMask | VisibilityChangeMask);
statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
if (statusWindow == NULL){
THROW_OUT_OF_MEMORY_ERROR();
return NULL;
}
statusWindow->w = status;
! //12-point font
! statusWindow->fontset = XCreateFontSet(dpy,
! "-*-*-medium-r-normal-*-*-120-*-*-*-*",
! &mclr, &mccr, &dsr);
! /* In case we didn't find the font set, release the list of missing characters */
! if (mccr > 0) {
! XFreeStringList(mclr);
! }
statusWindow->parent = parent;
statusWindow->on = False;
statusWindow->x = x;
statusWindow->y = y;
statusWindow->width = xwa.width;
statusWindow->height = xwa.height;
statusWindow->off_x = off_x;
statusWindow->off_y = off_y;
statusWindow->bWidth = bw;
statusWindow->statusH = height;
statusWindow->statusW = width;
statusWindow->rootH = xxwa.height;
statusWindow->rootW = xxwa.width;
statusWindow->lightGC = XCreateGC(dpy, status, valuemask, &values);
XSetForeground(dpy, statusWindow->lightGC, light);
statusWindow->dimGC = XCreateGC(dpy, status, valuemask, &values);
XSetForeground(dpy, statusWindow->dimGC, dim);
! statusWindow->fgGC = XCreateGC(dpy, status, valuemask, &values);
XSetForeground(dpy, statusWindow->fgGC, fg);
! statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
XSetForeground(dpy, statusWindow->bgGC, bg);
return statusWindow;
}
/* This method is to turn off or turn on the status window. */
static void onoffStatusWindow(X11InputMethodData* pX11IMData,
--- 613,662 ----
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,
*** 716,769 ****
XWindowAttributes xwa;
Window child;
int x, y;
StatusWindow *statusWindow = NULL;
! if (NULL == currentX11InputMethodInstance ||
! NULL == pX11IMData ||
NULL == (statusWindow = pX11IMData->statusWindow)){
return;
}
! if (ON == False){
XUnmapWindow(dpy, statusWindow->w);
- statusWindow->on = False;
return;
}
! parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
! "getCurrentParentWindow",
! "()J").j;
! if (statusWindow->parent != parent){
! statusWindow->parent = parent;
}
! XGetWindowAttributes(dpy, parent, &xwa);
! XTranslateCoordinates(dpy,
! parent, xwa.root,
! xwa.x, xwa.y,
! &x, &y,
! &child);
! if (statusWindow->x != x
! || statusWindow->y != y
! || statusWindow->height != xwa.height){
! statusWindow->x = x;
! statusWindow->y = y;
! statusWindow->height = xwa.height;
! x = statusWindow->x - statusWindow->off_x;
! y = statusWindow->y + statusWindow->height - statusWindow->off_y;
! if (x < 0 ){
! x = 0;
! }
! if (x + statusWindow->statusW > statusWindow->rootW){
! x = statusWindow->rootW - statusWindow->statusW;
! }
! if (y + statusWindow->statusH > statusWindow->rootH){
! y = statusWindow->rootH - statusWindow->statusH;
}
- XMoveWindow(dpy, statusWindow->w, x, y);
}
! statusWindow->on = True;
! XMapWindow(dpy, statusWindow->w);
}
void paintStatusWindow(StatusWindow *statusWindow){
Window win = statusWindow->w;
GC lightgc = statusWindow->lightGC;
--- 665,704 ----
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;
*** 772,896 ****
GC fggc = statusWindow->fgGC;
int width = statusWindow->statusW;
int height = statusWindow->statusH;
int bwidth = statusWindow->bWidth;
! XFillRectangle(dpy, win, bggc, 0, 0, width, height);
! /* draw border */
! XDrawLine(dpy, win, fggc, 0, 0, width, 0);
! XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
! XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
! XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);
!
! XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
! XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
! XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
! XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);
!
! XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
! XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
! XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
! XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
! if (statusWindow->fontset){
! XmbDrawString(dpy, win, statusWindow->fontset, fggc,
! bwidth + 2, height - bwidth - 4,
! statusWindow->status,
! strlen(statusWindow->status));
}
! else{
/*too bad we failed to create a fontset for this locale*/
XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
"[InputMethod ON]", strlen("[InputMethod ON]"));
}
}
! void statusWindowEventHandler(XEvent event){
JNIEnv *env = GetJNIEnv();
X11InputMethodData *pX11IMData = NULL;
StatusWindow *statusWindow;
! if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
! currentX11InputMethodInstance = NULL;
! return;
! }
!
! if (NULL == currentX11InputMethodInstance
! || NULL == (pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance))
! || NULL == (statusWindow = pX11IMData->statusWindow)
! || statusWindow->w != event.xany.window){
! return;
}
! switch (event.type){
! case Expose:
! paintStatusWindow(statusWindow);
! break;
! case MapNotify:
! case ConfigureNotify:
! {
! /*need to reset the stackMode...*/
! XWindowChanges xwc;
! int value_make = CWStackMode;
! xwc.stack_mode = TopIf;
! XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
! }
! break;
/*
! case UnmapNotify:
! case VisibilityNotify:
! break;
*/
! default:
! break;
! }
}
! static void adjustStatusWindow(Window shell){
JNIEnv *env = GetJNIEnv();
X11InputMethodData *pX11IMData = NULL;
StatusWindow *statusWindow;
if (NULL == currentX11InputMethodInstance
- || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
|| NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
|| NULL == (statusWindow = pX11IMData->statusWindow)
! || !statusWindow->on) {
! return;
! }
{
! XWindowAttributes xwa;
! int x, y;
! Window child;
! XGetWindowAttributes(dpy, shell, &xwa);
! XTranslateCoordinates(dpy,
! shell, xwa.root,
! xwa.x, xwa.y,
! &x, &y,
! &child);
! if (statusWindow->x != x
! || statusWindow->y != y
! || statusWindow->height != xwa.height){
! statusWindow->x = x;
! statusWindow->y = y;
! statusWindow->height = xwa.height;
!
! x = statusWindow->x - statusWindow->off_x;
! y = statusWindow->y + statusWindow->height - statusWindow->off_y;
! if (x < 0 ){
! x = 0;
! }
! if (x + statusWindow->statusW > statusWindow->rootW){
! x = statusWindow->rootW - statusWindow->statusW;
! }
! if (y + statusWindow->statusH > statusWindow->rootH){
! y = statusWindow->rootH - statusWindow->statusH;
! }
! XMoveWindow(dpy, statusWindow->w, x, y);
! }
}
}
! #endif /* __linux__ || MACOSX */
/*
* 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.
*
--- 707,828 ----
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.
*
*** 907,939 ****
createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
{
XVaNestedList preedit = NULL;
XVaNestedList status = NULL;
XIMStyle on_the_spot_styles = XIMPreeditCallbacks,
active_styles = 0,
passive_styles = 0,
no_styles = 0;
XIMCallback *callbacks;
unsigned short i;
XIMStyles *im_styles;
char *ret = NULL;
if (X11im == NULL) {
return False;
}
if (!w) {
return False;
}
ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);
if (ret != NULL) {
jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
return FALSE ;
}
- #if defined(__linux__) || defined(MACOSX)
on_the_spot_styles |= XIMStatusNothing;
/*kinput does not support XIMPreeditCallbacks and XIMStatusArea
at the same time, so use StatusCallback to draw the status
ourself
--- 839,881 ----
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
*** 942,988 ****
if (im_styles->supported_styles[i] == (XIMPreeditCallbacks | XIMStatusCallbacks)) {
on_the_spot_styles = (XIMPreeditCallbacks | XIMStatusCallbacks);
break;
}
}
- #else /*! __linux__ && !MACOSX */
- on_the_spot_styles |= XIMStatusNothing;
- #endif /* __linux__ || MACOSX */
for (i = 0; i < im_styles->count_styles; i++) {
! active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
! passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES;
! no_styles |= im_styles->supported_styles[i] & NO_STYLES;
}
XFree(im_styles);
if (active_styles != on_the_spot_styles) {
if (passive_styles == ROOT_WINDOW_STYLES)
active_styles = passive_styles;
else {
if (no_styles == NO_STYLES)
active_styles = passive_styles = NO_STYLES;
else
active_styles = passive_styles = 0;
}
} else {
if (passive_styles != ROOT_WINDOW_STYLES) {
if (no_styles == NO_STYLES)
active_styles = passive_styles = NO_STYLES;
else
active_styles = passive_styles = 0;
}
}
if (active_styles == on_the_spot_styles) {
- pX11IMData->ic_passive = XCreateIC(X11im,
- XNClientWindow, w,
- XNFocusWindow, w,
- XNInputStyle, passive_styles,
- NULL);
-
callbacks = (XIMCallback *)malloc(sizeof(XIMCallback) * NCALLBACKS);
if (callbacks == (XIMCallback *)NULL)
return False;
pX11IMData->callbacks = callbacks;
--- 884,935 ----
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;
*** 998,1090 ****
XNPreeditDrawCallback, &callbacks[PreeditDrawIndex],
XNPreeditCaretCallback, &callbacks[PreeditCaretIndex],
NULL);
if (preedit == (XVaNestedList)NULL)
goto err;
- #if defined(__linux__) || defined(MACOSX)
/*always try XIMStatusCallbacks for active client...*/
{
status = (XVaNestedList)XVaCreateNestedList(0,
XNStatusStartCallback, &callbacks[StatusStartIndex],
XNStatusDoneCallback, &callbacks[StatusDoneIndex],
XNStatusDrawCallback, &callbacks[StatusDrawIndex],
NULL);
if (status == NULL)
goto err;
pX11IMData->statusWindow = createStatusWindow(w);
pX11IMData->ic_active = XCreateIC(X11im,
XNClientWindow, w,
XNFocusWindow, w,
XNInputStyle, active_styles,
XNPreeditAttributes, preedit,
XNStatusAttributes, status,
NULL);
XFree((void *)status);
XFree((void *)preedit);
}
! #else /* !__linux__ && !MACOSX */
! pX11IMData->ic_active = XCreateIC(X11im,
! XNClientWindow, w,
! XNFocusWindow, w,
! XNInputStyle, active_styles,
! XNPreeditAttributes, preedit,
! NULL);
! XFree((void *)preedit);
! #endif /* __linux__ || MACOSX */
} else {
pX11IMData->ic_active = XCreateIC(X11im,
XNClientWindow, w,
XNFocusWindow, w,
XNInputStyle, active_styles,
NULL);
pX11IMData->ic_passive = pX11IMData->ic_active;
}
if (pX11IMData->ic_active == (XIC)0
|| pX11IMData->ic_passive == (XIC)0) {
return False;
}
! /*
! * Use commit string call back if possible.
! * This will ensure the correct order of preedit text and commit text
! */
! {
! XIMCallback cb;
! cb.client_data = (XPointer) pX11IMData->x11inputmethod;
! cb.callback = (XIMProc) CommitStringCallback;
! XSetICValues (pX11IMData->ic_active, XNCommitStringCallback, &cb, NULL);
! if (pX11IMData->ic_active != pX11IMData->ic_passive) {
! XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
! }
! }
!
! /* Add the global reference object to X11InputMethod to the list. */
! addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
return True;
err:
if (preedit)
XFree((void *)preedit);
THROW_OUT_OF_MEMORY_ERROR();
return False;
}
! static void
PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{
! /*ARGSUSED*/
! /* printf("Native: PreeditCaretCallback\n"); */
}
static void
PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
{
! /*ARGSUSED*/
! /* printf("Native: StatusStartCallback\n"); */
}
/*
* Translate the preedit draw callback items to Java values and invoke
* X11InputMethod.dispatchComposedText().
--- 945,1071 ----
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().
*** 1106,1141 ****
/* printf("Native: PreeditDrawCallback() \n"); */
if (pre_draw == NULL) {
return;
}
AWT_LOCK();
! if (!isX11InputMethodGRefInList((jobject)client_data)) {
! if ((jobject)client_data == currentX11InputMethodInstance) {
! currentX11InputMethodInstance = NULL;
! }
goto finally;
}
! if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
goto finally;
}
if ((text = pre_draw->text) != NULL) {
! if (text->string.multi_byte != NULL) {
! if (pre_draw->text->encoding_is_wchar == False) {
! javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
! 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;
--- 1087,1125 ----
/* 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;
*** 1174,1384 ****
style,
(jint)pre_draw->chg_first,
(jint)pre_draw->chg_length,
(jint)pre_draw->caret,
awt_util_nowMillisUTC());
finally:
AWT_UNLOCK();
return;
}
static void
PreeditCaretCallback(XIC ic, XPointer client_data,
XIMPreeditCaretCallbackStruct *pre_caret)
{
! /*ARGSUSED*/
! /* printf("Native: PreeditCaretCallback\n"); */
}
- #if defined(__linux__) || defined(MACOSX)
static void
StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{
/*ARGSUSED*/
/*printf("StatusStartCallback:\n"); */
-
}
static void
StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
{
/*ARGSUSED*/
/*printf("StatusDoneCallback:\n"); */
-
}
! static void
! StatusDrawCallback(XIC ic, XPointer client_data,
! XIMStatusDrawCallbackStruct *status_draw)
{
/*ARGSUSED*/
/*printf("StatusDrawCallback:\n"); */
JNIEnv *env = GetJNIEnv();
X11InputMethodData *pX11IMData = NULL;
StatusWindow *statusWindow;
AWT_LOCK();
- if (!isX11InputMethodGRefInList((jobject)client_data)) {
- if ((jobject)client_data == currentX11InputMethodInstance) {
- currentX11InputMethodInstance = NULL;
- }
- goto finally;
- }
-
if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
|| NULL == (statusWindow = pX11IMData->statusWindow)){
goto finally;
}
- currentX11InputMethodInstance = (jobject)client_data;
! if (status_draw->type == XIMTextType){
XIMText *text = (status_draw->data).text;
! if (text != NULL){
! if (text->string.multi_byte != NULL) {
! 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);
*/
onoffStatusWindow(pX11IMData, 0, False);
}
}
finally:
AWT_UNLOCK();
}
- #endif /* __linux__ || MACOSX */
! static void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
! JNIEnv *env = GetJNIEnv();
! XIMText * text = (XIMText *)call_data;
! X11InputMethodData *pX11IMData = NULL;
! jstring javastr;
! AWT_LOCK();
! if (!isX11InputMethodGRefInList((jobject)client_data)) {
! if ((jobject)client_data == currentX11InputMethodInstance) {
! currentX11InputMethodInstance = NULL;
! }
! goto finally;
}
! if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
! goto finally;
}
! currentX11InputMethodInstance = (jobject)client_data;
! if (text->encoding_is_wchar == False) {
! javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
} else {
! char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
! if (mbstr == NULL) {
! goto finally;
}
- javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
- free(mbstr);
}
! if (javastr != NULL) {
! JNU_CallMethodByName(env, NULL,
! pX11IMData->x11inputmethod,
! "dispatchCommittedText",
! "(Ljava/lang/String;J)V",
! javastr,
! awt_util_nowMillisUTC());
}
! finally:
! AWT_UNLOCK();
}
! static void OpenXIMCallback(Display *display, XPointer client_data, XPointer call_data) {
! XIMCallback ximCallback;
! X11im = XOpenIM(display, NULL, NULL, NULL);
! if (X11im == NULL) {
return;
}
! ximCallback.callback = (XIMProc)DestroyXIMCallback;
! ximCallback.client_data = NULL;
! XSetIMValues(X11im, XNDestroyCallback, &ximCallback, NULL);
}
! static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
! /* mark that XIM server was destroyed */
! X11im = NULL;
! JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
! /* free the old pX11IMData and set it to null. this also avoids crashing
! * the jvm if the XIM server reappears */
! 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)
{
Bool registered;
AWT_LOCK();
dpy = (Display *)jlong_to_ptr(display);
! /* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
! (4768335)
! */
! #if defined(__linux__) || defined(MACOSX)
! registered = XRegisterIMInstantiateCallback(dpy, NULL, NULL,
! NULL, (XIDProc)OpenXIMCallback, NULL);
! if (!registered) {
! /* directly call openXIM callback */
! #endif
! OpenXIMCallback(dpy, NULL, NULL);
! #if defined(__linux__) || defined(MACOSX)
}
- #endif
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;
--- 1158,1922 ----
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;
*** 1397,1434 ****
return JNI_FALSE;
}
globalRef = (*env)->NewGlobalRef(env, this);
pX11IMData->x11inputmethod = globalRef;
- #if defined(__linux__) || defined(MACOSX)
pX11IMData->statusWindow = NULL;
- #endif /* __linux__ || MACOSX */
! pX11IMData->lookup_buf = 0;
! pX11IMData->lookup_buf_len = 0;
if (createXIC(env, pX11IMData, (Window)window) == False) {
destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
pX11IMData = (X11InputMethodData *) NULL;
if ((*env)->ExceptionCheck(env)) {
goto finally;
}
}
- setX11InputMethodData(env, this, pX11IMData);
-
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) {
--- 1935,1968 ----
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) {
*** 1439,1505 ****
if (req) {
if (!w) {
AWT_UNLOCK();
return;
}
pX11IMData->current_ic = active ?
pX11IMData->ic_active : pX11IMData->ic_passive;
/*
* On Solaris2.6, setXICWindowFocus() has to be invoked
* before setting focus.
*/
! setXICWindowFocus(pX11IMData->current_ic, w);
! setXICFocus(pX11IMData->current_ic, req);
! currentX11InputMethodInstance = pX11IMData->x11inputmethod;
! currentFocusWindow = w;
! #if defined(__linux__) || defined(MACOSX)
! if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
onoffStatusWindow(pX11IMData, w, True);
- #endif
} else {
currentX11InputMethodInstance = NULL;
currentFocusWindow = 0;
- #if defined(__linux__) || defined(MACOSX)
onoffStatusWindow(pX11IMData, 0, False);
if (pX11IMData->current_ic != NULL)
- #endif
setXICFocus(pX11IMData->current_ic, req);
pX11IMData->current_ic = (XIC)0;
}
XFlush(dpy);
AWT_UNLOCK();
}
! JNIEXPORT void JNICALL
! Java_sun_awt_X11InputMethod_turnoffStatusWindow(JNIEnv *env,
! jobject this)
{
- #if defined(__linux__) || defined(MACOSX)
X11InputMethodData *pX11IMData;
StatusWindow *statusWindow;
AWT_LOCK();
if (NULL == currentX11InputMethodInstance
- || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
|| NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
|| NULL == (statusWindow = pX11IMData->statusWindow)
|| !statusWindow->on ){
AWT_UNLOCK();
return;
}
onoffStatusWindow(pX11IMData, 0, False);
AWT_UNLOCK();
- #endif
}
! JNIEXPORT void JNICALL
! Java_sun_awt_X11InputMethod_disposeXIC(JNIEnv *env,
! jobject this)
{
X11InputMethodData *pX11IMData = NULL;
AWT_LOCK();
pX11IMData = getX11InputMethodData(env, this);
--- 1973,2062 ----
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);
*** 1516,1528 ****
}
destroyX11InputMethodData(env, pX11IMData);
AWT_UNLOCK();
}
! JNIEXPORT jstring JNICALL
! Java_sun_awt_X11InputMethod_resetXIC(JNIEnv *env,
! jobject this)
{
X11InputMethodData *pX11IMData;
char *xText = NULL;
jstring jText = (jstring)0;
--- 2073,2089 ----
}
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;
*** 1531,1651 ****
if (pX11IMData == NULL) {
AWT_UNLOCK();
return jText;
}
! if (pX11IMData->current_ic)
! xText = XmbResetIC(pX11IMData->current_ic);
! else {
/*
* If there is no reference to the current XIC, try to reset both XICs.
*/
xText = XmbResetIC(pX11IMData->ic_active);
/*it may also means that the real client component does
not have focus -- has been deactivated... its xic should
not have the focus, bug#4284651 showes reset XIC for htt
may bring the focus back, so de-focus it again.
*/
setXICFocus(pX11IMData->ic_active, FALSE);
if (pX11IMData->ic_active != pX11IMData->ic_passive) {
! char *tmpText = XmbResetIC(pX11IMData->ic_passive);
setXICFocus(pX11IMData->ic_passive, FALSE);
if (xText == (char *)NULL && tmpText)
xText = tmpText;
}
-
}
if (xText != NULL) {
jText = JNU_NewStringPlatform(env, (const char *)xText);
XFree((void *)xText);
}
AWT_UNLOCK();
return jText;
}
/*
! * Class: sun_awt_X11InputMethod
* Method: setCompositionEnabledNative
! * Signature: (ZJ)V
*
* This method tries to set the XNPreeditState attribute associated with the current
* XIC to the passed in 'enable' state.
*
* Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
* 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
* java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
* method fails due to other reasons.
- *
*/
! JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_setCompositionEnabledNative
(JNIEnv *env, jobject this, jboolean enable)
{
X11InputMethodData *pX11IMData;
char * ret = NULL;
AWT_LOCK();
pX11IMData = getX11InputMethodData(env, this);
if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
AWT_UNLOCK();
return JNI_FALSE;
}
! ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
! (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
AWT_UNLOCK();
! if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
}
return (jboolean)(ret == 0);
}
/*
! * Class: sun_awt_X11InputMethod
* Method: isCompositionEnabledNative
! * Signature: (J)Z
*
* This method tries to get the XNPreeditState attribute associated with the current XIC.
*
* Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
* XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
* will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
- *
*/
! JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_isCompositionEnabledNative
(JNIEnv *env, jobject this)
{
X11InputMethodData *pX11IMData = NULL;
char * ret = NULL;
! XIMPreeditState state;
AWT_LOCK();
pX11IMData = getX11InputMethodData(env, this);
if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
AWT_UNLOCK();
return JNI_FALSE;
}
! ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
AWT_UNLOCK();
! if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
return JNI_FALSE;
}
return (jboolean)(state == XIMPreeditEnable);
}
JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
(JNIEnv *env, jobject this, jlong window)
{
! #if defined(__linux__) || defined(MACOSX)
! AWT_LOCK();
! adjustStatusWindow(window);
! AWT_UNLOCK();
! #endif
}
--- 2092,2269 ----
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;
}
< prev index next >