1 | /* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
|
---|
2 | * This software is quasi-public; it may be used freely with
|
---|
3 | * like software, but may NOT be sold or made part of licensed
|
---|
4 | * products without permission of the author.
|
---|
5 | */
|
---|
6 | /*
|
---|
7 | * EETERM ELLE Terminal Driver.
|
---|
8 | * Directly supports DM2500, H-19, Omron 8025AG, Coherent/IBM-PC, TVI925.
|
---|
9 | * Others also supported if using TX_TERMCAP.
|
---|
10 | */
|
---|
11 |
|
---|
12 | #include "elle.h"
|
---|
13 |
|
---|
14 | /* Define terminal indices (there may be holes but C preprocessor is too
|
---|
15 | * stupid to let us close them). Should be one TN_ definition for every
|
---|
16 | * hardwired terminal type, even though whether or not it is actually
|
---|
17 | * compiled depends on which TX_ switches are defined.
|
---|
18 | */
|
---|
19 | #define TN_TERMCAP 0
|
---|
20 | #define TN_DM2500 1
|
---|
21 | #define TN_H19 2
|
---|
22 | #define TN_OM8025 3
|
---|
23 | #define TN_COHIBM 4 /* Coherent IBM-PC console */
|
---|
24 | #define TN_TVI925 5
|
---|
25 |
|
---|
26 | #if TX_COHIBM && !(TX_H19) /* Ensure H19 defined if COHIBM is. */
|
---|
27 | #define TX_H19 1
|
---|
28 | #endif
|
---|
29 |
|
---|
30 | #ifndef TXS_DEFAULT /* If no default is explicitly specified */
|
---|
31 | #define TXS_DEFAULT "H19" /* Then settle for H-19 */
|
---|
32 | #endif /*TXS_DEFAULT*/
|
---|
33 | |
---|
34 |
|
---|
35 |
|
---|
36 |
|
---|
37 | extern char *tv_stype; /* If set, specifies terminal type */
|
---|
38 | extern int tibfmsk; /* Crock to mask off parity (meta) bit */
|
---|
39 | static int tv_padc; /* Pad character to use */
|
---|
40 | static int tv_cspeed; /* # msec per char (set from trm_ospeed) */
|
---|
41 | static int tv_type; /* Index of selected terminal type */
|
---|
42 |
|
---|
43 | /* Internal functions */
|
---|
44 | static void tpadn(), tpad();
|
---|
45 |
|
---|
46 | /* Character speed table, indexed by system output speed value (0-017).
|
---|
47 | * Value in table is 100 * <# msec used per character>.
|
---|
48 | */
|
---|
49 | static int cspdtab[] =
|
---|
50 | { /* Val Idx Baud CPS Time/char in msec */
|
---|
51 | 0, /* 0 Hangup - ---- */
|
---|
52 | 13333, /* 1 50 7.5 133.33 (Baudot) */
|
---|
53 | 10000, /* 2 75 10 100.0 (Baudot) */
|
---|
54 | 10000, /* 3 110 10 100.0 */
|
---|
55 | 8200, /* 4 134.5 12.2 82.0 (IBM2741) */
|
---|
56 | 6666, /* 5 150 15 66.6666 */
|
---|
57 | 5000, /* 6 200 20 50.0 */
|
---|
58 | 3333, /* 7 300 30 33.3333 */
|
---|
59 | 1666, /* 8 600 60 16.6666 */
|
---|
60 | 833, /* 9 1200 120 8.3333 */
|
---|
61 | 555, /* 10 1800 180 5.5555 */
|
---|
62 | 416, /* 11 2400 240 4.1666 */
|
---|
63 | 208, /* 12 4800 480 2.0833 */
|
---|
64 | 104, /* 13 9600 960 1.04166 */
|
---|
65 | 0, /* 14 Ext A ? ? */
|
---|
66 | 0 /* 15 Ext B ? ? */
|
---|
67 | };
|
---|
68 |
|
---|
69 | #if TX_TERMCAP
|
---|
70 | /* Declarations for TERMCAP stuff. Only EETERM knows about them. */
|
---|
71 |
|
---|
72 | /* Termcap routines */
|
---|
73 | extern int tgetent(), tgetnum(), tgetflag(), tputs();
|
---|
74 | extern char *tgetstr(), *tgoto();
|
---|
75 | static int getcap(); /* Internal routines */
|
---|
76 | static void putpad(), putnpad(), putpar();
|
---|
77 |
|
---|
78 | /* Gross disgusting externals that must be defined for TERMCAP rtns */
|
---|
79 | char PC; /* Pad char */
|
---|
80 | char *BC; /* Backspace to use, if not ^H */
|
---|
81 | char *UP; /* Cursor up */
|
---|
82 | short ospeed; /* Terminal output speed */
|
---|
83 |
|
---|
84 | /* Termcap numerical values/flags */
|
---|
85 | static int
|
---|
86 | tc_am, /* TRUE if has auto-wrap */
|
---|
87 | tc_km; /* TRUE if meta key exists */
|
---|
88 |
|
---|
89 | /* Termcap capability strings we want to know about */
|
---|
90 |
|
---|
91 | struct tcap { char tcicod1, tcicod2, *tccap; };
|
---|
92 | static struct tcap tcap[] = {
|
---|
93 | #define TC_al tcap[0].tccap /* Add (insert) line */
|
---|
94 | {'a','l', 0},
|
---|
95 | #define TC_AL tcap[1].tccap /* Add N lines */
|
---|
96 | {'A','L', 0},
|
---|
97 | #define TC_bc tcap[2].tccap /* Backspace Char (for BC) */
|
---|
98 | {'b','c', 0},
|
---|
99 | #define TC_ce tcap[3].tccap /* Erase to end of line (CLEOL) */
|
---|
100 | {'c','e', 0},
|
---|
101 | #define TC_cl tcap[4].tccap /* Clear screen */
|
---|
102 | {'c','l', 0},
|
---|
103 | #define TC_cm tcap[5].tccap /* Cursor motion */
|
---|
104 | {'c','m', 0},
|
---|
105 | #define TC_dc tcap[6].tccap /* Delete char */
|
---|
106 | {'d','c', 0},
|
---|
107 | #define TC_DC tcap[7].tccap /* Delete N chars */
|
---|
108 | {'D','C', 0},
|
---|
109 | #define TC_dl tcap[8].tccap /* Delete line */
|
---|
110 | {'d','l', 0},
|
---|
111 | #define TC_DL tcap[9].tccap /* Delete N lines */
|
---|
112 | {'D','L', 0},
|
---|
113 | #define TC_dm tcap[10].tccap /* Delete mode on */
|
---|
114 | {'d','m', 0},
|
---|
115 | #define TC_ed tcap[11].tccap /* Delete mode off */
|
---|
116 | {'e','d', 0},
|
---|
117 | #define TC_ei tcap[12].tccap /* Insert mode off */
|
---|
118 | {'e','i', 0},
|
---|
119 | #define TC_ia tcap[13].tccap /* Add line while in insert mode (see note) */
|
---|
120 | {'i','a', 0},
|
---|
121 | #define TC_ic tcap[14].tccap /* Insert blank char */
|
---|
122 | {'i','c', 0},
|
---|
123 | #define TC_IC tcap[15].tccap /* Insert N blank chars */
|
---|
124 | {'I','C', 0},
|
---|
125 | #define TC_id tcap[16].tccap /* Delete line while in del mode (see note) */
|
---|
126 | {'i','d', 0},
|
---|
127 | #define TC_im tcap[17].tccap /* Insert mode on */
|
---|
128 | {'i','m', 0},
|
---|
129 | #define TC_ip tcap[18].tccap /* Padding to send after char insertion */
|
---|
130 | {'i','p', 0},
|
---|
131 | #define TC_mm tcap[19].tccap /* String to set (turn on) meta-key mode */
|
---|
132 | {'m','m', 0},
|
---|
133 | #define TC_mo tcap[20].tccap /* String to reset (turn off) meta-key mode */
|
---|
134 | {'m','o', 0},
|
---|
135 | #define TC_pc tcap[21].tccap /* Pad Char (for PC) */
|
---|
136 | {'p','c', 0},
|
---|
137 | #define TC_se tcap[22].tccap /* End standout mode */
|
---|
138 | {'s','e', 0},
|
---|
139 | #define TC_so tcap[23].tccap /* Enter standout mode */
|
---|
140 | {'s','o', 0},
|
---|
141 | #define TC_te tcap[24].tccap /* String to end programs that use termcap */
|
---|
142 | {'t','e', 0},
|
---|
143 | #define TC_ti tcap[25].tccap /* String to beg programs that use termcap */
|
---|
144 | {'t','i', 0},
|
---|
145 | #define TC_up tcap[26].tccap /* Move cursor up (for UP) */
|
---|
146 | {'u','p', 0},
|
---|
147 | #define TC_vb tcap[27].tccap /* Visible bell */
|
---|
148 | {'v','b', 0},
|
---|
149 | };
|
---|
150 | #define NTCAPS ((sizeof(tcap))/(sizeof(struct tcap))) /* # entries */
|
---|
151 |
|
---|
152 | /*
|
---|
153 | * There are many other things that must be taken into account.
|
---|
154 | * The termcap code here will probably not work for many termcap entries,
|
---|
155 | * but the only sure way to find out which ones they are is to try them.
|
---|
156 | */
|
---|
157 | /* Note that the "ia" and "id" strings are not defined by the TERMCAP doc;
|
---|
158 | * their usage here is derived from examining other TERMCAP-using programs.
|
---|
159 | * Sigh!!!!
|
---|
160 | */
|
---|
161 | #endif /*TX_TERMCAP*/
|
---|
162 | |
---|
163 |
|
---|
164 | /* T_INIT is called once only at program startup, to identify the
|
---|
165 | * terminal type and set up any one-time things.
|
---|
166 | * T_FATAL is only called if some routine detects an error related to the
|
---|
167 | * terminal specification, before any initialization is done.
|
---|
168 | * It prints a short error message and exits the program.
|
---|
169 | * T_ENTER is called after TS_ENTER to set the terminal parameters for
|
---|
170 | * editing (as opposed to normal typeout). It may be called
|
---|
171 | * several times.
|
---|
172 | * T_EXIT is called before TS_EXIT to restore normal typeout modes.
|
---|
173 | * It is called on exit from the program, and perhaps other times.
|
---|
174 | */
|
---|
175 | t_init()
|
---|
176 | {
|
---|
177 | char *getenv();
|
---|
178 |
|
---|
179 | /* Set some default parameters */
|
---|
180 | scr_ht = 24;
|
---|
181 | scr_wid = 79;
|
---|
182 | trm_flags = 0;
|
---|
183 | tvc_cin = 1; /* Assume 1 char per char I/D pos */
|
---|
184 | tvc_cdn = 1;
|
---|
185 | tvc_pos = 4; /* Default abs-move cost is 4 chars */
|
---|
186 | tvc_bs = 1; /* Default backspace cost is 1 char */
|
---|
187 | tv_cspeed = cspdtab[trm_ospeed]; /* Find # msec per char */
|
---|
188 |
|
---|
189 | /* First must determine terminal type, and check for terminals
|
---|
190 | * that are hardwired into ELLE. */
|
---|
191 | if(!tv_stype /* String set in command line args? */
|
---|
192 | #if !(V6)
|
---|
193 | && !(tv_stype = getenv("TERM")) /* or given by TERM var? */
|
---|
194 | #endif /*-V6*/
|
---|
195 | ) tv_stype = TXS_DEFAULT; /* No, try using default */
|
---|
196 | if(0) ; /* Sigh, stupid construct */
|
---|
197 | #if TX_H19
|
---|
198 | else if(ustrcmp(tv_stype,"H19")) tv_type = TN_H19;
|
---|
199 | #endif /*TX_H19*/
|
---|
200 | #if TX_OM8025
|
---|
201 | else if(ustrcmp(tv_stype,"OM8025")) tv_type = TN_OM8025;
|
---|
202 | #endif /*TX_OM8025*/
|
---|
203 | #if TX_DM2500
|
---|
204 | else if(ustrcmp(tv_stype,"DM2500")) tv_type = TN_DM2500;
|
---|
205 | else if(ustrcmp(tv_stype,"DM3025")) tv_type = TN_DM2500;
|
---|
206 | #endif /*TX_DM2500*/
|
---|
207 | #if TX_COHIBM
|
---|
208 | else if(ustrcmp(tv_stype,"COHIBM")) tv_type = TN_COHIBM;
|
---|
209 | #endif /*TX_COHIBM*/
|
---|
210 | #if TX_TVI925
|
---|
211 | else if(ustrcmp(tv_stype,"TVI925")) tv_type = TN_TVI925;
|
---|
212 | #endif /*TX_TVI925*/
|
---|
213 | #if TX_TERMCAP /* This should be last thing */
|
---|
214 | else if(getcap(tv_stype)) tv_type = TN_TERMCAP;
|
---|
215 | #endif /*TX_TERMCAP*/
|
---|
216 | else t_fatal("type unknown"); /* Ugh, barf and exit */
|
---|
217 |
|
---|
218 | /* Terminal selected, now initialize parameters for it. */
|
---|
219 | switch(tv_type)
|
---|
220 | {
|
---|
221 | #if TX_DM2500
|
---|
222 | case TN_DM2500:
|
---|
223 | tv_padc = 0177; /* Use rubout for pad */
|
---|
224 | tvc_pos = 3; /* Only 3 chars for abs mov */
|
---|
225 | tvc_ci = 2;
|
---|
226 | /* tvc_cin = 1; */ /* Default is OK */
|
---|
227 | tvc_cd = 2;
|
---|
228 | /* tvc_cdn = 1; */ /* Default is OK */
|
---|
229 | tvc_ld = 2;
|
---|
230 | tvc_ldn = 1;
|
---|
231 | tvc_li = 2;
|
---|
232 | tvc_lin = 1;
|
---|
233 | if(trm_ospeed == 13) /* If 9600, */
|
---|
234 | { tvc_cin = 5; /* Sigh, high cost */
|
---|
235 | tvc_cdn = 2;
|
---|
236 | tvc_lin = 18;
|
---|
237 | tvc_ldn = 2;
|
---|
238 | }
|
---|
239 | trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY;
|
---|
240 | break;
|
---|
241 | #endif /*TX_DM2500*/
|
---|
242 | #if TX_H19
|
---|
243 | case TN_H19:
|
---|
244 | trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
|
---|
245 | tvc_ci = 8;
|
---|
246 | /* tvc_cin = 1; */ /* default is ok */
|
---|
247 | tvc_cd = 0;
|
---|
248 | tvc_cdn = 2;
|
---|
249 | /* tvc_ld = 0; */ /* Default is OK */
|
---|
250 | tvc_ldn = 1 << (trm_ospeed - 7);
|
---|
251 | /* tvc_li = 0; */ /* Default is OK */
|
---|
252 | tvc_lin = tvc_ldn;
|
---|
253 | break;
|
---|
254 | #endif /*TX_H19*/
|
---|
255 | #if TX_COHIBM
|
---|
256 | case TN_COHIBM:
|
---|
257 | trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY|TF_DIRVID;
|
---|
258 | /* Always use lowest possible costs */
|
---|
259 | /* tvc_ci = 0; */ /* Default */
|
---|
260 | tvc_cin = 2;
|
---|
261 | /* tvc_cd = 0; */ /* Default */
|
---|
262 | tvc_cdn = 2;
|
---|
263 | /* tvc_ld = 0; */ /* Default */
|
---|
264 | tvc_ldn = 2;
|
---|
265 | /* tvc_li = 0; */ /* Default */
|
---|
266 | tvc_lin = 2;
|
---|
267 | break;
|
---|
268 | #endif /*TX_COHIBM*/
|
---|
269 | #if TX_OM8025
|
---|
270 | case TN_OM8025:
|
---|
271 | trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
|
---|
272 | tvc_pos = 6;
|
---|
273 | /* tvc_ci = tvc_cd = 0; */ /* Default */
|
---|
274 | tvc_cin = 4;
|
---|
275 | tvc_cdn = 2;
|
---|
276 | /* tvc_ld = tvc_li = 0; */ /* Default */
|
---|
277 | tvc_ldn = 10; /* Crude approx */
|
---|
278 | tvc_lin = 10;
|
---|
279 | if(trm_ospeed > 7) /* If faster than 300 baud */
|
---|
280 | trm_flags &= ~TF_IDLIN; /* Turn off LID */
|
---|
281 | break;
|
---|
282 | #endif /*TX_OM8025*/
|
---|
283 | #if TX_TVI925
|
---|
284 | case TN_TVI925:
|
---|
285 | trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
|
---|
286 | tvc_ci = tvc_cd = tvc_cin = tvc_cdn
|
---|
287 | = tvc_ldn = tvc_lin = 2;
|
---|
288 | break;
|
---|
289 | #endif /*TX_TVI925*/
|
---|
290 | }
|
---|
291 | if(tibfmsk < 0) /* If mask is still default -1, set it. */
|
---|
292 | tibfmsk = ((trm_flags&TF_METAKEY) ? 0377 : 0177);
|
---|
293 | }
|
---|
294 |
|
---|
295 | /* T_FATAL(str) - prints error message and exits.
|
---|
296 | */
|
---|
297 | t_fatal(str)
|
---|
298 | char *str;
|
---|
299 | { writerr("ELLE: \"");
|
---|
300 | writerr(tv_stype);
|
---|
301 | writerr("\" terminal ");
|
---|
302 | writerr(str);
|
---|
303 | writerr("\n");
|
---|
304 | exit(1); /* Terminate with prejudice */
|
---|
305 | }
|
---|
306 | |
---|
307 |
|
---|
308 | /* T_ENTER is called after TS_ENTER to set the terminal parameters for
|
---|
309 | * editing (as opposed to normal typeout).
|
---|
310 | * Standout mode must initially be off.
|
---|
311 | */
|
---|
312 |
|
---|
313 | t_enter()
|
---|
314 | { switch(tv_type)
|
---|
315 | {
|
---|
316 | #if TX_TERMCAP
|
---|
317 | case TN_TERMCAP:
|
---|
318 | putpad(TC_ti);
|
---|
319 | if(tc_km) putpad(TC_mm); /* Use meta if poss */
|
---|
320 | #if FX_SOWIND
|
---|
321 | t_standout(0); /* Ensure standout mode off */
|
---|
322 | #endif
|
---|
323 | break;
|
---|
324 | #endif /*TX_TERMCAP*/
|
---|
325 | #if TX_DM2500
|
---|
326 | case TN_DM2500:
|
---|
327 | tput(030); /* Just in case, flush stray modes */
|
---|
328 | break;
|
---|
329 | #endif /*TX_DM2500*/
|
---|
330 | #if TX_COHIBM
|
---|
331 | case TN_COHIBM: /* Note TN_H19 will exist too */
|
---|
332 | #endif /*TX_COHIBM*/
|
---|
333 | #if TX_H19
|
---|
334 | case TN_H19:
|
---|
335 | /* Enter ZDS (Heath) mode, then
|
---|
336 | * Exit graphics mode (G) Exit ins-char mode (O)
|
---|
337 | * exit rev video mode (q) exit hold-screen mode (\)
|
---|
338 | * set cursor on (y5)
|
---|
339 | */
|
---|
340 | tputz("\033[?2h\033G\033O\033q\033\\\033y5");
|
---|
341 | /* Set Discard-at-EOL (w)
|
---|
342 | * Set no auto-CR (y9)
|
---|
343 | * Enable 25th line (x1)
|
---|
344 | */
|
---|
345 | tputz("\033w\033y9\033x1");
|
---|
346 | break;
|
---|
347 | #endif /*TX_H19*/
|
---|
348 | }
|
---|
349 | }
|
---|
350 | |
---|
351 |
|
---|
352 | /* T_EXIT - Leave editing modes. This function should restore
|
---|
353 | ** the terminal's modes to what they were before ELLE was started.
|
---|
354 | ** Standout mode is turned off.
|
---|
355 | */
|
---|
356 |
|
---|
357 | t_exit()
|
---|
358 | {
|
---|
359 | switch(tv_type)
|
---|
360 | {
|
---|
361 | #if TX_TERMCAP
|
---|
362 | case TN_TERMCAP:
|
---|
363 | if(tc_km) putpad(TC_mo); /* Turn off meta */
|
---|
364 | putpad(TC_te);
|
---|
365 | break;
|
---|
366 | #endif /*TX_TERMCAP*/
|
---|
367 | #if TX_DM2500
|
---|
368 | case TN_DM2500:
|
---|
369 | tput(035); /* Turn on roll mode */
|
---|
370 | break;
|
---|
371 | #endif /*TX_DM2500*/
|
---|
372 | #if TX_COHIBM
|
---|
373 | case TN_COHIBM: /* If this exists, TN_H19 will too */
|
---|
374 | #endif /*TX_COHIBM*/
|
---|
375 | #if TX_H19
|
---|
376 | case TN_H19:
|
---|
377 | tputz("\033v"); /* Turn EOL-wrap back on */
|
---|
378 | #if DNTTY
|
---|
379 | tputz("\033<"); /* Return to ANSI mode */
|
---|
380 | #endif /*DNTTY*/
|
---|
381 | break;
|
---|
382 | #endif /*TX_H19*/
|
---|
383 | }
|
---|
384 | }
|
---|
385 | |
---|
386 |
|
---|
387 | /* T_CLEAR() - Clears the screen and homes the cursor.
|
---|
388 | * Always valid - ELLE refuses to support terminals without this.
|
---|
389 | */
|
---|
390 |
|
---|
391 | t_clear ()
|
---|
392 | { switch(tv_type)
|
---|
393 | {
|
---|
394 | #if TX_TERMCAP
|
---|
395 | case TN_TERMCAP:
|
---|
396 | putnpad(TC_cl,scr_ht);
|
---|
397 | break;
|
---|
398 | #endif /*TX_TERMCAP*/
|
---|
399 | #if TX_DM2500
|
---|
400 | case TN_DM2500:
|
---|
401 | tputz("\036\036"); /* Double Master Clear */
|
---|
402 | break;
|
---|
403 | #endif /*TX_DM2500*/
|
---|
404 | #if TX_COHIBM
|
---|
405 | case TN_COHIBM: /* Note TN_H19 will exist too */
|
---|
406 | #endif /*TX_COHIBM*/
|
---|
407 | #if TX_H19
|
---|
408 | case TN_H19:
|
---|
409 | tputz("\033E");
|
---|
410 | /* tputn(zpadstr,9); */
|
---|
411 | break;
|
---|
412 | #endif /*TX_H19*/
|
---|
413 | #if TX_OM8025
|
---|
414 | case TN_OM8025:
|
---|
415 | tputz("\033H\033J"); /* Home then CLEOS */
|
---|
416 | tpad(1000); /* One second!!!! */
|
---|
417 | break;
|
---|
418 | #endif /*TX_OM8025*/
|
---|
419 | #if TX_TVI925
|
---|
420 | case TN_TVI925:
|
---|
421 | tput(032); /* ^Z */
|
---|
422 | break;
|
---|
423 | #endif /*TX_TVI925*/
|
---|
424 | }
|
---|
425 | curs_lin = curs_col = 0;
|
---|
426 | }
|
---|
427 | |
---|
428 |
|
---|
429 | /* T_CURPOS(y, x) - Absolute move. Place cursor in given position
|
---|
430 | * regardless of where it currently is.
|
---|
431 | * Updates curs_lin, curs_col.
|
---|
432 | * Always valid -- ELLE refuses to support terminals without this.
|
---|
433 | */
|
---|
434 |
|
---|
435 | t_curpos (lin, col)
|
---|
436 | register int lin, col;
|
---|
437 | {
|
---|
438 | if(col > scr_wid) /* Easiest to catch here */
|
---|
439 | col = scr_wid;
|
---|
440 |
|
---|
441 | /* Do absolute positioning */
|
---|
442 | switch(tv_type)
|
---|
443 | {
|
---|
444 | #if TX_TERMCAP
|
---|
445 | case TN_TERMCAP:
|
---|
446 | putpad(tgoto(TC_cm, col, lin));
|
---|
447 | break;
|
---|
448 | #endif /*TX_TERMCAP*/
|
---|
449 | #if TX_DM2500
|
---|
450 | case TN_DM2500:
|
---|
451 | tput(014);
|
---|
452 | tput(col^0140);
|
---|
453 | tput(lin^0140);
|
---|
454 | break;
|
---|
455 | #endif /*TX_DM2500*/
|
---|
456 | #if TX_COHIBM
|
---|
457 | case TN_COHIBM: /* If this exists, TN_H19 will too */
|
---|
458 | #endif /*TX_COHIBM*/
|
---|
459 | #if TX_H19
|
---|
460 | case TN_H19:
|
---|
461 | tputz("\033Y");
|
---|
462 | tput(lin+040);
|
---|
463 | tput(col+040);
|
---|
464 | break;
|
---|
465 | #endif /*TX_H19*/
|
---|
466 | #if TX_OM8025
|
---|
467 | case TN_OM8025:
|
---|
468 | tputz("\033\175");
|
---|
469 | tput(0100+((lin+1)>>4));
|
---|
470 | tput(0100+((lin+1)&017));
|
---|
471 | tput(0100+((col+1)>>4));
|
---|
472 | tput(0100+((col+1)&017));
|
---|
473 | break;
|
---|
474 | #endif /*TX_OM8025*/
|
---|
475 | #if TX_TVI925
|
---|
476 | case TN_TVI925:
|
---|
477 | tputz("\033=");
|
---|
478 | tput(lin+040);
|
---|
479 | tput(col+040);
|
---|
480 | break;
|
---|
481 | #endif /*TX_TVI925*/
|
---|
482 | }
|
---|
483 | curs_lin = lin;
|
---|
484 | curs_col = col;
|
---|
485 | }
|
---|
486 |
|
---|
487 | /* T_BACKSPACE() - Back up 1 character position.
|
---|
488 | * Updates curs_col.
|
---|
489 | * Only valid if tvc_bs has a "reasonable" value ( < 1000)
|
---|
490 | */
|
---|
491 |
|
---|
492 | t_backspace()
|
---|
493 | {
|
---|
494 | #if TX_TERMCAP
|
---|
495 | if(BC) tputz(BC); /* Use alternate BS */
|
---|
496 | else
|
---|
497 | #endif
|
---|
498 | tput('\010'); /* Send BS */
|
---|
499 | --curs_col;
|
---|
500 | }
|
---|
501 |
|
---|
502 | /* T_BELL() - Ring terminal's bell (or flash something, or whatever).
|
---|
503 | * Forces out all output thus far, to ensure immediate attention.
|
---|
504 | * This used to be an unbuffered feep, but was changed to use normal
|
---|
505 | * output path in order to avoid messing up terminal escape sequences.
|
---|
506 | */
|
---|
507 | t_bell()
|
---|
508 | {
|
---|
509 | #if TXC_VISBEL && TX_TERMCAP
|
---|
510 | if(TC_vb)
|
---|
511 | tputz(TC_vb); /* Do visible bell if possible */
|
---|
512 | else
|
---|
513 | #endif
|
---|
514 | tput(BELL);
|
---|
515 | tbufls(); /* Force it out */
|
---|
516 | }
|
---|
517 | |
---|
518 |
|
---|
519 | /* T_CLEOL() - Clear to End Of Line.
|
---|
520 | * Only valid if trm_flags has TF_CLEOL set.
|
---|
521 | */
|
---|
522 |
|
---|
523 | t_cleol ()
|
---|
524 | {
|
---|
525 | switch(tv_type)
|
---|
526 | {
|
---|
527 | #if TX_TERMCAP
|
---|
528 | case TN_TERMCAP:
|
---|
529 | putpad(TC_ce);
|
---|
530 | break;
|
---|
531 | #endif /*TX_TERMCAP*/
|
---|
532 | #if TX_DM2500
|
---|
533 | case TN_DM2500:
|
---|
534 | tput(027);
|
---|
535 | break;
|
---|
536 | #endif /*TX_DM2500*/
|
---|
537 | #if TX_COHIBM
|
---|
538 | case TN_COHIBM: /* If this exists, TN_H19 will too */
|
---|
539 | #endif /*TX_COHIBM*/
|
---|
540 | #if TX_H19
|
---|
541 | case TN_H19:
|
---|
542 | tputz("\033K");
|
---|
543 | break;
|
---|
544 | #endif /*TX_H19*/
|
---|
545 | #if TX_OM8025
|
---|
546 | case TN_OM8025:
|
---|
547 | tputz("\033K");
|
---|
548 | tpad(41); /* 1/25 sec padding */
|
---|
549 | break;
|
---|
550 | #endif /*TX_OM8025*/
|
---|
551 | #if TX_TVI925
|
---|
552 | case TN_TVI925:
|
---|
553 | tputz("\033T");
|
---|
554 | break;
|
---|
555 | #endif /*TX_TVI925*/
|
---|
556 | }
|
---|
557 | }
|
---|
558 | |
---|
559 |
|
---|
560 | /* T_INSLIN(n, bot) - Insert lines in window.
|
---|
561 | * n - # blank lines to insert.
|
---|
562 | * bot - # of last line of current window
|
---|
563 | *
|
---|
564 | * The current line is moved down and N blank lines inserted.
|
---|
565 | * Lines which are moved past bot are lost.
|
---|
566 | * May leave cursor in random place.
|
---|
567 | * Only valid if trm_flags has TF_IDLIN set.
|
---|
568 | */
|
---|
569 |
|
---|
570 | t_inslin (n, bot)
|
---|
571 | int n; /* number of lines */
|
---|
572 | int bot; /* line number of last line in window */
|
---|
573 | { register i, j;
|
---|
574 | int savc,savl;
|
---|
575 |
|
---|
576 | if((i = n) <= 0) return;
|
---|
577 | if(bot < (scr_ht-1))
|
---|
578 | { savc = curs_col;
|
---|
579 | savl = curs_lin;
|
---|
580 | t_curpos(bot-i, 0);
|
---|
581 | t_dellin(i, scr_ht);
|
---|
582 | t_curpos(savl, savc);
|
---|
583 | }
|
---|
584 | switch(tv_type)
|
---|
585 | {
|
---|
586 | #if TX_TERMCAP
|
---|
587 | case TN_TERMCAP:
|
---|
588 | if(TC_AL)
|
---|
589 | putpar(TC_AL, i, i);
|
---|
590 | else if(TC_ia)
|
---|
591 | { putpad(TC_im);
|
---|
592 | do { putpad(TC_ia);
|
---|
593 | } while(--i);
|
---|
594 | putpad(TC_ei);
|
---|
595 | }
|
---|
596 | else
|
---|
597 | do { putnpad(TC_al, scr_ht - curs_lin);
|
---|
598 | } while(--i);
|
---|
599 | break;
|
---|
600 | #endif /*TX_TERMCAP*/
|
---|
601 | #if TX_DM2500
|
---|
602 | case TN_DM2500:
|
---|
603 | tput(020); /* Enter I/D mode */
|
---|
604 | do { tput(012); /* Insert line */
|
---|
605 | switch(trm_ospeed)
|
---|
606 | { case 13: j = 17; break; /* 9600 */
|
---|
607 | case 12: j = 8; break; /* 4800 */
|
---|
608 | case 11: j = 4; break; /* 2400 */
|
---|
609 | case 9: j = 2; break; /* 1200 */
|
---|
610 | default: j = 0; break;
|
---|
611 | }
|
---|
612 | tpadn(j);
|
---|
613 | } while(--i);
|
---|
614 | tput(030); /* Exit I/D mode */
|
---|
615 | break;
|
---|
616 | #endif /*TX_DM2500*/
|
---|
617 | #if TX_H19
|
---|
618 | /* NOTE: H19 supposedly requires 19 ms for each line during line I/D
|
---|
619 | * operations.
|
---|
620 | * In actual practice, at 9600 baud 25 pads are necessary (24 wont work!)
|
---|
621 | * for both I and D. Plus esc-E needs 9 pads.
|
---|
622 | */
|
---|
623 | case TN_H19:
|
---|
624 | do { tputz("\033L");
|
---|
625 | switch(trm_ospeed)
|
---|
626 | { case 13: j = 25; break;
|
---|
627 | case 9: j = 4; break;
|
---|
628 | case 7: j = 1; break;
|
---|
629 | default: j = 0; break;
|
---|
630 | }
|
---|
631 | tpadn(j);
|
---|
632 | } while(--i);
|
---|
633 | break;
|
---|
634 | #endif /*TX_H19*/
|
---|
635 | #if TX_COHIBM
|
---|
636 | case TN_COHIBM:
|
---|
637 | do { tputz("\033L"); /* no padding required */
|
---|
638 | } while(--i);
|
---|
639 | break;
|
---|
640 | #endif /*TX_COHIBM*/
|
---|
641 | #if TX_OM8025
|
---|
642 | case TN_OM8025:
|
---|
643 | do { tputz("\033L");
|
---|
644 | tpad(100*(scr_ht - curs_lin)); /* .1 per moved line*/
|
---|
645 | } while(--i);
|
---|
646 | break;
|
---|
647 | #endif /*TX_OM8025*/
|
---|
648 | #if TX_TVI925
|
---|
649 | case TN_TVI925:
|
---|
650 | do tputz("\033E");
|
---|
651 | while(--i);
|
---|
652 | break;
|
---|
653 | #endif /*TX_TVI925*/
|
---|
654 | }
|
---|
655 | }
|
---|
656 | |
---|
657 |
|
---|
658 | /* T_DELLIN(n, bot) - Delete lines from window.
|
---|
659 | * n - # lines to delete.
|
---|
660 | * bot - # of last line of current window.
|
---|
661 | * The current line, and N-1 following lines, are deleted.
|
---|
662 | * Blank lines are inserted past bot.
|
---|
663 | * Cursor should be left at original position.
|
---|
664 | * Only valid if trm_flags has TF_IDLIN set.
|
---|
665 | */
|
---|
666 | t_dellin (n, bot)
|
---|
667 | int n; /* number of lines */
|
---|
668 | int bot; /* line number of last line in window */
|
---|
669 | { register i, j;
|
---|
670 | int savl, savc;
|
---|
671 |
|
---|
672 | if((i = n) <= 0) return;
|
---|
673 | switch(tv_type)
|
---|
674 | {
|
---|
675 | #if TX_TERMCAP
|
---|
676 | case TN_TERMCAP:
|
---|
677 | if(TC_DL)
|
---|
678 | putpar(TC_DL, i, i);
|
---|
679 | else if(TC_id)
|
---|
680 | { putpad(TC_dm);
|
---|
681 | do putpad(TC_id);
|
---|
682 | while(--i);
|
---|
683 | putpad(TC_ed);
|
---|
684 | }
|
---|
685 | else
|
---|
686 | do { putnpad(TC_dl,scr_ht - curs_lin);
|
---|
687 | } while(--i);
|
---|
688 |
|
---|
689 | break;
|
---|
690 | #endif /*TX_TERMCAP*/
|
---|
691 | #if TX_DM2500
|
---|
692 | case TN_DM2500:
|
---|
693 | tput(020);
|
---|
694 | do { tput(032);
|
---|
695 | if(trm_ospeed >= 13) /* 9600 */
|
---|
696 | tput(0177);
|
---|
697 | } while(--i);
|
---|
698 | tput(030);
|
---|
699 | break;
|
---|
700 | #endif /*TX_DM2500*/
|
---|
701 | #if TX_H19
|
---|
702 | case TN_H19:
|
---|
703 | do { tputz("\033M");
|
---|
704 | switch(trm_ospeed){
|
---|
705 | case 13: j = 25; break;
|
---|
706 | case 9: j = 4; break;
|
---|
707 | case 7: j = 1; break;
|
---|
708 | default: j = 0; break;
|
---|
709 | }
|
---|
710 | tpadn(j);
|
---|
711 | } while(--i);
|
---|
712 | break;
|
---|
713 | #endif /*TX_H19*/
|
---|
714 | #if TX_COHIBM
|
---|
715 | case TN_COHIBM:
|
---|
716 | do { tputz("\033M"); /* no padding required */
|
---|
717 | } while(--i);
|
---|
718 | break;
|
---|
719 | #endif /*TX_COHIBM*/
|
---|
720 | #if TX_OM8025
|
---|
721 | case TN_OM8025:
|
---|
722 | do { tputz("\033M");
|
---|
723 | tpad(100*(scr_ht - curs_lin));
|
---|
724 | } while(--i);
|
---|
725 | break;
|
---|
726 | #endif /*TX_OM8025*/
|
---|
727 | #if TX_TVI925
|
---|
728 | case TN_TVI925:
|
---|
729 | do { tputz("\033R");
|
---|
730 | } while(--i);
|
---|
731 | break;
|
---|
732 | #endif /*TX_TVI925*/
|
---|
733 | }
|
---|
734 | if(bot < (scr_ht-1))
|
---|
735 | { savl = curs_lin;
|
---|
736 | savc = curs_col;
|
---|
737 | t_curpos(bot-n,0);
|
---|
738 | t_inslin(n,scr_ht);
|
---|
739 | t_curpos(savl,savc);
|
---|
740 | }
|
---|
741 | }
|
---|
742 | |
---|
743 |
|
---|
744 | /* T_INSCHR(n, str) - Insert n chars in current line
|
---|
745 | * n - # characters to insert
|
---|
746 | * str - Pointer to char string. If 0, insert spaces.
|
---|
747 | *
|
---|
748 | * Insert N characters from string str at current position.
|
---|
749 | * The cursor may move but curs_col must be updated.
|
---|
750 | * Only valid if trm_flags has TF_IDCHR set.
|
---|
751 | */
|
---|
752 | t_inschr(n, str)
|
---|
753 | int n;
|
---|
754 | char *str;
|
---|
755 | { register int i;
|
---|
756 | register char *cp;
|
---|
757 |
|
---|
758 | if((i = n) <= 0) return;
|
---|
759 | cp = str;
|
---|
760 | switch(tv_type)
|
---|
761 | {
|
---|
762 | #if TX_TERMCAP
|
---|
763 | case TN_TERMCAP:
|
---|
764 | putpad(TC_im); /* Go into insert mode */
|
---|
765 | if(TC_IC)
|
---|
766 | { putpar(TC_IC, i, 1);
|
---|
767 | if(cp) tputn(cp, i);
|
---|
768 | else do tput(SP); while(--i);
|
---|
769 | }
|
---|
770 | else do {
|
---|
771 | if(TC_ic) putpad(TC_ic);
|
---|
772 | if(cp) tput(*cp++);
|
---|
773 | else tput(SP);
|
---|
774 | if(TC_ip) putpad(TC_ip);
|
---|
775 | } while(--i);
|
---|
776 | putpad(TC_ei); /* Exit insert mode */
|
---|
777 | curs_col += n;
|
---|
778 | break;
|
---|
779 | #endif /*TX_TERMCAP*/
|
---|
780 | #if TX_COHIBM
|
---|
781 | case TN_COHIBM: /* If this exists, TN_H19 will too */
|
---|
782 | #endif /*TX_COHIBM*/
|
---|
783 | #if TX_H19
|
---|
784 | case TN_H19:
|
---|
785 | tputz("\033@"); /* Enter ins char mode */
|
---|
786 | do { if(cp) tput(*cp++);
|
---|
787 | else tput(SP);
|
---|
788 | } while(--i);
|
---|
789 | tputz("\033O"); /* Exit ins char mode */
|
---|
790 | curs_col += n;
|
---|
791 | break;
|
---|
792 | #endif /*TX_H19*/
|
---|
793 | #if TX_DM2500
|
---|
794 | case TN_DM2500:
|
---|
795 | tput(020); /* Enter I/D mode */
|
---|
796 | if(trm_ospeed == 13) /* 9600 baud lossage */
|
---|
797 | { do {
|
---|
798 | tputz(" \177"); /* SP and DEL */
|
---|
799 | } while(--i);
|
---|
800 | tput(030);
|
---|
801 | i = n;
|
---|
802 | if(i < 3) /* If close enough, */
|
---|
803 | tputn("\010\010", i); /* use BSes */
|
---|
804 | else t_curpos(curs_lin, curs_col);
|
---|
805 | }
|
---|
806 | else /* Not 9600, can win */
|
---|
807 | { do { tput(034);
|
---|
808 | } while(--i);
|
---|
809 | tput(030);
|
---|
810 | if(cp == 0) return;
|
---|
811 | i = n;
|
---|
812 | }
|
---|
813 |
|
---|
814 | do { if(cp) tput(*cp++);
|
---|
815 | else tput(SP);
|
---|
816 | } while(--i);
|
---|
817 | curs_col += n;
|
---|
818 | break;
|
---|
819 | #endif /*TX_DM2500*/
|
---|
820 | #if TX_OM8025
|
---|
821 | case TN_OM8025:
|
---|
822 | do {
|
---|
823 | tputz("\033@");
|
---|
824 | if(cp) tput(*cp++);
|
---|
825 | else tput(SP);
|
---|
826 | } while(--i);
|
---|
827 | curs_col += n;
|
---|
828 | break;
|
---|
829 | #endif /*TX_OM8025*/
|
---|
830 | #if TX_TVI925
|
---|
831 | case TN_TVI925:
|
---|
832 | do { tputz("\033Q");
|
---|
833 | } while(--i);
|
---|
834 | if(cp)
|
---|
835 | { tputn(cp, n);
|
---|
836 | curs_col += n;
|
---|
837 | }
|
---|
838 | break;
|
---|
839 | #endif /*TX_TVI925*/
|
---|
840 | }
|
---|
841 | }
|
---|
842 | |
---|
843 |
|
---|
844 | /* T_DELCHR(n) - Delete N chars in current line.
|
---|
845 | * Deletes the N characters to the right of the cursor. Remaining
|
---|
846 | * chars are shifted left. The cursor should not move.
|
---|
847 | * Only valid if trm_flags has TF_IDCHR set.
|
---|
848 | */
|
---|
849 | t_delchr(n) /* Delete N chars at current loc */
|
---|
850 | int n;
|
---|
851 | { register int i;
|
---|
852 |
|
---|
853 | if((i = n) <= 0) return;
|
---|
854 | switch(tv_type)
|
---|
855 | {
|
---|
856 | #if TX_TERMCAP
|
---|
857 | case TN_TERMCAP:
|
---|
858 | putpad(TC_dm); /* Enter delete mode */
|
---|
859 | if(TC_DC)
|
---|
860 | putpar(TC_DC, i, 1);
|
---|
861 | else do { /* Delete char while in del mode */
|
---|
862 | putpad(TC_dc);
|
---|
863 | } while(--i);
|
---|
864 | putpad(TC_ed); /* Exit delete mode */
|
---|
865 | break;
|
---|
866 | #endif /*TX_TERMCAP*/
|
---|
867 | #if TX_COHIBM
|
---|
868 | case TN_COHIBM: /* If this exists, TN_H19 will too */
|
---|
869 | #endif /*TX_COHIBM*/
|
---|
870 | #if TX_H19
|
---|
871 | case TN_H19:
|
---|
872 | do tputz("\033N");
|
---|
873 | while(--i);
|
---|
874 | break;
|
---|
875 | #endif /*TX_H19*/
|
---|
876 | #if TX_DM2500
|
---|
877 | case TN_DM2500:
|
---|
878 | tput(020); /* Enter I/D mode */
|
---|
879 | do if(trm_ospeed == 13) /* 9600? */
|
---|
880 | tputz("\010\177"); /* BS and DEL */
|
---|
881 | else tput(010);
|
---|
882 | while(--i);
|
---|
883 | tput(030); /* Exit I/D mode */
|
---|
884 | break;
|
---|
885 | #endif /*TX_DM2500*/
|
---|
886 | #if TX_OM8025
|
---|
887 | case TN_OM8025:
|
---|
888 | do tputz("\033P");
|
---|
889 | while (--i);
|
---|
890 | break;
|
---|
891 | #endif /*TX_OM8025*/
|
---|
892 | #if TX_TVI925
|
---|
893 | case TN_TVI925:
|
---|
894 | do { tputz("\033W");
|
---|
895 | } while(--i);
|
---|
896 | #endif /*TX_TVI925*/
|
---|
897 | }
|
---|
898 | }
|
---|
899 | |
---|
900 |
|
---|
901 | #if FX_SOWIND
|
---|
902 |
|
---|
903 | /* T_STANDOUT(n) - Enter or leave standout mode.
|
---|
904 | * n - 0 to return to normal display mode,
|
---|
905 | * 1 to enter standout display mode.
|
---|
906 | * This is usually reverse video but may be something else.
|
---|
907 | *
|
---|
908 | * Only valid if trm_flags has TF_SO set.
|
---|
909 | */
|
---|
910 |
|
---|
911 | t_standout(on)
|
---|
912 | int on;
|
---|
913 | {
|
---|
914 | switch(tv_type)
|
---|
915 | {
|
---|
916 | #if TX_TERMCAP
|
---|
917 | case TN_TERMCAP:
|
---|
918 | putpad(on ? TC_so : TC_se);
|
---|
919 | break;
|
---|
920 | #endif /*TX_TERMCAP*/
|
---|
921 |
|
---|
922 | #if TX_COHIBM
|
---|
923 | case TN_COHIBM: /* Note TN_H19 will exist too */
|
---|
924 | #endif /*TX_COHIBM*/
|
---|
925 | #if TX_H19
|
---|
926 | case TN_H19:
|
---|
927 | tputz(on ? "\033p" : "\033q");
|
---|
928 | break;
|
---|
929 | #endif /*TX_H19*/
|
---|
930 | }
|
---|
931 | }
|
---|
932 | #endif /*FX_SOWIND*/
|
---|
933 | |
---|
934 |
|
---|
935 |
|
---|
936 | /* TPADN(n) - Output N pad chars.
|
---|
937 | */
|
---|
938 | static void
|
---|
939 | tpadn(n)
|
---|
940 | int n;
|
---|
941 | { register int i, pad;
|
---|
942 | if((i = n) > 0)
|
---|
943 | { pad = tv_padc;
|
---|
944 | do { tput(pad);
|
---|
945 | } while(--i);
|
---|
946 | }
|
---|
947 | }
|
---|
948 |
|
---|
949 | /* TPAD(msec) - Output padding for given # of milliseconds.
|
---|
950 | */
|
---|
951 | static void
|
---|
952 | tpad(n)
|
---|
953 | int n;
|
---|
954 | { register int i, i2;
|
---|
955 |
|
---|
956 | i = n;
|
---|
957 | while(i > 0)
|
---|
958 | { if((i2 = 320) < i) /* So can use integers */
|
---|
959 | i2 = i;
|
---|
960 | i -= i2;
|
---|
961 | i2 *= 100;
|
---|
962 | while((i2 -= tv_cspeed) > 0)
|
---|
963 | tput(tv_padc);
|
---|
964 | }
|
---|
965 | }
|
---|
966 | #if TX_TERMCAP
|
---|
967 | /*
|
---|
968 | * Print the string str, interpreting padding.
|
---|
969 | */
|
---|
970 | int tput(); /* Our output function */
|
---|
971 | static void
|
---|
972 | putpad(str)
|
---|
973 | char *str;
|
---|
974 | { if(str) tputs(str, 1, tput); /* Invoke TERMCAP function */
|
---|
975 | }
|
---|
976 | static void
|
---|
977 | putnpad(str,n)
|
---|
978 | char *str;
|
---|
979 | int n;
|
---|
980 | { if(str) tputs(str, n, tput);
|
---|
981 | }
|
---|
982 | static void
|
---|
983 | putpar(str, par, n) /* Wish we had tparm() */
|
---|
984 | char *str;
|
---|
985 | int par,n;
|
---|
986 | { putnpad(tgoto(str, 0, par), n);
|
---|
987 | }
|
---|
988 | #endif /*TX_TERMCAP*/
|
---|
989 | |
---|
990 |
|
---|
991 | /*
|
---|
992 | * Read in the stuff from termcap upon startup.
|
---|
993 | */
|
---|
994 |
|
---|
995 | #if TX_TERMCAP
|
---|
996 | static int tstrlen(), tstrlp();
|
---|
997 |
|
---|
998 | #ifndef TCAPSLEN
|
---|
999 | #define TCAPSLEN 1024 /* Default size of buffer for TERMCAP strings */
|
---|
1000 | #endif /*-TCAPSLEN*/
|
---|
1001 |
|
---|
1002 | static int
|
---|
1003 | getcap(stype)
|
---|
1004 | char *stype;
|
---|
1005 | { register char *t;
|
---|
1006 | register int i;
|
---|
1007 | int buflen;
|
---|
1008 | char *tcbuf, *tcbptr; /* Pointers into termcap buffer */
|
---|
1009 | char tmpstr[4];
|
---|
1010 | char tmpbuf[TCAPSLEN]; /* Allocate from stack */
|
---|
1011 | char *malloc();
|
---|
1012 | char *realloc();
|
---|
1013 |
|
---|
1014 | /* First see if can find the terminal type. */
|
---|
1015 | if((tgetent(tmpbuf, stype)) != 1)
|
---|
1016 | return(0);
|
---|
1017 |
|
---|
1018 | /* Found it! Set up a string buffer to save the caps. */
|
---|
1019 | if(!(tcbuf = malloc(TCAPSLEN))) /* Get permanent buffer */
|
---|
1020 | t_fatal(" - cannot allocate termcap buffer");
|
---|
1021 | tcbptr = tcbuf;
|
---|
1022 |
|
---|
1023 | /* Now gobble all the string caps that ELLE wants to know about. */
|
---|
1024 | tmpstr[3] = '\0';
|
---|
1025 | i = NTCAPS;
|
---|
1026 | do {
|
---|
1027 | tmpstr[0] = tcap[i].tcicod1; /* Make str of the code */
|
---|
1028 | tmpstr[1] = tcap[i].tcicod2;
|
---|
1029 | tcap[i].tccap = tgetstr(tmpstr, &tcbptr); /* Get cap */
|
---|
1030 | } while(--i);
|
---|
1031 | buflen = tcbptr - tcbuf; /* String buffer done, finalize */
|
---|
1032 | if(buflen >= TCAPSLEN)
|
---|
1033 | t_fatal("description too big!");
|
---|
1034 | realloc(tcbuf, buflen); /* Free up unused part of buffer */
|
---|
1035 | /* (this better not move it!!!) */
|
---|
1036 |
|
---|
1037 | /* Now get the number/flag stuff that ELLE needs. */
|
---|
1038 | tc_am = tgetflag("am"); /* auto wrap */
|
---|
1039 | if (tgetflag("xn")) tc_am = 0; /* auto wrap at 81st char, nice! */
|
---|
1040 | tc_km = (tgetflag("km") /* TTY has meta key */
|
---|
1041 | || tgetflag("MT")); /* Alternate version of "km"?? */
|
---|
1042 | scr_ht = tgetnum("li"); /* Set screen height (# lines) */
|
---|
1043 | scr_wid = tgetnum("co"); /* Set screen width (# cols) */
|
---|
1044 | ts_winsize();
|
---|
1045 |
|
---|
1046 | /* Now initialize the stupid external vars that TERMCAP rtns want. */
|
---|
1047 | if(TC_pc) PC = *TC_pc; /* Pad char */
|
---|
1048 | BC = TC_bc; /* Backspace str (if no BS) */
|
---|
1049 | UP = TC_up; /* Cursor up */
|
---|
1050 | ospeed = trm_ospeed; /* Put output speed here */
|
---|
1051 |
|
---|
1052 |
|
---|
1053 | /* Basic data extracted, now mull over it and set the remaining
|
---|
1054 | * ELLE variables
|
---|
1055 | */
|
---|
1056 | #if FX_SOWIND
|
---|
1057 | if(tgetnum("sg") <= 0) /* If no magic cookie problems */
|
---|
1058 | { if (TC_so && TC_se) /* And have standout caps, */
|
---|
1059 | trm_flags |= TF_SO; /* Say has standout cap */
|
---|
1060 | }
|
---|
1061 | #endif
|
---|
1062 |
|
---|
1063 | if (!(TC_cm && TC_cl))
|
---|
1064 | t_fatal("lacks cursor addressing or clear screen.");
|
---|
1065 | tvc_pos = tstrlen(TC_cm); /* Find cost of abs move */
|
---|
1066 | if(BC) /* Find cost of backspace */
|
---|
1067 | tvc_bs = tstrlen(BC);
|
---|
1068 |
|
---|
1069 | /* Find costs for doing I/D char operations */
|
---|
1070 | if ((TC_im||TC_ic) && (TC_dm||TC_dc))
|
---|
1071 | { trm_flags |= TF_IDCHR;
|
---|
1072 | tvc_ci = tstrlen(TC_im)+tstrlen(TC_ei);
|
---|
1073 | tvc_cin = tstrlen(TC_ic)+1+tstrlen(TC_ip);
|
---|
1074 | if(TC_IC) /* If have multi-IC, use it */
|
---|
1075 | { tvc_ci += tstrlp(TC_IC, 1);
|
---|
1076 | tvc_cin = 1;
|
---|
1077 | }
|
---|
1078 | tvc_cd = tstrlen(TC_dm)+tstrlen(TC_ed);
|
---|
1079 | tvc_cdn = tstrlen(TC_dc);
|
---|
1080 | if(TC_DC) /* If have multi-DC, use it */
|
---|
1081 | { tvc_cd += tstrlp(TC_DC, 1);
|
---|
1082 | tvc_cdn = 0;
|
---|
1083 | }
|
---|
1084 | }
|
---|
1085 |
|
---|
1086 | /* Find costs for doing I/D line operations */
|
---|
1087 | if ((TC_ia || TC_al) && (TC_id || TC_dl))
|
---|
1088 | { trm_flags |= TF_IDLIN;
|
---|
1089 | tvc_li = 0; /* Usual case */
|
---|
1090 | tvc_lin = tstrlen(TC_al);
|
---|
1091 | if(TC_AL) /* If have multi-IL, use it */
|
---|
1092 | { tvc_li = tstrlp(TC_AL, 1);
|
---|
1093 | tvc_lin = tstrlp(TC_AL, 2) - tvc_lin;
|
---|
1094 | }
|
---|
1095 | else if(TC_ia)
|
---|
1096 | { tvc_li = tstrlen(TC_im)+tstrlen(TC_ei);
|
---|
1097 | tvc_lin = tstrlen(TC_ia);
|
---|
1098 | }
|
---|
1099 |
|
---|
1100 | tvc_ld = 0; /* Usual case */
|
---|
1101 | tvc_ldn = tstrlen(TC_dl);
|
---|
1102 | if(TC_DL) /* If have multi-DL, use it */
|
---|
1103 | { tvc_ld = tstrlp(TC_DL, 1);
|
---|
1104 | tvc_ldn = tstrlp(TC_DL, 2) - tvc_ld;
|
---|
1105 | }
|
---|
1106 | else if(TC_id)
|
---|
1107 | { tvc_ld = tstrlen(TC_dm)+tstrlen(TC_ed);
|
---|
1108 | tvc_ldn = tstrlen(TC_id);
|
---|
1109 | }
|
---|
1110 | }
|
---|
1111 |
|
---|
1112 | if (tc_am)
|
---|
1113 | { scr_wid--; /* For now, avoid invoking wrap. */
|
---|
1114 | #if 0
|
---|
1115 | trm_flags |= AUTOWRAP; /* */
|
---|
1116 | #endif
|
---|
1117 | }
|
---|
1118 | if (TC_ce) trm_flags |= TF_CLEOL; /* Term has CLEOL? */
|
---|
1119 | if (tc_km) trm_flags |= TF_METAKEY; /* Term has meta key? */
|
---|
1120 |
|
---|
1121 | return(1);
|
---|
1122 | }
|
---|
1123 |
|
---|
1124 | /* Pair of routines which conspire in order to find # chars actually output
|
---|
1125 | * by a particular termcap string.
|
---|
1126 | */
|
---|
1127 | static int _tslen; /* Stored count */
|
---|
1128 | static void _tslinc(ch) { _tslen++; }
|
---|
1129 | static int
|
---|
1130 | tstrlen(str)
|
---|
1131 | char *str;
|
---|
1132 | { _tslen = 0;
|
---|
1133 | if(str && str[0])
|
---|
1134 | tputs(str, 1, _tslinc); /* Mult padding by just 1 */
|
---|
1135 | return(_tslen);
|
---|
1136 | }
|
---|
1137 |
|
---|
1138 | static int
|
---|
1139 | tstrlp(str, par) /* Same but with parameter */
|
---|
1140 | char *str;
|
---|
1141 | int par;
|
---|
1142 | {
|
---|
1143 | #if 0
|
---|
1144 | if(str)
|
---|
1145 | { char *cp = tgoto(str, 0, par);
|
---|
1146 | int i = strlen(cp);
|
---|
1147 | while(--i >= 0)
|
---|
1148 | printf(" %o", *cp++);
|
---|
1149 | printf("\n");
|
---|
1150 | }
|
---|
1151 | #endif
|
---|
1152 | return !str ? 0 : tstrlen(tgoto(str, 0, par));
|
---|
1153 | }
|
---|
1154 | #endif /*TX_TERMCAP*/
|
---|
1155 | |
---|
1156 |
|
---|
1157 | /* Direct-Video terminal output routine
|
---|
1158 | * Currently only COHERENT has this capability.
|
---|
1159 | */
|
---|
1160 |
|
---|
1161 | #if COHERENT
|
---|
1162 | #include <sgtty.h>
|
---|
1163 |
|
---|
1164 | struct vidctl {
|
---|
1165 | int v_position; /* Position in video memory */
|
---|
1166 | int v_count; /* Number of characters to transfer */
|
---|
1167 | char *v_buffer; /* Character buffer to read/write */
|
---|
1168 | };
|
---|
1169 | /*
|
---|
1170 | * Attribute masks for TIOVPUTB - attributes occupy odd addresses
|
---|
1171 | * in video memory.
|
---|
1172 | */
|
---|
1173 | #define VNORM 0x07 /* Ordinary Video */
|
---|
1174 | #define VINTE 0x08 /* Intense video */
|
---|
1175 | #define VBLIN 0x80 /* Blinking video */
|
---|
1176 | #define VREVE 0x70 /* Reverse video */
|
---|
1177 | #define VUNDE 0x01 /* Underline video (mono board) */
|
---|
1178 |
|
---|
1179 | /* T_DIRECT(line, col, string, len) - Do direct-video output of string.
|
---|
1180 | * Puts the string ("len" chars in length) on the screen starting at
|
---|
1181 | * the X,Y character position given by col, line.
|
---|
1182 | * This routine is only called if terminal has the "TF_DIRVID" flag set.
|
---|
1183 | */
|
---|
1184 | t_direct(lin, col, str, len)
|
---|
1185 | int lin, col;
|
---|
1186 | register char *str;
|
---|
1187 | register int len;
|
---|
1188 | { register char *cp;
|
---|
1189 | char vbuf[MAXLINE*2];
|
---|
1190 | struct vidctl v;
|
---|
1191 |
|
---|
1192 | if(len <= 0) return;
|
---|
1193 | tbufls(); /* Ensure normal output is forced out */
|
---|
1194 | v.v_position = (lin*80 + col)*2;
|
---|
1195 | v.v_count = len*2;
|
---|
1196 | v.v_buffer = cp = vbuf;
|
---|
1197 | do {
|
---|
1198 | *cp++ = *str++;
|
---|
1199 | *cp++ = VNORM;
|
---|
1200 | } while(--len);
|
---|
1201 | ioctl(1, TIOVPUTB, &v);
|
---|
1202 | }
|
---|
1203 | #endif /*COHERENT*/
|
---|
1204 | |
---|
1205 |
|
---|
1206 | /*
|
---|
1207 | * Terminal Output buffering routines
|
---|
1208 | */
|
---|
1209 |
|
---|
1210 | static char tbuf[TOBFSIZ]; /* Output buffer */
|
---|
1211 | static int tbufcnt = 0; /* # chars of room left in buffer */
|
---|
1212 | static char *tbufp = 0; /* Pointer to deposit in buffer */
|
---|
1213 |
|
---|
1214 | tput(ch)
|
---|
1215 | int ch;
|
---|
1216 | { if(--tbufcnt < 0)
|
---|
1217 | tbufls();
|
---|
1218 | *tbufp++ = ch;
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 | tputz(str)
|
---|
1222 | char *str;
|
---|
1223 | { register int c;
|
---|
1224 | register char *cp, *tp;
|
---|
1225 | cp = str;
|
---|
1226 | tp = tbufp;
|
---|
1227 | while(c = *cp++)
|
---|
1228 | { if(--tbufcnt < 0)
|
---|
1229 | { tbufp = tp;
|
---|
1230 | tbufls();
|
---|
1231 | tp = tbufp;
|
---|
1232 | }
|
---|
1233 | *tp++ = c;
|
---|
1234 | }
|
---|
1235 | tbufp = tp;
|
---|
1236 | }
|
---|
1237 |
|
---|
1238 | tputn(str,cnt)
|
---|
1239 | char *str;
|
---|
1240 | int cnt;
|
---|
1241 | { register int c;
|
---|
1242 | register char *cp, *tp;
|
---|
1243 | cp = str;
|
---|
1244 | tp = tbufp;
|
---|
1245 | if((c = cnt) > 0)
|
---|
1246 | do {
|
---|
1247 | if(--tbufcnt < 0)
|
---|
1248 | {
|
---|
1249 | tbufp = tp;
|
---|
1250 | tbufls();
|
---|
1251 | tp = tbufp;
|
---|
1252 | }
|
---|
1253 | *tp++ = *cp++;
|
---|
1254 | } while(--c);
|
---|
1255 | tbufp = tp;
|
---|
1256 | }
|
---|
1257 |
|
---|
1258 | tbufls()
|
---|
1259 | { register int cnt;
|
---|
1260 |
|
---|
1261 | if(tbufp
|
---|
1262 | && (cnt = tbufp - tbuf) > 0) /* # chars written */
|
---|
1263 | write(1, tbuf, cnt); /* Out they go */
|
---|
1264 | tbufp = tbuf;
|
---|
1265 | tbufcnt = TOBFSIZ-1; /* Allow for usual expected decrement */
|
---|
1266 | }
|
---|
1267 | |
---|
1268 |
|
---|
1269 | /*
|
---|
1270 | * Terminal Input buffering routines
|
---|
1271 | */
|
---|
1272 |
|
---|
1273 | int tibfmsk = -1; /* Mask AND'ed with input chars (external) */
|
---|
1274 | static char tibuf[TIBFSIZ]; /* TTY input buffer */
|
---|
1275 | static char *tibfp; /* Pointer to read from buffer */
|
---|
1276 | static int tibfcnt = 0; /* # chars left to be read from buffer */
|
---|
1277 |
|
---|
1278 | tgetc()
|
---|
1279 | {
|
---|
1280 | #if SUN
|
---|
1281 | register int c;
|
---|
1282 | extern int sun_winfd, sun_rdevf;
|
---|
1283 |
|
---|
1284 | if(sun_winfd)
|
---|
1285 | { if(!sun_rdevf)
|
---|
1286 | return(sun_input(1)&tibfmsk);
|
---|
1287 | sun_rdevf = 0; /* Check mouse too, but only once! */
|
---|
1288 | c = sun_input(0);
|
---|
1289 | if(c != -1) c &= tibfmsk;
|
---|
1290 | return(c);
|
---|
1291 | }
|
---|
1292 | #endif /*SUN*/
|
---|
1293 | while(--tibfcnt < 0)
|
---|
1294 | tibfcnt = read(0,(tibfp = tibuf),TIBFSIZ);
|
---|
1295 | return((*tibfp++)&tibfmsk);
|
---|
1296 | }
|
---|
1297 |
|
---|
1298 | tinwait()
|
---|
1299 | { return(tibfcnt > 0 || ts_inp());
|
---|
1300 | }
|
---|