1 /*
2  * $Id: display.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 "ext.h"
45 
46 extern wchar_t dol_wchar_t;
47 
48 wchar cursor_wchar = 0x20202020;
49 
50 GC currentGC;
51 
52 static void
JWwindow_move(xl)53 JWwindow_move (xl)
54      register XIMLangRec *xl;
55 {
56 
57   if ((check_mb (xl->buf, xl->vst)) == 2)
58     {
59       xl->vst++;
60     }
61   XMoveWindow (dpy, xl->w[0], -(xl->vst * FontWidth (xl)), 0);
62   if (IsPreeditPosition (cur_x))
63     {
64       XMoveWindow (dpy, xl->w[1], -((cur_x->c0 + xl->vst - xl->linefeed[1]) * FontWidth (xl)), 0);
65       XMoveWindow (dpy, xl->w[2], -((c01 (cur_x) + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0);
66     }
67   XFlush (dpy);
68 }
69 
70 static void
JWM_note(which)71 JWM_note (which)
72      int which;
73 {
74   register XIMLangRec *xl;
75   register XIMClientRec *xc = cur_p;
76   int x, y;
77 
78   xl = cur_p->cur_xl;
79 
80   if (xl->note[which])
81     return;
82 
83   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
84     {
85       XClearWindow (dpy, xl->wn[which]);
86       XMapWindow (dpy, xl->wn[which]);
87       XRaiseWindow (dpy, xl->wn[which]);
88       XwcDrawString (dpy, xl->wn[which], xl->pe_fs, xc->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1);
89     }
90   else if (IsPreeditPosition (cur_x))
91     {
92       if (which == 1)
93         {
94           if (xc->c2)
95             {
96               x = PreeditX (xc) + (xc->c2 * FontWidth (xl));
97               y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2;
98               if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
99                 {
100                   if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc)))
101                     {
102                       y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space;
103                     }
104                   else
105                     {
106                       y = PreeditY (xc);
107                     }
108                 }
109             }
110           else if (xc->c1)
111             {
112               x = PreeditX (xc) + (xc->c1 * FontWidth (xl));
113               y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space;
114               if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
115                 {
116                   y = PreeditY (xc);
117                 }
118             }
119           else
120             {
121               x = PreeditSpotX (xc) + xc->c0 * FontWidth (xl);
122               y = PreeditSpotY (xc);
123             }
124         }
125       else
126         {
127           x = PreeditSpotX (xc) - FontWidth (xl);
128           y = PreeditSpotY (xc);
129         }
130       XMoveWindow (dpy, xl->wn[which], x, y);
131       XClearWindow (dpy, xl->wn[which]);
132       XMapWindow (dpy, xl->wn[which]);
133       XRaiseWindow (dpy, xl->wn[which]);
134       XwcDrawString (dpy, xl->wn[which], xl->pe_fs, xc->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1);
135     }
136   XFlush (dpy);
137 }
138 
139 static void
JWM_note_null()140 JWM_note_null ()
141 {
142   register XIMLangRec *xl;
143   register XIMClientRec *xc = cur_p;
144   int x, y;
145 
146   xl = cur_p->cur_xl;
147 
148   if (xl->visible_line > 2)
149     {
150       x = PreeditX (xc) + ((xc->c2 - 1) * FontWidth (xl));
151       y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2;
152       if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
153         if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc)))
154           {
155             y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space;
156           }
157         else
158           {
159             y = PreeditY (xc);
160           }
161     }
162   else if (xl->visible_line > 1)
163     {
164       x = PreeditX (xc) + ((xc->c1 - 1) * FontWidth (xl));
165       y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space;
166       if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
167         y = PreeditY (xc);
168     }
169   else
170     {
171       x = PreeditSpotX (xc) + (xc->c0 - 1) * FontWidth (xl);
172       y = PreeditSpotY (xc);
173     }
174   XMoveWindow (dpy, xl->wn[2], x, y);
175   XMapWindow (dpy, xl->wn[2]);
176   XRaiseWindow (dpy, xl->wn[2]);
177   XFlush (dpy);
178 }
179 
180 static void
invisual_note(which)181 invisual_note (which)
182      int which;
183 {
184   register XIMLangRec *xl;
185 
186   xl = cur_p->cur_xl;
187 
188   if (xl->note[which])
189     {
190       XUnmapWindow (dpy, xl->wn[which]);
191       XFlush (dpy);
192     }
193 }
194 
195 static void
visible_line2()196 visible_line2 ()
197 {
198   register XIMLangRec *xl;
199   register XIMClientRec *xc = cur_p;
200   int x, y, width;
201 
202   xl = cur_p->cur_xl;
203 
204   if ((xc->c1 == 0) || !IsPreeditPosition (cur_x))
205     return;
206 
207   x = PreeditX (xc);
208   y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space;
209   if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
210     y = PreeditY (xc);
211   if (xl->max_cur > (xc->c0 + xc->c1))
212     {
213       width = xc->c1 * FontWidth (xl);
214     }
215   else
216     {
217       width = (xl->max_cur - xc->c0 + xl->linefeed[1]) * FontWidth (xl);
218     }
219   if (width == 0)
220     width = 1;
221   XMoveResizeWindow (dpy, xl->wp[1], x, y, width, FontHeight (xl));
222   XMoveWindow (dpy, xl->w[1], -((xc->c0 + xl->vst - xl->linefeed[1]) * FontWidth (xl)), 0);
223   XMapWindow (dpy, xl->wp[1]);
224   XRaiseWindow (dpy, xl->wp[1]);
225   XFlush (dpy);
226 }
227 
228 static void
visible_line3()229 visible_line3 ()
230 {
231   register XIMLangRec *xl;
232   register XIMClientRec *xc = cur_p;
233   int x, y, width;
234 
235   xl = cur_p->cur_xl;
236 
237   if ((xc->c2 == 0) || !IsPreeditPosition (cur_x))
238     return;
239   x = PreeditX (xc);
240   y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2;
241   if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc)))
242     {
243       if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc)))
244         {
245           y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space;
246         }
247       else
248         {
249           y = PreeditY (xc);
250         }
251     }
252   if (xl->max_cur > c012 (xc))
253     {
254       width = xc->c2 * FontWidth (xl);
255     }
256   else
257     {
258       width = (xl->max_cur - c01 (xc) + xl->linefeed[2]) * FontWidth (xl);
259     }
260   if (width == 0)
261     width = 1;
262   XMoveResizeWindow (dpy, xl->wp[2], x, y, width, FontHeight (xl));
263   XMoveWindow (dpy, xl->w[2], -((c01 (xc) + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0);
264   XMapWindow (dpy, xl->wp[2]);
265   XRaiseWindow (dpy, xl->wp[2]);
266   XFlush (dpy);
267 }
268 
269 static void
check_move1(xc,xl,mb)270 check_move1 (xc, xl, mb)
271      register XIMClientRec *xc;
272      register XIMLangRec *xl;
273      int mb;
274 {
275   register int currentcol_tmp;
276   int max_pos_tmp;
277 
278   currentcol_tmp = xl->currentcol + xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)];
279 
280   if ((currentcol_tmp - xl->vst + mb) >= xc->max_columns)
281     {
282       do
283         {
284           xl->vst = currentcol_tmp - xc->max_columns + mb + 1;
285           if ((check_mb (xl->buf, xl->vst)) == 2)
286             {
287               xl->vst++;
288             }
289           currentcol_tmp = xl->currentcol;
290           if (xl->visible_line > 1 && xc->c1)
291             {
292               if ((check_mb (xl->buf, (xc->c0 + xl->vst - 1))) == 1)
293                 {
294                   xl->linefeed[1] = 1;
295                 }
296               else
297                 {
298                   xl->linefeed[1] = 0;
299                 }
300               currentcol_tmp = xl->currentcol + xl->linefeed[1];
301             }
302           if (xl->visible_line > 2 && xc->c2)
303             {
304               if ((check_mb (xl->buf, (c01 (xc) + xl->vst - xl->linefeed[1] - 1))) == 1)
305                 {
306                   xl->linefeed[2] = xl->linefeed[1] + 1;
307                 }
308               else
309                 {
310                   xl->linefeed[2] = xl->linefeed[1];
311                 }
312               currentcol_tmp = xl->currentcol + xl->linefeed[2];
313             }
314         }
315       while ((currentcol_tmp - xl->vst + mb) >= xc->max_columns);
316       JWwindow_move (xl);
317     }
318   else if (xl->currentcol < xl->vst)
319     {
320       xl->vst = xl->currentcol;
321       if (xc->c1 && ((xl->visible_line > 1) || (xl->vst + xc->c0 < xl->max_pos)))
322         {
323           if ((check_mb (xl->buf, (xc->c0 + xl->vst - 1))) == 1)
324             {
325               xl->linefeed[1] = 1;
326             }
327           else
328             {
329               xl->linefeed[1] = 0;
330             }
331           if (xl->visible_line < 2 && (xl->vst + xc->c0 < xl->max_pos))
332             {
333               visible_line2 ();
334               xl->visible_line = 2;
335             }
336         }
337       if (xc->c2 && ((xl->visible_line > 2) || ((c01 (xc) + xl->vst - xl->linefeed[1]) < xl->max_pos)))
338         {
339           if ((check_mb (xl->buf, (c01 (xc) + xl->vst - xl->linefeed[1] - 1))) == 1)
340             {
341               xl->linefeed[2] = xl->linefeed[1] + 1;
342             }
343           else
344             {
345               xl->linefeed[2] = xl->linefeed[1];
346             }
347           if (xl->visible_line < 3 && (c01 (xc) + xl->vst - xl->linefeed[1] < xl->max_pos))
348             {
349               visible_line3 ();
350               xl->visible_line = 3;
351             }
352         }
353       JWwindow_move (xl);
354     }
355 
356   if (xl->vst)
357     {
358       if (!xl->note[0])
359         {
360           JWM_note (0);
361           xl->note[0] = 1;
362         }
363     }
364   else
365     {
366       if (xl->note[0])
367         {
368           invisual_note (0);
369           xl->note[0] = 0;
370         }
371     }
372   max_pos_tmp = xl->vst + xc->max_columns - xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)];
373 
374   if (xl->max_pos > max_pos_tmp)
375     {
376       if (!xl->note[1])
377         {
378           JWM_note (1);
379           xl->note[1] = 1;
380         }
381       if ((check_mb (xl->buf, (max_pos_tmp - 1))) == 1)
382         {
383           JWM_note_null ();
384         }
385       else
386         {
387           XUnmapWindow (dpy, xl->wn[2]);
388         }
389     }
390   else
391     {
392       if (xl->note[1])
393         {
394           invisual_note (1);
395           xl->note[1] = 0;
396         }
397       XUnmapWindow (dpy, xl->wn[2]);
398     }
399 }
400 
401 static void
check_move(xc,xl,mb)402 check_move (xc, xl, mb)
403      register XIMClientRec *xc;
404      register XIMLangRec *xl;
405      int mb;
406 {
407   if (IsPreeditPosition (cur_x))
408     {
409       check_move1 (xc, xl, mb);
410     }
411   else
412     {
413       if ((xl->currentcol - xl->vst + mb) >= xc->max_columns)
414         {
415           xl->vst = xl->currentcol - xc->max_columns + mb + 1;
416           JWwindow_move (xl);
417         }
418       else if (xl->currentcol < xl->vst)
419         {
420           xl->vst = xl->currentcol;
421           JWwindow_move (xl);
422         }
423       if (xl->vst)
424         {
425           JWM_note (0);
426           xl->note[0] = 1;
427         }
428       else
429         {
430           invisual_note (0);
431           xl->note[0] = 0;
432         }
433       if (xl->max_pos > (xl->vst + xc->max_columns))
434         {
435           JWM_note (1);
436           xl->note[1] = 1;
437           if ((check_mb (xl->buf, (xl->vst + xc->max_columns - 1))) == 1)
438             {
439               XMapWindow (dpy, xl->wn[2]);
440             }
441           else
442             {
443               XUnmapWindow (dpy, xl->wn[2]);
444             }
445         }
446       else
447         {
448           invisual_note (1);
449           xl->note[1] = 0;
450           XUnmapWindow (dpy, xl->wn[2]);
451         }
452     }
453 }
454 
455 static void
Resize_jw()456 Resize_jw ()
457 {
458   register XIMLangRec *xl;
459   Window window;
460   int width = 0;
461   char ok = '\0';
462 
463   xl = cur_p->cur_xl;
464   if (!IsPreeditPosition (cur_x) || !xl->m_cur_flag)
465     return;
466 
467   if (cur_p->c2)
468     {
469       if (xl->max_cur <= (c012 (cur_p) - xl->linefeed[2]))
470         {
471           width = (xl->max_cur - c01 (cur_p) + xl->linefeed[2]);
472           xl->max_l3 = 0;
473           ok = 1;
474         }
475       else if (!xl->max_l3)
476         {
477           width = cur_p->c2;
478           xl->max_l3 = 1;
479           ok = 1;
480         }
481       if (ok)
482         {
483           window = xl->wp[2];
484           XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl));
485         }
486     }
487   if (cur_p->c1)
488     {
489       ok = '\0';
490       if (xl->max_cur <= (c01 (cur_p) - xl->linefeed[1]))
491         {
492           width = (xl->max_cur - cur_p->c0 + xl->linefeed[1]);
493           xl->max_l2 = 0;
494           ok = 1;
495         }
496       else if (!xl->max_l2)
497         {
498           width = cur_p->c1;
499           xl->max_l2 = 1;
500           ok = 1;
501         }
502       if (ok)
503         {
504           window = xl->wp[1];
505           XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl));
506         }
507     }
508   if (cur_p->c0)
509     {
510       ok = '\0';
511       if (xl->max_cur <= cur_p->c0)
512         {
513           width = xl->max_cur;
514           xl->max_l1 = 0;
515           ok = 1;
516         }
517       else if (!xl->max_l1)
518         {
519           width = cur_p->c0;
520           xl->max_l1 = 1;
521           ok = 1;
522         }
523       if (ok)
524         {
525           window = xl->wp[0];
526           XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl));
527         }
528     }
529   XFlush (dpy);
530   xl->m_cur_flag = 0;
531 }
532 
533 void
JWmark_cursor(on)534 JWmark_cursor (on)
535      int on;
536 {
537   register XIMLangRec *xl;
538   register XIMClientRec *xc = cur_p;
539   wchar *JW_buf;
540   unsigned char *JW_att;
541   Window currentW = 0;
542   int mb_len;
543   unsigned char flg;
544   XCharStruct cs;
545 
546   xl = cur_p->cur_xl;
547   if (xl->cursor_flag != 1 || xl->mark_flag == on)
548     return;
549   xl->mark_flag = on;
550 
551   JW_buf = xl->buf + xl->currentcol;
552   JW_att = xl->att + xl->currentcol;
553   cs.width = FontWidth (xl);
554   cs.ascent = FontAscent (xl);
555   cs.descent = FontDescent (xl);
556 
557   if ((*JW_att & REV_FLAG) != 0)
558     return;
559 
560   if (*JW_buf)
561     {
562       if ((mb_len = get_columns_wchar (JW_buf)) > 0)
563         {
564           JW_buf += (mb_len - 1);
565           JW_att += (mb_len - 1);
566         }
567       flg = *JW_att;
568     }
569   else
570     {
571       JW_buf = &cursor_wchar;
572       JW_att = '\0';
573       mb_len = 1;
574       flg = 0;
575     }
576   if (on)
577     {
578       if (mb_len > 1)
579         {
580           check_move (xc, xl, 1);
581         }
582       else
583         {
584           check_move (xc, xl, 0);
585         }
586       currentGC = xc->pe.reversegc;
587       flg |= REV_FLAG;
588     }
589   else
590     {
591       currentGC = xc->pe.gc;
592     }
593 
594   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
595     {
596       currentW = xl->w[0];
597     }
598   else if (IsPreeditPosition (cur_x))
599     {
600       if ((xl->currentcol + mb_len - xl->vst) <= xc->c0)
601         {
602           currentW = xl->w[0];
603         }
604       else if ((xl->currentcol + xl->linefeed[1] + mb_len - xl->vst) <= c01 (xc))
605         {
606           currentW = xl->w[1];
607         }
608       else
609         {
610           currentW = xl->w[2];
611         }
612       if ((*(xl->buf + xl->currentcol) == 0) && on)
613         {
614           if (xc->c1 && ((xl->currentcol - xl->vst) == xc->c0))
615             {
616               xl->linefeed[1] = 0;
617               visible_line2 ();
618               if (xl->visible_line < 2)
619                 {
620                   xl->visible_line = 2;
621                 }
622             }
623           if (xc->c2 && ((xl->currentcol + xl->linefeed[1] - xl->vst) == c01 (xc)))
624             {
625               xl->linefeed[2] = xl->linefeed[1];
626               visible_line3 ();
627               if (xl->visible_line < 3)
628                 {
629                   xl->visible_line = 3;
630                 }
631             }
632           if ((xl->currentcol - xl->vst) >= xl->max_cur)
633             {
634               xl->max_cur += 1;
635               xl->m_cur_flag = 1;
636               Resize_jw ();
637             }
638         }
639       if (on)
640         {
641           if ((xl->max_pos - xl->vst) > xl->max_cur && !xl->m_cur_flag)
642             {
643               xl->max_cur = xl->max_pos - xl->vst;
644               xl->m_cur_flag = 1;
645               Resize_jw ();
646             }
647         }
648     }
649   JWOutput (currentW, xl->pe_fs, currentGC, xl->currentcol, mb_len, flg, 0, 0, &cs, JW_buf, 1);
650   XFlush (dpy);
651 }
652 
653 void
redraw_window3(x,width)654 redraw_window3 (x, width)
655      int x, width;
656 {
657   register XIMLangRec *xl;
658   wchar *JW_buf, *wc;
659   unsigned char *JW_att;
660   unsigned char old_JW_att;
661   int currentcol_tmp = 0;
662   int start, end, startcol;
663   int wc_len, mb_len;
664   int col;
665   XCharStruct cs;
666   Bool error = False;
667 
668   if (IsPreeditNothing (cur_x))
669     {
670       xl = cur_x->root_pointer->ximclient->cur_xl;
671     }
672   else if (IsPreeditArea (cur_x))
673     {
674       xl = cur_p->cur_xl;
675     }
676   else
677     {
678       return;
679     }
680 
681   currentcol_tmp = xl->currentcol;
682 
683   start = x / FontWidth (xl);
684   end = start + width / FontWidth (xl) + ((width % FontWidth (xl)) ? 1 : 0);
685   if (end > xl->max_pos)
686     end = xl->max_pos;
687   if (check_mb (xl->buf, (start)) == 2)
688     start--;
689   if (check_mb (xl->buf, (end - 1)) == 1)
690     end++;
691 
692   JW_buf = xl->buf + start;
693   JW_att = xl->att + start;
694   old_JW_att = *JW_att;
695   while (wc_buf_max < (end - start))
696     {
697       if (realloc_wc_buf () < 0)
698         return;
699     }
700   wc = wc_buf;
701   skip_pending_wchar (wc, JW_buf);
702   wc_len = 0;
703   col = 0;
704   startcol = start;
705   cs.width = FontWidth (xl);
706   cs.ascent = FontAscent (xl);
707   cs.descent = FontDescent (xl);
708 
709   for (xl->currentcol = start; xl->currentcol < end;)
710     {
711       JW_buf = xl->buf + xl->currentcol;
712       JW_att = xl->att + xl->currentcol;
713       if ((mb_len = get_columns_wchar (JW_buf)) > 0)
714         {
715           JW_buf += (mb_len - 1);
716           JW_att += (mb_len - 1);
717         }
718       else
719         {
720           error = True;
721         }
722       if (((error == True) || (*JW_att != old_JW_att)) && (wc_len > 0))
723         {
724           if (old_JW_att & REV_FLAG)
725             {
726               currentGC = cur_p->pe.reversegc;
727             }
728           else
729             {
730               currentGC = cur_p->pe.gc;
731             }
732           JWOutput (xl->w[0], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
733           old_JW_att = *JW_att;
734           wc += wc_len;
735           wc_len = 0;
736           col = 0;
737           startcol = xl->currentcol;
738         }
739       if (error == True)
740         {
741           wc_len = 0;
742           col += 1;
743           xl->currentcol += 1;
744           error = False;
745         }
746       else
747         {
748           wc_len++;
749           col += mb_len;
750           xl->currentcol += mb_len;
751         }
752     }
753   if (wc_len > 0)
754     {
755       if (old_JW_att & REV_FLAG)
756         {
757           currentGC = cur_p->pe.reversegc;
758         }
759       else
760         {
761           currentGC = cur_p->pe.gc;
762         }
763       JWOutput (xl->w[0], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
764     }
765   xl->currentcol = currentcol_tmp;
766   JW_buf = xl->buf + xl->currentcol;
767   JW_att = xl->att + xl->currentcol;
768   if (*JW_att & REV_FLAG)
769     {
770       for (; *JW_buf && (*JW_att & REV_FLAG); JW_buf++, JW_att++, xl->currentcol++);
771       if (get_columns_wchar (JW_buf))
772         {
773           check_move (cur_p, xl, 1);
774         }
775       else
776         {
777           check_move (cur_p, xl, 0);
778         }
779     }
780   xl->currentcol = currentcol_tmp;
781   if (xl->cursor_flag == 1 && xl->mark_flag == 1)
782     {
783       xl->mark_flag = 0;
784       JWmark_cursor (1);
785     }
786 }
787 
788 void
redraw_lines(x,width,line)789 redraw_lines (x, width, line)
790      int x, width, line;
791 {
792   register XIMLangRec *xl;
793   register XIMClientRec *xc = cur_p;
794   register wchar *JW_buf, *wc;
795   unsigned char *JW_att;
796   unsigned char old_JW_att;
797   int currentcol_tmp = 0;
798   int start, end, startcol;
799   int tmp_col = 0;
800   int wc_len, mb_len;
801   int col;
802   XCharStruct cs;
803   Bool error = False;
804 
805   xl = cur_p->cur_xl;
806   currentcol_tmp = xl->currentcol;
807   if (line == 1)
808     {
809       tmp_col = xc->c0;
810     }
811   else if (line == 2)
812     {
813       tmp_col = c01 (xc) - xl->linefeed[1];
814     }
815   start = x / FontWidth (xl);
816   end = start + width / FontWidth (xl) + ((width % FontWidth (xl)) ? 1 : 0);
817   if (end > xl->max_pos)
818     end = xl->max_pos;
819   if (check_mb (xl->buf, (start)) == 2 && start > 0)
820     start--;
821   if (check_mb (xl->buf, (end - 1)) == 1)
822     end++;
823 
824   JW_buf = xl->buf + start;
825   JW_att = xl->att + start;
826   old_JW_att = *JW_att;
827   while (wc_buf_max < (end - start))
828     {
829       if (realloc_wc_buf () < 0)
830         return;
831     }
832   wc = wc_buf;
833   wc_len = 0;
834   skip_pending_wchar (wc, JW_buf);
835   col = 0;
836   startcol = start;
837   cs.width = FontWidth (xl);
838   cs.ascent = FontAscent (xl);
839   cs.descent = FontDescent (xl);
840 
841   for (xl->currentcol = start; xl->currentcol < end;)
842     {
843       JW_buf = xl->buf + xl->currentcol;
844       JW_att = xl->att + xl->currentcol;
845       if ((mb_len = get_columns_wchar (JW_buf)) > 0)
846         {
847           JW_buf += (mb_len - 1);
848           JW_att += (mb_len - 1);
849         }
850       else
851         {
852           error = True;
853         }
854       if (((error == True) || (*JW_att != old_JW_att)) && (wc_len > 0))
855         {
856           if (old_JW_att & REV_FLAG)
857             {
858               currentGC = cur_p->pe.reversegc;
859             }
860           else
861             {
862               currentGC = cur_p->pe.gc;
863             }
864           JWOutput (xl->w[line - 1], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
865           old_JW_att = *JW_att;
866           wc += wc_len;
867           wc_len = 0;
868           col = 0;
869           startcol = xl->currentcol;
870         }
871       if (error == True)
872         {
873           wc_len = 0;
874           col += 1;
875           xl->currentcol += 1;
876         }
877       else
878         {
879           wc_len++;
880           col += mb_len;
881           xl->currentcol += mb_len;
882         }
883       if (*JW_att & REV_FLAG)
884         {
885           if (mb_len)
886             {
887               check_move (cur_p, xl, 1);
888             }
889           else
890             {
891               check_move (cur_p, xl, 0);
892             }
893         }
894       if (line != 3)
895         {
896           if (mb_len > 1)
897             {
898               if (xl->currentcol > (tmp_col + xl->vst - 2))
899                 {
900                   if ((line == 1 && xc->c1) || (line == 2 && xc->c2))
901                     {
902                       if (check_mb (xl->buf, (tmp_col + xl->vst - 1)) == 1)
903                         {
904                           xl->linefeed[line] = xl->linefeed[line - 1] + 1;
905                         }
906                       else
907                         {
908                           xl->linefeed[line] = xl->linefeed[line - 1];
909                         }
910                     }
911                   break;
912                 }
913             }
914           else
915             {
916               if (xl->currentcol > (tmp_col + xl->vst - 1))
917                 {
918                   if ((line == 1 && xc->c1) || (line == 2 && xc->c2))
919                     {
920                       xl->linefeed[line] = xl->linefeed[line - 1];
921                     }
922                   break;
923                 }
924             }
925         }
926     }
927   if (wc_len > 0)
928     {
929       if (old_JW_att & REV_FLAG)
930         {
931           currentGC = cur_p->pe.reversegc;
932         }
933       else
934         {
935           currentGC = cur_p->pe.gc;
936         }
937       JWOutput (xl->w[line - 1], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
938     }
939   xl->currentcol = currentcol_tmp;
940   if (line == 1)
941     {
942       if (xl->linefeed[line])
943         {
944           XClearArea (dpy, xl->w[line - 1], (xc->c0 + xl->vst - 1) * FontWidth (xl), 0, 0, 0, False);
945         }
946       if (xl->cursor_flag && xl->mark_flag && (xl->currentcol < (xc->c0 + xl->vst)))
947         {
948           xl->mark_flag = 0;
949           JWmark_cursor (1);
950         }
951     }
952   else if (line == 2)
953     {
954       if (xl->linefeed[line])
955         {
956           XClearArea (dpy, xl->w[line - 1], ((c01 (xc) + xl->vst + xl->linefeed[1] - 1) * FontWidth (xl)), 0, 0, 0, False);
957         }
958       if (xl->cursor_flag && xl->mark_flag && (xl->currentcol < (tmp_col + xl->vst)) && (xl->currentcol >= (xc->c0 + xl->vst - xl->linefeed[1])))
959         {
960           xl->mark_flag = 0;
961           JWmark_cursor (1);
962         }
963     }
964   else
965     {
966       if (xl->cursor_flag && xl->mark_flag && (xl->currentcol >= (tmp_col + xl->vst)))
967         {
968           xl->mark_flag = 0;
969           JWmark_cursor (1);
970         }
971     }
972 }
973 
974 void
redraw_note(which)975 redraw_note (which)
976      int which;
977 {
978   XIMLangRec *xl = cur_p->cur_xl;
979 
980   XClearWindow (dpy, xl->wn[which]);
981   XwcDrawString (dpy, xl->wn[which], xl->pe_fs, cur_p->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1);
982   XFlush (dpy);
983 }
984 
985 void
redraw_window0()986 redraw_window0 ()
987 {
988   register XIMLangRec *xl;
989   wchar *JW_buf, *wc;
990   int wc_len;
991   int col = 0;
992   int mb_len;
993   unsigned char flg;
994   XCharStruct cs;
995 
996   xl = cur_p->cur_xl;
997   JW_buf = xl->buf0;
998   flg = xl->att0[0];
999   cs.width = StatusFontWidth (xl);
1000   cs.ascent = StatusFontAscent (xl);
1001   cs.descent = StatusFontDescent (xl);
1002   for (; *JW_buf; JW_buf++)
1003     {
1004       mb_len = get_columns_wchar (JW_buf);
1005       JW_buf += (mb_len - 1);
1006       col += mb_len;
1007     }
1008   while (wc_buf_max < col)
1009     {
1010       if (realloc_wc_buf () < 0)
1011         return;
1012     }
1013   wc = wc_buf;
1014   wc_len = skip_pending_wchar (wc, xl->buf0);
1015   if (wc_len <= 0)
1016     return;
1017   JWOutput (xl->ws, xl->st_fs, ((flg & REV_FLAG) ? cur_p->st.reversegc : cur_p->st.gc), 0, col, flg, 0, 0, &cs, wc, wc_len);
1018 }
1019 
1020 void
redraw_xj_all()1021 redraw_xj_all ()
1022 {
1023   register XIMLangRec *xl;
1024 
1025   xl = cur_p->cur_xl;
1026 
1027   redraw_window0 ();
1028   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
1029     {
1030       redraw_window3 (0, xl->max_pos * FontWidth (xl));
1031     }
1032   else if (IsPreeditPosition (cur_x))
1033     {
1034       redraw_lines (xl->vst * FontWidth (xl), xl->max_pos * FontWidth (xl), 1);
1035       redraw_lines ((xl->vst + cur_p->c0 - xl->linefeed[1]) * FontWidth (xl), xl->max_pos * FontWidth (xl), 2);
1036       redraw_lines ((xl->vst + c01 (cur_p) - xl->linefeed[2]) * FontWidth (xl), xl->max_pos * FontWidth (xl), 3);
1037     }
1038   if (xl->note[0] != 0)
1039     JWM_note (0);
1040   if (xl->note[1] != 0)
1041     JWM_note (1);
1042 }
1043 
1044 static void
visual_window3()1045 visual_window3 ()
1046 {
1047   register XIMLangRec *xl;
1048 
1049   xl = cur_p->cur_xl;
1050 
1051   XMapWindow (dpy, xl->wp[0]);
1052   XMapWindow (dpy, xl->w[0]);
1053 /* Need not this, because window3 is redraw by exposure callback.
1054     if (xl->max_pos) {
1055         redraw_window3(0, xl->max_pos * FontWidth(xl));
1056     }
1057 */
1058   if (IsPreeditNothing (cur_x))
1059     {
1060       xl->visible = 3;
1061     }
1062   else
1063     {
1064       xl->visible = 1;
1065       xl->visible_line = 1;
1066     }
1067   if (xl->vst)
1068     {
1069       JWM_note (0);
1070       xl->note[0] = 1;
1071     }
1072   if (xl->max_pos > (xl->vst + cur_p->max_columns))
1073     {
1074       JWM_note (1);
1075       xl->note[1] = 1;
1076       if ((check_mb (xl->buf, (xl->vst + cur_p->max_columns - 1))) == 1)
1077         {
1078           XMapWindow (dpy, xl->wn[2]);
1079         }
1080       else
1081         {
1082           XUnmapWindow (dpy, xl->wn[2]);
1083         }
1084     }
1085 }
1086 
1087 void
visual_window1()1088 visual_window1 ()
1089 {
1090   int width;
1091   register int w_width;
1092   register XIMLangRec *xl;
1093   int max_pos_tmp;
1094   register XIMClientRec *xc = cur_p;
1095 
1096   xl = cur_p->cur_xl;
1097   if (xl->visible)
1098     return;
1099 
1100   if (IsPreeditPosition (cur_x))
1101     {
1102       w_width = (int) PreeditWidth (xc) / (int) FontWidth (xl);
1103       xc->max_columns = ((int) PreeditWidth (xc) / (int) FontWidth (xl));
1104       if (xc->max_columns <= 0)
1105         xc->max_columns = 1;
1106       xc->c0 = (int) (PreeditWidth (xc) + PreeditX (xc) - PreeditSpotX (xc)) / (int) FontWidth (xl);
1107       if (xc->c0 < 0)
1108         xc->c0 = 0;
1109       if (xc->c0 >= xc->max_columns)
1110         {
1111           xc->c0 = xc->max_columns;
1112           xc->c1 = xc->c2 = 0;
1113         }
1114       else if ((xc->c1 = xc->max_columns - xc->c0) > w_width)
1115         {
1116           xc->c1 = w_width;
1117           xc->c2 = xc->max_columns - xc->c0 - xc->c1;
1118         }
1119       else
1120         {
1121           xc->c2 = 0;
1122         }
1123       xl->max_cur = xl->max_pos - xl->vst;
1124       if (xl->max_cur > xc->c0)
1125         {
1126           width = xc->c0 * FontWidth (xl);
1127         }
1128       else
1129         {
1130           width = xl->max_cur * FontWidth (xl);
1131         }
1132       if (width == 0)
1133         width = 1;
1134       XMoveResizeWindow (dpy, xl->wp[0], PreeditSpotX (xc), PreeditSpotY (xc), width, FontHeight (xl));
1135       XMoveWindow (dpy, xl->w[0], -(xl->vst * FontWidth (xl)), 0);
1136       XFlush (dpy);
1137     }
1138   if (xl->visible_line == 0)
1139     xl->visible_line = 1;
1140 
1141   XMapWindow (dpy, xl->wp[0]);
1142   XRaiseWindow (dpy, xl->wp[0]);
1143   XFlush (dpy);
1144   if (xc->c1 && (xl->max_pos >= xc->c0) && (xl->buf[xc->c0] != 0))
1145     {
1146       if (check_mb (xl->buf, (xc->c0 - 1)) == 1)
1147         {
1148           xl->linefeed[1] = 1;
1149         }
1150       else
1151         {
1152           xl->linefeed[1] = 0;
1153         }
1154       visible_line2 ();
1155       if (xl->visible_line < 2)
1156         xl->visible_line = 2;
1157     }
1158   if (xc->c2 && (xl->max_pos > (c01 (xc) - 1 - xl->linefeed[1])))
1159     {
1160       if (check_mb (xl->buf, (c01 (xc) - 1 - xl->linefeed[1])) == 1)
1161         {
1162           xl->linefeed[2] = xl->linefeed[1] + 1;
1163         }
1164       else
1165         {
1166           xl->linefeed[2] = xl->linefeed[1];
1167         }
1168       visible_line3 ();
1169       if (xl->visible_line < 3)
1170         xl->visible_line = 3;
1171     }
1172   if (xl->vst)
1173     {
1174       if (!xl->note[0])
1175         {
1176           JWM_note (0);
1177           xl->note[0] = 1;
1178         }
1179     }
1180   else
1181     {
1182       if (!xl->note[1])
1183         {
1184           invisual_note (0);
1185           xl->note[0] = 0;
1186         }
1187     }
1188   max_pos_tmp = xl->vst + xc->max_columns - xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)];
1189   if (xl->max_pos > max_pos_tmp)
1190     {
1191       if (!xl->note[1])
1192         {
1193           JWM_note (1);
1194           xl->note[1] = 1;
1195         }
1196       if ((check_mb (xl->buf, (max_pos_tmp - 1))) == 1)
1197         {
1198           JWM_note_null ();
1199         }
1200       else
1201         {
1202           XUnmapWindow (dpy, xl->wn[2]);
1203         }
1204     }
1205   else
1206     {
1207       if (xl->note[1])
1208         {
1209           invisual_note (1);
1210           xl->note[1] = 0;
1211         }
1212       XUnmapWindow (dpy, xl->wn[2]);
1213     }
1214   xl->visible = 1;
1215 }
1216 
1217 #ifdef  CALLBACKS
1218 static void
visual_window_cb()1219 visual_window_cb ()
1220 {
1221   register XIMLangRec *xl;
1222 
1223   xl = cur_p->cur_xl;
1224 
1225   if (xl->visible == 0)
1226     {
1227       CBPreeditStart ();
1228       if (xl->max_pos)
1229         {
1230           CBPreeditRedraw (xl);
1231         }
1232       xl->visible = 1;
1233     }
1234 }
1235 #endif /* CALLBACKS */
1236 
1237 void
visual_window()1238 visual_window ()
1239 {
1240   if (cur_p->cur_xl->visible)
1241     return;
1242 
1243   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
1244     {
1245       visual_window3 ();
1246     }
1247   else if (IsPreeditPosition (cur_x))
1248     {
1249       visual_window1 ();
1250 #ifdef  CALLBACKS
1251     }
1252   else if (IsPreeditCallbacks (cur_x))
1253     {
1254       visual_window_cb ();
1255 #endif /* CALLBACKS */
1256 
1257     }
1258   XFlush (dpy);
1259 }
1260 
1261 static void
invisual_line2()1262 invisual_line2 ()
1263 {
1264   XUnmapWindow (dpy, cur_p->cur_xl->wp[1]);
1265   XFlush (dpy);
1266 }
1267 
1268 static void
invisual_line3()1269 invisual_line3 ()
1270 {
1271   XUnmapWindow (dpy, cur_p->cur_xl->wp[2]);
1272   XFlush (dpy);
1273 }
1274 
1275 static void
invisual_window3()1276 invisual_window3 ()
1277 {
1278   register XIMLangRec *xl;
1279 
1280   xl = cur_p->cur_xl;
1281 
1282   if (xl->note[0])
1283     {
1284       XUnmapWindow (dpy, xl->wn[0]);
1285       xl->note[0] = 0;
1286     }
1287   if (xl->note[1])
1288     {
1289       XUnmapWindow (dpy, xl->wn[1]);
1290       xl->note[1] = 0;
1291     }
1292   if (IsPreeditNothing (cur_x))
1293     {
1294       xl->visible = 0;
1295     }
1296   else
1297     {
1298       xl->visible_line = 0;
1299     }
1300   xl->vst = 0;
1301   XClearWindow (dpy, xl->w[0]);
1302   XUnmapWindow (dpy, xl->wp[0]);
1303   JWwindow_move (xl);
1304 }
1305 
1306 void
invisual_window1()1307 invisual_window1 ()
1308 {
1309   register XIMLangRec *xl;
1310 
1311   xl = cur_p->cur_xl;
1312 
1313   XUnmapWindow (dpy, xl->wp[0]);
1314   invisual_line2 ();
1315   invisual_line3 ();
1316   xl->visible = 0;
1317   xl->visible_line = 0;
1318   xl->linefeed[0] = xl->linefeed[1] = xl->linefeed[2] = 0;
1319   if (xl->note[0])
1320     {
1321       XUnmapWindow (dpy, xl->wn[0]);
1322       xl->note[0] = 0;
1323     }
1324   if (xl->note[1])
1325     {
1326       XUnmapWindow (dpy, xl->wn[1]);
1327       xl->note[1] = 0;
1328     }
1329   XUnmapWindow (dpy, xl->wn[2]);
1330 }
1331 
1332 void
invisual_window()1333 invisual_window ()
1334 {
1335   if (!cur_p->cur_xl->visible)
1336     return;
1337   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
1338     {
1339       invisual_window3 ();
1340     }
1341   else if (IsPreeditPosition (cur_x))
1342     {
1343       invisual_window1 ();
1344 #ifdef  CALLBACKS
1345     }
1346   else if (IsPreeditCallbacks (cur_x))
1347     {
1348       CBPreeditDone ();
1349 #endif /* CALLBACKS */
1350     }
1351   cur_p->cur_xl->visible = 0;
1352   XFlush (dpy);
1353 }
1354 
1355 static void
JW0Mputwc(wc,wc_len,status)1356 JW0Mputwc (wc, wc_len, status)
1357      register wchar *wc;
1358      int wc_len;
1359      char status;               /* 0: Preedit Window, 1: Status Window */
1360 {
1361   register int cnt = wc_len;
1362   register XIMLangRec *xl;
1363   register XIMClientRec *xc = cur_p;
1364   register wchar *JW_buf, *p = wc;
1365   unsigned char *JW_att;
1366   int mb_len;
1367   short *cur_col, start_col = 0, end_col = 0;
1368   register unsigned char flg = 0;
1369   XCharStruct cs;
1370 
1371   if (cnt <= 0)
1372     return;
1373 
1374   xl = xc->cur_xl;
1375 
1376   if (status)
1377     {
1378       JW_buf = xl->buf0 + xl->currentcol0;
1379       JW_att = xl->att0 + xl->currentcol0;
1380       cs.width = StatusFontWidth (xl);
1381       cs.ascent = StatusFontAscent (xl);
1382       cs.descent = StatusFontDescent (xl);
1383       start_col = xl->currentcol0;
1384       cur_col = &xl->currentcol0;
1385     }
1386   else
1387     {
1388       visual_window ();
1389       if (xl->currentcol >= xc->maxcolumns)
1390         return;
1391       JW_buf = xl->buf + xl->currentcol;
1392       JW_att = xl->att + xl->currentcol;
1393       cs.width = FontWidth (xl);
1394       cs.ascent = FontAscent (xl);
1395       cs.descent = FontDescent (xl);
1396       start_col = xl->currentcol;
1397       cur_col = &xl->currentcol;
1398     }
1399 
1400   if (xl->r_flag)
1401     flg |= REV_FLAG;
1402   if (xl->b_flag)
1403     flg |= BOLD_FLAG;
1404   if (xl->u_line_flag)
1405     flg |= UNDER_FLAG;
1406 
1407   for (; cnt > 0; cnt--)
1408     {
1409       mb_len = put_pending_wchar_and_flg (*p++, JW_buf, JW_att, flg);
1410       JW_buf += mb_len;
1411       JW_att += mb_len;
1412       end_col += mb_len;
1413       if (flg & REV_FLAG)
1414         {
1415           if (mb_len)
1416             {
1417               check_move (xc, xl, 1);
1418             }
1419           else
1420             {
1421               check_move (xc, xl, 0);
1422             }
1423         }
1424       *cur_col += mb_len;
1425     }
1426   if (status)
1427     {
1428       JWOutput (xl->ws, xl->st_fs, ((flg & REV_FLAG) ? xc->st.reversegc : xc->st.gc), start_col, end_col, flg, 0, 0, &cs, wc, wc_len);
1429     }
1430   else
1431     {
1432       JWOutput (xl->w[0], xl->pe_fs, ((flg & REV_FLAG) ? xc->pe.reversegc : xc->pe.gc), start_col, end_col, flg, 0, 0, &cs, wc, wc_len);
1433     }
1434 }
1435 
1436 static void
JWMputwc(wc,wc_len)1437 JWMputwc (wc, wc_len)
1438      register wchar *wc;
1439      int wc_len;
1440 {
1441   register int cnt = wc_len;
1442   register XIMLangRec *xl;
1443   register XIMClientRec *xc = cur_p;
1444   register wchar *JW_buf, *p = wc;
1445   unsigned char *JW_att;
1446   Window currentW = 0;
1447   int mb_len;
1448   short col = 0;
1449   register unsigned char flg = 0;
1450   XCharStruct cs;
1451 
1452   if (cnt <= 0)
1453     return;
1454 
1455   xl = xc->cur_xl;
1456 
1457   if (xl->currentcol >= xc->maxcolumns)
1458     return;
1459   if (xl->currentcol == 0 && xl->visible == 0)
1460     visual_window1 ();
1461 
1462   if (xl->r_flag)
1463     flg |= REV_FLAG;
1464   if (xl->b_flag)
1465     flg |= BOLD_FLAG;
1466   if (xl->u_line_flag)
1467     flg |= UNDER_FLAG;
1468 
1469   JW_buf = xl->buf + xl->currentcol;
1470   JW_att = xl->att + xl->currentcol;
1471   cs.width = FontWidth (xl);
1472   cs.ascent = FontAscent (xl);
1473   cs.descent = FontDescent (xl);
1474 
1475   for (; cnt > 0; cnt--)
1476     {
1477       mb_len = put_pending_wchar_and_flg (*p++, JW_buf, JW_att, flg);
1478       JW_buf += mb_len;
1479       JW_att += mb_len;
1480       col += mb_len;
1481       if (mb_len > 1)
1482         {
1483           if (((xl->currentcol + mb_len - xl->vst) > xc->c0) && ((xl->currentcol - xl->vst) <= xc->c0) && (xc->c1))
1484             {
1485               xl->linefeed[1] = xc->c0 + xl->vst - xl->currentcol;
1486               if (xl->linefeed[1] == 1)
1487                 XClearArea (dpy, xl->w[0], (xc->c0 + xl->vst - 1) * FontWidth (xl), 0, 0, 0, False);
1488               visible_line2 ();
1489               if (xl->visible_line < 2)
1490                 xl->visible_line = 2;
1491               if (((xl->currentcol + mb_len + xl->linefeed[1] - xl->vst) > (xc->c0 + xc->c1)) && ((xl->currentcol + xl->linefeed[1] - xl->vst) <= (xc->c0 + xc->c1)) && (xc->c2))
1492                 {
1493                   xl->linefeed[2] = xc->c0 + xc->c1 + xl->vst - xl->currentcol;
1494                   if ((xl->linefeed[2] - xl->linefeed[1]) == 1)
1495                     XClearArea (dpy, xl->w[1], ((xc->c0 + xc->c1 + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0, 0, 0, False);
1496                   visible_line3 ();
1497                   if (xl->visible_line < 3)
1498                     xl->visible_line = 3;
1499                 }
1500             }
1501           if (flg & REV_FLAG)
1502             {
1503               check_move (xc, xl, 1);
1504             }
1505           if ((xl->currentcol - xl->vst) <= (xc->c0 - 2))
1506             {
1507               currentW = xl->w[0];
1508             }
1509           else if ((xl->currentcol - xl->vst) <= (xc->c0 + xc->c1 - 2 - xl->linefeed[1]))
1510             {
1511               currentW = xl->w[1];
1512             }
1513           else
1514             {
1515               currentW = xl->w[2];
1516             }
1517         }
1518       else
1519         {
1520           if (((xl->currentcol - xl->vst) == xc->c0) && (xc->c1))
1521             {
1522               xl->linefeed[1] = 0;
1523               visible_line2 ();
1524               if (xl->visible_line < 2)
1525                 xl->visible_line = 2;
1526               if (((xl->currentcol + xl->linefeed[1] - xl->vst) == (xc->c0 + xc->c1)) && (xc->c2))
1527                 {
1528                   xl->linefeed[2] = xl->linefeed[1];
1529                   visible_line3 ();
1530                   if (xl->visible_line < 3)
1531                     xl->visible_line = 3;
1532                 }
1533             }
1534           if (flg & REV_FLAG)
1535             check_move (xc, xl, 0);
1536           if ((xl->currentcol - xl->vst) <= (xc->c0 - 1))
1537             {
1538               currentW = xl->w[0];
1539             }
1540           else if ((xl->currentcol - xl->vst) <= (xc->c0 + xc->c1 - 1 - xl->linefeed[1]))
1541             {
1542               currentW = xl->w[1];
1543             }
1544           else
1545             {
1546               currentW = xl->w[2];
1547             }
1548         }
1549       JWOutput (currentW, xl->pe_fs, ((flg & REV_FLAG) ? xc->pe.reversegc : xc->pe.gc), xl->currentcol, col, flg, 0, 0, &cs, wc, 1);
1550       if ((xl->currentcol + col - xl->vst) > xl->max_cur)
1551         {
1552           xl->max_cur = xl->currentcol + col - xl->vst;
1553           xl->m_cur_flag = 1;
1554           Resize_jw ();
1555         }
1556       xl->currentcol += col;
1557       col = 0;
1558       wc++;
1559     }
1560   return;
1561 }
1562 
1563 void
JWMflushw_buf(w_buf,len)1564 JWMflushw_buf (w_buf, len)
1565      w_char *w_buf;
1566      int len;
1567 {
1568   XIMLangRec *xl = cur_p->cur_xl;
1569   int wc_len;
1570 
1571   if (len <= 0)
1572     return;
1573   while (1)
1574     {
1575       wc_len = w_char_to_wchar (xl->xlc, w_buf, wc_buf, len, wc_buf_max);
1576       if (wc_len < -1)
1577         {
1578           return;
1579         }
1580       else if (wc_len == -1)
1581         {
1582           if (realloc_wc_buf () < 0)
1583             return;
1584         }
1585       else
1586         {
1587           break;
1588         }
1589     }
1590   if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x))
1591     {
1592       (void) JW0Mputwc (wc_buf, wc_len, 0);
1593     }
1594   else if (IsPreeditPosition (cur_x))
1595     {
1596       (void) JWMputwc (wc_buf, wc_len);
1597 #ifdef  CALLBACKS
1598     }
1599   else if (IsPreeditCallbacks (cur_x))
1600     {
1601       (void) CBPreeditDraw (wc_buf, wc_len);
1602 #endif /* CALLBACKS */
1603     }
1604   if (xl->currentcol > xl->max_pos)
1605     {
1606       xl->max_pos = xl->currentcol;
1607     }
1608   XFlush (dpy);
1609 }
1610 
1611 void
jw_disp_mode(c)1612 jw_disp_mode (c)
1613      unsigned char *c;
1614 {
1615   XIMLangRec *xl = cur_p->cur_xl;
1616   int c_len;
1617   int wc_len;
1618 
1619   c_len = strlen ((char *) c);
1620   while (1)
1621     {
1622       wc_len = char_to_wchar (xl->xlc, c, wc_buf, c_len, wc_buf_max);
1623       if (wc_len < -1)
1624         {
1625           return;
1626         }
1627       else if (wc_len == -1)
1628         {
1629           if (realloc_wc_buf () < 0)
1630             return;
1631         }
1632       else
1633         {
1634           break;
1635         }
1636     }
1637 
1638   xl->currentcol0 = 0;
1639   if (IsStatusNothing (cur_x) || IsStatusArea (cur_x))
1640     {
1641       JW0Mputwc (wc_buf, wc_len, 1);
1642 #ifdef  CALLBACKS
1643     }
1644   else if (IsStatusCallbacks (cur_x))
1645     {
1646       CBStatusDraw (wc_buf, wc_len);
1647 #endif /* CALLBACKS */
1648     }
1649   if (xl->currentcol0 > xl->max_pos0)
1650     {
1651       xl->max_pos0 = xl->currentcol0;
1652     }
1653   return;
1654 }
1655 
1656 void
JWMline_clear(x)1657 JWMline_clear (x)
1658      register int x;
1659 {
1660   register XIMLangRec *xl;
1661   register int cnt;
1662   register wchar *JW_buf;
1663   unsigned char *JW_att;
1664 
1665   xl = cur_p->cur_xl;
1666   JW_buf = xl->buf + x;
1667   JW_att = xl->att + x;
1668 
1669   if (IsPreeditArea (cur_x) || IsPreeditNothing (cur_x))
1670     {
1671       XClearArea (dpy, xl->w[0], x * FontWidth (xl), 0, (xl->max_pos - x) * FontWidth (xl) + 1, 0, False);
1672       if (x <= (xl->vst + cur_x->max_columns))
1673         {
1674           invisual_note (1);
1675           xl->note[1] = 0;
1676           XUnmapWindow (dpy, xl->wn[2]);
1677         }
1678       if (x <= 0)
1679         {
1680           invisual_window ();
1681         }
1682 #ifdef  CALLBACKS
1683     }
1684   else if (IsPreeditCallbacks (cur_x))
1685     {
1686       if (x <= 0)
1687         {
1688           invisual_window ();
1689         }
1690       else
1691         {
1692           CBPreeditClear (x, xl->max_pos);
1693         }
1694 #endif /* CALLBACKS */
1695     }
1696   else if (IsPreeditPosition (cur_x))
1697     {
1698       xl->del_x = x;
1699     }
1700   for (cnt = x; cnt < xl->max_pos; cnt++)
1701     {
1702       *JW_buf++ = 0;
1703       *JW_att++ = 0;
1704     }
1705   xl->currentcol = x;
1706   xl->max_pos = x;
1707   XFlush (dpy);
1708 }
1709 
1710 void
JWMline_clear1()1711 JWMline_clear1 ()
1712 {
1713   register XIMLangRec *xl;
1714   register XIMClientRec *xc = cur_p;
1715   register int xx;
1716 
1717   xl = xc->cur_xl;
1718   xx = xl->del_x;
1719   if (xl->currentcol == xl->max_pos)
1720     xx++;
1721   if (xc->c2 && (((xx - xl->vst) <= (c01 (xc) - xl->linefeed[1])) || (xl->visible_line < 3)))
1722     {
1723       XUnmapWindow (dpy, xl->wp[2]);
1724       xl->visible_line = 2;
1725     }
1726   if (xc->c1 && (((xx - xl->vst) <= cur_p->c0) || (xl->visible_line < 2)))
1727     {
1728       XUnmapWindow (dpy, xl->wp[1]);
1729       xl->visible_line = 1;
1730     }
1731   xl->m_cur_flag = 1;
1732   if (xl->del_x <= 0)
1733     {
1734       invisual_window ();
1735       xl->visible_line = 0;
1736       xl->max_l1 = 0;
1737       xl->max_cur = 0;
1738       xl->m_cur_flag = 1;
1739     }
1740   xl->del_x = -1;
1741   xl->max_cur = xx - xl->vst;
1742   Resize_jw ();
1743   XFlush (dpy);
1744 }
1745 
1746 void
visual_status()1747 visual_status ()
1748 {
1749   register XIMLangRec *xl;
1750 
1751   xl = cur_p->cur_xl;
1752 
1753 #ifdef  CALLBACKS
1754   if (IsStatusCallbacks (cur_x))
1755     {
1756       CBStatusStart ();
1757       if (henkan_off_flag == 0)
1758         {
1759           disp_mode ();
1760         }
1761       else
1762         {
1763           display_henkan_off_mode ();
1764         }
1765     }
1766   else
1767     {
1768 #endif /* CALLBACKS */
1769       XMapWindow (dpy, xl->ws);
1770       XRaiseWindow (dpy, xl->ws);
1771 #ifdef  CALLBACKS
1772     }
1773 #endif /* CALLBACKS */
1774 }
1775 
1776 void
invisual_status()1777 invisual_status ()
1778 {
1779   register XIMLangRec *xl;
1780 
1781   xl = cur_p->cur_xl;
1782 
1783 #ifdef  CALLBACKS
1784   if (IsStatusCallbacks (cur_x))
1785     {
1786       CBStatusDone ();
1787     }
1788   else
1789     {
1790 #endif /* CALLBACKS */
1791       XUnmapWindow (dpy, xl->ws);
1792 #ifdef  CALLBACKS
1793     }
1794 #endif /* CALLBACKS */
1795 }
1796 
1797 void
JWcursor_visible()1798 JWcursor_visible ()
1799 {
1800   cur_p->cur_xl->cursor_flag = 1;
1801 #ifdef  CALLBACKS
1802   if (IsPreeditCallbacks (cur_x))
1803     {
1804       CBCursorMark (1);
1805     }
1806   else
1807     {
1808 #endif /* CALLBACKS */
1809       JWmark_cursor (1);
1810 #ifdef  CALLBACKS
1811     }
1812 #endif /* CALLBACKS */
1813 }
1814 
1815 void
JWcursor_invisible()1816 JWcursor_invisible ()
1817 {
1818 #ifdef  CALLBACKS
1819   if (IsPreeditCallbacks (cur_x))
1820     {
1821       CBCursorMark (0);
1822     }
1823   else
1824     {
1825 #endif /* CALLBACKS */
1826       JWmark_cursor (0);
1827 #ifdef  CALLBACKS
1828     }
1829 #endif /* CALLBACKS */
1830   cur_p->cur_xl->cursor_flag = 0;
1831 }
1832 
1833 void
JWcursor_move(x)1834 JWcursor_move (x)
1835      int x;
1836 {
1837   register XIMLangRec *xl;
1838 
1839   xl = cur_p->cur_xl;
1840 
1841   if ((xl->visible != 0) && (xl->max_pos > 0))
1842     {
1843       visual_window ();
1844     }
1845 #ifdef  CALLBACKS
1846   if (IsPreeditCallbacks (cur_x))
1847     {
1848       if (xl->currentcol != x)
1849         {
1850           xl->currentcol = x;
1851           CBCursorMove (xl->currentcol);
1852         }
1853     }
1854   else
1855     {
1856 #endif /* CALLBACKS */
1857       JWmark_cursor (0);
1858       xl->currentcol = x;
1859       if (x >= 0)
1860         JWmark_cursor (1);
1861 #ifdef  CALLBACKS
1862     }
1863 #endif /* CALLBACKS */
1864   if (IsPreeditPosition (cur_x) && xl->max_pos < xl->max_cur && xl->max_pos >= x)
1865     {
1866       xl->del_x = xl->max_pos;
1867     }
1868 }
1869 
1870 void
check_scroll()1871 check_scroll ()
1872 {
1873   register XIMLangRec *xl = cur_p->cur_xl;
1874   register int mb;
1875 
1876   mb = check_mb (xl->buf, xl->currentcol);
1877   if ((xl->currentcol < xl->vst) || ((xl->currentcol + xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)] - xl->vst - mb) >= cur_p->max_columns))
1878     {
1879       if (mb == 1)
1880         {
1881           check_move (cur_p, xl, 1);
1882         }
1883       else
1884         {
1885           check_move (cur_p, xl, 0);
1886         }
1887     }
1888 }
1889 
1890 
1891 void
visible_root()1892 visible_root ()
1893 {
1894   register XIMClientRec *xc;
1895   register XIMRootRec *root = cur_x->root_pointer;
1896   XWMHints wm_hints;
1897 
1898   if (!root->root_visible)
1899     return;
1900   for (xc = ximclient_list; xc != NULL; xc = xc->next)
1901     {
1902       if (xc->root_pointer == root && IsPreeditNothing (xc))
1903         break;
1904     }
1905   if (!root->root_visible_flag && xc && !root->ximclient->cur_xl->w_c->h_flag)
1906     {
1907       wm_hints.initial_state = NormalState;
1908       wm_hints.flags = StateHint;
1909       XSetWMHints (dpy, root->ximclient->w, &wm_hints);
1910       XMapWindow (dpy, root->ximclient->w);
1911       root->root_visible_flag = (char) 1;
1912     }
1913 }
1914 
1915 void
invisible_root()1916 invisible_root ()
1917 {
1918   register XIMRootRec *root = cur_x->root_pointer;
1919 
1920   if (!root->root_visible)
1921     return;
1922   if (root->root_visible_flag)
1923     {
1924       XWithdrawWindow (dpy, root->ximclient->w, DefaultScreen (dpy));
1925       root->root_visible_flag = (char) 0;
1926     }
1927 }
1928 
1929 void
check_root_mapping(root)1930 check_root_mapping (root)
1931      register XIMRootRec *root;
1932 {
1933   register XIMClientRec *xc;
1934   XWMHints wm_hints;
1935 
1936   if (!root->root_visible)
1937     return;
1938   for (xc = ximclient_list; xc != NULL; xc = xc->next)
1939     {
1940       if (xc->root_pointer == root && IsPreeditNothing (xc))
1941         break;
1942     }
1943   if (root->root_visible_flag && !xc)
1944     {
1945       XWithdrawWindow (dpy, root->ximclient->w, DefaultScreen (dpy));
1946       root->root_visible_flag = (char) 0;
1947     }
1948   else if (!root->root_visible_flag && xc && !root->ximclient->cur_xl->w_c->h_flag)
1949     {
1950       wm_hints.initial_state = NormalState;
1951       wm_hints.flags = StateHint;
1952       XSetWMHints (dpy, root->ximclient->w, &wm_hints);
1953       XMapWindow (dpy, root->ximclient->w);
1954       root->root_visible_flag = (char) 1;
1955     }
1956 }
1957