1 /*
2  *  $Id: termcap.c,v 1.6 2002/06/13 21:27:47 hiroo 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 Kyoto University Research Institute for Mathematical Sciences
10  *                 1987, 1988, 1989, 1990, 1991, 1992
11  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13  * Copyright FreeWnn Project 1999, 2000, 2002
14  *
15  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  */
31 #ifdef HAVE_CONFIG_H
32 #  include <config.h>
33 #endif
34 
35 #include <stdio.h>
36 #include <ctype.h>
37 #if STDC_HEADERS
38 #  include <stdlib.h>
39 #  include <string.h>
40 #else
41 #  if HAVE_MALLOC_H
42 #    include <malloc.h>
43 #  endif
44 #  if HAVE_STRINGS_H
45 #    include <strings.h>
46 #  endif
47 #endif /* STDC_HEADERS */
48 #include <sys/errno.h>
49 #include <sys/ioctl.h>
50 #if HAVE_CURSES_H
51 #  include <curses.h>
52 #elif HAVE_NCURSES_H
53 #  include <ncurses.h>
54 #endif /* HAVE_CURSES_H */
55 #if HAVE_TERM_H
56 #  include <term.h>
57 #endif
58 
59 #include "commonhd.h"
60 
61 #include "sdefine.h"
62 #include "sheader.h"
63 
64 #undef DEFAULT_KKCAP
65 /* declaration about terminal */
66 
67 int kkcap_mode;
68 
69 int Term_LineWidth;
70 int Term_RowWidth;
71 /*
72 char    *Term_Bell;
73 */
74 char *Term_ClrScreen;
75 char *Term_ClrEofLine;
76 char *Term_CleEndScreen;
77 char *Term_ThrowCursor;
78 char *Term_StandOutStart;       /* These variables has value even if terminfo is used. see termio.c. */
79 char *Term_StandOutEnd;
80 static int bold_mode_fun;
81 char *Term_BoldOutStart;
82 char *Term_BoldOutEnd;
83 /*
84 int     Term_StandOutBlankNum;
85 char    *Term_DelChar;
86 */
87 char *Term_UnderScoreStart;
88 char *Term_UnderScoreEnd;
89 
90 char *Term_KeyPadOn;
91 char *Term_KeyPadOff;
92 #ifdef TERMCAP
93 char *Term_CursorNormal;
94 char *Term_CursorInvisible;
95 
96 
97 char *Term_SaveCursor;
98 char *Term_RestoreCursor;
99 char *Term_SetScrollRegion;
100 char *Term_ScrollRegion;
101 char *Term_ResetScreen;
102 char TermDataArea[1024];
103 static char TermData[1024];
104 
105 int cursor_state;
106 
107 #ifdef DCUREOR
108 FILE *debugc;
109 #endif
110 
111 
112 int
getTermData()113 getTermData ()
114 {
115   char *name;
116   char *pter;
117   char *sr_set ();
118   char *j;
119   extern char *getenv (), *get_kbd_env ();
120 
121 
122 #ifdef DCUREOR
123   if ((debugc = fopen (DP, "w")) == NULL)
124     {
125       fprintf (stderr, "OPEN ERR IN %d. \n", DP);
126     }
127 #endif
128 
129   /* for convert_key --- added by Nide 10/3 */
130   if (NULL == (name = get_kbd_env ()) || 0 != convert_getterm (name, (0 != verbose_option)))
131     {
132       fprintf (stderr, "Cannot get keyboard information.\n");
133       return (-1);
134     }
135 
136   if (((name = getenv ("TERM")) == NULL) || (tgetent (TermData, name) <= 0))
137     {
138       fprintf (stderr, "Cannot get terminal information.\n");
139       return (-1);
140     }
141   strcpy (Term_Name, name);
142   pter = TermDataArea;
143 
144   Term_ResetScreen = tgetstr ("rs", &pter);
145   Term_UnderScoreEnd = tgetstr ("ue", &pter);
146   if (!((Term_UnderScoreEnd = tgetstr (j = "ue", &pter)) && ((Term_LineWidth = tgetnum (j = "co")) != -1) && ((Term_RowWidth = tgetnum (j = "li")) != -1) &&    /* line */
147         /*          (Term_Bell = tgetstr(j = "bl", &pter)) &&  */
148         (Term_ClrScreen = tgetstr (j = "cl", &pter)) &&
149         (Term_ClrEofLine = tgetstr (j = "ce", &pter)) && (Term_CleEndScreen = tgetstr (j = "cd", &pter)) && (Term_ThrowCursor = tgetstr (j = "cm", &pter)) &&
150         /* Check padding */
151         (Term_StandOutStart = tgetstr (j = "so", &pter)) && (Term_StandOutEnd = tgetstr (j = "se", &pter)) &&
152         /*
153            ((Term_StandOutBlankNum = tgetnum(j = "sg")) != -1) &&
154            (Term_DelChar = tgetstr(j = "dc", &pter)) &&
155          */
156         (Term_UnderScoreStart = tgetstr (j = "us", &pter)) &&
157         (Term_SaveCursor = tgetstr (j = "sc", &pter)) &&
158         (Term_RestoreCursor = tgetstr (j = "rc", &pter)) && (Term_SetScrollRegion = tgetstr (j = "cs", &pter)) && (Term_ScrollRegion = sr_set (&pter, 0, Term_RowWidth - 2))))
159     {
160       fprintf (stderr, "Your terminal doesn't have %s entry in termcap.\n", j);
161       fprintf (stderr, "Maybe, your terminal is not strong enough to use Uum!\n");
162       return (-1);
163     }
164 
165   if (Term_BoldOutStart && Term_BoldOutEnd)
166     {
167       bold_mode_fun = 1;
168     }
169   else
170     {
171       bold_mode_fun = 0;
172     }
173   Term_BoldOutStart = tgetstr ("md", &pter);
174   Term_BoldOutEnd = tgetstr ("me", &pter);
175 
176   Term_CursorInvisible = tgetstr ("vi", &pter);
177   Term_CursorNormal = tgetstr ("ve", &pter);
178   if (Term_CursorInvisible && Term_CursorNormal)
179     {
180       cursor_invisible_fun = 1;
181     }
182   else
183     {
184       cursor_invisible_fun = 0;
185     }
186   Term_KeyPadOn = tgetstr ("ks", &pter);
187   Term_KeyPadOff = tgetstr ("ke", &pter);
188   if (Term_KeyPadOn && Term_KeyPadOff)
189     {
190       keypad_fun = 1;
191     }
192   else
193     {
194       keypad_fun = 0;
195     }
196 /*  and needs more precise check of Terminal status. */
197 #ifdef DGUX                     /* copied from JLS5.4.2 */
198   {
199     struct winsize ws;
200     if ((ioctl (0, TIOCGWINSZ, &ws) == 0) && (ws.ws_row > 0) && (ws.ws_col > 0))
201       {
202         Term_LineWidth = ws.ws_col;
203         Term_RowWidth = ws.ws_row;
204       }
205   }
206 #endif /* DGUX */
207 
208   maxlength = Term_LineWidth;
209   crow = Term_RowWidth - conv_lines;
210 
211 /*    decfline(TermData); decfline is moved after reading uumrc.*/
212 
213   return (0);
214 }
215 
216 char *
strsch(str1,str2)217 strsch (str1, str2)
218      char *str1, *str2;
219 {
220   char *c = NULL;
221   int flag = 0;
222   for (; *str1++;)
223     {
224       if (!flag)
225         {
226           if (*str1 == *str2)
227             {
228               flag = 1;
229               c = str2 + 1;
230             }
231         }
232       else
233         {
234           if (*c == 0)
235             return (str1);
236           if (*c++ != *str1)
237             flag = 0;
238         }
239     }
240   return (NULL);
241 }
242 
243 /* Remove an entry from TERMCAP string   by T.S. */
244 
245 static char *
remove(p,ob)246 remove (p, ob)
247      char *p, *ob;
248 {
249   char *r;
250 
251   if ((r = strsch (p, ob)) != NULL)
252     {
253       p = r - strlen (ob);
254       for (; *r != ':'; r++);
255       strcpy (p, r);
256     };
257   return (r);
258 }
259 
260 static void strascii ();
261 static int decfline ();
262 
263 int
set_TERMCAP()264 set_TERMCAP ()
265 {
266   return (decfline (TermData));
267 }
268 
269 
270 /** termcap no entry no naka de li: to cs: wo kakikaemasu */
271 static int
decfline(name)272 decfline (name)
273      char *name;
274 {
275   char *name1;
276   char *c;
277 
278   if ((name1 = malloc (strlen (name) + 1024)) == NULL)
279     {
280       return (-1);
281     }
282   if ((c = strsch (name, "li#")) != NULL)
283     {
284       strncpy (name1, name, c - name);
285       name1[c - name] = 0;
286       for (; *c >= '0' && *c <= '9'; c++);
287       sprintf (name1 + strlen (name1), "%d", crow);
288       strcat (name1, c);
289     }
290 /* add rs entry to termcap */
291   remove (name1, ":rs");
292   strcat (name1, "rs=");
293   if (Term_ResetScreen)
294     strascii (name1 + strlen (name1), Term_ResetScreen);
295   strascii (name1 + strlen (name1), Term_ScrollRegion);
296   strcat (name1, ":");
297 
298   if (remove_cs_from_termcap)
299     {
300       remove (name1, ":cs");
301     }
302   remove (name1, ":sc");
303   remove (name1, ":rc");
304   setenv ("TERMCAP", name1, 1);
305   free (name1);
306   return (0);
307 }
308 
309 /* functions using Terminal Information. */
310 
311 char *
sr_set(st,start,end)312 sr_set (st, start, end)
313      int start, end;
314      char **st;
315 {
316   char *string = *st;
317   char *pt = Term_SetScrollRegion;
318   char *pt1;
319   char nextch;
320   int params[2];
321   int i = 0;                    /* points tp params */
322 
323   *string = 0;
324   params[0] = start;
325   params[1] = end;
326   for (; *pt != 0; pt++)
327     {
328       if (i > 2)
329         {
330           fprintf (stderr, "ERROR in tparam few parameters.");
331           /* Message ga wakaridurai? */
332           return (NULL);
333         }
334       if (*pt == '%')
335         {
336           switch (*++pt)
337             {
338             case 'd':
339               sprintf (string + strlen (string), "%d", params[i++]);
340               break;
341             case '2':
342               sprintf (string + strlen (string), "%2d", params[i++]);
343               break;
344             case '3':
345               sprintf (string + strlen (string), "%3d", params[i++]);
346               break;
347             case '.':
348               sprintf (string + strlen (string), "%c", params[i++]);
349               break;
350             case '+':
351               if (!(nextch = *++pt))
352                 {
353                   fprintf (stderr, "Unexpected EOL in cs string.\n");
354                   return NULL;
355                 }
356               sprintf (string + strlen (string), "%c", params[i++] + nextch);
357               break;
358             case '>':
359               if (!(nextch = *++pt))
360                 {
361                   fprintf (stderr, "Unexpected EOL in cs string.\n");
362                   return NULL;
363                 }
364               if (params[i] > nextch)
365                 {
366                   if (!(nextch = *++pt))
367                     {
368                       fprintf (stderr, "Unexpected EOL in cs string.\n");
369                       return NULL;
370                     }
371                   params[i] += nextch;
372                 }
373               break;
374             case 'r':
375               {
376                 int temp;
377                 temp = params[0];
378                 params[0] = params[1];
379                 params[1] = temp;
380               }
381               break;
382             case 'i':
383               params[0]++;
384               params[1]++;
385               break;
386             case '%':
387               strcat (string, "%");
388               break;
389             case 'n':
390               params[0] ^= 0140;
391               params[1] ^= 0140;
392               break;
393             case 'B':
394               params[i] = ((params[i] / 10) << 4) + params[i] % 10;
395               break;
396             case 'D':
397               params[i] = params[i] - 2 * (params[i] % 16);
398               break;
399             case '\0':
400               fprintf (stderr, "Unexpected EOL in cs string.\n");
401               return NULL;
402             }
403         }
404       else
405         {
406           pt1 = string + strlen (string);
407           *pt1 = *pt;
408           *++pt1 = 0;
409         }
410     }
411   *st = string + strlen (string);
412   return (string);
413 }
414 
415 void
set_keypad_on()416 set_keypad_on ()
417 {
418   tputs (Term_KeyPadOn, 1, putchar);
419 }
420 
421 void
set_keypad_off()422 set_keypad_off ()
423 {
424   tputs (Term_KeyPadOff, 1, putchar);
425 }
426 
427 void
set_scroll_region(start,end)428 set_scroll_region (start, end)
429      int start, end;
430 {
431   char *a;
432   char TERM_SCROLLREGION[24];
433   a = TERM_SCROLLREGION;
434 
435   sr_set (&a, start, end);      /* changed in June 9 */
436   fputs (TERM_SCROLLREGION, stdout);
437 }
438 
439 void
clr_end_screen()440 clr_end_screen ()
441 {
442   tputs (Term_CleEndScreen, 1, putchar);
443 }
444 
445 void
clr_screen()446 clr_screen ()
447 {
448   tputs (Term_ClrScreen, Term_RowWidth, putchar);
449 }
450 
451 void
clr_line1()452 clr_line1 ()
453 {
454   tputs (Term_ClrEofLine, 1, putchar);
455 }
456 
457 void
throw_cur_raw(col,row)458 throw_cur_raw (col, row)
459      int col, row;
460 {
461   tputs (tgoto (Term_ThrowCursor, col, row), 1, putchar);
462 }
463 
464 void
h_r_on_raw()465 h_r_on_raw ()
466 {
467   tputs (Term_StandOutStart, 1, putchar);
468 }
469 
470 void
h_r_off_raw()471 h_r_off_raw ()
472 {
473   tputs (Term_StandOutEnd, 1, putchar);
474 }
475 
476 void
u_s_on_raw()477 u_s_on_raw ()
478 {
479   tputs (Term_UnderScoreStart, 1, putchar);
480 }
481 
482 void
u_s_off_raw()483 u_s_off_raw ()
484 {
485   tputs (Term_UnderScoreEnd, 1, putchar);
486   flush ();
487 }
488 
489 void
b_s_on_raw()490 b_s_on_raw ()
491 {
492   if (bold_mode_fun)
493     tputs (Term_BoldOutStart, 1, putchar);
494   else
495     tputs (Term_UnderScoreStart, 1, putchar);
496   flush ();
497 }
498 
499 void
b_s_off_raw()500 b_s_off_raw ()
501 {
502   if (bold_mode_fun)
503     tputs (Term_BoldOutEnd, 1, putchar);
504   else
505     tputs (Term_UnderScoreEnd, 1, putchar);
506   flush ();
507 }
508 
509 void
ring_bell()510 ring_bell ()
511 {
512   putchar (Ctrl ('G'));
513   flush ();
514 /*
515     tputs(Term_Bell, 1, putchar);
516 */
517 }
518 
519 void
save_cursor_raw()520 save_cursor_raw ()
521 {
522   tputs (Term_SaveCursor, 1, putchar);
523 }
524 
525 void
restore_cursor_raw()526 restore_cursor_raw ()
527 {
528   tputs (Term_RestoreCursor, 1, putchar);
529 }
530 
531 void
cursor_invisible_raw()532 cursor_invisible_raw ()
533 {
534   tputs (Term_CursorInvisible, 1, putchar);
535 }
536 
537 void
cursor_normal_raw()538 cursor_normal_raw ()
539 {
540   fputs (Term_CursorNormal, stdout);
541 }
542 
543 static void
strascii(dest,str)544 strascii (dest, str)
545      unsigned char *dest, *str;
546 {
547   for (; *str; str++)
548     {
549       if (*str >= ' ')
550         {
551           *dest++ = *str;
552         }
553       else if (*str == '\033')
554         {
555           *dest++ = '\\';
556           *dest++ = 'E';
557         }
558       else
559         {
560           *dest++ = '^';
561           *dest++ = *str + '@';
562         }
563     }
564   *dest = '\0';
565 }
566 
567 #endif /* TERMCAP */
568