1 /*
2  * $Id: multi_lang.c,v 1.2 2001/06/14 18:16:16 ura Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10  * Copyright 1991, 1992 by Massachusetts Institute of Technology
11  *
12  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU Emacs; see the file COPYING.  If not, write to the
26  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  * Commentary:
29  *
30  * Change log:
31  *
32  * Last modified date: 8,Feb.1999
33  *
34  * Code:
35  *
36  */
37 /*      Version 4.0
38  */
39 #include <stdio.h>
40 #include "commonhd.h"
41 #include "sdefine.h"
42 #include "xim.h"
43 #ifdef X11R5
44 #include "Xlocaleint.h"
45 #endif /* X11R5 */
46 #include "sheader.h"
47 #include "proto.h"
48 #include "ext.h"
49 
50 
51 XSetWindowAttributes attributes;
52 XGCValues xgcv;
53 
54 char *
get_default_font_name(lang)55 get_default_font_name (lang)
56      register char *lang;
57 {
58   return (DEFAULT_FONTSET_NAME);
59 }
60 
61 int
load_font_set(xl,p,s)62 load_font_set (xl, p, s)
63      register XIMLangRec *xl;
64      register char *p, *s;
65 {
66   xl->pe_fs = xl->st_fs = (XFontSet) NULL;
67   xl->pe_b_char = xl->st_b_char = NULL;
68   if ((xl->pe_fs = create_font_set (p)) && (xl->pe_b_char = get_base_char (xl->pe_fs)) && (xl->st_fs = create_font_set (p)) && (xl->st_b_char = get_base_char (xl->st_fs)))
69     return (0);
70   if (xl->pe_fs)
71     XFreeFontSet (dpy, xl->pe_fs);
72   if (xl->pe_b_char)
73     Free (xl->pe_b_char);
74   if (xl->st_fs)
75     XFreeFontSet (dpy, xl->st_fs);
76   if (xl->st_b_char)
77     Free (xl->st_b_char);
78   xl->pe_fs = xl->st_fs = (XFontSet) NULL;
79   xl->pe_b_char = xl->st_b_char = NULL;
80   return (-1);
81 }
82 
83 int
add_locale_to_xl(xl,lang)84 add_locale_to_xl (xl, lang)
85      XIMLangRec *xl;
86      XIMNestLangRec *lang;
87 {
88   register XIMNestLangRec *lr;
89   register int size;
90   register char *alloc;
91 
92   size = sizeof (XIMNestLangRec) + strlen (lang->lc_name) + 1;
93   if (lang->alias_name)
94     size += strlen (lang->alias_name) + 1;
95 
96   if (!(alloc = Calloc (1, size)))
97     {
98       malloc_error ("allocation of work data");
99       return (-1);
100     }
101   lr = (XIMNestLangRec *) alloc;
102   alloc += sizeof (XIMNestLangRec);
103   lr->lc_name = alloc;
104   strcpy (lr->lc_name, lang->lc_name);
105   if (lang->alias_name)
106     {
107       alloc += strlen (lang->lc_name) + 1;
108       lr->alias_name = alloc;
109       strcpy (lr->alias_name, lang->alias_name);
110     }
111   else
112     {
113       lr->alias_name = NULL;
114     }
115   lr->lang_db = NULL;
116   lr->next = xl->lc_list;
117   xl->lc_list = lr;
118   return (0);
119 }
120 
121 void
remove_locale_to_xl(xl,lang)122 remove_locale_to_xl (xl, lang)
123      XIMLangRec *xl;
124      XIMNestLangRec *lang;
125 {
126   register XIMNestLangRec *p, **prev;
127 
128   for (prev = &xl->lc_list; p = *prev; prev = &p->next)
129     {
130       if (lang == NULL || !strcmp (lang->lc_name, p->lc_name))
131         {
132           *prev = p->next;
133           Free ((char *) p);
134           if (lang)
135             break;
136         }
137     }
138 }
139 
140 static int
create_lang_env(xc,num,lang,pre_font,st_font,detail)141 create_lang_env (xc, num, lang, pre_font, st_font, detail)
142      register XIMClientRec *xc;
143      int num;
144      XIMNestLangList lang;
145      char *pre_font, *st_font;
146      short *detail;
147 {
148   register XIMLangRec *xl;
149   register XIMRootRec *root = xc->root_pointer;
150 #ifdef X11R5
151   XLocale xlc;
152 #endif /* X11R5 */
153 
154   if (!setlocale (LC_ALL, lang->lang_db->lc_name))
155     {
156       *detail = BadLanguage;
157       return (0);
158     }
159 
160 #ifdef  CALLBACKS
161   if (IsPreeditCallbacks (xc))
162     {
163       if (pre_font == NULL || *pre_font == '\0')
164         {
165           if ((pre_font = get_default_font_name ()) == NULL)
166             {
167               *detail = BadFontSet;
168               return (0);
169             }
170         }
171     }
172   if (IsStatusCallbacks (xc))
173     {
174       if (st_font == NULL || *st_font == '\0')
175         {
176           if ((st_font = get_default_font_name ()) == NULL)
177             {
178               *detail = BadFontSet;
179               return (0);
180             }
181         }
182     }
183 #endif /* CALLBACKS */
184   if ((xl = xc->xl[num] = (XIMLangRec *) Calloc (1, sizeof (XIMLangRec))) == NULL)
185     {
186       *detail = AllocError;
187       return (-1);
188     }
189 #ifdef X11R5
190   if (!(xlc = _XFallBackConvert ()) || !(xl->xlc = _XlcDupLocale (xlc)))
191     {
192 #else
193   if (!(xl->xlc = _XlcCurrentLC ()))
194     {
195 #endif /* X11R5 */
196       print_out ("Could not create locale environment.");
197       Free (xl);
198       *detail = AllocError;
199       return (-1);
200     }
201   xl->lc_list = NULL;
202   if (add_locale_to_xl (xl, lang) < 0)
203     {
204       Free (xl);
205       *detail = AllocError;
206       return (-1);
207     }
208   xl->lang_db = lang->lang_db;
209   xl->w_c = NULL;
210 #ifdef  USING_XJUTIL
211   xl->xjutil_fs_id = -1;
212   xl->working_xjutil = 0;
213 #endif /* USING_XJUTIL */
214   if (IsPreeditArea (xc) || IsPreeditPosition (xc) || IsPreeditCallbacks (xc))
215     {
216       /*
217        * Loading multipule fonts
218        */
219       if (load_font_set (xl, pre_font, st_font) == -1)
220         {
221           *detail = BadFontSet;
222           goto ERROR_OCCUR1;
223           return (0);
224         }
225       /*
226        * Creating GC
227        */
228       if (num == 0)
229         {
230           if (!(xc->yes_no = (YesOrNo *) Malloc (sizeof (YesOrNo))))
231             {
232               malloc_error ("allocation of client data");
233               goto ERROR_OCCUR2;
234             }
235           if (create_yes_no (xc) < 0)
236             goto ERROR_OCCUR3;
237           xgcv.foreground = xc->pe.fg;
238           xgcv.background = xc->pe.bg;
239           if (!(xc->pe.gc = XCreateGC (dpy, root->root_window, (GCForeground | GCBackground), &xgcv)))
240             goto ERROR_OCCUR3;
241           xgcv.foreground = xc->pe.bg;
242           xgcv.background = xc->pe.fg;
243           if (!(xc->pe.reversegc = XCreateGC (dpy, root->root_window, (GCForeground | GCBackground), &xgcv)))
244             goto ERROR_OCCUR4;
245           xgcv.foreground = xc->pe.bg;
246           xgcv.function = GXinvert;
247           xgcv.plane_mask = XOR (xc->pe.fg, xc->pe.bg);
248           if (!(xc->pe.invertgc = XCreateGC (dpy, root->root_window, (GCForeground | GCFunction | GCPlaneMask), &xgcv)))
249             goto ERROR_OCCUR4;
250           xgcv.foreground = xc->st.fg;
251           xgcv.background = xc->st.bg;
252           if (!(xc->st.gc = XCreateGC (dpy, root->root_window, (GCForeground | GCBackground), &xgcv)))
253             goto ERROR_OCCUR4;
254           xgcv.foreground = xc->st.bg;
255           xgcv.background = xc->st.fg;
256           if (!(xc->st.reversegc = XCreateGC (dpy, root->root_window, (GCForeground | GCBackground), &xgcv)))
257             goto ERROR_OCCUR4;
258           if (IsPreeditArea (xc))
259             {
260               xc->max_columns = ((int) PreeditWidth (xc) / (int) FontWidth (xl));
261               if (xc->max_columns <= 0)
262                 xc->max_columns = 1;
263               xc->columns = xc->max_columns;
264             }
265           else if (IsPreeditPosition (xc))
266             {
267               xc->max_columns = ((int) xc->client_area.width / (int) FontWidth (xl));
268               if (xc->max_columns <= 0)
269                 xc->max_columns = 1;
270               xc->columns = xc->max_columns;
271             }
272         }
273     }
274   if (new_client (xc, xl, False) != -1)
275     return (1);
276   if (num == 0)
277     {
278     ERROR_OCCUR4:
279       if (xc->pe.gc)
280         XFreeGC (dpy, xc->pe.gc);
281       if (xc->pe.invertgc)
282         XFreeGC (dpy, xc->pe.invertgc);
283       if (xc->pe.reversegc)
284         XFreeGC (dpy, xc->pe.reversegc);
285       if (xc->st.gc)
286         XFreeGC (dpy, xc->st.gc);
287       if (xc->st.reversegc)
288         XFreeGC (dpy, xc->st.reversegc);
289       remove_box (xc->yes_no->title);
290       remove_box (xc->yes_no->button[0]);
291       remove_box (xc->yes_no->button[1]);
292     ERROR_OCCUR3:
293       Free ((char *) xc->yes_no);
294     }
295 ERROR_OCCUR2:
296   if (xl->pe_fs)
297     XFreeFontSet (dpy, xl->pe_fs);
298   if (xl->pe_b_char)
299     Free ((char *) xl->pe_b_char);
300   if (xl->st_fs)
301     XFreeFontSet (dpy, xl->st_fs);
302   if (xl->st_b_char)
303     Free ((char *) xl->st_b_char);
304 ERROR_OCCUR1:
305   remove_locale_to_xl (xl, lang);
306 #ifdef X11R5
307   XFree ((char *) xl->xlc);
308 #endif /* X11R5 */
309   Free ((char *) xl);
310   return (0);
311 }
312 
313 int
add_lang_env(xc,lang,new)314 add_lang_env (xc, lang, new)
315      register XIMClientRec *xc;
316      XIMNestLangRec *lang;
317      int *new;
318 {
319   register int i;
320   register char *p;
321   Status match = False;
322   int ret;
323   short detail;
324 
325   *new = 0;
326   for (i = 0; i < xc->lang_num; i++)
327     {
328       if (lang->lang_db == xc->xl[i]->lang_db)
329         {
330           match = True;
331           break;
332         }
333     }
334   if (match == True)
335     {
336       if (add_locale_to_xl (xc->xl[i], lang) < 0)
337         return (-1);
338       return (i);
339     }
340   if (!(p = Malloc (sizeof (XIMLangRec *) * (xc->lang_num + 1))))
341     {
342       malloc_error ("allocation of client data");
343       return (-2);
344     }
345   if (xc->lang_num > 0)
346     {
347       bcopy ((char *) xc->xl, (char *) p, sizeof (XIMLangRec *) * xc->lang_num);
348       Free ((char *) xc->xl);
349     }
350   xc->xl = (XIMLangRec **) p;
351   if ((ret = create_lang_env (xc, xc->lang_num, lang, xc->pe.fontset, xc->st.fontset, &detail)) <= 0)
352     {
353       return (ret - 1);
354     }
355   *new = 1;
356   return (xc->lang_num);
357 }
358 
359 void
default_xc_set(xc)360 default_xc_set (xc)
361      register XIMClientRec *xc;
362 {
363   register XIMRootRec *root = xc->root_pointer;
364   XWindowAttributes attr;
365 
366   if (xc->w)
367     {
368       XGetWindowAttributes (dpy, xc->w, &attr);
369     }
370   else
371     {
372       XGetWindowAttributes (dpy, root->root_window, &attr);
373     }
374   xc->filter_events = MaskNeeded;
375   xc->client_area.x = attr.x;
376   xc->client_area.y = attr.y;
377   xc->client_area.width = attr.width;
378   xc->client_area.height = attr.height;
379   xc->pe.colormap = attr.colormap;
380   xc->pe.std_colormap = 0;
381   xc->pe.fg = root->ximclient->pe.fg;
382   xc->pe.bg = root->ximclient->pe.bg;
383   xc->pe.bg_pixmap = NULL;
384   xc->pe.line_space = 0;
385   xc->pe.cursor = NULL;
386   xc->pe.area_needed.width = xc->pe.area_needed.height = 0;
387   xc->st.colormap = attr.colormap;
388   xc->st.std_colormap = 0;
389   xc->st.fg = root->ximclient->st.fg;
390   xc->st.bg = root->ximclient->st.bg;
391   xc->st.bg_pixmap = NULL;
392   xc->st.line_space = 0;
393   xc->st.cursor = NULL;
394   xc->st.area_needed.width = xc->st.area_needed.height = 0;
395 #ifdef  CALLBACKS
396   xc->cb_pe_start = xc->cb_st_start = 0;
397 #endif /* CALLBACKS */
398   xc->have_ch_lc = 0;
399   xc->ch_lc_flg = 0;
400 }
401 
402 XIMClientRec *
create_client(ic_req,pre_req,st_req,lc_list,init_lc,have_world,cur_is_world,pre_font,st_font,c_data,detail)403 create_client (ic_req, pre_req, st_req, lc_list, init_lc, have_world, cur_is_world, pre_font, st_font, c_data, detail)
404      ximICValuesReq *ic_req;
405      ximICAttributesReq *pre_req, *st_req;
406      XIMNestLangList lc_list, init_lc;
407      int have_world, cur_is_world;
408      char *pre_font, *st_font;
409      char *c_data;
410      short *detail;
411 {
412   register XIMClientRec *xc;
413   register i, num, num_xl = 0, using_l_len = 0;
414   register WnnClientRec *save_c_c;
415   register XIMClientRec *save_cur_p, *save_cur_x;
416   register XIMNestLangList p, xp;
417   register XIMLangDataBase *cur_lang_sv;
418   register XIMRootRec *root;
419   XIMLangRec *cur_xl = NULL;
420   XIMNestLangRec *cur_lc = NULL;
421   int ret, error = 0;
422   int count;
423   int screen;
424   Status match = False, same = False;
425 #ifdef  X11R3
426   XStandardColormap map_info;
427 #else /* X11R3 */
428   XStandardColormap *map_info;
429 #endif /* !X11R3 */
430   XWindowAttributes attr;
431 
432   if ((xc = (XIMClientRec *) Calloc (1, sizeof (XIMClientRec))) == NULL)
433     {
434       *detail = AllocError;
435       return (NULL);
436     }
437   if ((screen = get_client_screen ()) == -1)
438     {
439       screen = DefaultScreen (dpy);
440     }
441   for (xc->root_pointer = NULL, i = 0; i < xim->screen_count; i++)
442     {
443       if (screen == xim->root_pointer[i]->screen)
444         {
445           xc->root_pointer = root = xim->root_pointer[i];
446           break;
447         }
448     }
449   if (!xc->root_pointer)
450     xc->root_pointer = root = xim->root_pointer[xim->default_screen];
451   xc->cur_xl = NULL;
452   xc->next = NULL;
453   xc->using_language = NULL;
454   if (!xc->user_name || !*xc->user_name)
455     {
456       if (root->ximclient->user_name)
457         {
458           xc->user_name = alloc_and_copy (root->ximclient->user_name);
459         }
460     }
461   else
462     {
463       xc->user_name = alloc_and_copy (c_data);
464     }
465   if (!xc->user_name)
466     {
467       Free (xc);
468       *detail = AllocError;
469       return (NULL);
470     }
471   if (!(ic_req->mask & (1 << ICClientWindow)))
472     xc->w = RootWindow (dpy, root->screen);
473   else
474     xc->w = ic_req->c_window;
475   xc->mask = ic_req->mask;
476   xc->fd = get_cur_sock ();
477   xc->focus_window = xc->w;
478   xc->have_world = have_world;
479   xc->world_on = cur_is_world;
480 #ifdef  CALLBACKS
481   xc->max_keycode = ic_req->max_keycode;
482 #endif /* CALLBACKS */
483   default_xc_set (xc);
484 
485   if (xc->w)
486     XSelectInput (dpy, xc->w, StructureNotifyMask);
487 
488   update_ic (xc, ic_req, pre_req, st_req, pre_font, st_font, &error);
489   if (error)
490     goto ERROR_RET2;
491 
492   if (xc->focus_window != xc->w)
493     {
494       XSelectInput (dpy, xc->focus_window, StructureNotifyMask);
495       XGetWindowAttributes (dpy, xc->focus_window, &attr);
496       xc->focus_area.x = attr.x;
497       xc->focus_area.y = attr.y;
498       xc->focus_area.width = attr.width;
499       xc->focus_area.height = attr.height;
500     }
501   else
502     {
503       xc->focus_area.x = 0;
504       xc->focus_area.y = 0;
505       xc->focus_area.x = xc->focus_area.y = 0;
506       xc->focus_area.width = xc->focus_area.height = 0;
507     }
508 
509   if (xc->pe.std_colormap)
510     {
511 #ifdef  X11R3
512       if (XGetStandardColormap (dpy, root->root_window, &map_info, xc->pe.std_colormap))
513         {
514           xc->pe.colormap = map_info.colormap;
515 #else /* X11R3 */
516       if (XGetRGBColormaps (dpy, root->root_window, &map_info, &count, xc->pe.std_colormap))
517         {
518           xc->pe.colormap = map_info->colormap;
519           XFree (map_info);
520 #endif /* X11R3 */
521         }
522     }
523   if (xc->st.std_colormap)
524     {
525 #ifdef  X11R3
526       if (XGetStandardColormap (dpy, root->root_window, &map_info, xc->st.std_colormap))
527         {
528           xc->st.colormap = map_info.colormap;
529 #else /* X11R3 */
530       if (XGetRGBColormaps (dpy, root->root_window, &map_info, &count, xc->st.std_colormap))
531         {
532           xc->pe.colormap = map_info->colormap;
533           XFree (map_info);
534 #endif /* X11R3 */
535         }
536     }
537 
538   if (!(IsPreeditNothing (xc)))
539     {
540       if (ClientWidth (xc) <= 0 || ClientHeight (xc) <= 0)
541         {
542           goto ERROR_RET2;
543         }
544       if (pre_font == NULL)
545         {
546           if (IsPreeditArea (xc) || IsPreeditPosition (xc))
547             {
548               *detail = BadFontSet;
549               goto ERROR_RET2;
550             }
551         }
552       if (st_font == NULL)
553         {
554           if (IsStatusArea (xc))
555             {
556               st_font = pre_font;
557             }
558         }
559       for (num = 0, p = lc_list; p != NULL; p = p->next)
560         {
561           num++;
562           using_l_len += strlen (p->lc_name) + 1;
563         }
564       if ((xc->using_language = (char *) Malloc (sizeof (char) * using_l_len)) == NULL)
565         {
566           malloc_error ("allocation of client data");
567           *detail = AllocError;
568           goto ERROR_RET2;
569         }
570       xc->using_language[0] = '\0';
571       if ((xc->xl = (XIMLangRec **) Malloc (sizeof (XIMLangRec *) * num)) == NULL)
572         {
573           malloc_error ("allocation of client data");
574           *detail = AllocError;
575           goto ERROR_RET2;
576         }
577       /*
578        * Create lang env.
579        */
580       save_c_c = c_c;
581       save_cur_p = cur_p;
582       save_cur_x = cur_x;
583       cur_lang_sv = cur_lang;
584       cur_p = cur_x = xc;
585       for (i = 0, p = lc_list; p != NULL; p = p->next)
586         {
587           match = False;
588           same = False;
589           for (i = 0; i < num_xl; i++)
590             {
591               if (p->lang_db == xc->xl[i]->lang_db)
592                 {
593                   match = True;
594                   break;
595                 }
596             }
597           if (match == True)
598             {
599               for (xp = xc->xl[i]->lc_list; xp != NULL; xp = xp->next)
600                 {
601                   if (!strcmp (p->lc_name, xp->lc_name))
602                     {
603                       same = True;
604                       break;
605                     }
606                 }
607               if (same == True)
608                 continue;
609               if (add_locale_to_xl (xc->xl[i], p) < 0)
610                 {
611                   for (i = 0; i < num_xl; i++)
612                     {
613                       destroy_xl (xc, xc->xl[i]);
614                     }
615                   Free ((char *) xc->xl);
616                   goto ERROR_RET1;
617                 }
618               if (init_lc && !strcmp (p->lc_name, init_lc->lc_name))
619                 {
620                   cur_xl = xc->xl[i];
621                   cur_lc = cur_xl->lc_list;
622                 }
623             }
624           else
625             {
626               if ((ret = create_lang_env (xc, num_xl, p, pre_font, st_font, detail)) == -1)
627                 {
628                   for (i = 0; i < num_xl; i++)
629                     {
630                       destroy_xl (xc, xc->xl[i]);
631                     }
632                   Free ((char *) xc->xl);
633                   goto ERROR_RET1;
634                 }
635               else if (ret == 0)
636                 {
637                   continue;
638                 }
639               if (init_lc && !strcmp (p->lc_name, init_lc->lc_name))
640                 {
641                   cur_xl = xc->xl[i];
642                   cur_lc = cur_xl->lc_list;
643                 }
644               num_xl++;
645             }
646           strcat (xc->using_language, p->lc_name);
647           strcat (xc->using_language, ";");
648         }
649       c_c = save_c_c;
650       cur_p = save_cur_p;
651       cur_x = save_cur_x;
652       cur_lang = cur_lang_sv;
653       if (c_c)
654         {
655           cur_rk = c_c->rk;
656           cur_rk_table = cur_rk->rk_table;
657         }
658       if (num_xl == 0)
659         {
660           Free ((char *) xc->xl);
661           *detail = BadLanguage;
662           goto ERROR_RET2;
663         }
664       xc->using_language[strlen (xc->using_language) - 1] = '\0';
665       if (cur_xl == NULL)
666         {
667           cur_xl = xc->xl[0];
668           cur_lc = cur_xl->lc_list;
669         }
670       xc->lang_num = num_xl;
671     }
672   else
673     {
674       xc->cur_xl = NULL;
675       xc->lang_num = 0;
676     }
677   add_ximclientlist (xc);
678   if (IsPreeditNothing (xc) || xc->lang_num == 0)
679     {
680       xc->yes_no = NULL;
681       return (xc);
682     }
683   save_c_c = c_c;
684   save_cur_p = cur_p;
685   save_cur_x = cur_x;
686   cur_lang_sv = cur_lang;
687   if (IsPreeditPosition (xc))
688     {
689       if (!(xc->mask & (1 << ICArea)))
690         {
691           xc->pe.area.x = xc->focus_area.x;
692           xc->pe.area.y = xc->focus_area.y;
693           xc->pe.area.width = xc->focus_area.width;
694           xc->pe.area.height = xc->focus_area.height;
695         }
696       update_spotlocation (xc, ic_req, pre_req);
697     }
698   cur_p = cur_x = xc;
699   cur_p->cur_xl = cur_xl;
700   cur_xl->cur_lc = cur_lc;
701   cur_lang = cur_p->cur_xl->lang_db;
702   c_c = cur_p->cur_xl->w_c;
703   cur_rk = c_c->rk;
704   cur_rk_table = cur_rk->rk_table;
705   if (IsStatusArea (xc)
706 #ifdef  CALLBACKS
707       || IsStatusCallbacks (xc)
708 #endif /* CALLBACKS */
709     )
710     {
711 #ifdef  nodef
712       visual_status ();
713 #endif /* nodef */
714       if (henkan_off_flag == 0)
715         {
716           disp_mode ();
717         }
718       else
719         {
720           display_henkan_off_mode ();
721         }
722     }
723 
724   XSelectInput (dpy, xc->w, StructureNotifyMask);
725   if (c_c->use_server && !jl_isconnect (bun_data_))
726     {
727       if (servername && *servername)
728         {
729           print_msg_getc (" I can not connect server(at %s)", servername, NULL, NULL);
730         }
731       else
732         {
733           print_msg_getc (" I can not connect server", NULL, NULL, NULL);
734         }
735     }
736   c_c = save_c_c;
737   cur_p = save_cur_p;
738   cur_x = save_cur_x;
739   cur_lang = cur_lang_sv;
740   if (c_c)
741     {
742       cur_rk = c_c->rk;
743       cur_rk_table = cur_rk->rk_table;
744     }
745   return (xc);
746 
747 ERROR_RET1:
748   c_c = save_c_c;
749   cur_p = save_cur_p;
750   cur_x = save_cur_x;
751   cur_lang = cur_lang_sv;
752   if (c_c)
753     {
754       cur_rk = c_c->rk;
755       cur_rk_table = cur_rk->rk_table;
756     }
757 ERROR_RET2:
758   if (xc->using_language)
759     Free ((char *) xc->using_language);
760   Free ((char *) xc->user_name);
761   if (xc->pe.fontset != NULL && *(xc->pe.fontset) != '\0')
762     {
763       Free (xc->pe.fontset);
764     }
765   if (xc->st.fontset != NULL && *(xc->st.fontset) != '\0')
766     {
767       Free (xc->st.fontset);
768     }
769   Free ((char *) xc);
770   return (NULL);
771 }
772 
773 static char *lang_title = "LANGUAGE";
774 int
lang_set(in,p_xl,p_lang)775 lang_set (in, p_xl, p_lang)
776      int in;
777      XIMLangRec **p_xl;
778      XIMNestLangRec **p_lang;
779 {
780   static int init;
781   static int c, cnt;
782   int i;
783   static char *buf[MAX_LANGS];
784   static WnnClientRec *c_c_sv = 0;
785   static lang_step = 0;
786   XIMNestLangRec *p;
787 
788 /*
789     if (henkan_off_flag == 1) {
790         return(-1);
791     }
792 */
793   if (c_c_sv != 0 && c_c != c_c_sv)
794     {
795       ring_bell ();
796       return (-1);
797     }
798   if (lang_step == 0)
799     {
800       if ((cur_p->lang_num == 0) || (cur_p->have_ch_lc == 0))
801         return (-1);
802       c_c_sv = c_c;
803       cnt = 0;
804       for (i = 0; i < cur_p->lang_num; i++)
805         {
806           for (p = cur_p->xl[i]->lc_list; p; p = p->next)
807             {
808               if (p->alias_name)
809                 buf[cnt] = p->alias_name;
810               else
811                 buf[cnt] = p->lc_name;
812               if (cur_p->cur_xl == cur_p->xl[i] && cur_p->xl[i]->cur_lc == p)
813                 init = cnt;
814               cnt++;
815             }
816         }
817       if (cur_p->have_world)
818         {
819           buf[cnt] = world_locale;
820           if (cur_p->world_on)
821             {
822               init = cnt;
823             }
824           cnt++;
825         }
826       lang_step++;
827     }
828   if (lang_step == 1)
829     {
830       c = xw_select_one_element (buf, cnt, init, lang_title, SENTAKU, main_table[4], in);
831       if (c == BUFFER_IN_CONT)
832         {
833           return (BUFFER_IN_CONT);
834         }
835       if (c == -1 || c == -3)
836         {
837           c_c_sv = 0;
838           lang_step = 0;
839           return (-1);
840         }
841       lang_step++;
842     }
843   if (lang_step == 2)
844     {
845       c_c_sv = 0;
846       lang_step = 0;
847       if (cur_p->have_world)
848         {
849           if (!strcmp (cur_p->xl[0]->lc_list->lc_name, buf[c]))
850             {
851               *p_xl = cur_p->xl[0];
852               *p_lang = cur_p->xl[0]->lc_list;
853               cur_p->ch_lc_flg = 1;
854               cur_p->world_on = 1;
855               return (c);
856             }
857           else
858             {
859               cur_p->world_on = 0;
860             }
861         }
862       for (i = 0; i < cur_p->lang_num; i++)
863         {
864           for (p = cur_p->xl[i]->lc_list; p; p = p->next)
865             {
866               if ((p->alias_name && !strcmp (p->alias_name, buf[c])) || !strcmp (p->lc_name, buf[c]))
867                 {
868                   *p_xl = cur_p->xl[i];
869                   *p_lang = p;
870                   cur_p->ch_lc_flg = 1;
871                   return (c);
872                 }
873             }
874         }
875       return (-1);
876     }
877   c_c_sv = 0;
878   lang_step = 0;
879   return (-1);
880 }
881 
882 static char *lang_title_ct = "LANGUAGE_CT";
883 int
lang_set_ct(in,p_xl,p_lang)884 lang_set_ct (in, p_xl, p_lang)
885      int in;
886      XIMLangRec **p_xl;
887      XIMNestLangRec **p_lang;
888 {
889   static int init;
890   static int c;
891   int i;
892   static char *buf[MAX_LANGS];
893   static WnnClientRec *c_c_sv = 0;
894   static lang_step = 0;
895 
896   if (c_c_sv != 0 && c_c != c_c_sv)
897     {
898       ring_bell ();
899       return (-1);
900     }
901   if (lang_step == 0)
902     {
903       if ((cur_p->lang_num == 0) || (cur_p->world_on == 0))
904         return (-1);
905       c_c_sv = c_c;
906       for (i = 0; i < cur_p->lang_num; i++)
907         {
908           buf[i] = cur_p->xl[i]->lang_db->lang;
909           if (cur_p->cur_xl == cur_p->xl[i])
910             init = i;
911         }
912       lang_step++;
913     }
914   if (lang_step == 1)
915     {
916       c = xw_select_one_element (buf, cur_p->lang_num, init, lang_title_ct, SENTAKU, main_table[4], in);
917       if (c == BUFFER_IN_CONT)
918         {
919           return (BUFFER_IN_CONT);
920         }
921       if (c == -1 || c == -3)
922         {
923           c_c_sv = 0;
924           lang_step = 0;
925           return (-1);
926         }
927       lang_step++;
928     }
929   if (lang_step == 2)
930     {
931       c_c_sv = 0;
932       lang_step = 0;
933       for (i = 0; i < cur_p->lang_num; i++)
934         {
935           if (!strcmp (cur_p->xl[i]->lang_db->lang, buf[c]))
936             {
937               *p_xl = cur_p->xl[i];
938               *p_lang = cur_p->xl[i]->lc_list;
939               return (c);
940             }
941         }
942       return (-1);
943     }
944   c_c_sv = 0;
945   lang_step = 0;
946   return (-1);
947 }
948 
949 void
change_lang(xl,p)950 change_lang (xl, p)
951      XIMLangRec *xl;
952      XIMNestLangRec *p;
953 {
954   if (IsPreeditNothing (cur_p))
955     return;
956   if (cur_p->cur_xl == xl)
957     {
958       if (cur_p->cur_xl->cur_lc == p)
959         return;
960       cur_p->cur_xl->cur_lc = p;
961     }
962   else
963     {
964       invisual_window1 ();
965       invisual_status ();
966       cur_p->cur_xl = xl;
967       cur_p->cur_xl->cur_lc = p;
968       c_c = cur_p->cur_xl->w_c;
969       cur_lang = cur_p->cur_xl->lang_db;
970       cur_rk = c_c->rk;
971       cur_rk_table = cur_rk->rk_table;
972       visual_status ();
973       if (henkan_off_flag == 0)
974         {
975           disp_mode ();
976         }
977       else
978         {
979           display_henkan_off_mode ();
980         }
981       if (!ifempty ())
982         {
983           visual_window ();
984         }
985       cur_input = NULL;
986     }
987 }
988