1 /*
2  *  screen.c,v 1.7 2002/06/22 13:26:21 hiroo Exp
3  *  Canna: $Id: screen.c,v 1.2 2003/01/04 07:31:02 aida_s Exp $
4  */
5 
6 /*
7  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
8  * This file is part of FreeWnn.
9  *
10  * Copyright Kyoto University Research Institute for Mathematical Sciences
11  *                 1987, 1988, 1989, 1990, 1991, 1992
12  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
13  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
14  * Copyright FreeWnn Project 1999, 2000, 2002
15  *
16  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31  */
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35 
36 #include <stdio.h>
37 #if STDC_HEADERS
38 #  include <string.h>
39 #else
40 #  if HAVE_STRINGS_H
41 #    include <strings.h>
42 #  endif
43 #endif /* STDC_HEADERS */
44 
45 #include "commonhd.h"
46 #include "wnn_config.h"
47 #include "sdefine.h"
48 #include "sheader.h"
49 #include "wnn_os.h"
50 #include "buffer.h"
51 
52 /*
53 ���Υե�����ϡ�����������ʬ�ȤΥ������ե�������Ԥ��ؿ���
54 ������Ƥ��롣�����δؿ����Ѥ����ˡ����̤����椷�ƤϤʤ�ʤ���
55 ���Υե����뤫��extern ����Ƥ���ؿ�������
56 �ʤ������̤�����ϡ�c_b->buffer ����ǤΥ���ǥå������Ѥ���
57 �Ԥ��롣����c_b->buffer ����Τɤ���ʬ�����̤˽Ф���Ƥ���
58 ���ϰռ����ʤ��Ƥ褤��
59 
60 t_move(x) :
61 	��������� x �����Ф�����ɥ���ɬ�� (ȿž���������
62 	����) ����ʬ�⾡��˹ͤ��ƹԤä����롣
63 t_redraw_move(x , start , end,clr_l) :
64 	buffer ����ǡ�start ���� end �ޤǤΥХåե������Ƥ�
65 	�Ѥ���줿���ˡ����������x �����Ф��Τ��Ѥ��롣
66 print_buf_msg(msg) :
67 	��å�������ʬ��ɽ�����롣
68 disp_mode():
69 	romkan �Υ⡼�ɤ�ɽ�����롣
70 disp_mode_line():
71 	romkan �Υ⡼�ɤ�ɽ�����롣
72 t_print_l():
73 	���̤��ɥ����롣
74 t_throw():
75 	������������Ф�
76 init_screen():
77 	���̴ط�(vst)���˥���饤����������ɽ����Ԥ���
78 */
79 
80 /* ʸ���β��̾�Ǥ��礭�����֤���*/
81 
82 static int col = 0; /** startichi����β��̾�Υ���������� */
83 static int oldmaxcol = 0; /** redraw sita tokini doko made mae ni kaita data ga nokotteiruka wo simesu */
84 
85 #define CHAR_BYTE 2
86 
87 #define w_putchar_move(x) {col += w_putchar(x);}
88 #define putchar_move(x) {col += 1; putchar_norm(x);}
89 #define putchar_move1(x) {col += 1; putchar1(x);}
90 
91 #define throw0(x)       throw_c((x) + c_b->start_col)
92 /*
93 #define throw(x) {int tmptmp = (x);if(cs == 0 || col != tmptmp){throw0((col = tmptmp) + 1);}}
94 */
95 
96 /* ���������col �����Ф��Τˤϡ�throw��
97 �Ѥ��롣 */
98 #define MARJIN 1                /* �������뤬��ü���餳������ν�ˤ���С����β��̤˹Ԥ� */
99 
100 static void t_cont_line_note ();
101 static int find_character_on_that_col (), set_vst ();
102 
103 void
throw(x)104 throw (x)
105      int x;
106 {
107   throw0 ((col = x) + 1);
108 }
109 
110 int
char_len(x)111 char_len (x)
112      w_char x;
113 {
114   return ((*char_len_func) (x));
115 }
116 
117 /* vst ���åȤ�ľ���ơ���ɥ�����*/
118 void
t_redraw_one_line()119 t_redraw_one_line ()
120 {
121   if (c_b->vst)
122     {
123       t_cont_line_note ();
124     }
125   else
126     {
127       t_cont_line_note_delete ();
128     }
129   t_print_line (c_b->vst, c_b->maxlen, 1);
130 }
131 
132 void
init_screen()133 init_screen ()
134 {
135   int tmp;
136 
137   oldmaxcol = 0;
138   tmp = cur_ichi (c_b->t_c_p, 0);
139   if ((tmp >= c_b->vlen - c_b->duplicate) && (tmp % (c_b->vlen - c_b->duplicate)) < c_b->duplicate - 1)
140     {
141       c_b->vst = find_character_on_that_col ((tmp / (c_b->vlen - c_b->duplicate) - 1) * (c_b->vlen - c_b->duplicate), 0);
142     }
143   else
144     {
145       c_b->vst = find_character_on_that_col ((tmp / (c_b->vlen - c_b->duplicate)) * (c_b->vlen - c_b->duplicate), 0);
146     }
147   if (c_b->maxlen || *c_b->buf_msg)
148     t_print_l ();
149 }
150 
151 /* hituyouga areba vst wo settosinaosite, settosinaosita tokiniha 1 wo kaesu */
152 int
check_vst()153 check_vst ()
154 {
155   int k = -1;
156 
157   if ((c_b->t_c_p < c_b->vst) || (cur_ichi (c_b->t_c_p, c_b->vst) >= (c_b->vlen - MARJIN)) || (cur_ichi (c_b->t_m_start, c_b->vst) > (c_b->vlen - MARJIN)))
158     {
159       k = set_vst ();
160     }
161   if (k == -1)
162     {
163       return (0);
164     }
165   else
166     {
167       return (1);
168     }
169 }
170 
171 int
t_redraw_move(x,start,end,clr_l)172 t_redraw_move (x, start, end, clr_l)
173      int x;
174      int start;
175      int end;
176      int clr_l;
177 {
178   (*t_redraw_move_func) (x, start, end, clr_l);
179   return (0);
180 }
181 
182 int
t_move(x)183 t_move (x)
184      int x;
185 {
186   int old_cp = c_b->t_c_p;
187 
188   if (((c_b->hanten >> 2) & 0x3) != ((c_b->hanten >> 4) & 0x3))
189     {
190       t_redraw_move_normal (x, min (old_cp, x), max (old_cp, x), 0);
191       return (0);
192     }
193   if (x >= c_b->maxlen)
194     x = c_b->maxlen;
195   c_b->t_c_p = x;
196   if (check_vst ())
197     {
198       t_redraw_one_line ();
199     }
200   throw (cur_ichi (c_b->t_c_p, c_b->vst));
201   flush ();
202   return (0);
203 }
204 
205 int
t_print_l()206 t_print_l ()
207 {
208   (*t_print_l_func) ();
209   return (0);
210 }
211 
212 #define set_screen_reverse(X,Y){set_hanten_ul(c_b->hanten & X, c_b->hanten & Y);}
213 #define reset_screen_reverse(X,Y){flushw_buf(); if(c_b->hanten & X)h_r_off();if(c_b->hanten & Y)u_s_off(); flush();}
214 
215 #define set_screen_bold(X){flushw_buf(); set_bold(c_b->hanten & X);}
216 #define reset_screen_bold(X){flushw_buf(); reset_bold(c_b->hanten & X);flush();}
217 
218 /* st must be bigger than vst */
219 
220 
221 /* ���Υե�����ǰ��ֽ��פʴؿ���
222 c_b->buffer ����ǡ�st ���� end �ޤǤDz��̤˸���Ƥ����(vst�����)��
223 ɽ����ľ�������������⤹�롣
224 ��С����ξ����ϡ�c_b->hanten�ˤ�äƷ����롣
225 */
226 
227 void
t_print_line(st,end,clr_l)228 t_print_line (st, end, clr_l)
229      int st, end, clr_l;
230 {
231   register int k;
232   register int col1;
233   register int end_of_line = maxlength - disp_mode_length - 1 - c_b->start_col;
234   int tmp;
235 
236   int mst = min (c_b->t_m_start, c_b->t_c_p);
237   int mend = max (c_b->t_m_start, c_b->t_c_p);
238 
239   int bst = c_b->t_b_st;
240   int bend = c_b->t_b_end;
241   int bold = 0;
242 
243   if (end > c_b->maxlen)
244     end = c_b->maxlen;
245   col1 = cur_ichi (st, c_b->vst);
246   if (col1 == -1)
247     {
248       col1 = 0;
249       k = st = c_b->vst;
250     }
251   else
252     {
253       k = st;
254     }
255 
256   for (; end_of_line <= col1; end_of_line += maxlength);
257 
258   throw (col1);
259   if (mst >= 0)
260     {
261       if (st < mst)
262         {
263           set_screen_reverse (0x01, 0x02);
264           for (k = st; k < mst; k++)
265             {
266 
267               if (bold == 0 && k >= bst && k < bend)
268                 {
269                   set_screen_bold (0x40);
270                   bold = 1;
271                 }
272               else if (bold && (k < bst || k >= bend))
273                 {
274                   reset_screen_bold (0x40);
275                   set_screen_reverse (0x01, 0x02);
276                   bold = 0;
277                 }
278               if (k >= end)
279                 {
280                   reset_screen_reverse (0x01, 0x02);
281                   reset_screen_bold (0x40);
282                   bold = 0;
283                   goto normal_out;
284                 }
285               tmp = char_len (c_b->buffer[k]);
286               if (tmp + col > c_b->vlen)
287                 {
288                   reset_screen_reverse (0x01, 0x02);
289                   reset_screen_bold (0x40);
290                   bold = 0;
291                   goto end_syori;
292                 }
293               w_putchar_move (c_b->buffer[k]);
294               if (col > end_of_line - CHAR_BYTE)
295                 {
296                   flushw_buf ();
297                   if (col < end_of_line)
298                     {
299                       reset_screen_reverse (0x01, 0x02);
300                       reset_screen_bold (0x40);
301                       bold = 0;
302                       putchar_move (' ');
303                       set_screen_reverse (0x01, 0x02);
304                       if (k >= bst && k < bend)
305                         {
306                           set_screen_bold (0x40);
307                           bold = 1;
308                         }
309                     }
310                   throw (end_of_line);
311                   end_of_line += maxlength;
312                 }
313 
314             }
315           reset_screen_reverse (0x01, 0x02);
316           reset_screen_bold (0x40);
317           bold = 0;
318         }
319       if (k < mend)
320         {
321           set_screen_reverse (0x04, 0x08);
322           for (; k < mend; k++)
323             {
324 
325               if (bold == 0 && k >= bst && k < bend)
326                 {
327                   set_screen_bold (0x40);
328                   bold = 1;
329                 }
330               else if (bold && (k < bst || k >= bend))
331                 {
332                   reset_screen_bold (0x40);
333                   set_screen_reverse (0x04, 0x08);
334                   bold = 0;
335                 }
336 
337               if (k >= end)
338                 {
339                   reset_screen_reverse (0x04, 0x08);
340                   reset_screen_bold (0x40);
341                   bold = 0;
342                   goto normal_out;
343                 }
344               tmp = char_len (c_b->buffer[k]);
345               if (col + tmp > c_b->vlen)
346                 {
347                   reset_screen_reverse (0x04, 0x08);
348                   reset_screen_bold (0x40);
349                   bold = 0;
350                   goto end_syori;
351                 }
352               w_putchar_move (c_b->buffer[k]);
353               if (col > end_of_line - CHAR_BYTE)
354                 {
355                   flushw_buf ();
356                   if (col < end_of_line)
357                     {
358                       reset_screen_reverse (0x04, 0x08);
359                       reset_screen_bold (0x40);
360                       bold = 0;
361                       putchar_move (' ');
362                       set_screen_reverse (0x04, 0x08);
363                       if (k >= bst && k < bend)
364                         {
365                           set_screen_bold (0x40);
366                           bold = 1;
367                         }
368                     }
369                   throw (end_of_line);
370                   end_of_line += maxlength;
371                 }
372             }
373           reset_screen_reverse (0x04, 0x08);
374           reset_screen_bold (0x40);
375           bold = 0;
376         }
377     }
378   if (k < c_b->maxlen && k < end)
379     {
380       set_screen_reverse (0x10, 0x20);
381       for (; k < c_b->maxlen; k++)
382         {
383 
384           if (bold == 0 && k >= bst && k < bend)
385             {
386               set_screen_bold (0x40);
387               bold = 1;
388             }
389           else if (bold && (k < bst || k >= bend))
390             {
391               reset_screen_bold (0x40);
392               set_screen_reverse (0x10, 0x20);
393               bold = 0;
394             }
395 
396           if (k >= end)
397             {
398               reset_screen_reverse (0x10, 0x20);
399               reset_screen_bold (0x40);
400               bold = 0;
401               goto normal_out;
402             }
403           tmp = char_len (c_b->buffer[k]);
404           if (col + tmp > c_b->vlen)
405             {
406               reset_screen_reverse (0x10, 0x20);
407               reset_screen_bold (0x40);
408               bold = 0;
409               goto end_syori;
410             }
411           w_putchar_move (c_b->buffer[k]);
412           if (col > end_of_line - CHAR_BYTE)
413             {
414               flushw_buf ();
415               if (col < end_of_line)
416                 {
417                   reset_screen_reverse (0x10, 0x20);
418                   reset_screen_bold (0x40);
419                   bold = 0;
420                   putchar_move (' ');
421                   set_screen_reverse (0x10, 0x20);
422                   if (k >= bst && k < bend)
423                     {
424                       set_screen_bold (0x40);
425                       bold = 1;
426                     }
427                 }
428               throw (end_of_line);
429               end_of_line += maxlength;
430             }
431         }
432       reset_screen_reverse (0x10, 0x20);
433       reset_screen_bold (0x40);
434       bold = 0;
435     }
436 
437 normal_out:
438   if (clr_l == 1)
439     {
440       clr_line ();
441       oldmaxcol = col;
442     }
443   else if (clr_l == 2)
444     {
445       clr_line ();
446       oldmaxcol = col;
447 /*      k = oldmaxcol - col;
448       oldmaxcol = col;
449       if(k > 0){
450           push_hrus();
451           for(; k > 0 ; k--){
452               putchar_move1(' ');
453           }
454           pop_hrus();
455       }
456 */
457     }
458   else
459     {
460       oldmaxcol = max (oldmaxcol, col);
461     }
462   flush ();
463   return;
464 
465 end_syori:
466   for (k = col; k <= c_b->vlen; k++)
467     {
468       putchar_move ('$');
469     }
470   oldmaxcol = col;
471   flush ();
472   return;
473 }
474 
475 /* �Ԥ���Ƭ���� */
476 static void
t_cont_line_note()477 t_cont_line_note ()
478 {
479   throw0 (0);
480   putchar_norm ('$');
481 }
482 
483 /* �Ԥ���Ƭ���� */
484 void
t_cont_line_note_delete()485 t_cont_line_note_delete ()
486 {
487   throw0 (0);
488   putchar_norm (' ');
489 }
490 
491 /*���̤Υ����0���Хåե�����start_point �λ��������c �ˤ���ʸ�����֤�*/
492 static int
find_character_on_that_col(c,start_point)493 find_character_on_that_col (c, start_point)
494      int c;                     /* colum */
495      int start_point;           /* in_buffer as vst */
496 {
497 
498   int k;
499   register int end_of_line = maxlength - disp_mode_length - 1 - c_b->start_col;
500   int len = 0;
501   for (k = start_point; k <= c_b->maxlen; k++)
502     {
503       len += char_len (c_b->buffer[k]);
504       if (len >= c)
505         return (k);
506       if (len > end_of_line - CHAR_BYTE)
507         {
508           len = end_of_line;
509           end_of_line += maxlength;
510         }
511     }
512   /*error but default to 0 */
513   return (0);
514 }
515 
516 /*���̤Υ����0���Хåե�����start_point �λ���ʸ��cp�β��̾�ΰ��֤��֤���*/
517 /* static */
518 int
cur_ichi(cp,start_point)519 cur_ichi (cp, start_point)
520      register int cp;
521      int start_point;
522 {
523   register int k;
524   register int end_of_line = maxlength - disp_mode_length - 1 - c_b->start_col;
525   register int len = 0;
526   if (cp < start_point)
527     return (-1);
528   if (cp > c_b->maxlen)
529     cp = c_b->maxlen;
530 
531   for (k = start_point; k < cp; k++)
532     {
533       len += char_len (c_b->buffer[k]);
534       if (len > end_of_line - CHAR_BYTE)
535         {
536           len = end_of_line;
537           end_of_line += maxlength;
538         }
539     }
540   return (len);
541 }
542 
543 
544 void
print_buf_msg(msg)545 print_buf_msg (msg)
546      char *msg;
547 {
548   push_cursor ();
549   throw_c (0);
550   printf (msg);
551   pop_cursor ();
552   flush ();
553 }
554 
555 /* vst���åȤ���*/
556 /* returns -1 if not changed
557    else returns new start colum
558 */
559 static int
set_vst()560 set_vst ()
561 {
562   int tmp;
563   int vst1;
564 
565   tmp = cur_ichi (c_b->t_c_p, 0);
566   vst1 = find_character_on_that_col ((tmp / (c_b->vlen - c_b->duplicate)) * (c_b->vlen - c_b->duplicate), 0);
567   if (cur_ichi (c_b->t_m_start, vst1) >= c_b->vlen)
568     {
569       vst1 = c_b->t_c_p;
570     }
571   c_b->vst = vst1;
572   return (vst1);
573 }
574 
575 
576 static char rk_modes[80];
577 extern char *romkan_dispmode (), *romkan_offmode ();
578 
579 char *
get_rk_modes()580 get_rk_modes ()
581 {
582   char *p;
583 
584   strcpy (rk_modes, (NULL == (p = romkan_dispmode ())? "[   ]" : p));
585   if ((p = (char *) strchr (rk_modes, ':')) != NULL && *(p + 1))
586     {
587       set_cur_env (*(++p));
588       *p = '\0';
589     }
590   return (rk_modes);
591 }
592 
593 int
disp_mode()594 disp_mode ()
595 {
596   push_cursor ();
597   throw_col (0);
598   printf ("%s", get_rk_modes ());
599   pop_cursor ();
600   flush ();
601   return (0);
602 }
603 
604 /* cursor status is saved before call it */
605 void
display_henkan_off_mode()606 display_henkan_off_mode ()
607 {
608   char *p;
609 
610   strcpy (rk_modes, (NULL == (p = romkan_offmode ())? "[---]" : p));
611   throw_col (0);
612   printf ("%s", rk_modes);
613   kk_restore_cursor ();
614   flush ();
615 }
616 
617 
618 /* ������������Ф�*/
619 void
t_throw()620 t_throw ()
621 {
622   throw0 (col + 1);
623   flush ();
624 }
625 
626 
627 void
clr_line()628 clr_line ()
629 {
630   clr_end_screen ();
631 }
632