1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/inmethod.c,v 1.14 2011/06/14 02:32:18 william Exp $
19 */
20
21 #define _INCLUDE_FROM_INMETHOD_C_
22
23 #include "tgifdefs.h"
24
25 #ifndef _NO_XCIN
26 #include "cli_xcin.e"
27 #endif /* ~_NO_XCIN */
28 #ifndef _NO_CHINPUT
29 #include "chinput.e"
30 #endif /* ~_NO_CHINPUT */
31 #ifndef _NO_KINPUT
32 #include "convkinput.e"
33 #endif /* ~_NO_KINPUT */
34 #ifndef _NO_XIM
35 #include "convxim.e"
36 #endif /* ~_NO_XIM */
37 #ifndef _NO_TGTWB5
38 #include "tgtwb5.e"
39 #endif /* ~_NO_TGTWB5 */
40
41 #include "dialog.e"
42 #include "inmethod.e"
43 #include "msg.e"
44 #include "util.e"
45 #include "setup.e"
46 #include "strtbl.e"
47 #include "tidget.e"
48
49 #ifndef _NO_DL_SUPPORT
50 #define CLOSE_DL(handle) dlclose(handle)
51 #define OPEN_DL(path,flag) dlopen((path),(flag))
52 #define GET_DL_SYM(handle,symbol) dlsym((handle),(symbol))
53 #ifndef RTLD_NOW
54 #define OPEN_DL_MODE 1
55 #else /* RTLD_NOW */
56 #define OPEN_DL_MODE (RTLD_NOW|RTLD_GLOBAL)
57 #endif /* ~RTLD_NOW */
58 #else /* _NO_DL_SUPPORT */
59 #define CLOSE_DL(handle)
60 #define OPEN_DL(path,flag) NULL
61 #define GET_DL_SYM(handle,symbol) NULL
62 #define OPEN_DL_MODE 0
63 #endif /* ~_NO_DL_SUPPORT */
64
65 int gnInputMethod=TGIM_NONE; /* one of TGIM_* */
66 int gnOverTheSpot=FALSE;
67
68 int cmdLineHasInputMethod=FALSE;
69 int cmdLineDoubleByteInputMethod=FALSE;
70 char cmdLineInputMethod[MAXSTRING];
71
72 static int gnInputMethodIndex=INVALID;
73 static int gnSingleOrDoubleByteInputMethod=0;
74
75 typedef void (CleanUpFunc)ARGS_DECL((Display *dpy, Window win));
76 typedef int (InitFunc)ARGS_DECL((Display *dpy, Window win, char *arg));
77 typedef int (FocusInFunc)ARGS_DECL((Display *dpy, Window win));
78 typedef int (FocusOutFunc)ARGS_DECL((Display *dpy, Window win));
79 typedef int (SendKeyFunc)ARGS_DECL((Display *dpy, Window win,
80 XKeyEvent *key_ev, char *buf));
81 typedef int (ConvPropertyFunc)ARGS_DECL((Display *dpy, Window win,
82 XPropertyEvent *prop_ev,
83 char **ppsz_buf));
84 typedef int (ExpectCMFunc)ARGS_DECL((Display *dpy, Window win));
85 typedef int (HandleCMFunc)ARGS_DECL((Display *dpy, Window win,
86 XClientMessageEvent *cm_ev,
87 XKeyEvent *key_ev, char *buf));
88 typedef int (ActivateOnCntrlSpaceFunc)ARGS_DECL((Display *dpy, Window win));
89 typedef int (HandleCntrlSpaceFunc)ARGS_DECL((Display *dpy, Window win));
90 typedef int (DeactivateOnCreateTextFunc)ARGS_DECL((Display *dpy, Window win));
91 typedef int (HandleCreateTextFunc)ARGS_DECL((Display *dpy, Window win));
92 typedef int (TellCursorPosFunc)ARGS_DECL((Display *dpy, Window win,
93 int cur_x, int cur_y));
94 typedef int (ExpectNextEventFunc)ARGS_DECL((Display *dpy, Window win));
95 typedef int (HandleNextEventFunc)ARGS_DECL((Display *dpy, Window win,
96 XEvent *ev));
97 typedef int (HandleNewCurTextFunc)ARGS_DECL((Display *dpy, Window win));
98 typedef int (ExpectLookupStringFunc)ARGS_DECL((Display *dpy, Window win));
99 typedef int (HandleLookupStringFunc)ARGS_DECL((Display *dpy, Window win,
100 XKeyEvent *key_ev, char *psz_buf,
101 int buf_size, KeySym *p_key_sym,
102 int *pn_has_ch));
103
104 typedef struct tagIMInfo {
105 char *pszName;
106 int nInputMethod;
107 int nSingleDouble;
108 CleanUpFunc *pCleanUpFunc;
109 InitFunc *pInitFunc;
110 FocusInFunc *pFocusInFunc;
111 FocusOutFunc *pFocusOutFunc;
112 SendKeyFunc *pSendKeyFunc;
113 ConvPropertyFunc *pConvPropertyFunc;
114 ExpectCMFunc *pExpectCMFunc;
115 HandleCMFunc *pHandleCMFunc;
116 ActivateOnCntrlSpaceFunc *pActivateOnCntrlSpaceFunc;
117 HandleCntrlSpaceFunc *pHandleCntrlSpaceFunc;
118 DeactivateOnCreateTextFunc *pDeactivateOnCreateTextFunc;
119 HandleCreateTextFunc *pHandleCreateTextFunc;
120 TellCursorPosFunc *pTellCursorPosFunc;
121 ExpectNextEventFunc *pExpectNextEventFunc;
122 HandleNextEventFunc *pHandleNextEventFunc;
123 HandleNewCurTextFunc *pHandleNewCurTextFunc;
124 ExpectLookupStringFunc *pExpectLookupStringFunc;
125 HandleLookupStringFunc *pHandleLookupStringFunc;
126 } IMInfo;
127
128 static IMInfo *gpIMInfo=NULL;
129
130 /* --------------------- xcin Routines --------------------- */
131
132 #ifndef _NO_XCIN
133 static
XcinInit(dpy,win,arg)134 int XcinInit(dpy, win, arg)
135 Display *dpy;
136 Window win;
137 char *arg;
138 {
139 return TRUE;
140 }
141
142 static
XcinFocusIn(dpy,win)143 int XcinFocusIn(dpy, win)
144 Display *dpy;
145 Window win;
146 {
147 Tg_send_FocusIn(dpy, win);
148 return TRUE;
149 }
150
151 static
XcinFocusOut(dpy,win)152 int XcinFocusOut(dpy, win)
153 Display *dpy;
154 Window win;
155 {
156 Tg_send_FocusOut(dpy, win);
157 return TRUE;
158 }
159
160 static
XcinSendKey(dpy,win,key_ev,buf)161 int XcinSendKey(dpy, win, key_ev, buf)
162 Display *dpy;
163 Window win;
164 XKeyEvent *key_ev;
165 char *buf;
166 {
167 return Tg_send_key(dpy, win, key_ev, buf);
168 }
169
170 static
XcinExpectCM(dpy,win)171 int XcinExpectCM(dpy, win)
172 Display *dpy;
173 Window win;
174 {
175 return FALSE;
176 }
177 #endif /* ~_NO_XCIN */
178
179 /* --------------------- chinput Routines --------------------- */
180
181 #ifndef _NO_CHINPUT
182 static
ChinputInit(dpy,win,arg)183 int ChinputInit(dpy, win, arg)
184 Display *dpy;
185 Window win;
186 char *arg;
187 {
188 return (Tg_HZclientInit(dpy)==0);
189 }
190
191 static
ChinputFocusIn(dpy,win)192 int ChinputFocusIn(dpy, win)
193 Display *dpy;
194 Window win;
195 {
196 return TRUE;
197 }
198
199 static
ChinputFocusOut(dpy,win)200 int ChinputFocusOut(dpy, win)
201 Display *dpy;
202 Window win;
203 {
204 return TRUE;
205 }
206
207 static
ChinputSendKey(dpy,win,key_ev,buf)208 int ChinputSendKey(dpy, win, key_ev, buf)
209 Display *dpy;
210 Window win;
211 XKeyEvent *key_ev;
212 char *buf;
213 {
214 Tg_HZsendKey(dpy, win, key_ev);
215 *buf = '\0';
216 return TRUE;
217 }
218
219 static
ChinputExpectCM(dpy,win)220 int ChinputExpectCM(dpy, win)
221 Display *dpy;
222 Window win;
223 {
224 return TRUE;
225 }
226
227 static
ChinputHandleCM(dpy,win,cm_ev,key_ev,buf)228 int ChinputHandleCM(dpy, win, cm_ev, key_ev, buf)
229 Display *dpy;
230 Window win;
231 XClientMessageEvent *cm_ev;
232 XKeyEvent *key_ev;
233 char *buf;
234 {
235 return Tg_HZhandleCM(cm_ev, key_ev, buf);
236 }
237 #endif /* ~_NO_CHINPUT */
238
239 /* --------------------- kinput Routines --------------------- */
240
241 #ifndef _NO_KINPUT
242 static
KinputCleanUp(dpy,win)243 void KinputCleanUp(dpy, win)
244 Display *dpy;
245 Window win;
246 {
247 imProtocol = IM_NONE;
248 }
249
250 static
KinputInit(dpy,win,arg)251 int KinputInit(dpy, win, arg)
252 Display *dpy;
253 Window win;
254 char *arg;
255 {
256 char *c_ptr=NULL;
257
258 copyAndPasteJIS = FALSE;
259 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "CopyAndPasteJIS")) != NULL &&
260 UtilStrICmp(c_ptr, "true") == 0) {
261 copyAndPasteJIS = TRUE;
262 }
263 gnOverTheSpot = FALSE;
264 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "PreeditType")) != NULL &&
265 UtilStrICmp(c_ptr, "overthespot") == 0) {
266 gnOverTheSpot = TRUE;
267 }
268 KinputSetConvOverSpot(gnOverTheSpot);
269
270 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "ConvSelection")) != NULL) {
271 UtilTrimBlanks(c_ptr);
272 strncpy(kinputConvSelName, c_ptr, MAXSTRING-1);
273 kinputConvSelName[MAXSTRING-1] = '\0';
274 }
275
276 imProtocol = IM_KINPUT;
277 return TRUE;
278 }
279
280 static
KinputFocusIn(dpy,win)281 int KinputFocusIn(dpy, win)
282 Display *dpy;
283 Window win;
284 {
285 return TRUE;
286 }
287
288 static
KinputFocusOut(dpy,win)289 int KinputFocusOut(dpy, win)
290 Display *dpy;
291 Window win;
292 {
293 return TRUE;
294 }
295
296 static
KinputSendKey(dpy,win,key_ev,buf)297 int KinputSendKey(dpy, win, key_ev, buf)
298 Display *dpy;
299 Window win;
300 XKeyEvent *key_ev;
301 char *buf;
302 {
303 return FALSE;
304 }
305
306 static
KinputConvProperty(dpy,win,prop_ev,ppsz_buf)307 int KinputConvProperty(dpy, win, prop_ev, ppsz_buf)
308 Display *dpy;
309 Window win;
310 XPropertyEvent *prop_ev;
311 char **ppsz_buf;
312 {
313 char *c_ptr=KinputCheckConvProperty(dpy, win, prop_ev);
314
315 if (c_ptr != NULL && ppsz_buf != NULL) {
316 *ppsz_buf = c_ptr;
317 return TRUE;
318 }
319 return FALSE;
320 }
321
322 static
KinputExpectCM(dpy,win)323 int KinputExpectCM(dpy, win)
324 Display *dpy;
325 Window win;
326 {
327 return (win == drawWindow ||
328 (TidgetHasFocus() && win == TidgetGetFocusWindow()));
329 }
330
331 static
KinputHandleCM(dpy,win,cm_ev,key_ev,buf)332 int KinputHandleCM(dpy, win, cm_ev, key_ev, buf)
333 Display *dpy;
334 Window win;
335 XClientMessageEvent *cm_ev;
336 XKeyEvent *key_ev;
337 char *buf;
338 {
339 KinputCheckClientMessage(dpy, win, cm_ev);
340 return FALSE;
341 }
342
343 static
KinputActiveOnCntrlSpace(dpy,win)344 int KinputActiveOnCntrlSpace(dpy, win)
345 Display *dpy;
346 Window win;
347 {
348 return (win == drawWindow ||
349 (TidgetHasFocus() && win == TidgetGetFocusWindow()));
350 }
351
352 static
KinputHandleCntrlSpace(dpy,win)353 int KinputHandleCntrlSpace(dpy, win)
354 Display *dpy;
355 Window win;
356 {
357 KinputBeginConversion(dpy, win);
358 return TRUE;
359 }
360
361 static
KinputDeactiveOnCreateText(dpy,win)362 int KinputDeactiveOnCreateText(dpy, win)
363 Display *dpy;
364 Window win;
365 {
366 return TRUE;
367 }
368
369 static
KinputHandleCreateText(dpy,win)370 int KinputHandleCreateText(dpy, win)
371 Display *dpy;
372 Window win;
373 {
374 KinputEndConversion(dpy, win);
375 return TRUE;
376 }
377
378 static
KinputTellCursorPos(dpy,win,cur_x,cur_y)379 int KinputTellCursorPos(dpy, win, cur_x, cur_y)
380 Display *dpy;
381 Window win;
382 int cur_x, cur_y;
383 {
384 KinputTellCursorPosition(dpy, win, cur_x, cur_y);
385 return TRUE;
386 }
387 #endif /* ~_NO_KINPUT */
388
389 /* --------------------- xim Routines --------------------- */
390
391 #ifndef _NO_XIM
392 static
XimCleanUp(dpy,win)393 void XimCleanUp(dpy, win)
394 Display *dpy;
395 Window win;
396 {
397 XIMCleanUp();
398 }
399
400 static
XimInit(dpy,win,arg)401 int XimInit(dpy, win, arg)
402 Display *dpy;
403 Window win;
404 char *arg;
405 {
406 char *c_ptr=NULL;
407 XIMInit();
408 gnOverTheSpot = FALSE;
409 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "PreeditType")) != NULL &&
410 UtilStrICmp(c_ptr, "overthespot") == 0) {
411 gnOverTheSpot = TRUE;
412 }
413 XIMSetConvOverSpot(gnOverTheSpot);
414 return TRUE;
415 }
416
417 static
XimFocusIn(dpy,win)418 int XimFocusIn(dpy, win)
419 Display *dpy;
420 Window win;
421 {
422 XIMSetICFocus(dpy, win);
423 return TRUE;
424 }
425
426 static
XimFocusOut(dpy,win)427 int XimFocusOut(dpy, win)
428 Display *dpy;
429 Window win;
430 {
431 XIMUnsetICFocus(win);
432 return TRUE;
433 }
434
435 static
XimDeactiveOnCreateText(dpy,win)436 int XimDeactiveOnCreateText(dpy, win)
437 Display *dpy;
438 Window win;
439 {
440 return TRUE;
441 }
442
443 static
XimHandleCreateText(dpy,win)444 int XimHandleCreateText(dpy, win)
445 Display *dpy;
446 Window win;
447 {
448 XIMUnsetICFocus(win);
449 return TRUE;
450 }
451
452 static
XimExpectNextEvent(dpy,win)453 int XimExpectNextEvent(dpy, win)
454 Display *dpy;
455 Window win;
456 {
457 return (win == drawWindow ||
458 (TidgetHasFocus() && win == TidgetGetFocusWindow()));
459 }
460
461 static
XimHandleNextEvent(dpy,win,ev)462 int XimHandleNextEvent(dpy, win, ev)
463 Display *dpy;
464 Window win;
465 XEvent *ev;
466 {
467 XIMNextEvent(dpy, win, ev);
468 return TRUE;
469 }
470
471 static
XimHandleNewCurText(dpy,win)472 int XimHandleNewCurText(dpy, win)
473 Display *dpy;
474 Window win;
475 {
476 XIMSetICFocus(dpy, win);
477 return TRUE;
478 }
479
480 static
XimExpectLookupString(dpy,win)481 int XimExpectLookupString(dpy, win)
482 Display *dpy;
483 Window win;
484 {
485 return (win == drawWindow ||
486 (TidgetHasFocus() && win == TidgetGetFocusWindow()));
487 }
488
489 static XIMStatus c_stat;
490
491 static
XimHandleLookupString(dpy,win,key_ev,psz_buf,buf_size,p_key_sym,pn_has_ch)492 int XimHandleLookupString(dpy, win, key_ev, psz_buf, buf_size, p_key_sym,
493 pn_has_ch)
494 Display *dpy;
495 Window win;
496 XKeyEvent *key_ev;
497 char *psz_buf;
498 int buf_size;
499 KeySym *p_key_sym;
500 int *pn_has_ch;
501 {
502 *pn_has_ch = XIMLookupString(key_ev, psz_buf, buf_size, p_key_sym, &c_stat);
503 return TRUE;
504 }
505
506 static
XimTellCursorPos(dpy,win,cur_x,cur_y)507 int XimTellCursorPos(dpy, win, cur_x, cur_y)
508 Display *dpy;
509 Window win;
510 int cur_x, cur_y;
511 {
512 XIMTellCursorPosition(dpy, win, cur_x, cur_y);
513 return TRUE;
514 }
515 #endif /* ~_NO_XIM */
516
517 /* --------------------- tgtwb5 Routines --------------------- */
518
519 #ifndef _NO_TGTWB5
520 static
Tgtwb5CleanUp(dpy,win)521 void Tgtwb5CleanUp(dpy, win)
522 Display *dpy;
523 Window win;
524 {
525 Tgtwb5_CleanUp(dpy, win);
526 }
527
528 static
Tgtwb5Init(dpy,win,arg)529 int Tgtwb5Init(dpy, win, arg)
530 Display *dpy;
531 Window win;
532 char *arg;
533 {
534 return Tgtwb5_Init(dpy, win, arg);
535 }
536
537 static
Tgtwb5SendKey(dpy,win,key_ev,buf)538 int Tgtwb5SendKey(dpy, win, key_ev, buf)
539 Display *dpy;
540 Window win;
541 XKeyEvent *key_ev;
542 char *buf;
543 {
544 return Tgtwb5_SendKey(dpy, win, key_ev, buf);
545 }
546
547 static
Tgtwb5ExpectCM(dpy,win)548 int Tgtwb5ExpectCM(dpy, win)
549 Display *dpy;
550 Window win;
551 {
552 return FALSE;
553 }
554
555 static
Tgtwb5ActiveOnCntrlSpace(dpy,win)556 int Tgtwb5ActiveOnCntrlSpace(dpy, win)
557 Display *dpy;
558 Window win;
559 {
560 return (win == drawWindow ||
561 (TidgetHasFocus() && win == TidgetGetFocusWindow()));
562 }
563
564 static
Tgtwb5HandleCntrlSpace(dpy,win)565 int Tgtwb5HandleCntrlSpace(dpy, win)
566 Display *dpy;
567 Window win;
568 {
569 return Tgtwb5_HandleCntrlSpace(dpy, win);
570 }
571
572 static
Tgtwb5DeactiveOnCreateText(dpy,win)573 int Tgtwb5DeactiveOnCreateText(dpy, win)
574 Display *dpy;
575 Window win;
576 {
577 return TRUE;
578 }
579
580 static
Tgtwb5HandleCreateText(dpy,win)581 int Tgtwb5HandleCreateText(dpy, win)
582 Display *dpy;
583 Window win;
584 {
585 Tgtwb5_HandleCreateText(dpy, win);
586 return TRUE;
587 }
588 #endif /* ~_NO_XCIN */
589
590 /* --------------------- Global Routines --------------------- */
591
592 static struct tagIMInfo gstIMInfo[] = {
593 #ifndef _NO_XCIN
594 { "xcin", TGIM_XCIN, TGIM_DBIM,
595 NULL, XcinInit, XcinFocusIn, XcinFocusOut,
596 XcinSendKey, NULL, XcinExpectCM, NULL,
597 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
598 },
599 #endif /* ~_NO_XCIN */
600 #ifndef _NO_CHINPUT
601 { "chinput", TGIM_CHINPUT, TGIM_DBIM,
602 NULL, ChinputInit, ChinputFocusIn, ChinputFocusOut,
603 ChinputSendKey, NULL, ChinputExpectCM, ChinputHandleCM,
604 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
605 },
606 #endif /* ~_NO_CHINPUT */
607 #ifndef _NO_KINPUT
608 { "kinput2", TGIM_KINPUT, TGIM_DBIM,
609 KinputCleanUp, KinputInit, KinputFocusIn, KinputFocusOut,
610 KinputSendKey, KinputConvProperty, KinputExpectCM, KinputHandleCM,
611 KinputActiveOnCntrlSpace, KinputHandleCntrlSpace,
612 KinputDeactiveOnCreateText, KinputHandleCreateText,
613 KinputTellCursorPos, NULL, NULL, NULL, NULL, NULL
614 },
615 #endif /* ~_NO_KINPUT */
616 #ifndef _NO_XIM
617 { "xim", TGIM_XIM, (TGIM_DBIM|TGIM_SBIM),
618 XimCleanUp, XimInit, XimFocusIn, XimFocusOut,
619 NULL, NULL, NULL, NULL, NULL, NULL,
620 XimDeactiveOnCreateText, XimHandleCreateText,
621 XimTellCursorPos, XimExpectNextEvent, XimHandleNextEvent,
622 XimHandleNewCurText, XimExpectLookupString, XimHandleLookupString
623 },
624 #endif /* ~_NO_XIM */
625 #ifndef _NO_TGTWB5
626 { "tgtwb5/tgchgb", TGIM_TGTWB5, TGIM_DBIM,
627 Tgtwb5CleanUp, Tgtwb5Init, NULL, NULL,
628 Tgtwb5SendKey, NULL, Tgtwb5ExpectCM, NULL,
629 Tgtwb5ActiveOnCntrlSpace, Tgtwb5HandleCntrlSpace,
630 Tgtwb5DeactiveOnCreateText, Tgtwb5HandleCreateText,
631 NULL, NULL, NULL, NULL, NULL, NULL
632 },
633 #endif /* ~_NO_TGTWB5 */
634 { NULL, TGIM_NONE, 0, NULL, NULL, NULL, NULL,
635 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
636 NULL, NULL, NULL, NULL, NULL
637 }
638 };
639
640 static void *gpLibIdnHandle=NULL;
641 static Tgim_stringprep_convert_Func *gpfn_stringprep_convert=NULL;
642
643 static
CleanUpTgim_stringprep_convert()644 void CleanUpTgim_stringprep_convert()
645 {
646 if (gpLibIdnHandle != NULL) {
647 gpfn_stringprep_convert = NULL;
648 CLOSE_DL(gpLibIdnHandle);
649 gpLibIdnHandle = NULL;
650 }
651 }
652
653 static
InitTgim_stringprep_convert()654 void InitTgim_stringprep_convert()
655 {
656 #if (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ))
657 gpLibIdnHandle = OPEN_DL("libidn.so", OPEN_DL_MODE);
658 if (gpLibIdnHandle != NULL) {
659 gpfn_stringprep_convert =
660 (Tgim_stringprep_convert_Func*)GET_DL_SYM(gpLibIdnHandle,
661 "stringprep_convert");
662 if (gpfn_stringprep_convert == NULL) {
663 CLOSE_DL(gpLibIdnHandle);
664 gpLibIdnHandle = NULL;
665 }
666 }
667 #endif /* (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ)) */
668 }
669
Tgim_has_stringprep_convert()670 int Tgim_has_stringprep_convert()
671 {
672 #if (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ))
673 if (gpLibIdnHandle != NULL && gpfn_stringprep_convert != NULL) {
674 return TRUE;
675 }
676 #endif /* (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ)) */
677 return FALSE;
678 }
679
Tgim_stringprep_convert(const char * str,const char * to_codeset,const char * from_codeset)680 char *Tgim_stringprep_convert(const char *str, const char *to_codeset,
681 const char *from_codeset)
682 {
683 #if (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ))
684 if (gpLibIdnHandle != NULL && gpfn_stringprep_convert != NULL) {
685 return (gpfn_stringprep_convert)(str, to_codeset, from_codeset);
686 }
687 #endif /* (!defined(_NO_IDNLIB) || defined(HAVE_LIBZ)) */
688 return NULL;
689 }
690
CleanUpInputMethods()691 void CleanUpInputMethods()
692 {
693 CleanUpTgim_stringprep_convert();
694 if (gnInputMethodIndex != INVALID &&
695 gstIMInfo[gnInputMethodIndex].pCleanUpFunc != NULL) {
696 (gstIMInfo[gnInputMethodIndex].pCleanUpFunc)(mainDisplay, mainWindow);
697 }
698 gnInputMethodIndex = INVALID;
699 cmdLineHasInputMethod = FALSE;
700 cmdLineDoubleByteInputMethod = FALSE;
701 *cmdLineInputMethod = '\0';
702 gpIMInfo = NULL;
703 gnSingleOrDoubleByteInputMethod = 0;
704 }
705
InitInputMethods()706 int InitInputMethods()
707 {
708 char *psz=NULL, single_double=0;
709
710 gnInputMethod = gnInputMethodIndex = INVALID;
711 if (cmdLineHasInputMethod) {
712 UtilTrimBlanks(cmdLineInputMethod);
713 psz = cmdLineInputMethod;
714 single_double = (cmdLineDoubleByteInputMethod ? TGIM_DBIM : TGIM_SBIM);
715 } else {
716 psz = XGetDefault(mainDisplay, TOOL_NAME, "DoubleByteInputMethod");
717 if (psz == NULL) {
718 psz = XGetDefault(mainDisplay, TOOL_NAME, "SingleByteInputMethod");
719 single_double = TGIM_SBIM;
720 } else {
721 if (XGetDefault(mainDisplay, TOOL_NAME, "SingleByteInputMethod") !=
722 NULL) {
723 sprintf(gszMsgBox, TgLoadString(STID_TWO_XDEF_ONE_IGNORED),
724 TOOL_NAME, "DoubleByteInputMethod", TOOL_NAME,
725 "SingleByteInputMethod", TOOL_NAME, "SingleByteInputMethod");
726 Msg(gszMsgBox);
727 fprintf(stderr, "%s\n", gszMsgBox);
728 }
729 single_double = TGIM_DBIM;
730 }
731 }
732 gnSingleOrDoubleByteInputMethod = single_double;
733
734 if (psz != NULL) {
735 IMInfo *pIMInfo=gstIMInfo;
736 char *psz_comma=strchr(psz, ',');
737 int i=0;
738
739 if (psz_comma != NULL) *psz_comma = '\0';
740 for ( ; pIMInfo->pszName != NULL; pIMInfo++, i++) {
741 char *psz_slash=strchr(pIMInfo->pszName,'/');
742
743 if (psz_slash == NULL) {
744 if (UtilStrICmp(psz, pIMInfo->pszName) == 0 &&
745 (single_double & pIMInfo->nSingleDouble) == single_double) {
746 gnInputMethod = pIMInfo->nInputMethod;
747 gnInputMethodIndex = i;
748 gpIMInfo = pIMInfo;
749 if (gstIMInfo[gnInputMethodIndex].pInitFunc != NULL) {
750 if (psz_comma == NULL) {
751 if (!((gstIMInfo[gnInputMethodIndex].pInitFunc)(mainDisplay,
752 mainWindow, NULL))) {
753 /* may not be a problem */
754 }
755 } else {
756 if (!((gstIMInfo[gnInputMethodIndex].pInitFunc)(mainDisplay,
757 mainWindow, &psz_comma[1]))) {
758 /* may not be a problem */
759 }
760 }
761 }
762 break;
763 }
764 } else {
765 char *psz_dup=UtilStrDup(pIMInfo->pszName), *psz_cur=NULL;
766 int done=FALSE;
767
768 if (psz_dup == NULL) FailAllocMessage();
769 psz_cur = psz_dup;
770 psz_slash = strchr(psz_cur, '/');
771 while (!done) {
772 if (psz_slash != NULL) *psz_slash = '\0';
773 if (UtilStrICmp(psz, psz_cur) == 0 &&
774 (single_double & pIMInfo->nSingleDouble) == single_double) {
775 gnInputMethod = pIMInfo->nInputMethod;
776 gnInputMethodIndex = i;
777 gpIMInfo = pIMInfo;
778 if (gstIMInfo[gnInputMethodIndex].pInitFunc != NULL) {
779 if (psz_comma == NULL) {
780 if (!((gstIMInfo[gnInputMethodIndex].pInitFunc)(mainDisplay,
781 mainWindow, NULL))) {
782 /* may not be a problem */
783 }
784 } else {
785 if (!((gstIMInfo[gnInputMethodIndex].pInitFunc)(mainDisplay,
786 mainWindow, &psz_comma[1]))) {
787 /* may not be a problem */
788 }
789 }
790 }
791 done = TRUE;
792 }
793 if (psz_slash != NULL) {
794 *psz_slash++ = '/';
795 psz_cur = psz_slash;
796 psz_slash = strchr(psz_cur, '/');
797 } else {
798 break;
799 }
800 }
801 UtilFree(psz_dup);
802 if (done) {
803 break;
804 }
805 }
806 }
807 if (psz_comma != NULL) *psz_comma++ = ',';
808
809 if (gnInputMethod == INVALID) {
810 if (single_double == TGIM_DBIM) {
811 fprintf(stderr, TgLoadString(STID_DBIM_UNSUPPORTED), psz);
812 } else {
813 fprintf(stderr, TgLoadString(STID_SBIM_UNSUPPORTED), psz);
814 }
815 fprintf(stderr, "\n");
816 }
817 }
818 if (gnSingleOrDoubleByteInputMethod == TGIM_SBIM &&
819 gnInputMethod != INVALID) {
820 InitTgim_stringprep_convert();
821 }
822 return TRUE;
823 }
824
ResetInputMethod()825 int ResetInputMethod()
826 {
827 int rc=FALSE;
828
829 if (gpIMInfo == NULL) return FALSE;
830
831 sprintf(gszMsgBox, TgLoadString(STID_OK_TO_RESET_GIVEN_IM),
832 gpIMInfo->pszName);
833 if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
834 return FALSE;
835 }
836 CleanUpInputMethods();
837 rc = InitInputMethods();
838
839 sprintf(gszMsgBox, TgLoadString(STID_GIVEN_IM_RESETED), gpIMInfo->pszName);
840 Msg(gszMsgBox);
841
842 return rc;
843 }
844
InputMethodTypeMatched(double_byte)845 int InputMethodTypeMatched(double_byte)
846 int double_byte;
847 {
848 if (gnInputMethodIndex == INVALID || gpIMInfo == NULL) return FALSE;
849
850 if (double_byte) {
851 return (gnSingleOrDoubleByteInputMethod == TGIM_DBIM &&
852 (gpIMInfo->nSingleDouble & TGIM_DBIM) == TGIM_DBIM);
853 } else {
854 return (gnSingleOrDoubleByteInputMethod == TGIM_SBIM &&
855 (gpIMInfo->nSingleDouble & TGIM_SBIM) == TGIM_SBIM);
856 }
857 }
858
tgIMFocusIn(dpy,win)859 int tgIMFocusIn(dpy, win)
860 Display *dpy;
861 Window win;
862 {
863 if (gnInputMethodIndex == INVALID ||
864 gstIMInfo[gnInputMethodIndex].pFocusInFunc == NULL) {
865 return FALSE;
866 }
867 return ((gstIMInfo[gnInputMethodIndex].pFocusInFunc)(dpy, win));
868 }
869
tgIMFocusOut(dpy,win)870 int tgIMFocusOut(dpy, win)
871 Display *dpy;
872 Window win;
873 {
874 if (gnInputMethodIndex == INVALID ||
875 gstIMInfo[gnInputMethodIndex].pFocusOutFunc == NULL) {
876 return FALSE;
877 }
878 return ((gstIMInfo[gnInputMethodIndex].pFocusOutFunc)(dpy, win));
879 }
880
tgIMTranslateKeyEvent(dpy,win,key_ev,buf)881 int tgIMTranslateKeyEvent(dpy, win, key_ev, buf)
882 Display *dpy;
883 Window win;
884 XKeyEvent *key_ev;
885 char *buf;
886 {
887 if (gnInputMethodIndex == INVALID ||
888 gstIMInfo[gnInputMethodIndex].pSendKeyFunc == NULL) {
889 return FALSE;
890 }
891 return ((gstIMInfo[gnInputMethodIndex].pSendKeyFunc)(dpy, win, key_ev, buf));
892 }
893
tgIMConvertProperty(dpy,win,prop_ev,ppsz_buf)894 int tgIMConvertProperty(dpy, win, prop_ev, ppsz_buf)
895 Display *dpy;
896 Window win;
897 XPropertyEvent *prop_ev;
898 char **ppsz_buf;
899 {
900 if (gnInputMethodIndex == INVALID ||
901 gstIMInfo[gnInputMethodIndex].pConvPropertyFunc == NULL) {
902 return FALSE;
903 }
904 return ((gstIMInfo[gnInputMethodIndex].pConvPropertyFunc)(dpy, win, prop_ev,
905 ppsz_buf));
906 }
907
tgIMExpectClientMessage(dpy,win)908 int tgIMExpectClientMessage(dpy, win)
909 Display *dpy;
910 Window win;
911 {
912 if (gnInputMethodIndex == INVALID ||
913 gstIMInfo[gnInputMethodIndex].pExpectCMFunc == NULL) {
914 return FALSE;
915 }
916 return ((gstIMInfo[gnInputMethodIndex].pExpectCMFunc)(dpy, win));
917 }
918
tgIMHandleClientMessage(dpy,win,cm_ev,key_ev,buf)919 int tgIMHandleClientMessage(dpy, win, cm_ev, key_ev, buf)
920 Display *dpy;
921 Window win;
922 XClientMessageEvent *cm_ev;
923 XKeyEvent *key_ev;
924 char *buf;
925 {
926 if (gnInputMethodIndex == INVALID ||
927 gstIMInfo[gnInputMethodIndex].pHandleCMFunc == NULL) {
928 return FALSE;
929 }
930 return ((gstIMInfo[gnInputMethodIndex].pHandleCMFunc)(dpy, win, cm_ev,
931 key_ev, buf));
932 }
933
tgIMActiveOnCntrlSpace(dpy,win)934 int tgIMActiveOnCntrlSpace(dpy, win)
935 Display *dpy;
936 Window win;
937 {
938 if (gnInputMethodIndex == INVALID ||
939 gstIMInfo[gnInputMethodIndex].pActivateOnCntrlSpaceFunc == NULL) {
940 return FALSE;
941 }
942 return ((gstIMInfo[gnInputMethodIndex].pActivateOnCntrlSpaceFunc)(dpy, win));
943 }
944
tgIMHandleCntrlSpace(dpy,win)945 int tgIMHandleCntrlSpace(dpy, win)
946 Display *dpy;
947 Window win;
948 {
949 if (gnInputMethodIndex == INVALID ||
950 gstIMInfo[gnInputMethodIndex].pHandleCntrlSpaceFunc == NULL) {
951 return FALSE;
952 }
953 return ((gstIMInfo[gnInputMethodIndex].pHandleCntrlSpaceFunc)(dpy, win));
954 }
955
tgIMDeactiveOnCreateText(dpy,win)956 int tgIMDeactiveOnCreateText(dpy, win)
957 Display *dpy;
958 Window win;
959 {
960 if (gnInputMethodIndex == INVALID ||
961 gstIMInfo[gnInputMethodIndex].pDeactivateOnCreateTextFunc == NULL) {
962 return FALSE;
963 }
964 return ((gstIMInfo[gnInputMethodIndex].pDeactivateOnCreateTextFunc)(dpy,
965 win));
966 }
967
tgIMHandleCreateText(dpy,win)968 int tgIMHandleCreateText(dpy, win)
969 Display *dpy;
970 Window win;
971 {
972 if (gnInputMethodIndex == INVALID ||
973 gstIMInfo[gnInputMethodIndex].pHandleCreateTextFunc == NULL) {
974 return FALSE;
975 }
976 return ((gstIMInfo[gnInputMethodIndex].pHandleCreateTextFunc)(dpy, win));
977 }
978
tgIMTellCursorPosition(dpy,win,cur_x,cur_y)979 int tgIMTellCursorPosition(dpy, win, cur_x, cur_y)
980 Display *dpy;
981 Window win;
982 int cur_x, cur_y;
983 {
984 if (gnInputMethodIndex == INVALID ||
985 gstIMInfo[gnInputMethodIndex].pTellCursorPosFunc == NULL) {
986 return FALSE;
987 }
988 return ((gstIMInfo[gnInputMethodIndex].pTellCursorPosFunc)(dpy, win,
989 cur_x, cur_y));
990 }
991
tgIMExpectNextEvent(dpy,win)992 int tgIMExpectNextEvent(dpy, win)
993 Display *dpy;
994 Window win;
995 {
996 if (gnInputMethodIndex == INVALID ||
997 gstIMInfo[gnInputMethodIndex].pExpectNextEventFunc == NULL) {
998 return FALSE;
999 }
1000 return ((gstIMInfo[gnInputMethodIndex].pExpectNextEventFunc)(dpy, win));
1001 }
1002
tgIMHandleNextEvent(dpy,win,ev)1003 int tgIMHandleNextEvent(dpy, win, ev)
1004 Display *dpy;
1005 Window win;
1006 XEvent *ev;
1007 {
1008 if (gnInputMethodIndex == INVALID ||
1009 gstIMInfo[gnInputMethodIndex].pHandleNextEventFunc == NULL) {
1010 return FALSE;
1011 }
1012 return ((gstIMInfo[gnInputMethodIndex].pHandleNextEventFunc)(dpy, win, ev));
1013 }
1014
tgIMHandleNewCurText(dpy,win)1015 int tgIMHandleNewCurText(dpy, win)
1016 Display *dpy;
1017 Window win;
1018 {
1019 if (gnInputMethodIndex == INVALID ||
1020 gstIMInfo[gnInputMethodIndex].pHandleNewCurTextFunc == NULL) {
1021 return FALSE;
1022 }
1023 return ((gstIMInfo[gnInputMethodIndex].pHandleNewCurTextFunc)(dpy, win));
1024 }
1025
tgIMExpectLookupString(dpy,win)1026 int tgIMExpectLookupString(dpy, win)
1027 Display *dpy;
1028 Window win;
1029 {
1030 if (gnInputMethodIndex == INVALID ||
1031 gstIMInfo[gnInputMethodIndex].pExpectLookupStringFunc == NULL) {
1032 return FALSE;
1033 }
1034 return ((gstIMInfo[gnInputMethodIndex].pExpectLookupStringFunc)(dpy, win));
1035 }
1036
tgIMHandleLookupString(dpy,win,key_ev,psz_buf,buf_size,p_key_sym,pn_has_ch)1037 int tgIMHandleLookupString(dpy, win, key_ev, psz_buf, buf_size, p_key_sym,
1038 pn_has_ch)
1039 Display *dpy;
1040 Window win;
1041 XKeyEvent *key_ev;
1042 char *psz_buf;
1043 int buf_size;
1044 KeySym *p_key_sym;
1045 int *pn_has_ch;
1046 {
1047 if (gnInputMethodIndex == INVALID ||
1048 gstIMInfo[gnInputMethodIndex].pHandleLookupStringFunc == NULL) {
1049 return FALSE;
1050 }
1051 return ((gstIMInfo[gnInputMethodIndex].pHandleLookupStringFunc)(dpy, win,
1052 key_ev, psz_buf, buf_size, p_key_sym, pn_has_ch));
1053 }
1054
1055