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