Bug Summary

File:jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
Warning:line 1194, column 21
Although the value stored to 'statusWindow' is used in the enclosing expression, the value is never actually read from 'statusWindow'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name awt_InputMethod.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D XAWT -D XAWT_HACK -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt_xawt -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/awt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/font -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/font -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.desktop -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image/cvutils -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/loops -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/pipe -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt_xawt/awt -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/include -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/include -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/awt/systemscale -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/font -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/font -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/java2d/opengl -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/java2d/opengl -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/java2d/x11 -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wno-unused -Wno-type-limits -Wno-pointer-to-int-cast -Wno-unused-result -Wno-maybe-uninitialized -Wno-format -Wno-format-security -Wno-int-to-pointer-cast -Wno-parentheses -Wno-implicit-fallthrough -Wno-undef -Wno-unused-function -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
1/*
2 * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#ifdef HEADLESS
27 #error This file should not be included in headless library
28#endif
29
30#include "awt.h"
31#include "awt_p.h"
32
33#include <sun_awt_X11InputMethodBase.h>
34#include <sun_awt_X11_XInputMethod.h>
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <sys/time.h>
39#include <X11/keysym.h>
40#include <X11/Xlib.h>
41
42#define THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
\
43 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_20x00010002), NULL((void*)0))
44
45struct X11InputMethodIDs {
46 jfieldID pData;
47} x11InputMethodIDs;
48
49static int PreeditStartCallback(XIC, XPointer, XPointer);
50static void PreeditDoneCallback(XIC, XPointer, XPointer);
51static void PreeditDrawCallback(XIC, XPointer,
52 XIMPreeditDrawCallbackStruct *);
53static void PreeditCaretCallback(XIC, XPointer,
54 XIMPreeditCaretCallbackStruct *);
55#if defined(__linux__1)
56static void StatusStartCallback(XIC, XPointer, XPointer);
57static void StatusDoneCallback(XIC, XPointer, XPointer);
58static void StatusDrawCallback(XIC, XPointer,
59 XIMStatusDrawCallbackStruct *);
60#endif
61
62#define ROOT_WINDOW_STYLES(0x0008L | 0x0400L) (XIMPreeditNothing0x0008L | XIMStatusNothing0x0400L)
63#define NO_STYLES(0x0010L | 0x0800L) (XIMPreeditNone0x0010L | XIMStatusNone0x0800L)
64
65#define PreeditStartIndex0 0
66#define PreeditDoneIndex1 1
67#define PreeditDrawIndex2 2
68#define PreeditCaretIndex3 3
69#if defined(__linux__1)
70#define StatusStartIndex4 4
71#define StatusDoneIndex5 5
72#define StatusDrawIndex6 6
73#define NCALLBACKS7 7
74#else
75#define NCALLBACKS7 4
76#endif
77
78/*
79 * Callback function pointers: the order has to match the *Index
80 * values above.
81 */
82static XIMProc callback_funcs[NCALLBACKS7] = {
83 (XIMProc)(void *)&PreeditStartCallback,
84 (XIMProc)PreeditDoneCallback,
85 (XIMProc)PreeditDrawCallback,
86 (XIMProc)PreeditCaretCallback,
87#if defined(__linux__1)
88 (XIMProc)StatusStartCallback,
89 (XIMProc)StatusDoneCallback,
90 (XIMProc)StatusDrawCallback,
91#endif
92};
93
94#if defined(__linux__1)
95#define MAX_STATUS_LEN100 100
96typedef struct {
97 Window w; /*status window id */
98 Window root; /*the root window id */
99 Window parent; /*parent shell window */
100 int x, y; /*parent's upperleft position */
101 int width, height; /*parent's width, height */
102 GC lightGC; /*gc for light border */
103 GC dimGC; /*gc for dim border */
104 GC bgGC; /*normal painting */
105 GC fgGC; /*normal painting */
106 int statusW, statusH; /*status window's w, h */
107 int rootW, rootH; /*root window's w, h */
108 int bWidth; /*border width */
109 char status[MAX_STATUS_LEN100]; /*status text */
110 XFontSet fontset; /*fontset for drawing */
111 int off_x, off_y;
112 Boolint on; /*if the status window on*/
113} StatusWindow;
114#endif
115
116/*
117 * X11InputMethodData keeps per X11InputMethod instance information. A pointer
118 * to this data structure is kept in an X11InputMethod object (pData).
119 */
120typedef struct _X11InputMethodData {
121 XIC current_ic; /* current X Input Context */
122 XIC ic_active; /* X Input Context for active clients */
123 XIC ic_passive; /* X Input Context for passive clients */
124 XIMCallback *callbacks; /* callback parameters */
125 jobject x11inputmethod; /* global ref to X11InputMethod instance */
126 /* associated with the XIC */
127#if defined(__linux__1)
128 StatusWindow *statusWindow; /* our own status window */
129#endif
130 char *lookup_buf; /* buffer used for XmbLookupString */
131 int lookup_buf_len; /* lookup buffer size in bytes */
132} X11InputMethodData;
133
134/*
135 * When XIC is created, a global reference is created for
136 * sun.awt.X11InputMethod object so that it could be used by the XIM callback
137 * functions. This could be a dangerous thing to do when the original
138 * X11InputMethod object is garbage collected and as a result,
139 * destroyX11InputMethodData is called to delete the global reference.
140 * If any XIM callback function still holds and uses the "already deleted"
141 * global reference, disaster is going to happen. So we have to maintain
142 * a list for these global references which is consulted first when the
143 * callback functions or any function tries to use "currentX11InputMethodObject"
144 * which always refers to the global reference try to use it.
145 *
146 */
147typedef struct _X11InputMethodGRefNode {
148 jobject inputMethodGRef;
149 struct _X11InputMethodGRefNode* next;
150} X11InputMethodGRefNode;
151
152X11InputMethodGRefNode *x11InputMethodGRefListHead = NULL((void*)0);
153
154/* reference to the current X11InputMethod instance, it is always
155 point to the global reference to the X11InputMethodObject since
156 it could be referenced by different threads. */
157jobject currentX11InputMethodInstance = NULL((void*)0);
158
159Window currentFocusWindow = 0; /* current window that has focus for input
160 method. (the best place to put this
161 information should be
162 currentX11InputMethodInstance's pData) */
163static XIM X11im = NULL((void*)0);
164Display * dpy = NULL((void*)0);
165
166#define GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002) (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_20x00010002)
167
168static void DestroyXIMCallback(XIM, XPointer, XPointer);
169static void OpenXIMCallback(Display *, XPointer, XPointer);
170/* Solaris XIM Extention */
171#define XNCommitStringCallback"commitStringCallback" "commitStringCallback"
172static void CommitStringCallback(XIC, XPointer, XPointer);
173
174static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
175static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
176static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
177static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
178#if defined(__linux__1)
179static Window getParentWindow(Window);
180#endif
181
182/*
183 * This function is stolen from /src/solaris/hpi/src/system_md.c
184 * It is used in setting the time in Java-level InputEvents
185 */
186jlong
187awt_util_nowMillisUTC()
188{
189 struct timeval t;
190 gettimeofday(&t, NULL((void*)0));
191 return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
192}
193
194/*
195 * Converts the wchar_t string to a multi-byte string calling wcstombs(). A
196 * buffer is allocated by malloc() to store the multi-byte string. NULL is
197 * returned if the given wchar_t string pointer is NULL or buffer allocation is
198 * failed.
199 */
200static char *
201wcstombsdmp(wchar_t *wcs, int len)
202{
203 size_t n;
204 char *mbs;
205
206 if (wcs == NULL((void*)0))
207 return NULL((void*)0);
208
209 n = len*MB_CUR_MAX(__ctype_get_mb_cur_max ()) + 1;
210
211 mbs = (char *) malloc(n * sizeof(char));
212 if (mbs == NULL((void*)0)) {
213 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
214 return NULL((void*)0);
215 }
216
217 /* TODO: check return values... Handle invalid characters properly... */
218 if (wcstombs(mbs, wcs, n) == (size_t)-1) {
219 free(mbs);
220 return NULL((void*)0);
221 }
222
223 return mbs;
224}
225
226/*
227 * Returns True if the global reference is still in the list,
228 * otherwise False.
229 */
230static Boolint isX11InputMethodGRefInList(jobject imGRef) {
231 X11InputMethodGRefNode *pX11InputMethodGRef = x11InputMethodGRefListHead;
232
233 if (imGRef == NULL((void*)0)) {
234 return False0;
235 }
236
237 while (pX11InputMethodGRef != NULL((void*)0)) {
238 if (pX11InputMethodGRef->inputMethodGRef == imGRef) {
239 return True1;
240 }
241 pX11InputMethodGRef = pX11InputMethodGRef->next;
242 }
243
244 return False0;
245}
246
247/*
248 * Add the new created global reference to the list.
249 */
250static void addToX11InputMethodGRefList(jobject newX11InputMethodGRef) {
251 X11InputMethodGRefNode *newNode = NULL((void*)0);
252
253 if (newX11InputMethodGRef == NULL((void*)0) ||
254 isX11InputMethodGRefInList(newX11InputMethodGRef)) {
255 return;
256 }
257
258 newNode = (X11InputMethodGRefNode *)malloc(sizeof(X11InputMethodGRefNode));
259
260 if (newNode == NULL((void*)0)) {
261 return;
262 } else {
263 newNode->inputMethodGRef = newX11InputMethodGRef;
264 newNode->next = x11InputMethodGRefListHead;
265 x11InputMethodGRefListHead = newNode;
266 }
267}
268
269/*
270 * Remove the global reference from the list.
271 */
272static void removeX11InputMethodGRefFromList(jobject x11InputMethodGRef) {
273 X11InputMethodGRefNode *pX11InputMethodGRef = NULL((void*)0);
274 X11InputMethodGRefNode *cX11InputMethodGRef = x11InputMethodGRefListHead;
275
276 if (x11InputMethodGRefListHead == NULL((void*)0) ||
277 x11InputMethodGRef == NULL((void*)0)) {
278 return;
279 }
280
281 /* cX11InputMethodGRef always refers to the current node while
282 pX11InputMethodGRef refers to the previous node.
283 */
284 while (cX11InputMethodGRef != NULL((void*)0)) {
285 if (cX11InputMethodGRef->inputMethodGRef == x11InputMethodGRef) {
286 break;
287 }
288 pX11InputMethodGRef = cX11InputMethodGRef;
289 cX11InputMethodGRef = cX11InputMethodGRef->next;
290 }
291
292 if (cX11InputMethodGRef == NULL((void*)0)) {
293 return; /* Not found. */
294 }
295
296 if (cX11InputMethodGRef == x11InputMethodGRefListHead) {
297 x11InputMethodGRefListHead = x11InputMethodGRefListHead->next;
298 } else {
299 pX11InputMethodGRef->next = cX11InputMethodGRef->next;
300 }
301 free(cX11InputMethodGRef);
302
303 return;
304}
305
306
307static X11InputMethodData * getX11InputMethodData(JNIEnv * env, jobject imInstance) {
308 X11InputMethodData *pX11IMData =
309 (X11InputMethodData *)JNU_GetLongFieldAsPtr(env, imInstance, x11InputMethodIDs.pData)(((void*)((*(env))->GetLongField((env),(imInstance),(x11InputMethodIDs
.pData)))))
;
310
311 /*
312 * In case the XIM server was killed somehow, reset X11InputMethodData.
313 */
314 if (X11im == NULL((void*)0) && pX11IMData != NULL((void*)0)) {
315 JNU_CallMethodByName(env, NULL((void*)0), pX11IMData->x11inputmethod,
316 "flushText",
317 "()V");
318 JNU_CHECK_EXCEPTION_RETURN(env, NULL)do { if ((*env)->ExceptionCheck(env)) { return (((void*)0)
); } } while (0)
;
319 /* IMPORTANT:
320 The order of the following calls is critical since "imInstance" may
321 point to the global reference itself, if "freeX11InputMethodData" is called
322 first, the global reference will be destroyed and "setX11InputMethodData"
323 will in fact fail silently. So pX11IMData will not be set to NULL.
324 This could make the original java object refers to a deleted pX11IMData
325 object.
326 */
327 setX11InputMethodData(env, imInstance, NULL((void*)0));
328 freeX11InputMethodData(env, pX11IMData);
329 pX11IMData = NULL((void*)0);
330 }
331
332 return pX11IMData;
333}
334
335static void setX11InputMethodData(JNIEnv * env, jobject imInstance, X11InputMethodData *pX11IMData) {
336 JNU_SetLongFieldFromPtr(env, imInstance, x11InputMethodIDs.pData, pX11IMData)(*(env))->SetLongField((env),(imInstance),(x11InputMethodIDs
.pData),((jlong)(pX11IMData)))
;
337}
338
339/* this function should be called within AWT_LOCK() */
340static void
341destroyX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
342{
343 /*
344 * Destroy XICs
345 */
346 if (pX11IMData == NULL((void*)0)) {
347 return;
348 }
349
350 if (pX11IMData->ic_active != (XIC)0) {
351 XUnsetICFocus(pX11IMData->ic_active);
352 XDestroyIC(pX11IMData->ic_active);
353 if (pX11IMData->ic_active != pX11IMData->ic_passive) {
354 if (pX11IMData->ic_passive != (XIC)0) {
355 XUnsetICFocus(pX11IMData->ic_passive);
356 XDestroyIC(pX11IMData->ic_passive);
357 }
358 pX11IMData->ic_passive = (XIC)0;
359 pX11IMData->current_ic = (XIC)0;
360 }
361 }
362
363 freeX11InputMethodData(env, pX11IMData);
364}
365
366static void
367freeX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
368{
369#if defined(__linux__1)
370 if (pX11IMData->statusWindow != NULL((void*)0)){
371 StatusWindow *sw = pX11IMData->statusWindow;
372 XFreeGC(awt_display, sw->lightGC);
373 XFreeGC(awt_display, sw->dimGC);
374 XFreeGC(awt_display, sw->bgGC);
375 XFreeGC(awt_display, sw->fgGC);
376 if (sw->fontset != NULL((void*)0)) {
377 XFreeFontSet(awt_display, sw->fontset);
378 }
379 XDestroyWindow(awt_display, sw->w);
380 free((void*)sw);
381 }
382#endif
383
384 if (pX11IMData->callbacks)
385 free((void *)pX11IMData->callbacks);
386
387 if (env) {
388 /* Remove the global reference from the list, so that
389 the callback function or whoever refers to it could know.
390 */
391 removeX11InputMethodGRefFromList(pX11IMData->x11inputmethod);
392 (*env)->DeleteGlobalRef(env, pX11IMData->x11inputmethod);
393 }
394
395 if (pX11IMData->lookup_buf) {
396 free((void *)pX11IMData->lookup_buf);
397 }
398
399 free((void *)pX11IMData);
400}
401
402/*
403 * Sets or unsets the focus to the given XIC.
404 */
405static void
406setXICFocus(XIC ic, unsigned short req)
407{
408 if (ic == NULL((void*)0)) {
409 (void)fprintf(stderr, "Couldn't find X Input Context\n")__fprintf_chk (stderr, 2 - 1, "Couldn't find X Input Context\n"
)
;
410 return;
411 }
412 if (req == 1)
413 XSetICFocus(ic);
414 else
415 XUnsetICFocus(ic);
416}
417
418/*
419 * Sets the focus window to the given XIC.
420 */
421static void
422setXICWindowFocus(XIC ic, Window w)
423{
424 if (ic == NULL((void*)0)) {
425 (void)fprintf(stderr, "Couldn't find X Input Context\n")__fprintf_chk (stderr, 2 - 1, "Couldn't find X Input Context\n"
)
;
426 return;
427 }
428 (void) XSetICValues(ic, XNFocusWindow"focusWindow", w, NULL((void*)0));
429}
430
431/*
432 * Invokes XmbLookupString() to get something from the XIM. It invokes
433 * X11InputMethod.dispatchCommittedText() if XmbLookupString() returns
434 * committed text. This function is called from handleKeyEvent in canvas.c and
435 * it's under the Motif event loop thread context.
436 *
437 * Buffer usage: There is a bug in XFree86-4.3.0 XmbLookupString implementation,
438 * where it never returns XBufferOverflow. We need to allocate the initial lookup buffer
439 * big enough, so that the possibility that user encounters this problem is relatively
440 * small. When this bug gets fixed, we can make the initial buffer size smaller.
441 * Note that XmbLookupString() sometimes produces a non-null-terminated string.
442 *
443 * Returns True when there is a keysym value to be handled.
444 */
445#define INITIAL_LOOKUP_BUF_SIZE512 512
446
447Boolean
448awt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
449{
450 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
451 X11InputMethodData *pX11IMData = NULL((void*)0);
452 KeySym keysym = NoSymbol0L;
453 Statusint status;
454 int mblen;
455 jstring javastr;
456 XIC ic;
457 Boolean result = True1;
458 static Boolean composing = False0;
459
460 /*
461 printf("lookupString: entering...\n");
462 */
463
464 if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
465 currentX11InputMethodInstance = NULL((void*)0);
466 return False0;
467 }
468
469 pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
470
471 if (pX11IMData == NULL((void*)0)) {
472#if defined(__linux__1)
473 return False0;
474#else
475 return result;
476#endif
477 }
478
479 if ((ic = pX11IMData->current_ic) == (XIC)0){
480#if defined(__linux__1)
481 return False0;
482#else
483 return result;
484#endif
485 }
486
487 /* allocate the lookup buffer at the first invocation */
488 if (pX11IMData->lookup_buf_len == 0) {
489 pX11IMData->lookup_buf = (char *)malloc(INITIAL_LOOKUP_BUF_SIZE512);
490 if (pX11IMData->lookup_buf == NULL((void*)0)) {
491 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
492 return result;
493 }
494 pX11IMData->lookup_buf_len = INITIAL_LOOKUP_BUF_SIZE512;
495 }
496
497 mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
498 pX11IMData->lookup_buf_len - 1, &keysym, &status);
499
500 /*
501 * In case of overflow, a buffer is allocated and it retries
502 * XmbLookupString().
503 */
504 if (status == XBufferOverflow-1) {
505 free((void *)pX11IMData->lookup_buf);
506 pX11IMData->lookup_buf_len = 0;
507 pX11IMData->lookup_buf = (char *)malloc(mblen + 1);
508 if (pX11IMData->lookup_buf == NULL((void*)0)) {
509 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
510 return result;
511 }
512 pX11IMData->lookup_buf_len = mblen + 1;
513 mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
514 pX11IMData->lookup_buf_len - 1, &keysym, &status);
515 }
516 pX11IMData->lookup_buf[mblen] = 0;
517
518 /* Get keysym without taking modifiers into account first to map
519 * to AWT keyCode table.
520 */
521 switch (status) {
522 case XLookupBoth4:
523 if (!composing) {
524 if (event->keycode != 0) {
525 *keysymp = keysym;
526 result = False0;
527 break;
528 }
529 }
530 composing = False0;
531 /*FALLTHRU*/
532 case XLookupChars2:
533 /*
534 printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
535 event->type, event->state, event->keycode, keysym);
536 */
537 javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
538 if (javastr != NULL((void*)0)) {
539 JNU_CallMethodByName(env, NULL((void*)0),
540 currentX11InputMethodInstance,
541 "dispatchCommittedText",
542 "(Ljava/lang/String;J)V",
543 javastr,
544 event->time);
545 }
546 break;
547
548 case XLookupKeySym3:
549 /*
550 printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
551 event->type, event->state, event->keycode, keysym);
552 */
553 if (keysym == XK_Multi_key0xff20)
554 composing = True1;
555 if (! composing) {
556 *keysymp = keysym;
557 result = False0;
558 }
559 break;
560
561 case XLookupNone1:
562 /*
563 printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
564 event->type, event->state, event->keycode, keysym);
565 */
566 break;
567 }
568
569 return result;
570}
571
572#if defined(__linux__1)
573static StatusWindow *createStatusWindow(Window parent) {
574 StatusWindow *statusWindow;
575 XSetWindowAttributes attrib;
576 unsigned long attribmask;
577 Window containerWindow;
578 Window status;
579 Window child;
580 XWindowAttributes xwa;
581 XWindowAttributes xxwa;
582 /* Variable for XCreateFontSet()*/
583 char **mclr;
584 int mccr = 0;
585 char *dsr;
586 unsigned long bg, fg, light, dim;
587 int x, y, off_x, off_y, xx, yy;
588 unsigned int w, h, bw, depth;
589 XGCValues values;
590 unsigned long valuemask = 0; /*ignore XGCvalue and use defaults*/
591 int screen = 0;
592 int i;
593 AwtGraphicsConfigDataPtr adata;
594 extern int awt_numScreens;
595 /*hardcode the size right now, should get the size base on font*/
596 int width=80, height=22;
597 Window rootWindow;
598 Window *ignoreWindowPtr;
599 unsigned int ignoreUnit;
600
601 XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
602
603 attrib.override_redirect = True1;
604 attribmask = CWOverrideRedirect(1L<<9);
605 for (i = 0; i < awt_numScreens; i++) {
606 if (RootWindow(dpy, i)((&((_XPrivDisplay)(dpy))->screens[i])->root) == rootWindow) {
607 screen = i;
608 break;
609 }
610 }
611 adata = getDefaultConfig(screen);
612 bg = adata->AwtColorMatch(255, 255, 255, adata);
613 fg = adata->AwtColorMatch(0, 0, 0, adata);
614 light = adata->AwtColorMatch(195, 195, 195, adata);
615 dim = adata->AwtColorMatch(128, 128, 128, adata);
616
617 XGetWindowAttributes(dpy, parent, &xwa);
618 bw = 2; /*xwa.border_width does not have the correct value*/
619
620 /*compare the size difference between parent container
621 and shell widget, the diff should be the border frame
622 and title bar height (?)*/
623
624 XQueryTree( dpy,
625 parent,
626 &rootWindow,
627 &containerWindow,
628 &ignoreWindowPtr,
629 &ignoreUnit);
630 XGetWindowAttributes(dpy, containerWindow, &xxwa);
631
632 off_x = (xxwa.width - xwa.width) / 2;
633 off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */
634
635 /*get the size of root window*/
636 XGetWindowAttributes(dpy, rootWindow, &xxwa);
637
638 XTranslateCoordinates(dpy,
639 parent, xwa.root,
640 xwa.x, xwa.y,
641 &x, &y,
642 &child);
643 xx = x - off_x;
644 yy = y + xwa.height - off_y;
645 if (xx < 0 ){
646 xx = 0;
647 }
648 if (xx + width > xxwa.width) {
649 xx = xxwa.width - width;
650 }
651 if (yy + height > xxwa.height) {
652 yy = xxwa.height - height;
653 }
654
655 status = XCreateWindow(dpy,
656 xwa.root,
657 xx, yy,
658 width, height,
659 0,
660 xwa.depth,
661 InputOutput1,
662 adata->awt_visInfo.visual,
663 attribmask, &attrib);
664 XSelectInput(dpy, status,
665 ExposureMask(1L<<15) | StructureNotifyMask(1L<<17) | EnterWindowMask(1L<<4) |
666 LeaveWindowMask(1L<<5) | VisibilityChangeMask(1L<<16));
667 statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
668 if (statusWindow == NULL((void*)0)){
669 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
670 return NULL((void*)0);
671 }
672 statusWindow->w = status;
673 //12, 13-point fonts
674 statusWindow->fontset = XCreateFontSet(dpy,
675 "-*-*-medium-r-normal-*-*-120-*-*-*-*," \
676 "-*-*-medium-r-normal-*-*-130-*-*-*-*",
677 &mclr, &mccr, &dsr);
678 /* In case we didn't find the font set, release the list of missing characters */
679 if (mccr > 0) {
680 XFreeStringList(mclr);
681 }
682 statusWindow->parent = parent;
683 statusWindow->on = False0;
684 statusWindow->x = x;
685 statusWindow->y = y;
686 statusWindow->width = xwa.width;
687 statusWindow->height = xwa.height;
688 statusWindow->off_x = off_x;
689 statusWindow->off_y = off_y;
690 statusWindow->bWidth = bw;
691 statusWindow->statusH = height;
692 statusWindow->statusW = width;
693 statusWindow->rootH = xxwa.height;
694 statusWindow->rootW = xxwa.width;
695 statusWindow->lightGC = XCreateGC(dpy, status, valuemask, &values);
696 XSetForeground(dpy, statusWindow->lightGC, light);
697 statusWindow->dimGC = XCreateGC(dpy, status, valuemask, &values);
698 XSetForeground(dpy, statusWindow->dimGC, dim);
699 statusWindow->fgGC = XCreateGC(dpy, status, valuemask, &values);
700 XSetForeground(dpy, statusWindow->fgGC, fg);
701 statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
702 XSetForeground(dpy, statusWindow->bgGC, bg);
703 return statusWindow;
704}
705
706/* This method is to turn off or turn on the status window. */
707static void onoffStatusWindow(X11InputMethodData* pX11IMData,
708 Window parent,
709 Boolint ON){
710 XWindowAttributes xwa;
711 Window child;
712 int x, y;
713 StatusWindow *statusWindow = NULL((void*)0);
714
715 if (NULL((void*)0) == currentX11InputMethodInstance ||
716 NULL((void*)0) == pX11IMData ||
717 NULL((void*)0) == (statusWindow = pX11IMData->statusWindow)){
718 return;
719 }
720
721 if (ON == False0) {
722 XUnmapWindow(dpy, statusWindow->w);
723 statusWindow->on = False0;
724 return;
725 }
726 parent = JNU_CallMethodByName(GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002), NULL((void*)0), pX11IMData->x11inputmethod,
727 "getCurrentParentWindow",
728 "()J").j;
729 if (statusWindow->parent != parent) {
730 statusWindow->parent = parent;
731 }
732 XGetWindowAttributes(dpy, parent, &xwa);
733 XTranslateCoordinates(dpy,
734 parent, xwa.root,
735 xwa.x, xwa.y,
736 &x, &y,
737 &child);
738 if (statusWindow->x != x ||
739 statusWindow->y != y ||
740 statusWindow->height != xwa.height)
741 {
742 statusWindow->x = x;
743 statusWindow->y = y;
744 statusWindow->height = xwa.height;
745 x = statusWindow->x - statusWindow->off_x;
746 y = statusWindow->y + statusWindow->height - statusWindow->off_y;
747 if (x < 0 ) {
748 x = 0;
749 }
750 if (x + statusWindow->statusW > statusWindow->rootW) {
751 x = statusWindow->rootW - statusWindow->statusW;
752 }
753 if (y + statusWindow->statusH > statusWindow->rootH) {
754 y = statusWindow->rootH - statusWindow->statusH;
755 }
756 XMoveWindow(dpy, statusWindow->w, x, y);
757 }
758 statusWindow->on = True1;
759 XMapWindow(dpy, statusWindow->w);
760}
761
762void paintStatusWindow(StatusWindow *statusWindow){
763 Window win = statusWindow->w;
764 GC lightgc = statusWindow->lightGC;
765 GC dimgc = statusWindow->dimGC;
766 GC bggc = statusWindow->bgGC;
767 GC fggc = statusWindow->fgGC;
768
769 int width = statusWindow->statusW;
770 int height = statusWindow->statusH;
771 int bwidth = statusWindow->bWidth;
772 XFillRectangle(dpy, win, bggc, 0, 0, width, height);
773 /* draw border */
774 XDrawLine(dpy, win, fggc, 0, 0, width, 0);
775 XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
776 XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
777 XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);
778
779 XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
780 XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
781 XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
782 XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);
783
784 XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
785 XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
786 XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
787 XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
788 if (statusWindow->fontset) {
789 XmbDrawString(dpy, win, statusWindow->fontset, fggc,
790 bwidth + 2, height - bwidth - 4,
791 statusWindow->status,
792 strlen(statusWindow->status));
793 } else {
794 /*too bad we failed to create a fontset for this locale*/
795 XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
796 "[InputMethod ON]", strlen("[InputMethod ON]"));
797 }
798}
799
800static void adjustStatusWindow(Window shell) {
801 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
802 X11InputMethodData *pX11IMData = NULL((void*)0);
803 StatusWindow *statusWindow;
804
805 if (NULL((void*)0) == currentX11InputMethodInstance
806 || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
807 || NULL((void*)0) == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
808 || NULL((void*)0) == (statusWindow = pX11IMData->statusWindow)
809 || !statusWindow->on)
810 {
811 return;
812 }
813
814 {
815 XWindowAttributes xwa;
816 int x, y;
817 Window child;
818 XGetWindowAttributes(dpy, shell, &xwa);
819 XTranslateCoordinates(dpy,
820 shell, xwa.root,
821 xwa.x, xwa.y,
822 &x, &y,
823 &child);
824 if (statusWindow->x != x
825 || statusWindow->y != y
826 || statusWindow->height != xwa.height){
827 statusWindow->x = x;
828 statusWindow->y = y;
829 statusWindow->height = xwa.height;
830
831 x = statusWindow->x - statusWindow->off_x;
832 y = statusWindow->y + statusWindow->height - statusWindow->off_y;
833 if (x < 0 ) {
834 x = 0;
835 }
836 if (x + statusWindow->statusW > statusWindow->rootW){
837 x = statusWindow->rootW - statusWindow->statusW;
838 }
839 if (y + statusWindow->statusH > statusWindow->rootH){
840 y = statusWindow->rootH - statusWindow->statusH;
841 }
842 XMoveWindow(dpy, statusWindow->w, x, y);
843 }
844 }
845}
846#endif /* __linux__ */
847
848/*
849 * Creates two XICs, one for active clients and the other for passive
850 * clients. All information on those XICs are stored in the
851 * X11InputMethodData given by the pX11IMData parameter.
852 *
853 * For active clients: Try to use preedit callback to support
854 * on-the-spot. If tc is not null, the XIC to be created will
855 * share the Status Area with Motif widgets (TextComponents). If the
856 * preferable styles can't be used, fallback to root-window styles. If
857 * root-window styles failed, fallback to None styles.
858 *
859 * For passive clients: Try to use root-window styles. If failed,
860 * fallback to None styles.
861 */
862static Boolint
863createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
864{
865 XVaNestedList preedit = NULL((void*)0);
866 XVaNestedList status = NULL((void*)0);
867 XIMStyle on_the_spot_styles = XIMPreeditCallbacks0x0002L,
868 active_styles = 0,
869 passive_styles = 0,
870 no_styles = 0;
871 XIMCallback *callbacks;
872 unsigned short i;
873 XIMStyles *im_styles;
874 char *ret = NULL((void*)0);
875
876 if (X11im == NULL((void*)0)) {
877 return False0;
878 }
879 if (!w) {
880 return False0;
881 }
882
883 ret = XGetIMValues(X11im, XNQueryInputStyle"queryInputStyle", &im_styles, NULL((void*)0));
884
885 if (ret != NULL((void*)0)) {
886 jio_fprintf(stderrstderr,"XGetIMValues: %s\n",ret);
887 return FALSE0 ;
888 }
889
890 on_the_spot_styles |= XIMStatusNothing0x0400L;
891
892#if defined(__linux__1)
893 /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
894 at the same time, so use StatusCallback to draw the status
895 ourself
896 */
897 for (i = 0; i < im_styles->count_styles; i++) {
898 if (im_styles->supported_styles[i] == (XIMPreeditCallbacks0x0002L | XIMStatusCallbacks0x0200L)) {
899 on_the_spot_styles = (XIMPreeditCallbacks0x0002L | XIMStatusCallbacks0x0200L);
900 break;
901 }
902 }
903#endif /* __linux__ */
904
905 for (i = 0; i < im_styles->count_styles; i++) {
906 active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
907 passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES(0x0008L | 0x0400L);
908 no_styles |= im_styles->supported_styles[i] & NO_STYLES(0x0010L | 0x0800L);
909 }
910
911 XFree(im_styles);
912
913 if (active_styles != on_the_spot_styles) {
914 if (passive_styles == ROOT_WINDOW_STYLES(0x0008L | 0x0400L))
915 active_styles = passive_styles;
916 else {
917 if (no_styles == NO_STYLES(0x0010L | 0x0800L))
918 active_styles = passive_styles = NO_STYLES(0x0010L | 0x0800L);
919 else
920 active_styles = passive_styles = 0;
921 }
922 } else {
923 if (passive_styles != ROOT_WINDOW_STYLES(0x0008L | 0x0400L)) {
924 if (no_styles == NO_STYLES(0x0010L | 0x0800L))
925 active_styles = passive_styles = NO_STYLES(0x0010L | 0x0800L);
926 else
927 active_styles = passive_styles = 0;
928 }
929 }
930
931 if (active_styles == on_the_spot_styles) {
932 pX11IMData->ic_passive = XCreateIC(X11im,
933 XNClientWindow"clientWindow", w,
934 XNFocusWindow"focusWindow", w,
935 XNInputStyle"inputStyle", passive_styles,
936 NULL((void*)0));
937
938 callbacks = (XIMCallback *)malloc(sizeof(XIMCallback) * NCALLBACKS7);
939 if (callbacks == (XIMCallback *)NULL((void*)0))
940 return False0;
941 pX11IMData->callbacks = callbacks;
942
943 for (i = 0; i < NCALLBACKS7; i++, callbacks++) {
944 callbacks->client_data = (XPointer) pX11IMData->x11inputmethod;
945 callbacks->callback = callback_funcs[i];
946 }
947
948 callbacks = pX11IMData->callbacks;
949 preedit = (XVaNestedList)XVaCreateNestedList(0,
950 XNPreeditStartCallback"preeditStartCallback", &callbacks[PreeditStartIndex0],
951 XNPreeditDoneCallback"preeditDoneCallback", &callbacks[PreeditDoneIndex1],
952 XNPreeditDrawCallback"preeditDrawCallback", &callbacks[PreeditDrawIndex2],
953 XNPreeditCaretCallback"preeditCaretCallback", &callbacks[PreeditCaretIndex3],
954 NULL((void*)0));
955 if (preedit == (XVaNestedList)NULL((void*)0))
956 goto err;
957#if defined(__linux__1)
958 /*always try XIMStatusCallbacks for active client...*/
959 {
960 status = (XVaNestedList)XVaCreateNestedList(0,
961 XNStatusStartCallback"statusStartCallback", &callbacks[StatusStartIndex4],
962 XNStatusDoneCallback"statusDoneCallback", &callbacks[StatusDoneIndex5],
963 XNStatusDrawCallback"statusDrawCallback", &callbacks[StatusDrawIndex6],
964 NULL((void*)0));
965
966 if (status == NULL((void*)0))
967 goto err;
968 pX11IMData->statusWindow = createStatusWindow(w);
969 pX11IMData->ic_active = XCreateIC(X11im,
970 XNClientWindow"clientWindow", w,
971 XNFocusWindow"focusWindow", w,
972 XNInputStyle"inputStyle", active_styles,
973 XNPreeditAttributes"preeditAttributes", preedit,
974 XNStatusAttributes"statusAttributes", status,
975 NULL((void*)0));
976 XFree((void *)status);
977 XFree((void *)preedit);
978 }
979#else /* !__linux__ */
980 pX11IMData->ic_active = XCreateIC(X11im,
981 XNClientWindow"clientWindow", w,
982 XNFocusWindow"focusWindow", w,
983 XNInputStyle"inputStyle", active_styles,
984 XNPreeditAttributes"preeditAttributes", preedit,
985 NULL((void*)0));
986 XFree((void *)preedit);
987#endif /* __linux__ */
988 } else {
989 pX11IMData->ic_active = XCreateIC(X11im,
990 XNClientWindow"clientWindow", w,
991 XNFocusWindow"focusWindow", w,
992 XNInputStyle"inputStyle", active_styles,
993 NULL((void*)0));
994 pX11IMData->ic_passive = pX11IMData->ic_active;
995 }
996
997 if (pX11IMData->ic_active == (XIC)0
998 || pX11IMData->ic_passive == (XIC)0) {
999 return False0;
1000 }
1001
1002 /*
1003 * Use commit string call back if possible.
1004 * This will ensure the correct order of preedit text and commit text
1005 */
1006 {
1007 XIMCallback cb;
1008 cb.client_data = (XPointer) pX11IMData->x11inputmethod;
1009 cb.callback = (XIMProc) CommitStringCallback;
1010 XSetICValues (pX11IMData->ic_active, XNCommitStringCallback"commitStringCallback", &cb, NULL((void*)0));
1011 if (pX11IMData->ic_active != pX11IMData->ic_passive) {
1012 XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback"commitStringCallback", &cb, NULL((void*)0));
1013 }
1014 }
1015
1016 // The code set the IC mode that the preedit state is not initialied
1017 // at XmbResetIC. This attribute can be set at XCreateIC. I separately
1018 // set the attribute to avoid the failure of XCreateIC at some platform
1019 // which does not support the attribute.
1020 if (pX11IMData->ic_active != 0)
1021 XSetICValues(pX11IMData->ic_active,
1022 XNResetState"resetState", XIMInitialState1L,
1023 NULL((void*)0));
1024 if (pX11IMData->ic_passive != 0
1025 && pX11IMData->ic_active != pX11IMData->ic_passive)
1026 XSetICValues(pX11IMData->ic_passive,
1027 XNResetState"resetState", XIMInitialState1L,
1028 NULL((void*)0));
1029
1030 /* Add the global reference object to X11InputMethod to the list. */
1031 addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
1032
1033 /* Unset focus to avoid unexpected IM on */
1034 setXICFocus(pX11IMData->ic_active, False0);
1035 if (pX11IMData->ic_active != pX11IMData->ic_passive)
1036 setXICFocus(pX11IMData->ic_passive, False0);
1037
1038 return True1;
1039
1040 err:
1041 if (preedit)
1042 XFree((void *)preedit);
1043 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
1044 return False0;
1045}
1046
1047static int
1048PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1049{
1050 /*ARGSUSED*/
1051 /* printf("Native: PreeditStartCallback\n"); */
1052 return -1;
1053}
1054
1055static void
1056PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1057{
1058 /*ARGSUSED*/
1059 /* printf("Native: PreeditDoneCallback\n"); */
1060}
1061
1062/*
1063 * Translate the preedit draw callback items to Java values and invoke
1064 * X11InputMethod.dispatchComposedText().
1065 *
1066 * client_data: X11InputMethod object
1067 */
1068static void
1069PreeditDrawCallback(XIC ic, XPointer client_data,
1070 XIMPreeditDrawCallbackStruct *pre_draw)
1071{
1072 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
1073 X11InputMethodData *pX11IMData = NULL((void*)0);
1074 jmethodID x11imMethodID;
1075
1076 XIMText *text;
1077 jstring javastr = NULL((void*)0);
1078 jintArray style = NULL((void*)0);
1079
1080 /* printf("Native: PreeditDrawCallback() \n"); */
1081 if (pre_draw == NULL((void*)0)) {
1082 return;
1083 }
1084 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1085 if (!isX11InputMethodGRefInList((jobject)client_data)) {
1086 if ((jobject)client_data == currentX11InputMethodInstance) {
1087 currentX11InputMethodInstance = NULL((void*)0);
1088 }
1089 goto finally;
1090 }
1091 if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL((void*)0)) {
1092 goto finally;
1093 }
1094
1095 if ((text = pre_draw->text) != NULL((void*)0)) {
1096 if (text->string.multi_byte != NULL((void*)0)) {
1097 if (pre_draw->text->encoding_is_wchar == False0) {
1098 javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
1099 if (javastr == NULL((void*)0)) {
1100 goto finally;
1101 }
1102 } else {
1103 char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
1104 if (mbstr == NULL((void*)0)) {
1105 goto finally;
1106 }
1107 javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
1108 free(mbstr);
1109 if (javastr == NULL((void*)0)) {
1110 goto finally;
1111 }
1112 }
1113 }
1114 if (text->feedback != NULL((void*)0)) {
1115 int cnt;
1116 jint *tmpstyle;
1117
1118 style = (*env)->NewIntArray(env, text->length);
1119 if (JNU_IsNull(env, style)((style) == ((void*)0))) {
1120 (*env)->ExceptionClear(env);
1121 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
1122 goto finally;
1123 }
1124
1125 if (sizeof(XIMFeedback) == sizeof(jint)) {
1126 /*
1127 * Optimization to avoid copying the array
1128 */
1129 (*env)->SetIntArrayRegion(env, style, 0,
1130 text->length, (jint *)text->feedback);
1131 } else {
1132 tmpstyle = (jint *)malloc(sizeof(jint)*(text->length));
1133 if (tmpstyle == (jint *) NULL((void*)0)) {
1134 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
1135 goto finally;
1136 }
1137 for (cnt = 0; cnt < (int)text->length; cnt++)
1138 tmpstyle[cnt] = text->feedback[cnt];
1139 (*env)->SetIntArrayRegion(env, style, 0,
1140 text->length, (jint *)tmpstyle);
1141 free(tmpstyle);
1142 }
1143 }
1144 }
1145 JNU_CallMethodByName(env, NULL((void*)0), pX11IMData->x11inputmethod,
1146 "dispatchComposedText",
1147 "(Ljava/lang/String;[IIIIJ)V",
1148 javastr,
1149 style,
1150 (jint)pre_draw->chg_first,
1151 (jint)pre_draw->chg_length,
1152 (jint)pre_draw->caret,
1153 awt_util_nowMillisUTC());
1154finally:
1155 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1156 return;
1157}
1158
1159static void
1160PreeditCaretCallback(XIC ic, XPointer client_data,
1161 XIMPreeditCaretCallbackStruct *pre_caret)
1162{
1163 /*ARGSUSED*/
1164 /* printf("Native: PreeditCaretCallback\n"); */
1165}
1166
1167#if defined(__linux__1)
1168static void
1169StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1170{
1171 /*ARGSUSED*/
1172 /*printf("StatusStartCallback:\n"); */
1173}
1174
1175static void
1176StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1177{
1178 /*ARGSUSED*/
1179 /*printf("StatusDoneCallback:\n"); */
1180 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
1181 X11InputMethodData *pX11IMData = NULL((void*)0);
1182 StatusWindow *statusWindow;
1183
1184 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1185
1186 if (!isX11InputMethodGRefInList((jobject)client_data)) {
1187 if ((jobject)client_data == currentX11InputMethodInstance) {
1188 currentX11InputMethodInstance = NULL((void*)0);
1189 }
1190 goto finally;
1191 }
1192
1193 if (NULL((void*)0) == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
1194 || NULL((void*)0) == (statusWindow = pX11IMData->statusWindow)){
Although the value stored to 'statusWindow' is used in the enclosing expression, the value is never actually read from 'statusWindow'
1195 goto finally;
1196 }
1197 currentX11InputMethodInstance = (jobject)client_data;
1198
1199 onoffStatusWindow(pX11IMData, 0, False0);
1200
1201 finally:
1202 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1203}
1204
1205static void
1206StatusDrawCallback(XIC ic, XPointer client_data,
1207 XIMStatusDrawCallbackStruct *status_draw)
1208{
1209 /*ARGSUSED*/
1210 /*printf("StatusDrawCallback:\n"); */
1211 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
1212 X11InputMethodData *pX11IMData = NULL((void*)0);
1213 StatusWindow *statusWindow;
1214
1215 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1216
1217 if (!isX11InputMethodGRefInList((jobject)client_data)) {
1218 if ((jobject)client_data == currentX11InputMethodInstance) {
1219 currentX11InputMethodInstance = NULL((void*)0);
1220 }
1221 goto finally;
1222 }
1223
1224 if (NULL((void*)0) == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
1225 || NULL((void*)0) == (statusWindow = pX11IMData->statusWindow)){
1226 goto finally;
1227 }
1228 currentX11InputMethodInstance = (jobject)client_data;
1229
1230 if (status_draw->type == XIMTextType) {
1231 XIMText *text = (status_draw->data).text;
1232 if (text != NULL((void*)0)) {
1233 if (text->string.multi_byte != NULL((void*)0)) {
1234 strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN100);
1235 statusWindow->status[MAX_STATUS_LEN100 - 1] = '\0';
1236 } else {
1237 char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
1238 if (mbstr == NULL((void*)0)) {
1239 goto finally;
1240 }
1241 strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN100);
1242 statusWindow->status[MAX_STATUS_LEN100 - 1] = '\0';
1243 free(mbstr);
1244 }
1245 statusWindow->on = True1;
1246 onoffStatusWindow(pX11IMData, statusWindow->parent, True1);
1247 paintStatusWindow(statusWindow);
1248 } else {
1249 statusWindow->on = False0;
1250 /*just turnoff the status window
1251 paintStatusWindow(statusWindow);
1252 */
1253 onoffStatusWindow(pX11IMData, 0, False0);
1254 }
1255 }
1256
1257 finally:
1258 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1259}
1260#endif /* __linux__ */
1261
1262static void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
1263 JNIEnv *env = GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002);
1264 XIMText * text = (XIMText *)call_data;
1265 X11InputMethodData *pX11IMData = NULL((void*)0);
1266 jstring javastr;
1267
1268 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1269
1270 if (!isX11InputMethodGRefInList((jobject)client_data)) {
1271 if ((jobject)client_data == currentX11InputMethodInstance) {
1272 currentX11InputMethodInstance = NULL((void*)0);
1273 }
1274 goto finally;
1275 }
1276
1277 if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL((void*)0)) {
1278 goto finally;
1279 }
1280 currentX11InputMethodInstance = (jobject)client_data;
1281
1282 if (text->encoding_is_wchar == False0) {
1283 javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
1284 } else {
1285 char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
1286 if (mbstr == NULL((void*)0)) {
1287 goto finally;
1288 }
1289 javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
1290 free(mbstr);
1291 }
1292
1293 if (javastr != NULL((void*)0)) {
1294 JNU_CallMethodByName(env, NULL((void*)0),
1295 pX11IMData->x11inputmethod,
1296 "dispatchCommittedText",
1297 "(Ljava/lang/String;J)V",
1298 javastr,
1299 awt_util_nowMillisUTC());
1300 }
1301 finally:
1302 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1303}
1304
1305static void OpenXIMCallback(Display *display, XPointer client_data, XPointer call_data) {
1306 XIMCallback ximCallback;
1307
1308 X11im = XOpenIM(display, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1309 if (X11im == NULL((void*)0)) {
1310 return;
1311 }
1312
1313 ximCallback.callback = (XIMProc)DestroyXIMCallback;
1314 ximCallback.client_data = NULL((void*)0);
1315 XSetIMValues(X11im, XNDestroyCallback"destroyCallback", &ximCallback, NULL((void*)0));
1316}
1317
1318static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
1319 /* mark that XIM server was destroyed */
1320 X11im = NULL((void*)0);
1321 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_20x00010002);
1322
1323 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1324 /* free the old pX11IMData and set it to null. this also avoids crashing
1325 * the jvm if the XIM server reappears */
1326 while (x11InputMethodGRefListHead != NULL((void*)0)) {
1327 if (getX11InputMethodData(env,
1328 x11InputMethodGRefListHead->inputMethodGRef) == NULL((void*)0)) {
1329 /* Clear possible exceptions
1330 */
1331 if ((*env)->ExceptionOccurred(env)) {
1332 (*env)->ExceptionDescribe(env);
1333 (*env)->ExceptionClear(env);
1334 }
1335 }
1336 }
1337 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1338}
1339
1340JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL
1341Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
1342 jobject this,
1343 jlong display)
1344{
1345 Boolint registered;
1346
1347 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1348
1349 dpy = (Display *)jlong_to_ptr(display)((void*)(display));
1350
1351/* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
1352 (4768335)
1353*/
1354#if defined(__linux__1)
1355 registered = XRegisterIMInstantiateCallback(dpy, NULL((void*)0), NULL((void*)0),
1356 NULL((void*)0), (XIDProc)OpenXIMCallback, NULL((void*)0));
1357 if (!registered) {
1358 /* directly call openXIM callback */
1359#endif
1360 OpenXIMCallback(dpy, NULL((void*)0), NULL((void*)0));
1361#if defined(__linux__1)
1362 }
1363#endif
1364
1365 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1366
1367 return JNI_TRUE1;
1368}
1369
1370JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL
1371Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
1372 jobject this,
1373 jlong window)
1374{
1375 X11InputMethodData *pX11IMData;
1376 jobject globalRef;
1377 XIC ic;
1378
1379 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1380
1381 if (!window) {
1382 JNU_ThrowNullPointerException(env, "NullPointerException");
1383 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1384 return JNI_FALSE0;
1385 }
1386
1387 pX11IMData = (X11InputMethodData *) calloc(1, sizeof(X11InputMethodData));
1388 if (pX11IMData == NULL((void*)0)) {
1389 THROW_OUT_OF_MEMORY_ERROR()JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, 0x00010002
), ((void*)0))
;
1390 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1391 return JNI_FALSE0;
1392 }
1393
1394 globalRef = (*env)->NewGlobalRef(env, this);
1395 pX11IMData->x11inputmethod = globalRef;
1396#if defined(__linux__1)
1397 pX11IMData->statusWindow = NULL((void*)0);
1398#endif /* __linux__ */
1399
1400 pX11IMData->lookup_buf = 0;
1401 pX11IMData->lookup_buf_len = 0;
1402
1403 if (createXIC(env, pX11IMData, (Window)window) == False0) {
1404 destroyX11InputMethodData((JNIEnv *) NULL((void*)0), pX11IMData);
1405 pX11IMData = (X11InputMethodData *) NULL((void*)0);
1406 if ((*env)->ExceptionCheck(env)) {
1407 goto finally;
1408 }
1409 }
1410
1411 setX11InputMethodData(env, this, pX11IMData);
1412
1413finally:
1414 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1415 return (pX11IMData != NULL((void*)0));
1416}
1417
1418JNIEXPORT__attribute__((visibility("default"))) void JNICALL
1419Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
1420 jobject this,
1421 jlong w,
1422 jboolean req,
1423 jboolean active)
1424{
1425 X11InputMethodData *pX11IMData;
1426 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1427 pX11IMData = getX11InputMethodData(env, this);
1428 if (pX11IMData == NULL((void*)0)) {
1429 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1430 return;
1431 }
1432
1433 if (req) {
1434 if (!w) {
1435 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1436 return;
1437 }
1438 pX11IMData->current_ic = active ?
1439 pX11IMData->ic_active : pX11IMData->ic_passive;
1440 /*
1441 * On Solaris2.6, setXICWindowFocus() has to be invoked
1442 * before setting focus.
1443 */
1444 setXICWindowFocus(pX11IMData->current_ic, w);
1445 setXICFocus(pX11IMData->current_ic, req);
1446 currentX11InputMethodInstance = pX11IMData->x11inputmethod;
1447 currentFocusWindow = w;
1448#if defined(__linux__1)
1449 if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
1450 onoffStatusWindow(pX11IMData, w, True1);
1451#endif
1452 } else {
1453 currentX11InputMethodInstance = NULL((void*)0);
1454 currentFocusWindow = 0;
1455#if defined(__linux__1)
1456 onoffStatusWindow(pX11IMData, 0, False0);
1457 if (pX11IMData->current_ic != NULL((void*)0))
1458#endif
1459 setXICFocus(pX11IMData->current_ic, req);
1460
1461 pX11IMData->current_ic = (XIC)0;
1462 }
1463
1464 XFlush(dpy);
1465 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1466}
1467
1468/*
1469 * Class: sun_awt_X11InputMethodBase
1470 * Method: initIDs
1471 * Signature: ()V
1472 * This function gets called from the static initializer for
1473 * X11InputMethod.java to initialize the fieldIDs for fields
1474 * that may be accessed from C
1475 */
1476JNIEXPORT__attribute__((visibility("default"))) void JNICALL Java_sun_awt_X11InputMethodBase_initIDs
1477 (JNIEnv *env, jclass cls)
1478{
1479 x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
1480}
1481
1482/*
1483 * Class: sun_awt_X11InputMethodBase
1484 * Method: turnoffStatusWindow
1485 * Signature: ()V
1486 */
1487JNIEXPORT__attribute__((visibility("default"))) void JNICALL Java_sun_awt_X11InputMethodBase_turnoffStatusWindow
1488 (JNIEnv *env, jobject this)
1489{
1490#if defined(__linux__1)
1491 X11InputMethodData *pX11IMData;
1492 StatusWindow *statusWindow;
1493
1494 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1495
1496 if (NULL((void*)0) == currentX11InputMethodInstance
1497 || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
1498 || NULL((void*)0) == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
1499 || NULL((void*)0) == (statusWindow = pX11IMData->statusWindow)
1500 || !statusWindow->on ){
1501 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1502 return;
1503 }
1504 onoffStatusWindow(pX11IMData, 0, False0);
1505
1506 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1507#endif
1508}
1509
1510/*
1511 * Class: sun_awt_X11InputMethodBase
1512 * Method: disposeXIC
1513 * Signature: ()V
1514 */
1515JNIEXPORT__attribute__((visibility("default"))) void JNICALL Java_sun_awt_X11InputMethodBase_disposeXIC
1516 (JNIEnv *env, jobject this)
1517{
1518 X11InputMethodData *pX11IMData = NULL((void*)0);
1519
1520 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1521 pX11IMData = getX11InputMethodData(env, this);
1522 if (pX11IMData == NULL((void*)0)) {
1523 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1524 return;
1525 }
1526
1527 setX11InputMethodData(env, this, NULL((void*)0));
1528
1529 if (pX11IMData->x11inputmethod == currentX11InputMethodInstance) {
1530 currentX11InputMethodInstance = NULL((void*)0);
1531 currentFocusWindow = 0;
1532 }
1533 destroyX11InputMethodData(env, pX11IMData);
1534 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1535}
1536
1537/*
1538 * Class: sun_awt_X11InputMethodBase
1539 * Method: resetXIC
1540 * Signature: ()Ljava/lang/String;
1541 */
1542JNIEXPORT__attribute__((visibility("default"))) jstring JNICALL Java_sun_awt_X11InputMethodBase_resetXIC
1543 (JNIEnv *env, jobject this)
1544{
1545 X11InputMethodData *pX11IMData;
1546 char *xText = NULL((void*)0);
1547 jstring jText = (jstring)0;
1548
1549 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1550 pX11IMData = getX11InputMethodData(env, this);
1551 if (pX11IMData == NULL((void*)0)) {
1552 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1553 return jText;
1554 }
1555
1556 if (pX11IMData->current_ic)
1557 xText = XmbResetIC(pX11IMData->current_ic);
1558 else {
1559 /*
1560 * If there is no reference to the current XIC, try to reset both XICs.
1561 */
1562 xText = XmbResetIC(pX11IMData->ic_active);
1563 /*it may also means that the real client component does
1564 not have focus -- has been deactivated... its xic should
1565 not have the focus, bug#4284651 showes reset XIC for htt
1566 may bring the focus back, so de-focus it again.
1567 */
1568 setXICFocus(pX11IMData->ic_active, FALSE0);
1569 if (pX11IMData->ic_active != pX11IMData->ic_passive) {
1570 char *tmpText = XmbResetIC(pX11IMData->ic_passive);
1571 setXICFocus(pX11IMData->ic_passive, FALSE0);
1572 if (xText == (char *)NULL((void*)0) && tmpText)
1573 xText = tmpText;
1574 }
1575
1576 }
1577 if (xText != NULL((void*)0)) {
1578 jText = JNU_NewStringPlatform(env, (const char *)xText);
1579 XFree((void *)xText);
1580 }
1581
1582 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1583 return jText;
1584}
1585
1586/*
1587 * Class: sun_awt_X11InputMethodBase
1588 * Method: setCompositionEnabledNative
1589 * Signature: (Z)Z
1590 *
1591 * This method tries to set the XNPreeditState attribute associated with the current
1592 * XIC to the passed in 'enable' state.
1593 *
1594 * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
1595 * 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
1596 * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
1597 * method fails due to other reasons.
1598 */
1599JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative
1600 (JNIEnv *env, jobject this, jboolean enable)
1601{
1602 X11InputMethodData *pX11IMData;
1603 char * ret = NULL((void*)0);
1604 XVaNestedList pr_atrb;
1605#if defined(__linux__1)
1606 Boolean calledXSetICFocus = False0;
1607#endif
1608
1609 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1610 pX11IMData = getX11InputMethodData(env, this);
1611
1612 if ((pX11IMData == NULL((void*)0)) || (pX11IMData->current_ic == NULL((void*)0))) {
1613 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1614 return JNI_FALSE0;
1615 }
1616
1617#if defined(__linux__1)
1618 if (NULL((void*)0) != pX11IMData->statusWindow) {
1619 Window focus = 0;
1620 int revert_to;
1621#if defined(_LP641) && !defined(_LITTLE_ENDIAN1)
1622 // The Window value which is used for XGetICValues must be 32bit on BigEndian XOrg's xlib
1623 unsigned int w = 0;
1624#else
1625 Window w = 0;
1626#endif
1627 XGetInputFocus(awt_display, &focus, &revert_to);
1628 XGetICValues(pX11IMData->current_ic, XNFocusWindow"focusWindow", &w, NULL((void*)0));
1629 if (RevertToPointerRoot(int)1L == revert_to
1630 && pX11IMData->ic_active != pX11IMData->ic_passive) {
1631 if (pX11IMData->current_ic == pX11IMData->ic_active) {
1632 if (getParentWindow(focus) == getParentWindow(w)) {
1633 XUnsetICFocus(pX11IMData->ic_active);
1634 calledXSetICFocus = True1;
1635 }
1636 }
1637 }
1638 }
1639#endif
1640 pr_atrb = XVaCreateNestedList(0,
1641 XNPreeditState"preeditState", (enable ? XIMPreeditEnable1L : XIMPreeditDisable(1L<<1)),
1642 NULL((void*)0));
1643 ret = XSetICValues(pX11IMData->current_ic, XNPreeditAttributes"preeditAttributes", pr_atrb, NULL((void*)0));
1644 XFree((void *)pr_atrb);
1645#if defined(__linux__1)
1646 if (calledXSetICFocus) {
1647 XSetICFocus(pX11IMData->ic_active);
1648 }
1649#endif
1650 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1651
1652 if ((ret != 0)
1653 && ((strcmp(ret, XNPreeditAttributes"preeditAttributes") == 0)
1654 || (strcmp(ret, XNPreeditState"preeditState") == 0))) {
1655 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1656 }
1657
1658 return (jboolean)(ret == 0);
1659}
1660
1661/*
1662 * Class: sun_awt_X11InputMethodBase
1663 * Method: isCompositionEnabledNative
1664 * Signature: ()Z
1665 *
1666 * This method tries to get the XNPreeditState attribute associated with the current XIC.
1667 *
1668 * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
1669 * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
1670 * will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
1671 */
1672JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative
1673 (JNIEnv *env, jobject this)
1674{
1675 X11InputMethodData *pX11IMData = NULL((void*)0);
1676 char * ret = NULL((void*)0);
1677#if defined(__linux__1) && defined(_LP641) && !defined(_LITTLE_ENDIAN1)
1678 // XIMPreeditState value which is used for XGetICValues must be 32bit on BigEndian XOrg's xlib
1679 unsigned int state = XIMPreeditUnKnown0L;
1680#else
1681 XIMPreeditState state = XIMPreeditUnKnown0L;
1682#endif
1683
1684 XVaNestedList pr_atrb;
1685
1686 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1687 pX11IMData = getX11InputMethodData(env, this);
1688
1689 if ((pX11IMData == NULL((void*)0)) || (pX11IMData->current_ic == NULL((void*)0))) {
1690 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1691 return JNI_FALSE0;
1692 }
1693
1694 pr_atrb = XVaCreateNestedList(0, XNPreeditState"preeditState", &state, NULL((void*)0));
1695 ret = XGetICValues(pX11IMData->current_ic, XNPreeditAttributes"preeditAttributes", pr_atrb, NULL((void*)0));
1696 XFree((void *)pr_atrb);
1697 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1698
1699 if ((ret != 0)
1700 && ((strcmp(ret, XNPreeditAttributes"preeditAttributes") == 0)
1701 || (strcmp(ret, XNPreeditState"preeditState") == 0))) {
1702 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1703 return JNI_FALSE0;
1704 }
1705
1706 return (jboolean)(state == XIMPreeditEnable1L);
1707}
1708
1709JNIEXPORT__attribute__((visibility("default"))) void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
1710 (JNIEnv *env, jobject this, jlong window)
1711{
1712#if defined(__linux__1)
1713 AWT_LOCK()do { (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID
); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionClear
(env); } } while(0)
;
1714 adjustStatusWindow(window);
1715 AWT_UNLOCK()do { awt_output_flush(); do { jthrowable pendingException; if
((pendingException = (*env)->ExceptionOccurred(env)) != (
(void*)0)) { (*env)->ExceptionClear(env); } (*env)->CallStaticVoidMethod
(env, tkClass, awtUnlockMID); if ((*env)->ExceptionCheck(env
)) { (*env)->ExceptionClear(env); } if (pendingException) {
(*env)->Throw(env, pendingException); } } while (0); } while
(0)
;
1716#endif
1717}
1718
1719#if defined(__linux__1)
1720static Window getParentWindow(Window w)
1721{
1722 Window root=None0L, parent=None0L, *ignore_children=NULL((void*)0);
1723 unsigned int ignore_uint=0;
1724 Statusint status = 0;
1725
1726 if (w == None0L)
1727 return None0L;
1728 status = XQueryTree(dpy, w, &root, &parent, &ignore_children, &ignore_uint);
1729 XFree(ignore_children);
1730 if (status == 0)
1731 return None0L;
1732 return parent;
1733}
1734#endif