1 /*
2  * $Id: change.c,v 1.2 2001/06/14 18:16:14 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 #include "sheader.h"
44 #include "proto.h"
45 #include "ext.h"
46 
47 XGCValues xgcv;
48 
49 void
reset_preedit(xc)50 reset_preedit (xc)
51      register XIMClientRec *xc;
52 {
53   XIMClientRec *save_cur_p, *save_cur_x;
54   WnnClientRec *save_c_c;
55 
56   if (!xc->cur_xl->w_c->h_flag && xc->cur_xl->max_pos)
57     {
58       save_c_c = c_c;
59       save_cur_p = cur_p;
60       save_cur_x = cur_x;
61       cur_p = cur_x = xc;
62       c_c = cur_p->cur_xl->w_c;
63       cur_rk = c_c->rk;
64       cur_rk_table = cur_rk->rk_table;
65       if (IsPreeditPosition (xc))
66         {
67           invisual_window1 ();
68           xc->cur_xl->visible = 0;
69           visual_window1 ();
70           check_scroll ();
71 #ifdef  CALLBACKS
72         }
73       else if (IsPreeditArea (xc) || IsPreeditCallbacks (xc))
74         {
75 #else /* CALLBACKS */
76         }
77       else if (IsPreeditArea (xc))
78         {
79 #endif /* CALLBACKS */
80           invisual_window ();
81           xc->cur_xl->visible = 0;
82           visual_window ();
83         }
84       c_c = save_c_c;
85       cur_p = save_cur_p;
86       cur_x = save_cur_x;
87       if (c_c)
88         {
89           cur_rk = c_c->rk;
90           cur_rk_table = cur_rk->rk_table;
91         }
92     }
93 }
94 
95 void
reset_status(xc)96 reset_status (xc)
97      register XIMClientRec *xc;
98 {
99   XIMClientRec *save_cur_p, *save_cur_x;
100   WnnClientRec *save_c_c;
101 
102   save_c_c = c_c;
103   save_cur_p = cur_p;
104   save_cur_x = cur_x;
105   cur_p = cur_x = xc;
106   c_c = cur_p->cur_xl->w_c;
107   cur_rk = c_c->rk;
108   cur_rk_table = cur_rk->rk_table;
109 #ifdef  CALLBACKS
110   if (IsStatusArea (xc) || IsStatusCallbacks (xc))
111     {
112 #else /* CALLBACKS */
113   if (IsStatusArea (xc))
114     {
115 #endif /* CALLBACKS */
116       if (!henkan_off_flag)
117         {
118           disp_mode ();
119         }
120       else
121         {
122           display_henkan_off_mode ();
123         }
124     }
125   c_c = save_c_c;
126   cur_p = save_cur_p;
127   cur_x = save_cur_x;
128   if (c_c)
129     {
130       cur_rk = c_c->rk;
131       cur_rk_table = cur_rk->rk_table;
132     }
133 }
134 
135 unsigned long
update_ic(xc,ic,pre,st,pre_font,st_font,ret)136 update_ic (xc, ic, pre, st, pre_font, st_font, ret)
137      register XIMClientRec *xc;
138      register ximICValuesReq *ic;
139      register ximICAttributesReq *pre, *st;
140      char *pre_font, *st_font;
141      int *ret;
142 {
143   unsigned long mask;
144   unsigned long dirty = 0L;
145 
146   *ret = 0;
147   mask = ic->mask;
148 
149   if (mask & (1 << ICInputStyle))
150     {
151       xc->input_style = ic->input_style;
152     }
153 
154   if (mask & (1 << ICClientWindow))
155     {
156       if (xc->w == xc->root_pointer->root_window)
157         {
158           xc->w = ic->c_window;
159           dirty |= ChClientWindow;
160         }
161     }
162   if (mask & (1 << ICFocusWindow))
163     {
164       if (xc->focus_window != ic->focus_window)
165         {
166           xc->focus_window = ic->focus_window;
167           dirty |= ChFocusWindow;
168         }
169     }
170   if (mask & (1 << ICArea))
171     {
172       if ((xc->pe.area.x != pre->area_x) || (xc->pe.area.y != pre->area_y))
173         {
174           xc->pe.area.x = pre->area_x;
175           xc->pe.area.y = pre->area_y;
176           dirty |= ChPreeditLocation;
177         }
178       if ((xc->pe.area.width != pre->area_width) || (xc->pe.area.height != pre->area_height))
179         {
180           xc->pe.area.width = pre->area_width;
181           xc->pe.area.height = pre->area_height;
182           dirty |= ChPreeditSize;
183         }
184     }
185   if (mask & (1 << ICAreaNeeded))
186     {
187       if (xc->pe.area_needed.width < pre->areaneeded_width)
188         {
189           xc->pe.area_needed.width = pre->areaneeded_width;
190         }
191       if (xc->pe.area_needed.height < pre->areaneeded_height)
192         {
193           xc->pe.area_needed.height = pre->areaneeded_height;
194         }
195     }
196   if (mask & (1 << ICColormap))
197     {
198       if (xc->pe.colormap != pre->colormap)
199         {
200           xc->pe.colormap = pre->colormap;
201           dirty |= ChPreColormap;
202         }
203     }
204   if (mask & (1 << ICForeground))
205     {
206       if (xc->pe.fg != pre->foreground)
207         {
208           xc->pe.fg = pre->foreground;
209           dirty |= ChPreForeground;
210         }
211     }
212   if (mask & (1 << ICBackground))
213     {
214       if (xc->pe.bg != pre->background)
215         {
216           xc->pe.bg = pre->background;
217           dirty |= ChPreBackground;
218         }
219     }
220   if (mask & (1 << ICBackgroundPixmap))
221     {
222       if (xc->pe.bg_pixmap != pre->pixmap)
223         {
224           xc->pe.bg_pixmap = pre->pixmap;
225           dirty |= ChPreBackgroundPixmap;
226         }
227     }
228   if (pre_font && (mask & (1 << ICFontSet)))
229     {
230       if (xc->pe.fontset != NULL && *(xc->pe.fontset) != '\0')
231         {
232           Free (xc->pe.fontset);
233         }
234       if (!(xc->pe.fontset = alloc_and_copy (pre_font)))
235         {
236           *ret = 1;
237           return (0);
238         }
239       dirty |= ChPreFontSet;
240     }
241   if (mask & (1 << ICLineSpace))
242     {
243       if (xc->pe.line_space != pre->line_space)
244         {
245           xc->pe.line_space = pre->line_space;
246           dirty |= ChPreLineSpace;
247         }
248     }
249   if (mask & (1 << ICCursor))
250     {
251       if (xc->pe.cursor != pre->cursor)
252         {
253           xc->pe.cursor = pre->cursor;
254           dirty |= ChPreCursor;
255         }
256     }
257   if (mask & (1 << (ICArea + StatusOffset)))
258     {
259       if ((xc->st.area.x != st->area_x) || (xc->st.area.y != st->area_y))
260         {
261           xc->st.area.x = st->area_x;
262           xc->st.area.y = st->area_y;
263           dirty |= ChStatusLocation;
264         }
265       if ((xc->st.area.width != st->area_width) || (xc->st.area.height != st->area_height))
266         {
267           xc->st.area.width = st->area_width;
268           xc->st.area.height = st->area_height;
269           dirty |= ChStatusSize;
270         }
271     }
272   if (mask & (1 << (ICAreaNeeded + StatusOffset)))
273     {
274 /* No op area_needed of Status because the area of it is fixed.
275         if (xc->st.area_needed.width < st->areaneeded_width) {
276             xc->st.area_needed.width = st->areaneeded_width;
277         }
278         if (xc->st.area_needed.height < st->areaneeded_height) {
279             xc->st.area_needed.height = st->areaneeded_height;
280         }
281 */
282     }
283   if (mask & (1 << (ICColormap + StatusOffset)))
284     {
285       if (xc->st.colormap != st->colormap)
286         {
287           xc->st.colormap = st->colormap;
288           dirty |= ChStColormap;
289         }
290     }
291   if (mask & (1 << (ICForeground + StatusOffset)))
292     {
293       if (xc->st.fg != st->foreground)
294         {
295           xc->st.fg = st->foreground;
296           dirty |= ChStForeground;
297         }
298     }
299   if (mask & (1 << (ICBackground + StatusOffset)))
300     {
301       if (xc->st.bg != st->background)
302         {
303           xc->st.bg = st->background;
304           dirty |= ChStBackground;
305         }
306     }
307   if (mask & (1 << (ICBackgroundPixmap + StatusOffset)))
308     {
309       if (xc->st.bg_pixmap != st->pixmap)
310         {
311           xc->st.bg_pixmap = st->pixmap;
312           dirty |= ChStBackgroundPixmap;
313         }
314     }
315   if (st_font && (mask & (1 << (ICFontSet + StatusOffset))))
316     {
317       if (xc->st.fontset != NULL && *(xc->st.fontset) != '\0')
318         {
319           Free (xc->st.fontset);
320         }
321       if (!(xc->st.fontset = alloc_and_copy (st_font)))
322         {
323           *ret = 1;
324           return (0);
325         }
326       dirty |= ChStFontSet;
327     }
328   if (mask & (1 << (ICLineSpace + StatusOffset)))
329     {
330       if (xc->st.line_space != st->line_space)
331         {
332           xc->st.line_space = st->line_space;
333           dirty |= ChStLineSpace;
334         }
335     }
336   if (mask & (1 << (ICCursor + StatusOffset)))
337     {
338       if (xc->st.cursor != st->cursor)
339         {
340           xc->st.cursor = st->cursor;
341           dirty |= ChStCursor;
342         }
343     }
344   if (mask & (1 << (ICChangeLocaleCB)))
345     {
346       xc->have_ch_lc = 1;
347     }
348   return (dirty);
349 }
350 
351 
352 /*
353  * update spotlocation.
354  */
355 unsigned long
update_spotlocation(xc,ic,pre)356 update_spotlocation (xc, ic, pre)
357      register XIMClientRec *xc;
358      register ximICValuesReq *ic;
359      register ximICAttributesReq *pre;
360 {
361   unsigned long dirty = 0L;
362 
363   if (ic->mask & (1 << ICSpotLocation))
364     {
365       if ((xc->point.x != pre->spot_x) || (xc->point.y != (pre->spot_y - FontAscent (xc->cur_xl))))
366         {
367           xc->point.x = pre->spot_x;
368           xc->point.y = (pre->spot_y - FontAscent (xc->cur_xl));
369           dirty = ChPreeditLocation;
370         }
371     }
372   return (dirty);
373 }
374 
375 int
change_current_language(xc,cur_l,cur_is_world)376 change_current_language (xc, cur_l, cur_is_world)
377      register XIMClientRec *xc;
378      register XIMNestLangRec *cur_l;
379      int cur_is_world;
380 {
381   register XIMLangRec *xl;
382   register XIMNestLangRec *p, *pp;
383   register int i, ret;
384   int new = 0;
385 
386   xc->world_on = 0;
387   for (pp = cur_l; pp != NULL; pp = pp->next)
388     {
389       for (i = 0; i < xc->lang_num; i++)
390         {
391           for (p = xc->xl[i]->lc_list; p; p = p->next)
392             {
393               if (!strcmp (pp->lc_name, p->lc_name))
394                 {
395                   if (cur_is_world > 0)
396                     break;
397                   if (xc->cur_xl == xc->xl[i] && xc->xl[i]->cur_lc == pp)
398                     {
399                       return (0);
400                     }
401                   cur_p = cur_x = xc;
402                   change_lang (xc->xl[i], p);
403                   return (0);
404                 }
405             }
406           if (p)
407             break;
408         }
409       if (i < xc->lang_num)
410         continue;
411       if ((ret = add_lang_env (xc, pp, &new)) == -2)
412         {
413           return (-1);
414         }
415       else if (ret == -1)
416         {
417           if (!cur_is_world)
418             return (-1);
419         }
420       else
421         {
422           xl = xc->xl[ret];
423           if (new != 0)
424             {
425               xc->lang_num++;
426             }
427           if (!cur_is_world)
428             {
429               change_lang (xl, pp);
430               return (0);
431             }
432         }
433     }
434   if (cur_is_world)
435     {
436       cur_p = cur_x = xc;
437       xc->world_on = 1;
438       xc->have_world = 1;
439       change_lang (xc->xl[0], xc->xl[0]->lc_list);
440       return (0);
441     }
442   return (-1);
443 }
444 
445 static void
change_client_window(xc,old)446 change_client_window (xc, old)
447      register XIMClientRec *xc;
448      Window old;
449 {
450   register int i;
451   register Window w = xc->w;
452 
453   if (old)
454     XSelectInput (dpy, old, NoEventMask);
455   XSelectInput (dpy, w, StructureNotifyMask);
456 
457   if (IsPreeditPosition (xc) && xc->focus_window == 0)
458     {
459       for (i = 0; i < xc->lang_num; i++)
460         {
461           XReparentWindow (dpy, xc->xl[i]->wp[0], w, 0, 0);
462           XReparentWindow (dpy, xc->xl[i]->wp[1], w, 0, 0);
463           XReparentWindow (dpy, xc->xl[i]->wp[2], w, 0, 0);
464           XReparentWindow (dpy, xc->xl[i]->wn[0], w, 0, 0);
465           XReparentWindow (dpy, xc->xl[i]->wn[1], w, 0, 0);
466           XReparentWindow (dpy, xc->xl[i]->wn[2], w, 0, 0);
467         }
468     }
469   else if (IsPreeditArea (xc))
470     {
471       for (i = 0; i < xc->lang_num; i++)
472         {
473           XReparentWindow (dpy, xc->xl[i]->wp[0], w, 0, 0);
474         }
475     }
476   if (IsStatusArea (xc))
477     {
478       for (i = 0; i < xc->lang_num; i++)
479         {
480           XReparentWindow (dpy, xc->xl[i]->ws, w, 0, 0);
481         }
482     }
483 }
484 
485 static int
change_focus_window(xc,old)486 change_focus_window (xc, old)
487      register XIMClientRec *xc;
488      Window old;
489 {
490   register XIMInputRec *xi;
491   register int i;
492   register Window w = xc->focus_window;
493   XWindowAttributes attr;
494 
495   /*
496    * Get the attributes of focus_window.
497    */
498   if (XGetWindowAttributes (dpy, w, &attr) == 0)
499     {
500       return (BadFocusWindow);
501     }
502   if (old)
503     XSelectInput (dpy, old, NoEventMask);
504   XSelectInput (dpy, w, StructureNotifyMask);
505   xc->focus_area.x = attr.x;
506   xc->focus_area.y = attr.y;
507   xc->focus_area.width = attr.width;
508   xc->focus_area.height = attr.height;
509 
510   for (xi = input_list; xi != NULL; xi = xi->next)
511     {
512       if (xc == xi->pclient)
513         {
514           xi->w = w;
515         }
516     }
517   if (IsPreeditPosition (xc))
518     {
519       if (!(xc->mask & (1 << ICArea)))
520         {
521           xc->pe.area.x = xc->focus_area.x;
522           xc->pe.area.y = xc->focus_area.y;
523           xc->pe.area.width = xc->focus_area.width;
524           xc->pe.area.height = xc->focus_area.height;
525         }
526       for (i = 0; i < xc->lang_num; i++)
527         {
528           XReparentWindow (dpy, xc->xl[i]->wp[0], w, 0, 0);
529           XReparentWindow (dpy, xc->xl[i]->wp[1], w, 0, 0);
530           XReparentWindow (dpy, xc->xl[i]->wp[2], w, 0, 0);
531           XReparentWindow (dpy, xc->xl[i]->wn[0], w, 0, 0);
532           XReparentWindow (dpy, xc->xl[i]->wn[1], w, 0, 0);
533           XReparentWindow (dpy, xc->xl[i]->wn[2], w, 0, 0);
534         }
535     }
536   return (0);
537 }
538 
539 void
change_client_area(xc,x,y,width,height)540 change_client_area (xc, x, y, width, height)
541      register XIMClientRec *xc;
542      int x, y, width, height;
543 {
544   if (IsPreeditPosition (xc))
545     {
546       xc->client_area.x = x;
547       xc->client_area.y = y;
548       xc->client_area.width = width;
549       xc->client_area.height = height;
550       reset_preedit (xc);
551     }
552 }
553 
554 void
change_focus_area(xc,x,y,width,height)555 change_focus_area (xc, x, y, width, height)
556      register XIMClientRec *xc;
557      int x, y, width, height;
558 {
559   if (IsPreeditPosition (xc))
560     {
561       if (!(xc->mask & (1 << ICArea)))
562         {
563           xc->pe.area.x = xc->focus_area.x;
564           xc->pe.area.y = xc->focus_area.y;
565           xc->pe.area.width = xc->focus_area.width;
566           xc->pe.area.height = xc->focus_area.height;
567         }
568       xc->focus_area.x = x;
569       xc->focus_area.y = y;
570       xc->focus_area.width = width;
571       xc->focus_area.height = height;
572       reset_preedit (xc);
573     }
574 }
575 
576 static void
change_pre_fontset(xc)577 change_pre_fontset (xc)
578      register XIMClientRec *xc;
579 {
580   register int i, j;
581   register XIMLangRec *xl;
582   register XFontSet save_fs;
583   register XCharStruct *save_b_char;
584   int width, height;
585 
586   if (IsPreeditPosition (xc) || IsPreeditArea (xc))
587     {
588       for (i = 0; i < xc->lang_num; i++)
589         {
590           xl = xc->xl[i];
591           setlocale (LC_ALL, xl->lang_db->lc_name);
592           save_fs = xl->pe_fs;
593           save_b_char = xl->pe_b_char;
594           if ((xl->pe_fs = create_font_set (xc->pe.fontset)) && (xl->pe_b_char = get_base_char (xl->pe_fs)))
595             {
596               if (save_fs)
597                 XFreeFontSet (dpy, save_fs);
598               if (xl->pe_b_char)
599                 Free (xl->pe_b_char);
600               xl->pe_b_char = get_base_char (xl->pe_fs);
601               height = FontHeight (xl);
602               if (IsPreeditPosition (xc))
603                 {
604                   width = FontWidth (xl) * (xc->maxcolumns + 1);
605                   for (j = 0; j < 3; j++)
606                     {
607                       XResizeWindow (dpy, xl->w[j], width, height);
608                       XResizeWindow (dpy, xl->wn[j], FontWidth (xl), height);
609                     }
610                 }
611               else
612                 {
613                   XResizeWindow (dpy, xl->w[0], FontWidth (xl) * (xc->maxcolumns + 1), height);
614                   XResizeWindow (dpy, xl->wn[0], FontWidth (xl), height);
615                   XResizeWindow (dpy, xl->wn[1], FontWidth (xl), height);
616                 }
617             }
618           else
619             {
620               if (xl->pe_fs)
621                 XFreeFontSet (dpy, xl->pe_fs);
622               xl->pe_fs = save_fs;
623               xl->pe_b_char = save_b_char;
624             }
625           if (xc->pe.area_needed.width < FontWidth (xl) * 2)
626             xc->pe.area_needed.width = FontWidth (xl) * 2;
627           if (xc->pe.area_needed.height < FontHeight (xl))
628             xc->pe.area_needed.height = FontHeight (xl);
629         }
630     }
631 }
632 
633 
634 static void
change_pre_location(xc)635 change_pre_location (xc)
636      register XIMClientRec *xc;
637 {
638   register int i;
639 
640   if (IsPreeditPosition (xc))
641     {
642       /*
643        * Need not calling X functions, because the change_client() calles
644        * invisual_window() and visual_window().
645        */
646     }
647   else if (IsPreeditArea (xc))
648     {
649       for (i = 0; i < xc->lang_num; i++)
650         {
651           XMoveWindow (dpy, xc->xl[i]->wp[0], PreeditX (xc), PreeditY (xc));
652         }
653     }
654 }
655 
656 static void
change_pre_size(xc)657 change_pre_size (xc)
658      register XIMClientRec *xc;
659 {
660   register int i;
661   register XIMLangRec *xl;
662 
663   if (IsPreeditPosition (xc))
664     {
665       /*
666        * Need not calling X functions, because the change_client() calles
667        * invisual_window() and visual_window().
668        */
669     }
670   else if (IsPreeditArea (xc))
671     {
672       for (i = 0; i < xc->lang_num; i++)
673         {
674           xl = xc->xl[i];
675           xc->max_columns = (int) PreeditWidth (xc) / (int) FontWidth (xl);
676           if (xc->max_columns <= 0)
677             xc->max_columns = 1;
678           XResizeWindow (dpy, xl->wp[0], PreeditWidth (xc), PreeditHeight (xc));
679           XMoveWindow (dpy, xl->wn[1], PreeditWidth (xc) - FontWidth (xl), 0);
680         }
681     }
682 }
683 
684 static void
change_pre_colormap(xc)685 change_pre_colormap (xc)
686      register XIMClientRec *xc;
687 {
688   register int i;
689   register XIMLangRec *xl;
690   register Colormap c = xc->pe.colormap;
691 
692   if (IsPreeditPosition (xc) || IsPreeditArea (xc))
693     {
694       for (i = 0; i < xc->lang_num; i++)
695         {
696           xl = xc->xl[i];
697           XSetWindowColormap (dpy, xl->wp[0], c);
698           XSetWindowColormap (dpy, xl->w[0], c);
699           XSetWindowColormap (dpy, xl->wn[0], c);
700           XSetWindowColormap (dpy, xl->wn[1], c);
701           XSetWindowColormap (dpy, xl->wn[2], c);
702           if (IsPreeditPosition (xc))
703             {
704               XSetWindowColormap (dpy, xl->wp[1], c);
705               XSetWindowColormap (dpy, xl->w[1], c);
706               XSetWindowColormap (dpy, xl->wp[2], c);
707               XSetWindowColormap (dpy, xl->w[2], c);
708             }
709         }
710     }
711 }
712 
713 static void
change_pre_stdcolormap(xc)714 change_pre_stdcolormap (xc)
715      register XIMClientRec *xc;
716 {
717   XStandardColormap cmap;
718 
719   XGetStandardColormap (dpy, xc->root_pointer->root_window, &cmap, xc->pe.std_colormap);
720   xc->pe.colormap = cmap.colormap;
721   change_pre_colormap (xc);
722 }
723 
724 static void
change_pre_fg(xc)725 change_pre_fg (xc)
726      register XIMClientRec *xc;
727 {
728   if (IsPreeditPosition (xc) || IsPreeditArea (xc))
729     {
730       xgcv.foreground = xc->pe.fg;
731       if (xc->pe.gc)
732         {
733           XChangeGC (dpy, xc->pe.gc, GCForeground, &xgcv);
734         }
735       xgcv.background = xc->pe.fg;
736       if (xc->pe.reversegc)
737         {
738           XChangeGC (dpy, xc->pe.reversegc, GCBackground, &xgcv);
739         }
740       xgcv.plane_mask = XOR (xc->pe.fg, xc->pe.bg);
741       if (xc->pe.invertgc)
742         {
743           XChangeGC (dpy, xc->pe.invertgc, (GCForeground | GCPlaneMask), &xgcv);
744         }
745     }
746 }
747 
748 static void
change_pre_bg(xc)749 change_pre_bg (xc)
750      register XIMClientRec *xc;
751 {
752   register int i;
753   register XIMLangRec *xl;
754   register unsigned long bg = xc->pe.bg;
755 
756   if (IsPreeditPosition (xc) || IsPreeditArea (xc))
757     {
758       xgcv.background = xc->pe.bg;
759       if (xc->pe.gc)
760         {
761           XChangeGC (dpy, xc->pe.gc, GCBackground, &xgcv);
762         }
763       xgcv.foreground = xc->pe.bg;
764       if (xc->pe.reversegc)
765         {
766           XChangeGC (dpy, xc->pe.reversegc, GCForeground, &xgcv);
767         }
768       xgcv.plane_mask = XOR (xc->pe.fg, xc->pe.bg);
769       if (xc->pe.invertgc)
770         {
771           XChangeGC (dpy, xc->pe.invertgc, GCPlaneMask, &xgcv);
772         }
773       for (i = 0; i < xc->lang_num; i++)
774         {
775           xl = xc->xl[i];
776           XSetWindowBackground (dpy, xl->wp[0], bg);
777           XSetWindowBackground (dpy, xl->w[0], bg);
778           XSetWindowBackground (dpy, xl->wn[0], bg);
779           XSetWindowBackground (dpy, xl->wn[1], bg);
780           XSetWindowBackground (dpy, xl->wn[2], bg);
781           if (IsPreeditPosition (xc))
782             {
783               XSetWindowBackground (dpy, xl->wp[1], bg);
784               XSetWindowBackground (dpy, xl->w[1], bg);
785               XSetWindowBackground (dpy, xl->wp[2], bg);
786               XSetWindowBackground (dpy, xl->w[2], bg);
787             }
788         }
789     }
790 }
791 
792 static void
change_pre_bgpixmap(xc)793 change_pre_bgpixmap (xc)
794      register XIMClientRec *xc;
795 {
796   register int i;
797   register XIMLangRec *xl;
798   register Pixmap bg_p = xc->pe.bg_pixmap;
799 
800   if (IsPreeditPosition (xc) || IsPreeditArea (xc))
801     {
802       for (i = 0; i < xc->lang_num; i++)
803         {
804           xl = xc->xl[i];
805           XSetWindowBackgroundPixmap (dpy, xl->wp[0], bg_p);
806           XSetWindowBackgroundPixmap (dpy, xl->w[0], bg_p);
807           XSetWindowBackgroundPixmap (dpy, xl->wn[0], bg_p);
808           XSetWindowBackgroundPixmap (dpy, xl->wn[1], bg_p);
809           XSetWindowBackgroundPixmap (dpy, xl->wn[2], bg_p);
810           if (IsPreeditPosition (xc))
811             {
812               XSetWindowBackgroundPixmap (dpy, xl->wp[1], bg_p);
813               XSetWindowBackgroundPixmap (dpy, xl->w[1], bg_p);
814               XSetWindowBackgroundPixmap (dpy, xl->wp[2], bg_p);
815               XSetWindowBackgroundPixmap (dpy, xl->w[2], bg_p);
816             }
817         }
818     }
819 }
820 
821 static void
change_pre_linespace(xc)822 change_pre_linespace (xc)
823      register XIMClientRec *xc;
824 {
825   if (IsPreeditPosition (xc))
826     {
827     }
828 }
829 
830 static void
change_pre_cursor(xc)831 change_pre_cursor (xc)
832      register XIMClientRec *xc;
833 {
834   /*
835    * Not support
836    */
837 }
838 
839 static void
change_pre_attr(xc,mask)840 change_pre_attr (xc, mask)
841      register XIMClientRec *xc;
842      unsigned long mask;
843 {
844   if (mask & ChPreFontSet)
845     change_pre_fontset (xc);
846   if (mask & ChPreeditLocation)
847     change_pre_location (xc);
848   if (mask & ChPreeditSize)
849     change_pre_size (xc);
850   if (mask & ChPreColormap)
851     change_pre_colormap (xc);
852   if (mask & ChPreStdColormap)
853     change_pre_stdcolormap (xc);
854   if (mask & ChPreForeground)
855     change_pre_fg (xc);
856   if (mask & ChPreBackground)
857     change_pre_bg (xc);
858   if (mask & ChPreBackgroundPixmap)
859     change_pre_bgpixmap (xc);
860   if (mask & ChPreLineSpace)
861     change_pre_linespace (xc);
862   if (mask & ChPreCursor)
863     change_pre_cursor (xc);
864 }
865 
866 static void
change_st_fontset(xc)867 change_st_fontset (xc)
868      register XIMClientRec *xc;
869 {
870   register int i;
871   register XIMLangRec *xl;
872   register XFontSet save_fs;
873   register XCharStruct *save_b_char;
874 
875   if (IsStatusArea (xc))
876     {
877       for (i = 0; i < xc->lang_num; i++)
878         {
879           xl = xc->xl[i];
880           setlocale (LC_ALL, xl->lang_db->lc_name);
881           save_fs = xl->st_fs;
882           save_b_char = xl->st_b_char;
883           if ((xl->st_fs = create_font_set (xc->st.fontset)) && (xl->st_b_char = get_base_char (xl->st_fs)))
884             {
885               if (save_fs)
886                 XFreeFontSet (dpy, save_fs);
887               if (xl->st_b_char)
888                 Free (xl->st_b_char);
889               xl->st_b_char = get_base_char (xl->st_fs);
890               XResizeWindow (dpy, xl->ws, StatusWidth (xc), StatusHeight (xc));
891               XClearWindow (dpy, xl->ws);
892             }
893           else
894             {
895               if (xl->st_fs)
896                 XFreeFontSet (dpy, xl->st_fs);
897               xl->st_fs = save_fs;
898               xl->st_b_char = save_b_char;
899             }
900           if (xc->st.area_needed.width < StatusFontWidth (xl) * MHL0);
901           xc->st.area_needed.width = StatusFontWidth (xl) * MHL0;
902           if (xc->st.area_needed.height < StatusFontHeight (xl))
903             xc->st.area_needed.height = StatusFontHeight (xl);
904         }
905     }
906 }
907 
908 static void
change_st_location(xc)909 change_st_location (xc)
910      register XIMClientRec *xc;
911 {
912   register int i;
913 
914   if (IsStatusArea (xc))
915     {
916       for (i = 0; i < xc->lang_num; i++)
917         {
918           XMoveWindow (dpy, xc->xl[i]->ws, StatusX (xc), StatusY (xc));
919         }
920     }
921 }
922 
923 static void
change_st_size(xc)924 change_st_size (xc)
925      register XIMClientRec *xc;
926 {
927   register int i;
928 
929   if (IsStatusArea (xc))
930     {
931       for (i = 0; i < xc->lang_num; i++)
932         {
933           XResizeWindow (dpy, xc->xl[i]->ws, StatusWidth (xc), StatusHeight (xc));
934         }
935     }
936 }
937 
938 static void
change_st_colormap(xc)939 change_st_colormap (xc)
940      register XIMClientRec *xc;
941 {
942   register int i;
943 
944   if (IsStatusArea (xc))
945     {
946       for (i = 0; i < xc->lang_num; i++)
947         {
948           XSetWindowColormap (dpy, xc->xl[i]->ws, xc->st.colormap);
949         }
950     }
951 }
952 
953 static void
change_st_stdcolormap(xc)954 change_st_stdcolormap (xc)
955      register XIMClientRec *xc;
956 {
957   XStandardColormap cmap;
958 
959   XGetStandardColormap (dpy, xc->root_pointer->root_window, &cmap, xc->st.std_colormap);
960   xc->st.colormap = cmap.colormap;
961   change_st_colormap (xc);
962 }
963 
964 static void
change_st_fg(xc)965 change_st_fg (xc)
966      register XIMClientRec *xc;
967 {
968   if (IsStatusArea (xc))
969     {
970       xgcv.foreground = xc->st.fg;
971       if (xc->st.gc)
972         {
973           XChangeGC (dpy, xc->st.gc, GCForeground, &xgcv);
974         }
975       xgcv.background = xc->st.fg;
976       if (xc->st.reversegc)
977         {
978           XChangeGC (dpy, xc->st.reversegc, GCBackground, &xgcv);
979         }
980     }
981 }
982 
983 static void
change_st_bg(xc)984 change_st_bg (xc)
985      register XIMClientRec *xc;
986 {
987   register int i;
988   if (IsStatusArea (xc))
989     {
990       xgcv.background = xc->st.bg;
991       if (xc->st.gc)
992         {
993           XChangeGC (dpy, xc->st.gc, GCBackground, &xgcv);
994         }
995       xgcv.foreground = xc->st.bg;
996       if (xc->st.reversegc)
997         {
998           XChangeGC (dpy, xc->st.reversegc, GCForeground, &xgcv);
999         }
1000       for (i = 0; i < xc->lang_num; i++)
1001         {
1002           XSetWindowBackground (dpy, xc->xl[i]->ws, xc->st.bg);
1003           XClearWindow (dpy, xc->xl[i]->ws);
1004         }
1005       XFlush (dpy);
1006     }
1007 }
1008 
1009 static void
change_st_bgpixmap(xc)1010 change_st_bgpixmap (xc)
1011      register XIMClientRec *xc;
1012 {
1013   register int i;
1014 
1015   if (IsStatusArea (xc))
1016     {
1017       for (i = 0; i < xc->lang_num; i++)
1018         {
1019           XSetWindowBackgroundPixmap (dpy, xc->xl[i]->ws, xc->st.bg_pixmap);
1020         }
1021     }
1022 }
1023 
1024 static void
change_st_linespace(xc)1025 change_st_linespace (xc)
1026      register XIMClientRec *xc;
1027 {
1028   /*
1029    * Not support
1030    */
1031 }
1032 
1033 static void
change_st_cursor(xc)1034 change_st_cursor (xc)
1035      register XIMClientRec *xc;
1036 {
1037   /*
1038    * Not support
1039    */
1040 }
1041 
1042 static void
change_st_attr(xc,mask)1043 change_st_attr (xc, mask)
1044      register XIMClientRec *xc;
1045      unsigned long mask;
1046 {
1047   if (mask & ChStFontSet)
1048     change_st_fontset (xc);
1049   if (mask & ChStatusLocation)
1050     change_st_location (xc);
1051   if (mask & ChStatusSize)
1052     change_st_size (xc);
1053   if (mask & ChStColormap)
1054     change_st_colormap (xc);
1055   if (mask & ChStStdColormap)
1056     change_st_stdcolormap (xc);
1057   if (mask & ChStForeground)
1058     change_st_fg (xc);
1059   if (mask & ChStBackground)
1060     change_st_bg (xc);
1061   if (mask & ChStBackgroundPixmap)
1062     change_st_bgpixmap (xc);
1063   if (mask & ChStLineSpace)
1064     change_st_linespace (xc);
1065   if (mask & ChStCursor)
1066     change_st_cursor (xc);
1067 }
1068 
1069 /*
1070  * Update the client's attributes.
1071  */
1072 int
change_client(xc,ic,pre,st,cur_l,cur_is_world,pre_font,st_font,detail)1073 change_client (xc, ic, pre, st, cur_l, cur_is_world, pre_font, st_font, detail)
1074      register XIMClientRec *xc;
1075      register ximICValuesReq *ic;
1076      register ximICAttributesReq *pre, *st;
1077      XIMNestLangRec *cur_l;
1078      int cur_is_world;
1079      char *pre_font, *st_font;
1080      short *detail;             /* If error is occured, set. */
1081 {
1082   unsigned long dirty = 0L;
1083   WnnClientRec *save_c_c;
1084   XIMClientRec *save_cur_p, *save_cur_x;
1085   XIMLangDataBase *cur_lang_sv;
1086   int ret, error = 0;
1087   Window old_client_window, old_focus_window;
1088 
1089   xc->mask |= ic->mask;
1090   old_client_window = xc->w;
1091   old_focus_window = xc->focus_window;
1092   dirty = update_ic (xc, ic, pre, st, pre_font, st_font, &error);
1093   if (error)
1094     {
1095       *detail = (short) error;
1096       xc->focus_window = old_focus_window;
1097       return (-1);
1098     }
1099 
1100   if (dirty & ChClientWindow)
1101     change_client_window (xc, old_client_window);
1102   if (dirty & ChFocusWindow)
1103     {
1104       if ((ret = change_focus_window (xc, old_focus_window)) > 0)
1105         {
1106           *detail = (short) ret;
1107           xc->focus_window = old_focus_window;
1108           return (-1);
1109         }
1110     }
1111   if (IsPreeditArea (xc) || IsPreeditPosition (xc))
1112     {
1113       if (dirty & ChPreeditAttributes)
1114         change_pre_attr (xc, dirty);
1115       if (dirty & ChStatusAttributes)
1116         change_st_attr (xc, dirty);
1117       if (IsPreeditPosition (xc))
1118         {
1119           dirty |= update_spotlocation (xc, ic, pre);
1120         }
1121 
1122       if ((dirty & ChClientWindow) || (dirty & ChPreeditAttributes) || (IsPreeditPosition (xc) && (dirty & ChFocusWindow)))
1123         {
1124           reset_preedit (xc);
1125         }
1126       if ((dirty & ChClientWindow) || (dirty & ChStatusAttributes))
1127         {
1128           reset_status (xc);
1129         }
1130     }
1131   if (xc->mask & (1 << ICCurrentLanguage) && cur_l && (IsPreeditPosition (xc) || IsPreeditArea (xc)))
1132     {
1133       save_c_c = c_c;
1134       save_cur_p = cur_p;
1135       save_cur_x = cur_x;
1136       cur_lang_sv = cur_lang;
1137       ret = change_current_language (xc, cur_l, cur_is_world);
1138       c_c = save_c_c;
1139       cur_p = save_cur_p;
1140       cur_x = save_cur_x;
1141       cur_lang = cur_lang_sv;
1142       if (c_c)
1143         {
1144           cur_rk = c_c->rk;
1145           cur_rk_table = cur_rk->rk_table;
1146         }
1147       if (ret != 0)
1148         {
1149           *detail = BadSomething;
1150           return (-1);
1151         }
1152     }
1153   return (0);
1154 }
1155 
1156 #ifdef  SPOT
1157 int
change_spotlocation(xc,x,y)1158 change_spotlocation (xc, x, y)
1159      register XIMClientRec *xc;
1160      register short x, y;
1161 {
1162   if (!IsPreeditPosition (xc))
1163     return (-1);
1164   if ((xc->point.x == x) && (xc->point.y == (y - FontAscent (xc->cur_xl))))
1165     return (0);
1166   xc->point.x = x;
1167   xc->point.y = (y - FontAscent (xc->cur_xl));
1168   reset_preedit (xc);
1169   return (0);
1170 }
1171 #endif /* SPOT */
1172