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' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
45 | struct X11InputMethodIDs { |
46 | jfieldID pData; |
47 | } x11InputMethodIDs; |
48 | |
49 | static int PreeditStartCallback(XIC, XPointer, XPointer); |
50 | static void PreeditDoneCallback(XIC, XPointer, XPointer); |
51 | static void PreeditDrawCallback(XIC, XPointer, |
52 | XIMPreeditDrawCallbackStruct *); |
53 | static void PreeditCaretCallback(XIC, XPointer, |
54 | XIMPreeditCaretCallbackStruct *); |
55 | #if defined(__linux__1) |
56 | static void StatusStartCallback(XIC, XPointer, XPointer); |
57 | static void StatusDoneCallback(XIC, XPointer, XPointer); |
58 | static 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 | */ |
82 | static 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 |
96 | typedef 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 | */ |
120 | typedef 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 | */ |
147 | typedef struct _X11InputMethodGRefNode { |
148 | jobject inputMethodGRef; |
149 | struct _X11InputMethodGRefNode* next; |
150 | } X11InputMethodGRefNode; |
151 | |
152 | X11InputMethodGRefNode *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. */ |
157 | jobject currentX11InputMethodInstance = NULL((void*)0); |
158 | |
159 | Window 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) */ |
163 | static XIM X11im = NULL((void*)0); |
164 | Display * dpy = NULL((void*)0); |
165 | |
166 | #define GetJNIEnv()(JNIEnv *)JNU_GetEnv(jvm, 0x00010002) (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_20x00010002) |
167 | |
168 | static void DestroyXIMCallback(XIM, XPointer, XPointer); |
169 | static void OpenXIMCallback(Display *, XPointer, XPointer); |
170 | /* Solaris XIM Extention */ |
171 | #define XNCommitStringCallback"commitStringCallback" "commitStringCallback" |
172 | static void CommitStringCallback(XIC, XPointer, XPointer); |
173 | |
174 | static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject); |
175 | static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *); |
176 | static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *); |
177 | static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *); |
178 | #if defined(__linux__1) |
179 | static 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 | */ |
186 | jlong |
187 | awt_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 | */ |
200 | static char * |
201 | wcstombsdmp(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 | */ |
230 | static 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 | */ |
250 | static 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 | */ |
272 | static 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 | |
307 | static 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 | |
335 | static 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() */ |
340 | static void |
341 | destroyX11InputMethodData(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 | |
366 | static void |
367 | freeX11InputMethodData(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 | */ |
405 | static void |
406 | setXICFocus(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 | */ |
421 | static void |
422 | setXICWindowFocus(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 | |
447 | Boolean |
448 | awt_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) |
573 | static 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. */ |
707 | static 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 | |
762 | void 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 | |
800 | static 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 | */ |
862 | static Boolint |
863 | createXIC(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 | |
1047 | static int |
1048 | PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data) |
1049 | { |
1050 | /*ARGSUSED*/ |
1051 | /* printf("Native: PreeditStartCallback\n"); */ |
1052 | return -1; |
1053 | } |
1054 | |
1055 | static void |
1056 | PreeditDoneCallback(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 | */ |
1068 | static void |
1069 | PreeditDrawCallback(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()); |
1154 | finally: |
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 | |
1159 | static void |
1160 | PreeditCaretCallback(XIC ic, XPointer client_data, |
1161 | XIMPreeditCaretCallbackStruct *pre_caret) |
1162 | { |
1163 | /*ARGSUSED*/ |
1164 | /* printf("Native: PreeditCaretCallback\n"); */ |
1165 | } |
1166 | |
1167 | #if defined(__linux__1) |
1168 | static void |
1169 | StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data) |
1170 | { |
1171 | /*ARGSUSED*/ |
1172 | /*printf("StatusStartCallback:\n"); */ |
1173 | } |
1174 | |
1175 | static void |
1176 | StatusDoneCallback(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 | |
1205 | static void |
1206 | StatusDrawCallback(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 | |
1262 | static 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 | |
1305 | static 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 | |
1318 | static 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 | |
1340 | JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL |
1341 | Java_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 | |
1370 | JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL |
1371 | Java_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 | |
1413 | finally: |
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 | |
1418 | JNIEXPORT__attribute__((visibility("default"))) void JNICALL |
1419 | Java_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 | */ |
1476 | JNIEXPORT__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 | */ |
1487 | JNIEXPORT__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 | */ |
1515 | JNIEXPORT__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 | */ |
1542 | JNIEXPORT__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 | */ |
1599 | JNIEXPORT__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 | */ |
1672 | JNIEXPORT__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 | |
1709 | JNIEXPORT__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) |
1720 | static 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 |