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