1 | /* curses.c */
|
---|
2 |
|
---|
3 | /* Author:
|
---|
4 | * Steve Kirkendall
|
---|
5 | * 14407 SW Teal Blvd. #C
|
---|
6 | * Beaverton, OR 97005
|
---|
7 | * kirkenda@cs.pdx.edu
|
---|
8 | */
|
---|
9 |
|
---|
10 |
|
---|
11 | /* This file contains the functions & variables needed for a tiny subset of
|
---|
12 | * curses. The principle advantage of this version of curses is its
|
---|
13 | * extreme speed. Disadvantages are potentially larger code, few supported
|
---|
14 | * functions, limited compatibility with full curses, and only stdscr.
|
---|
15 | */
|
---|
16 |
|
---|
17 | #include "config.h"
|
---|
18 | #include "vi.h"
|
---|
19 |
|
---|
20 | #if ANY_UNIX
|
---|
21 | /* The termios/termio/sgtty #ifdefs were a mess, so I removed all but termios.
|
---|
22 | * (KJB)
|
---|
23 | */
|
---|
24 | # include <termios.h>
|
---|
25 | # if MINIX
|
---|
26 | # include <sys/ioctl.h>
|
---|
27 | # endif
|
---|
28 | #endif
|
---|
29 |
|
---|
30 | #if TOS
|
---|
31 | # include <osbind.h>
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #if OSK
|
---|
35 | # include <sgstat.h>
|
---|
36 | #endif
|
---|
37 |
|
---|
38 | #if VMS
|
---|
39 | extern int VMS_read_raw; /* Set in initscr() */
|
---|
40 | #endif
|
---|
41 |
|
---|
42 |
|
---|
43 | extern char *getenv();
|
---|
44 | static void starttcap();
|
---|
45 |
|
---|
46 | /* variables, publicly available & used in the macros */
|
---|
47 | char *termtype; /* name of terminal entry */
|
---|
48 | short ospeed; /* speed of the tty, eg B2400 */
|
---|
49 | #if OSK
|
---|
50 | char PC_; /* Pad char */
|
---|
51 | char *BC; /* backspace character string */
|
---|
52 | #else
|
---|
53 | char PC; /* Pad char */
|
---|
54 | #endif
|
---|
55 | WINDOW *stdscr; /* pointer into kbuf[] */
|
---|
56 | WINDOW kbuf[KBSIZ]; /* a very large output buffer */
|
---|
57 | int LINES; /* :li#: number of rows */
|
---|
58 | int COLS; /* :co#: number of columns */
|
---|
59 | int AM; /* :am: boolean: auto margins? */
|
---|
60 | int PT; /* :pt: boolean: physical tabs? */
|
---|
61 | char *VB; /* :vb=: visible bell */
|
---|
62 | char *UP; /* :up=: move cursor up */
|
---|
63 | char *SO = ""; /* :so=: standout start */
|
---|
64 | char *SE = ""; /* :se=: standout end */
|
---|
65 | char *US = ""; /* :us=: underline start */
|
---|
66 | char *UE = ""; /* :ue=: underline end */
|
---|
67 | char *MD = ""; /* :md=: bold start */
|
---|
68 | char *ME = ""; /* :me=: bold end */
|
---|
69 | char *AS = ""; /* :as=: alternate (italic) start */
|
---|
70 | char *AE = ""; /* :ae=: alternate (italic) end */
|
---|
71 | #ifndef NO_VISIBLE
|
---|
72 | char *MV; /* :mv=: "visible" selection start */
|
---|
73 | #endif
|
---|
74 | char *CM; /* :cm=: cursor movement */
|
---|
75 | char *CE; /* :ce=: clear to end of line */
|
---|
76 | char *CD; /* :cd=: clear to end of screen */
|
---|
77 | char *AL; /* :al=: add a line */
|
---|
78 | char *DL; /* :dl=: delete a line */
|
---|
79 | #if OSK
|
---|
80 | char *SR_; /* :sr=: scroll reverse */
|
---|
81 | #else
|
---|
82 | char *SR; /* :sr=: scroll reverse */
|
---|
83 | #endif
|
---|
84 | char *KS = ""; /* :ks=: init string for cursor */
|
---|
85 | char *KE = ""; /* :ke=: restore string for cursor */
|
---|
86 | char *KU; /* :ku=: key sequence sent by up arrow */
|
---|
87 | char *KD; /* :kd=: key sequence sent by down arrow */
|
---|
88 | char *KL; /* :kl=: key sequence sent by left arrow */
|
---|
89 | char *KR; /* :kr=: key sequence sent by right arrow */
|
---|
90 | char *HM; /* :HM=: key sequence sent by the <Home> key */
|
---|
91 | char *EN; /* :EN=: key sequence sent by the <End> key */
|
---|
92 | char *PU; /* :PU=: key sequence sent by the <PgUp> key */
|
---|
93 | char *PD; /* :PD=: key sequence sent by the <PgDn> key */
|
---|
94 | char *KI; /* :kI=: key sequence sent by the <Insert> key */
|
---|
95 | #ifndef NO_FKEY
|
---|
96 | char *FKEY[NFKEYS]; /* :k0=: ... :k9=: sequences sent by function keys */
|
---|
97 | #endif
|
---|
98 | char *IM = ""; /* :im=: insert mode start */
|
---|
99 | char *IC = ""; /* :ic=: insert the following character */
|
---|
100 | char *EI = ""; /* :ei=: insert mode end */
|
---|
101 | char *DC; /* :dc=: delete a character */
|
---|
102 | char *TI = ""; /* :ti=: terminal init */ /* GB */
|
---|
103 | char *TE = ""; /* :te=: terminal exit */ /* GB */
|
---|
104 | #ifndef NO_CURSORSHAPE
|
---|
105 | #if 1
|
---|
106 | char *CQ = (char *)0;/* :cQ=: normal cursor */
|
---|
107 | char *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
|
---|
108 | char *CV = (char *)2;/* :cV=: cursor used for VI command mode */
|
---|
109 | char *CI = (char *)3;/* :cI=: cursor used for VI input mode */
|
---|
110 | char *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
|
---|
111 | #else
|
---|
112 | char *CQ = ""; /* :cQ=: normal cursor */
|
---|
113 | char *CX = ""; /* :cX=: cursor used for EX command/entry */
|
---|
114 | char *CV = ""; /* :cV=: cursor used for VI command mode */
|
---|
115 | char *CI = ""; /* :cI=: cursor used for VI input mode */
|
---|
116 | char *CR = ""; /* :cR=: cursor used for VI replace mode */
|
---|
117 | #endif
|
---|
118 | #endif
|
---|
119 | char *aend = ""; /* end an attribute -- either UE or ME */
|
---|
120 | char ERASEKEY; /* backspace key taken from ioctl structure */
|
---|
121 | #ifndef NO_COLOR
|
---|
122 | char normalcolor[16];
|
---|
123 | char SOcolor[16];
|
---|
124 | char SEcolor[16];
|
---|
125 | char UScolor[16];
|
---|
126 | char UEcolor[16];
|
---|
127 | char MDcolor[16];
|
---|
128 | char MEcolor[16];
|
---|
129 | char AScolor[16];
|
---|
130 | char AEcolor[16];
|
---|
131 | # ifndef NO_POPUP
|
---|
132 | char POPUPcolor[16];
|
---|
133 | # endif
|
---|
134 | # ifndef NO_VISIBLE
|
---|
135 | char VISIBLEcolor[16];
|
---|
136 | # endif
|
---|
137 | #endif
|
---|
138 |
|
---|
139 | #if ANY_UNIX
|
---|
140 | static struct termios oldtermio; /* original tty mode */
|
---|
141 | static struct termios newtermio; /* cbreak/noecho tty mode */
|
---|
142 | #endif
|
---|
143 |
|
---|
144 | #if OSK
|
---|
145 | static struct sgbuf oldsgttyb; /* orginal tty mode */
|
---|
146 | static struct sgbuf newsgttyb; /* noecho tty mode */
|
---|
147 | #endif
|
---|
148 |
|
---|
149 | static char *capbuf; /* capability string buffer */
|
---|
150 |
|
---|
151 |
|
---|
152 | /* Initialize the Curses package. */
|
---|
153 | void initscr()
|
---|
154 | {
|
---|
155 | /* make sure TERM variable is set */
|
---|
156 | termtype = getenv("TERM");
|
---|
157 |
|
---|
158 | #if VMS
|
---|
159 | /* VMS getenv() handles TERM as a environment setting. Foreign
|
---|
160 | * terminal support can be implemented by setting the ELVIS_TERM
|
---|
161 | * logical or symbol to match a tinytcap entry.
|
---|
162 | */
|
---|
163 | if (!strcmp(termtype,"unknown"))
|
---|
164 | termtype = getenv("ELVIS_TERM");
|
---|
165 | #endif
|
---|
166 | #if MSDOS
|
---|
167 | /* For MS-DOS, if TERM is unset we can default to "pcbios", or
|
---|
168 | * maybe "rainbow".
|
---|
169 | */
|
---|
170 | if (!termtype)
|
---|
171 | {
|
---|
172 | #ifdef RAINBOW
|
---|
173 | if (*(unsigned char far*)(0xffff000eL) == 6 /* Rainbow 100a */
|
---|
174 | || *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */
|
---|
175 | {
|
---|
176 | termtype = "rainbow";
|
---|
177 | }
|
---|
178 | else
|
---|
179 | #endif
|
---|
180 | termtype = "pcbios";
|
---|
181 | }
|
---|
182 | if (!strcmp(termtype, "pcbios"))
|
---|
183 | #else
|
---|
184 | if (!termtype)
|
---|
185 | #endif
|
---|
186 | {
|
---|
187 | #if ANY_UNIX
|
---|
188 | write(2, "Environment variable TERM must be set\n", (unsigned)38);
|
---|
189 | exit(1);
|
---|
190 | #endif
|
---|
191 | #if OSK
|
---|
192 | writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
|
---|
193 | exit(1);
|
---|
194 | #endif
|
---|
195 | #if AMIGA
|
---|
196 | termtype = TERMTYPE;
|
---|
197 | starttcap(termtype);
|
---|
198 | #endif
|
---|
199 | #if MSDOS
|
---|
200 | starttcap("pcbios");
|
---|
201 | #endif
|
---|
202 | #if TOS
|
---|
203 | termtype = "vt52";
|
---|
204 | starttcap(termtype);
|
---|
205 | #endif
|
---|
206 | #if VMS
|
---|
207 | write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
|
---|
208 | exit(1);
|
---|
209 | #endif
|
---|
210 | }
|
---|
211 | else
|
---|
212 | {
|
---|
213 | #if MSDOS
|
---|
214 | *o_pcbios = 0;
|
---|
215 | #endif
|
---|
216 | /* start termcap stuff */
|
---|
217 | starttcap(termtype);
|
---|
218 | }
|
---|
219 |
|
---|
220 | /* create stdscr and curscr */
|
---|
221 | stdscr = kbuf;
|
---|
222 |
|
---|
223 | /* change the terminal mode to cbreak/noecho */
|
---|
224 | #if ANY_UNIX
|
---|
225 | tcgetattr(2, &oldtermio);
|
---|
226 | #endif
|
---|
227 |
|
---|
228 | #if OSK
|
---|
229 | _gs_opt(0, &oldsgttyb);
|
---|
230 | #endif
|
---|
231 |
|
---|
232 | #if VMS
|
---|
233 | VMS_read_raw = 1; /* cbreak/noecho */
|
---|
234 | vms_open_tty();
|
---|
235 | #endif
|
---|
236 | resume_curses(TRUE);
|
---|
237 | }
|
---|
238 |
|
---|
239 | /* Shut down the Curses package. */
|
---|
240 | void endwin()
|
---|
241 | {
|
---|
242 | /* change the terminal mode back the way it was */
|
---|
243 | suspend_curses();
|
---|
244 | #if AMIGA
|
---|
245 | amiclosewin();
|
---|
246 | #endif
|
---|
247 | }
|
---|
248 |
|
---|
249 |
|
---|
250 | static int curses_active = FALSE;
|
---|
251 |
|
---|
252 | /* Send any required termination strings. Turn off "raw" mode. */
|
---|
253 | void suspend_curses()
|
---|
254 | {
|
---|
255 | #ifndef NO_CURSORSHAPE
|
---|
256 | if (has_CQ)
|
---|
257 | {
|
---|
258 | do_CQ();
|
---|
259 | }
|
---|
260 | #endif
|
---|
261 | if (has_TE) /* GB */
|
---|
262 | {
|
---|
263 | do_TE();
|
---|
264 | }
|
---|
265 | if (has_KE)
|
---|
266 | {
|
---|
267 | do_KE();
|
---|
268 | }
|
---|
269 | #ifndef NO_COLOR
|
---|
270 | quitcolor();
|
---|
271 | #endif
|
---|
272 | refresh();
|
---|
273 |
|
---|
274 | /* change the terminal mode back the way it was */
|
---|
275 | #if ANY_UNIX
|
---|
276 | tcsetattr(2, TCSADRAIN, &oldtermio);
|
---|
277 | #endif
|
---|
278 | #if OSK
|
---|
279 | _ss_opt(0, &oldsgttyb);
|
---|
280 | #endif
|
---|
281 | #if AMIGA
|
---|
282 | ttyshutdown();
|
---|
283 | #endif
|
---|
284 | #if MSDOS
|
---|
285 | raw_set_stdio(FALSE);
|
---|
286 | #endif
|
---|
287 |
|
---|
288 | #if VMS
|
---|
289 | VMS_read_raw = 0;
|
---|
290 | #endif
|
---|
291 | curses_active = FALSE;
|
---|
292 | }
|
---|
293 |
|
---|
294 |
|
---|
295 | /* put the terminal in RAW mode. If "quietly" is FALSE, then ask the user
|
---|
296 | * to hit a key, and wait for keystroke before returning.
|
---|
297 | */
|
---|
298 | void resume_curses(quietly)
|
---|
299 | int quietly;
|
---|
300 | {
|
---|
301 | if (!curses_active)
|
---|
302 | {
|
---|
303 | /* change the terminal mode to cbreak/noecho */
|
---|
304 | #if ANY_UNIX
|
---|
305 | ospeed = cfgetospeed(&oldtermio);
|
---|
306 | ERASEKEY = oldtermio.c_cc[VERASE];
|
---|
307 | newtermio = oldtermio;
|
---|
308 | newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK);
|
---|
309 | newtermio.c_oflag &= ~OPOST;
|
---|
310 | newtermio.c_lflag &= ISIG;
|
---|
311 | newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */
|
---|
312 | newtermio.c_cc[VMIN] = 1;
|
---|
313 | newtermio.c_cc[VTIME] = 0;
|
---|
314 | newtermio.c_cc[VSUSP] = 0;
|
---|
315 | tcsetattr(2, TCSADRAIN, &newtermio);
|
---|
316 | #endif
|
---|
317 | #if OSK
|
---|
318 | newsgttyb = oldsgttyb;
|
---|
319 | newsgttyb.sg_echo = 0;
|
---|
320 | newsgttyb.sg_eofch = 0;
|
---|
321 | newsgttyb.sg_kbach = 0;
|
---|
322 | newsgttyb.sg_kbich = ctrl('C');
|
---|
323 | _ss_opt(0, &newsgttyb);
|
---|
324 | ospeed = oldsgttyb.sg_baud;
|
---|
325 | ERASEKEY = oldsgttyb.sg_bspch;
|
---|
326 | #endif
|
---|
327 | #if AMIGA
|
---|
328 | /* turn on window resize and RAW */
|
---|
329 | ttysetup();
|
---|
330 | #endif
|
---|
331 | #if MSDOS
|
---|
332 | raw_set_stdio(TRUE);
|
---|
333 | #endif
|
---|
334 |
|
---|
335 | #if VMS
|
---|
336 | VMS_read_raw = 1;
|
---|
337 | { int c;
|
---|
338 | read(0,&c,0); /* Flush the tty buffer. */
|
---|
339 | }
|
---|
340 | ERASEKEY = '\177'; /* Accept <DEL> as <^H> for VMS */
|
---|
341 | #endif
|
---|
342 |
|
---|
343 | if (has_TI) /* GB */
|
---|
344 | {
|
---|
345 | do_TI();
|
---|
346 | }
|
---|
347 | if (has_KS)
|
---|
348 | {
|
---|
349 | do_KS();
|
---|
350 | }
|
---|
351 |
|
---|
352 | curses_active = TRUE;
|
---|
353 | }
|
---|
354 |
|
---|
355 | /* If we're supposed to quit quietly, then we're done */
|
---|
356 | if (quietly)
|
---|
357 | {
|
---|
358 | return;
|
---|
359 | }
|
---|
360 |
|
---|
361 | signal(SIGINT, SIG_IGN);
|
---|
362 |
|
---|
363 | move(LINES - 1, 0);
|
---|
364 | do_SO();
|
---|
365 | #if VMS
|
---|
366 | qaddstr("\n[Press <RETURN> to continue]");
|
---|
367 | #else
|
---|
368 | qaddstr("[Press <RETURN> to continue]");
|
---|
369 | #endif
|
---|
370 | do_SE();
|
---|
371 | refresh();
|
---|
372 | ttyread(kbuf, 20, 0); /* in RAW mode, so <20 is very likely */
|
---|
373 | if (kbuf[0] == ':')
|
---|
374 | {
|
---|
375 | mode = MODE_COLON;
|
---|
376 | addch('\n');
|
---|
377 | refresh();
|
---|
378 | }
|
---|
379 | else
|
---|
380 | {
|
---|
381 | mode = MODE_VI;
|
---|
382 | redraw(MARK_UNSET, FALSE);
|
---|
383 | }
|
---|
384 | exwrote = FALSE;
|
---|
385 |
|
---|
386 | #if TURBOC || __GNUC__ || _ANSI
|
---|
387 | signal(SIGINT, (void(*)()) trapint);
|
---|
388 | #else
|
---|
389 | signal(SIGINT, trapint);
|
---|
390 | #endif
|
---|
391 | }
|
---|
392 |
|
---|
393 | /* This function fetches an optional string from termcap */
|
---|
394 | static void mayhave(T, s)
|
---|
395 | char **T; /* where to store the returned pointer */
|
---|
396 | char *s; /* name of the capability */
|
---|
397 | {
|
---|
398 | char *val;
|
---|
399 |
|
---|
400 | val = tgetstr(s, &capbuf);
|
---|
401 | if (val)
|
---|
402 | {
|
---|
403 | *T = val;
|
---|
404 | }
|
---|
405 | }
|
---|
406 |
|
---|
407 |
|
---|
408 | /* This function fetches a required string from termcap */
|
---|
409 | static void musthave(T, s)
|
---|
410 | char **T; /* where to store the returned pointer */
|
---|
411 | char *s; /* name of the capability */
|
---|
412 | {
|
---|
413 | mayhave(T, s);
|
---|
414 | if (!*T)
|
---|
415 | {
|
---|
416 | write(2, "This termcap entry lacks the :", (unsigned)30);
|
---|
417 | write(2, s, (unsigned)2);
|
---|
418 | write(2, "=: capability\n", (unsigned)14);
|
---|
419 | #if OSK
|
---|
420 | write(2, "\l", 1);
|
---|
421 | #endif
|
---|
422 | exit(1);
|
---|
423 | }
|
---|
424 | }
|
---|
425 |
|
---|
426 |
|
---|
427 | /* This function fetches a pair of strings from termcap. If one of them is
|
---|
428 | * missing, then the other one is ignored.
|
---|
429 | */
|
---|
430 | static void pair(T, U, sT, sU)
|
---|
431 | char **T; /* where to store the first pointer */
|
---|
432 | char **U; /* where to store the second pointer */
|
---|
433 | char *sT; /* name of the first capability */
|
---|
434 | char *sU; /* name of the second capability */
|
---|
435 | {
|
---|
436 | mayhave(T, sT);
|
---|
437 | mayhave(U, sU);
|
---|
438 | if (!**T || !**U)
|
---|
439 | {
|
---|
440 | *T = *U = "";
|
---|
441 | }
|
---|
442 | }
|
---|
443 |
|
---|
444 |
|
---|
445 |
|
---|
446 | /* Read everything from termcap */
|
---|
447 | static void starttcap(term)
|
---|
448 | char *term;
|
---|
449 | {
|
---|
450 | static char cbmem[800];
|
---|
451 |
|
---|
452 | /* allocate memory for capbuf */
|
---|
453 | capbuf = cbmem;
|
---|
454 |
|
---|
455 | /* get the termcap entry */
|
---|
456 | switch (tgetent(kbuf, term))
|
---|
457 | {
|
---|
458 | case -1:
|
---|
459 | write(2, "Can't read /etc/termcap\n", (unsigned)24);
|
---|
460 | #if OSK
|
---|
461 | write(2, "\l", 1);
|
---|
462 | #endif
|
---|
463 | exit(2);
|
---|
464 |
|
---|
465 | case 0:
|
---|
466 | write(2, "Unrecognized TERM type\n", (unsigned)23);
|
---|
467 | #if OSK
|
---|
468 | write(2, "\l", 1);
|
---|
469 | #endif
|
---|
470 | exit(3);
|
---|
471 | }
|
---|
472 |
|
---|
473 | /* get strings */
|
---|
474 | musthave(&UP, "up");
|
---|
475 | mayhave(&VB, "vb");
|
---|
476 | musthave(&CM, "cm");
|
---|
477 | pair(&SO, &SE, "so", "se");
|
---|
478 | mayhave(&TI, "ti");
|
---|
479 | mayhave(&TE, "te");
|
---|
480 | if (tgetnum("ug") <= 0)
|
---|
481 | {
|
---|
482 | pair(&US, &UE, "us", "ue");
|
---|
483 | pair(&MD, &ME, "md", "me");
|
---|
484 |
|
---|
485 | /* get italics, or have it default to underline */
|
---|
486 | pair(&AS, &AE, "as", "ae");
|
---|
487 | if (!*AS)
|
---|
488 | {
|
---|
489 | AS = US;
|
---|
490 | AE = UE;
|
---|
491 | }
|
---|
492 | }
|
---|
493 | #ifndef NO_VISIBLE
|
---|
494 | MV = SO; /* by default */
|
---|
495 | mayhave(&MV, "mv");
|
---|
496 | #endif
|
---|
497 | mayhave(&AL, "al");
|
---|
498 | mayhave(&DL, "dl");
|
---|
499 | musthave(&CE, "ce");
|
---|
500 | mayhave(&CD, "cd");
|
---|
501 | #if OSK
|
---|
502 | mayhave(&SR_, "sr");
|
---|
503 | #else
|
---|
504 | mayhave(&SR, "sr");
|
---|
505 | #endif
|
---|
506 | pair(&IM, &EI, "im", "ei");
|
---|
507 | mayhave(&IC, "ic");
|
---|
508 | mayhave(&DC, "dc");
|
---|
509 |
|
---|
510 | /* other termcap stuff */
|
---|
511 | AM = (tgetflag("am") && !tgetflag("xn"));
|
---|
512 | PT = tgetflag("pt");
|
---|
513 | #if AMIGA
|
---|
514 | amiopenwin(termtype); /* Must run this before ttysetup(); */
|
---|
515 | ttysetup(); /* Must run this before getsize(0); */
|
---|
516 | #endif
|
---|
517 | getsize(0);
|
---|
518 |
|
---|
519 | /* Key sequences */
|
---|
520 | pair(&KS, &KE, "ks", "ke");
|
---|
521 | mayhave(&KU, "ku"); /* up */
|
---|
522 | mayhave(&KD, "kd"); /* down */
|
---|
523 | mayhave(&KL, "kl"); /* left */
|
---|
524 | mayhave(&KR, "kr"); /* right */
|
---|
525 | mayhave(&PU, "kP"); /* PgUp */
|
---|
526 | mayhave(&PD, "kN"); /* PgDn */
|
---|
527 | mayhave(&HM, "kh"); /* Home */
|
---|
528 | mayhave(&EN, "kH"); /* End */
|
---|
529 | mayhave(&KI, "kI"); /* Insert */
|
---|
530 | #ifndef CRUNCH
|
---|
531 | if (!PU) mayhave(&PU, "K2"); /* "3x3 pad" names for PgUp, etc. */
|
---|
532 | if (!PD) mayhave(&PD, "K5");
|
---|
533 | if (!HM) mayhave(&HM, "K1");
|
---|
534 | if (!EN) mayhave(&EN, "K4");
|
---|
535 |
|
---|
536 | mayhave(&PU, "PU"); /* old XENIX names for PgUp, etc. */
|
---|
537 | mayhave(&PD, "PD"); /* (overrides others, if used.) */
|
---|
538 | mayhave(&HM, "HM");
|
---|
539 | mayhave(&EN, "EN");
|
---|
540 | #endif
|
---|
541 | #ifndef NO_FKEY
|
---|
542 | mayhave(&FKEY[0], "k0"); /* function key codes */
|
---|
543 | mayhave(&FKEY[1], "k1");
|
---|
544 | mayhave(&FKEY[2], "k2");
|
---|
545 | mayhave(&FKEY[3], "k3");
|
---|
546 | mayhave(&FKEY[4], "k4");
|
---|
547 | mayhave(&FKEY[5], "k5");
|
---|
548 | mayhave(&FKEY[6], "k6");
|
---|
549 | mayhave(&FKEY[7], "k7");
|
---|
550 | mayhave(&FKEY[8], "k8");
|
---|
551 | mayhave(&FKEY[9], "k9");
|
---|
552 | # ifndef NO_SHIFT_FKEY
|
---|
553 | mayhave(&FKEY[10], "s0"); /* shift function key codes */
|
---|
554 | mayhave(&FKEY[11], "s1");
|
---|
555 | mayhave(&FKEY[12], "s2");
|
---|
556 | mayhave(&FKEY[13], "s3");
|
---|
557 | mayhave(&FKEY[14], "s4");
|
---|
558 | mayhave(&FKEY[15], "s5");
|
---|
559 | mayhave(&FKEY[16], "s6");
|
---|
560 | mayhave(&FKEY[17], "s7");
|
---|
561 | mayhave(&FKEY[18], "s8");
|
---|
562 | mayhave(&FKEY[19], "s9");
|
---|
563 | # ifndef NO_CTRL_FKEY
|
---|
564 | mayhave(&FKEY[20], "c0"); /* control function key codes */
|
---|
565 | mayhave(&FKEY[21], "c1");
|
---|
566 | mayhave(&FKEY[22], "c2");
|
---|
567 | mayhave(&FKEY[23], "c3");
|
---|
568 | mayhave(&FKEY[24], "c4");
|
---|
569 | mayhave(&FKEY[25], "c5");
|
---|
570 | mayhave(&FKEY[26], "c6");
|
---|
571 | mayhave(&FKEY[27], "c7");
|
---|
572 | mayhave(&FKEY[28], "c8");
|
---|
573 | mayhave(&FKEY[29], "c9");
|
---|
574 | # ifndef NO_ALT_FKEY
|
---|
575 | mayhave(&FKEY[30], "a0"); /* alt function key codes */
|
---|
576 | mayhave(&FKEY[31], "a1");
|
---|
577 | mayhave(&FKEY[32], "a2");
|
---|
578 | mayhave(&FKEY[33], "a3");
|
---|
579 | mayhave(&FKEY[34], "a4");
|
---|
580 | mayhave(&FKEY[35], "a5");
|
---|
581 | mayhave(&FKEY[36], "a6");
|
---|
582 | mayhave(&FKEY[37], "a7");
|
---|
583 | mayhave(&FKEY[38], "a8");
|
---|
584 | mayhave(&FKEY[39], "a9");
|
---|
585 | # endif
|
---|
586 | # endif
|
---|
587 | # endif
|
---|
588 | #endif
|
---|
589 |
|
---|
590 | #ifndef NO_CURSORSHAPE
|
---|
591 | /* cursor shapes */
|
---|
592 | CQ = tgetstr("cQ", &capbuf);
|
---|
593 | if (has_CQ)
|
---|
594 | {
|
---|
595 | CX = tgetstr("cX", &capbuf);
|
---|
596 | if (!CX) CX = CQ;
|
---|
597 | CV = tgetstr("cV", &capbuf);
|
---|
598 | if (!CV) CV = CQ;
|
---|
599 | CI = tgetstr("cI", &capbuf);
|
---|
600 | if (!CI) CI = CQ;
|
---|
601 | CR = tgetstr("cR", &capbuf);
|
---|
602 | if (!CR) CR = CQ;
|
---|
603 | }
|
---|
604 | # ifndef CRUNCH
|
---|
605 | else
|
---|
606 | {
|
---|
607 | CQ = CV = "";
|
---|
608 | pair(&CQ, &CV, "ve", "vs");
|
---|
609 | CX = CI = CR = CQ;
|
---|
610 | }
|
---|
611 | # endif /* !CRUNCH */
|
---|
612 | #endif /* !NO_CURSORSHAPE */
|
---|
613 |
|
---|
614 | #ifndef NO_COLOR
|
---|
615 | strcpy(SOcolor, SO);
|
---|
616 | strcpy(SEcolor, SE);
|
---|
617 | strcpy(AScolor, AS);
|
---|
618 | strcpy(AEcolor, AE);
|
---|
619 | strcpy(MDcolor, MD);
|
---|
620 | strcpy(MEcolor, ME);
|
---|
621 | strcpy(UScolor, US);
|
---|
622 | strcpy(UEcolor, UE);
|
---|
623 | # ifndef NO_POPUP
|
---|
624 | strcpy(POPUPcolor, SO);
|
---|
625 | # endif
|
---|
626 | # ifndef NO_VISIBLE
|
---|
627 | strcpy(VISIBLEcolor, MV);
|
---|
628 | # endif
|
---|
629 | #endif
|
---|
630 |
|
---|
631 | }
|
---|
632 |
|
---|
633 |
|
---|
634 | /* This function gets the window size. It uses the TIOCGWINSZ ioctl call if
|
---|
635 | * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't.
|
---|
636 | * This function is called once during initialization, and thereafter it is
|
---|
637 | * called whenever the SIGWINCH signal is sent to this process.
|
---|
638 | */
|
---|
639 | int getsize(signo)
|
---|
640 | int signo;
|
---|
641 | {
|
---|
642 | int lines;
|
---|
643 | int cols;
|
---|
644 | #ifdef TIOCGWINSZ
|
---|
645 | struct winsize size;
|
---|
646 | #endif
|
---|
647 |
|
---|
648 | #ifdef SIGWINCH
|
---|
649 | /* reset the signal vector */
|
---|
650 | signal(SIGWINCH, getsize);
|
---|
651 | #endif
|
---|
652 |
|
---|
653 | /* get the window size, one way or another. */
|
---|
654 | lines = cols = 0;
|
---|
655 | #ifdef TIOCGWINSZ
|
---|
656 | if (ioctl(2, TIOCGWINSZ, &size) >= 0)
|
---|
657 | {
|
---|
658 | lines = size.ws_row;
|
---|
659 | cols = size.ws_col;
|
---|
660 | }
|
---|
661 | #endif
|
---|
662 | #if AMIGA
|
---|
663 | /* Amiga gets window size by asking the console.device */
|
---|
664 | if (!strcmp(TERMTYPE, termtype))
|
---|
665 | {
|
---|
666 | auto long len;
|
---|
667 | auto char buf[30];
|
---|
668 |
|
---|
669 | Write(Output(), "\2330 q", 4); /* Ask the console.device */
|
---|
670 | len = Read(Input(), buf, 29);
|
---|
671 | buf[len] = '\000';
|
---|
672 | sscanf(&buf[5], "%d;%d", &lines, &cols);
|
---|
673 | }
|
---|
674 | #endif
|
---|
675 | if ((lines == 0 || cols == 0) && signo == 0)
|
---|
676 | {
|
---|
677 | LINES = tgetnum("li");
|
---|
678 | COLS = tgetnum("co");
|
---|
679 | }
|
---|
680 | #if MSDOS
|
---|
681 | # ifdef RAINBOW
|
---|
682 | if (!strcmp(termtype, "rainbow"))
|
---|
683 | {
|
---|
684 | /* Determine whether Rainbow is in 80-column or 132-column mode */
|
---|
685 | cols = *(unsigned char far *)0xee000f57L;
|
---|
686 | }
|
---|
687 | else
|
---|
688 | # endif
|
---|
689 | {
|
---|
690 | lines = v_rows();
|
---|
691 | cols = v_cols();
|
---|
692 | }
|
---|
693 | #endif
|
---|
694 | if (lines >= 2)
|
---|
695 | {
|
---|
696 | LINES = lines;
|
---|
697 | }
|
---|
698 |
|
---|
699 | if (cols >= 30)
|
---|
700 | {
|
---|
701 | COLS = cols;
|
---|
702 | }
|
---|
703 |
|
---|
704 | /* Make sure we got values that we can live with */
|
---|
705 | if (LINES < 2 || COLS < 30)
|
---|
706 | {
|
---|
707 | write(2, "Screen too small\n", (unsigned)17);
|
---|
708 | #if OSK
|
---|
709 | write(2, "\l", 1);
|
---|
710 | #endif
|
---|
711 | endwin();
|
---|
712 | exit(2);
|
---|
713 | }
|
---|
714 |
|
---|
715 | #if AMIGA
|
---|
716 | if (*o_lines != LINES || *o_columns != COLS)
|
---|
717 | {
|
---|
718 | *o_lines = LINES;
|
---|
719 | *o_columns = COLS;
|
---|
720 | }
|
---|
721 | #endif
|
---|
722 |
|
---|
723 | return 0;
|
---|
724 | }
|
---|
725 |
|
---|
726 |
|
---|
727 | /* This is a function version of addch() -- it is used by tputs() */
|
---|
728 | int faddch(ch)
|
---|
729 | int ch;
|
---|
730 | {
|
---|
731 | addch(ch);
|
---|
732 |
|
---|
733 | return 0;
|
---|
734 | }
|
---|
735 |
|
---|
736 | /* This function quickly adds a string to the output queue. It does *NOT*
|
---|
737 | * convert \n into <CR><LF>.
|
---|
738 | */
|
---|
739 | void qaddstr(str)
|
---|
740 | char *str;
|
---|
741 | {
|
---|
742 | REG char *s_, *d_;
|
---|
743 |
|
---|
744 | #if MSDOS
|
---|
745 | if (o_pcbios[0])
|
---|
746 | {
|
---|
747 | while (*str)
|
---|
748 | qaddch(*str++);
|
---|
749 | return;
|
---|
750 | }
|
---|
751 | #endif
|
---|
752 | for (s_=(str), d_=stdscr; *d_++ = *s_++; )
|
---|
753 | {
|
---|
754 | }
|
---|
755 | stdscr = d_ - 1;
|
---|
756 | }
|
---|
757 |
|
---|
758 | /* Output the ESC sequence needed to go into any video mode, if supported */
|
---|
759 | void attrset(a)
|
---|
760 | int a;
|
---|
761 | {
|
---|
762 | do_aend();
|
---|
763 | if (a == A_BOLD)
|
---|
764 | {
|
---|
765 | do_MD();
|
---|
766 | aend = ME;
|
---|
767 | }
|
---|
768 | else if (a == A_UNDERLINE)
|
---|
769 | {
|
---|
770 | do_US();
|
---|
771 | aend = UE;
|
---|
772 | }
|
---|
773 | else if (a == A_ALTCHARSET)
|
---|
774 | {
|
---|
775 | do_AS();
|
---|
776 | aend = AE;
|
---|
777 | }
|
---|
778 | else
|
---|
779 | {
|
---|
780 | aend = "";
|
---|
781 | }
|
---|
782 | }
|
---|
783 |
|
---|
784 |
|
---|
785 | /* Insert a single character into the display */
|
---|
786 | void insch(ch)
|
---|
787 | int ch;
|
---|
788 | {
|
---|
789 | if (has_IM)
|
---|
790 | do_IM();
|
---|
791 | do_IC();
|
---|
792 | qaddch(ch);
|
---|
793 | if (has_EI)
|
---|
794 | do_EI();
|
---|
795 | }
|
---|
796 |
|
---|
797 | void wrefresh()
|
---|
798 | {
|
---|
799 | if (stdscr != kbuf)
|
---|
800 | {
|
---|
801 | VOIDBIOS(;,ttywrite(kbuf, (unsigned)(stdscr - kbuf)));
|
---|
802 | stdscr = kbuf;
|
---|
803 | }
|
---|
804 | }
|
---|
805 |
|
---|
806 | void wqrefresh()
|
---|
807 | {
|
---|
808 | if (stdscr - kbuf > 2000)
|
---|
809 | {
|
---|
810 | VOIDBIOS(stdscr = kbuf,
|
---|
811 | {
|
---|
812 | ttywrite(kbuf, (unsigned)(stdscr - kbuf));
|
---|
813 | stdscr = kbuf;
|
---|
814 | });
|
---|
815 | }
|
---|
816 | }
|
---|
817 |
|
---|
818 | #ifndef NO_COLOR
|
---|
819 | /* This function is called during termination. It resets color modes */
|
---|
820 | int ansiquit()
|
---|
821 | {
|
---|
822 | /* if ANSI color terminal, then reset the colors */
|
---|
823 | if (!strcmp(UP, "\033[A"))
|
---|
824 | {
|
---|
825 | tputs("\033[37;40m\033[m", 1, faddch);
|
---|
826 | clrtoeol();
|
---|
827 | return 1;
|
---|
828 | }
|
---|
829 | return 0;
|
---|
830 | }
|
---|
831 |
|
---|
832 | /* This sets the color strings that work for ANSI terminals. If the TERMCAP
|
---|
833 | * doesn't look like an ANSI terminal, then it returns FALSE. If the colors
|
---|
834 | * aren't understood, it also returns FALSE. If all goes well, it returns TRUE
|
---|
835 | */
|
---|
836 | int ansicolor(cmode, attrbyte)
|
---|
837 | int cmode; /* mode to set, e.g. A_NORMAL */
|
---|
838 | int attrbyte; /* IBM PC attribute byte */
|
---|
839 | {
|
---|
840 | char temp[16]; /* hold the new mode string */
|
---|
841 |
|
---|
842 | /* if not ANSI-ish, then fail */
|
---|
843 | if (strcmp(UP, "\033[A") && strcmp(UP, "\033OA"))
|
---|
844 | {
|
---|
845 | msg("Don't know how to set colors for this terminal");
|
---|
846 | return 0;
|
---|
847 | }
|
---|
848 |
|
---|
849 | /* construct the color string */
|
---|
850 | sprintf(temp, "\033[m\033[3%c;4%c%s%sm",
|
---|
851 | "04261537"[attrbyte & 0x07],
|
---|
852 | "04261537"[(attrbyte >> 4) & 0x07],
|
---|
853 | (attrbyte & 0x08) ? ";1" : "",
|
---|
854 | (attrbyte & 0x80) ? ";5" : "");
|
---|
855 |
|
---|
856 | /* stick it in the right place */
|
---|
857 | switch (cmode)
|
---|
858 | {
|
---|
859 | case A_NORMAL:
|
---|
860 | if (!strcmp(MEcolor, normalcolor))
|
---|
861 | strcpy(MEcolor, temp);
|
---|
862 | if (!strcmp(UEcolor, normalcolor))
|
---|
863 | strcpy(UEcolor, temp);
|
---|
864 | if (!strcmp(AEcolor, normalcolor))
|
---|
865 | strcpy(AEcolor, temp);
|
---|
866 | if (!strcmp(SEcolor, normalcolor))
|
---|
867 | strcpy(SEcolor, temp);
|
---|
868 |
|
---|
869 | strcpy(normalcolor, temp);
|
---|
870 | tputs(normalcolor, 1, faddch);
|
---|
871 | break;
|
---|
872 |
|
---|
873 | case A_BOLD:
|
---|
874 | strcpy(MDcolor, temp);
|
---|
875 | strcpy(MEcolor, normalcolor);
|
---|
876 | break;
|
---|
877 |
|
---|
878 | case A_UNDERLINE:
|
---|
879 | strcpy(UScolor, temp);
|
---|
880 | strcpy(UEcolor, normalcolor);
|
---|
881 | break;
|
---|
882 |
|
---|
883 | case A_ALTCHARSET:
|
---|
884 | strcpy(AScolor, temp);
|
---|
885 | strcpy(AEcolor, normalcolor);
|
---|
886 | break;
|
---|
887 |
|
---|
888 | case A_STANDOUT:
|
---|
889 | strcpy(SOcolor, temp);
|
---|
890 | strcpy(SEcolor, normalcolor);
|
---|
891 | break;
|
---|
892 |
|
---|
893 | #ifndef NO_POPUP
|
---|
894 | case A_POPUP:
|
---|
895 | strcpy(POPUPcolor, temp);
|
---|
896 | break;
|
---|
897 | #endif
|
---|
898 |
|
---|
899 | #ifndef NO_VISIBLE
|
---|
900 | case A_VISIBLE:
|
---|
901 | strcpy(VISIBLEcolor, temp);
|
---|
902 | break;
|
---|
903 | #endif
|
---|
904 | }
|
---|
905 |
|
---|
906 | return 1;
|
---|
907 | }
|
---|
908 |
|
---|
909 |
|
---|
910 | /* This function outputs the ESC sequence needed to switch the screen back
|
---|
911 | * to "normal" mode. On color terminals which haven't had their color set
|
---|
912 | * yet, this is one of the termcap strings; for color terminals that really
|
---|
913 | * have had colors defined, we just the "normal color" escape sequence.
|
---|
914 | */
|
---|
915 | endcolor()
|
---|
916 | {
|
---|
917 | if (aend == ME)
|
---|
918 | tputs(MEcolor, 1, faddch);
|
---|
919 | else if (aend == UE)
|
---|
920 | tputs(UEcolor, 1, faddch);
|
---|
921 | else if (aend == AE)
|
---|
922 | tputs(AEcolor, 1, faddch);
|
---|
923 | else if (aend == SE)
|
---|
924 | tputs(SEcolor, 1, faddch);
|
---|
925 | aend = "";
|
---|
926 | return 0;
|
---|
927 | }
|
---|
928 |
|
---|
929 |
|
---|
930 | #endif /* !NO_COLOR */
|
---|