1 /*======================================================================*\
2 |* Editor mined *|
3 |* operating system dependent I/O *|
4 \*======================================================================*/
5
6 #ifdef _AIX
7 #define _ALL_SOURCE /* get struct winsize defined */
8 #endif
9
10
11 #include "mined.h"
12 #include "io.h"
13 #include "termprop.h"
14
15
16 #ifdef vms
17
18 #define __BSD44_CURSES
19
20 #undef CURSES
21 #define ANSI
22
23 #include "vmsio.c"
24
25 #endif
26
27
28 #ifdef ANSI
29 #undef conio
30 #endif
31
32 #ifdef msdos
33
34 #ifndef __TURBOC__
35 #undef unix
36 /* don't #define ANSI */
37 #endif
38
39 #ifndef conio
40 #define ANSI
41 #endif
42
43 #endif
44
45
46 #include <errno.h>
47 #include <signal.h>
48 #ifndef __TURBOC__
49 extern int kill _((pid_t, int));
50 #endif
51
52 /* include configuration for SIGWINCH information retrieval */
53 #ifdef SGTTY
54 #undef TERMIO
55 #define include_SGTTY
56 #endif
57 #ifdef TERMIO
58 #define include_TERMIO
59 #endif
60
61
62 /* terminal handling selection */
63 #ifdef CURSES
64 #define _SGTTYB_ /* avoid duplicate definitions on SunOS */
65 #include <curses.h>
66 # undef FALSE
67 # undef TRUE
68
69 # ifdef SETLOCALE
70 # include <locale.h>
71 # endif
72
73 /* ensure window size detection capability */
74 # ifndef SGTTY
75 # define include_TERMIO
76 # endif
77
78 # ifdef vms
79 # undef include_TERMIO
80 # endif
81
82 # undef TERMIO /* \ must be */
83 # undef SGTTY /* / disabled */
84 #endif
85
86
87 #ifdef include_TERMIO
88 # ifdef questionable_but_recommended_by_some_SuSe_Guru_doesnt_work_on_HP
89 # if defined (__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1))
90 # include <termios.h> /* define POSIX.1 termios */
91 # include <sys/ioctl.h> /* declare ioctl() for winsize */
92 # undef TCGETS /* Use POSIX.1 instead */
93 # else
94 /* Compatible <termio.h> for old 'struct termio' ioctl interface. */
95 # include <termio.h>
96 # endif
97 # else
98 # include <termios.h> /* define POSIX.1 termios */
99 # include <sys/ioctl.h> /* declare ioctl() for winsize */
100 # endif
101 #endif
102
103 #ifdef include_SGTTY
104 #define BSD_COMP /* let SunOS #include <sys/ttold.h> in <sys/ioctl.h> */
105 #include <sys/ioctl.h>
106 #include <sgtty.h> /* after <sys/ttold.h> */
107 /*extern int ioctl ();*/
108 #endif
109
110
111 #ifdef __CYGWIN__
112 #include <sys/ioctl.h>
113 #endif
114
115 #ifdef SIGPHONE /* this trick was taken from less' screen.c */
116 #include <sys/window.h> /* for window size detection */
117 #endif
118
119 #ifdef msdos
120 #define _getch_
121 #define getch dosgetch
122 #endif
123
124 #ifdef msdos
125 /* make REGS "x." branch work with djgpp */
126 #define _NAIVE_DOS_REGS
127 #include <dos.h>
128 #ifndef __TURBOC__
129 #include <dpmi.h>
130 #include <go32.h> /* define transfer buffer __tb and function dosmemget */
131 #endif
132 #endif
133
134
135 #ifdef unix
136 # undef _POSIX_SOURCE
137 # undef _XOPEN_SOURCE
138 #ifndef __MINGW32__
139 /* use select () for peek/read? */
140 #define selectpeek
141 #define selectread
142 #endif
143 #endif
144
145 #ifdef __CYGWIN__
146 #include <cygwin/version.h> /* check CYGWIN_VERSION_DLL_* */
147 #if CYGWIN_VERSION_DLL_MAJOR == 1007 && CYGWIN_VERSION_DLL_MINOR <= 17
148 /* should in theory be checked dynamically, by calling uname(2) within #ifdef __CYGWIN__ ... */
149 /* support immediate response to WINCH */
150 #undef selectread
151 #endif
152 #endif
153
154 #define dont_debug_timeout_read
155 #ifdef debug_timeout_read
156 #undef selectread
157 #endif
158
159 #ifdef __EMX__
160 #undef selectpeek
161 #undef selectread
162 # ifdef CURSES
163 # define _getch_
164 # endif
165 #endif
166
167 #ifdef vms
168 # include <socket.h> /* for select () and struct timeval */
169 # ifdef CURSES
170 # define _getch_
171 # endif
172 #endif
173
174 #ifdef CURSES_INPUT /* currently not defined */
175 #define _getch_ /* not necessarily needed for Unix, but might be better
176 with new curs_readchar loop in inputreadyafter () */
177 #endif
178
179 #ifdef _getch_
180 #ifndef CURSES
181 extern int getch ();
182 #endif
183 #endif
184
185
186 #ifndef __TURBOC__
187 #include <sys/time.h> /* for struct timeval (for select in inputreadyafter) */
188 #endif
189
190
191 /*======================================================================*\
192 |* Mode indication *|
193 \*======================================================================*/
194
195 /* terminal capabilites and feature usage */
196 FLAG can_scroll_reverse = True;
197 FLAG can_add_line = True;
198 FLAG can_delete_line = True;
199 FLAG can_clear_eol = True;
200 FLAG can_clear_eos = True;
201 FLAG can_erase_chars = True;
202 FLAG can_reverse_mode = True;
203 FLAG can_hide_cursor = False;
204 FLAG can_dim = False;
205 FLAG can_alt_cset = True;
206 FLAG use_mouse_button_event_tracking = True;
207 FLAG colours_256 = False;
208 FLAG colours_88 = False;
209 FLAG ansi_esc = True;
210 FLAG standout_glitch = False;
211 FLAG use_appl_cursor = True;
212 FLAG use_appl_keypad = False;
213
214 /* menu border style */
215 FLAG use_ascii_graphics = False; /* use ASCII graphics for borders */
216 FLAG use_vga_block_graphics = False; /* charset is VGA with block graphics */
217 FLAG use_pc_block_graphics = False; /* alternate charset is VGA with block graphics */
218 FLAG use_vt100_block_graphics = False;
219 FLAG full_menu_bg = False; /* full coloured background */
220 char menu_border_style = 's';
221 int menumargin = 0;
222 FLAG explicit_border_style = False;
223 FLAG explicit_scrollbar_style = False;
224 FLAG explicit_keymap = False;
225 FLAG use_stylish_menu_selection = True;
226 FLAG bold_border = True;
227 #define use_normalchars_boxdrawing ((utf8_screen || use_ascii_graphics) && ! use_vt100_block_graphics && ! use_vga_block_graphics)
228
229 int
use_unicode_menubar()230 use_unicode_menubar ()
231 {
232 if (use_stylish_menu_selection
233 && use_normalchars_boxdrawing
234 && ! use_ascii_graphics
235 && menu_border_style != 'P'
236 && menu_border_style != '@') {
237 return 1 + (menu_border_style == 'd');
238 } else {
239 return 0;
240 }
241 }
242
243 /* feature usage options */
244 FLAG use_script_colour = True;
245 FLAG use_mouse = True;
246 FLAG use_mouse_release = True;
247 FLAG use_mouse_anymove_inmenu = True;
248 FLAG use_mouse_anymove_always = False;
249 FLAG use_mouse_extended = False; /* UTF-8 encoding of mouse coordinates */
250 FLAG use_mouse_1015 = False; /* numeric encoding of mouse coordinates */
251 FLAG use_bold = True;
252 FLAG use_bgcolor = True;
253 FLAG avoid_reverse_colour = False;
254 FLAG use_modifyOtherKeys = False;
255 int cursor_style = 0;
256
257 /* state */
258 static FLAG in_menu_mouse_mode = False; /* used in dosmouse.c */
259 FLAG in_menu_border = False;
260 /*int current_cursor_y = 0;*/
261 static FLAG is_mouse_button_event_mode_enabled = False;
262
263 /* screen attributes: ANSI sequences */
264 char * markansi = 0; /* line indicator marking (dim/red) */
265 char * emphansi = 0; /* status line emphasis mode (red bg) */
266 char * borderansi = 0; /* menu border colour (red) */
267 char * selansi = 0; /* menu selection */
268 char * selfgansi = 0; /* menu selection background */
269 char * ctrlansi = 0; /* Control character display */
270 char * uniansi = 0; /* Unicode character display */
271 char * specialansi = 0; /* Unicode (lineend) marker display */
272 char * combiningansi = 0; /* combining character display */
273 char * menuansi = 0; /* menu line */
274 char * HTMLansi = 0; /* HTML display */
275 char * XMLattribansi = 0; /* HTML/XML attribute display */
276 char * XMLvalueansi = 0; /* HTML/XML value display */
277 char * diagansi = 0; /* dialog (bottom status) line */
278 char * scrollfgansi = 0; /* scrollbar foreground */
279 char * scrollbgansi = 0; /* scrollbar background */
280
281 #define nonempty(ansi) (ansi && * ansi)
282
283 static int colour_token = -1;
284
285 void
set_colour_token(token)286 set_colour_token (token)
287 int token;
288 {
289 colour_token = token;
290 }
291
292
293 /*======================================================================*\
294 |* I/O channels *|
295 \*======================================================================*/
296
297 /* tty file handles */
298 int input_fd = STD_IN;
299 #ifdef __EMX__
300 int output_fd = STD_OUT;
301 #else
302 int output_fd = STD_ERR;
303 #endif
304
305 #define tty_fd output_fd
306
307
308 /*======================================================================*\
309 |* Interrupt signal handling *|
310 \*======================================================================*/
311
312 #define dont_debug_winchg
313
314 #ifdef debug_winchg
315 #define trace_winchg(params) printf params
316 #else
317 #define trace_winchg(params)
318 #endif
319
320
321 /* interrupt control */
322 FLAG tty_closed = False;
323 FLAG hup = False; /* set when SIGHUP is caught */
324 /* don't use 'static' for variables used in signal handler */
325 FLAG intr_char = False; /* set when SIGINT is caught */
326 int sigcaught = 0; /* set to signal caught */
327 FLAG continued = False; /* set when SIGCONT is receive */
328
329
330 /**
331 Signal handler for system
332 */
333 static
334 void
catch_interrupt(signum)335 catch_interrupt (signum)
336 int signum;
337 {
338 sigcaught = signum;
339 /*catch_signals ();*/
340 signal (signum, catch_interrupt);
341
342 /* To converge towards BSD signal() semantics:
343 don't handle_interrupt here; postpone (setting sigcaught flag)
344 and handle after select(), maybe after read(), elsewhere?
345 */
346 handle_interrupt (signum);
347 }
348
349 static
350 void
catch_crash(signum)351 catch_crash (signum)
352 int signum;
353 {
354 sigcaught = signum;
355 /*catch_signals ();*/
356 signal (signum, catch_crash);
357
358 /* To converge towards BSD signal() semantics:
359 don't handle_interrupt here; postpone (setting sigcaught flag)
360 and handle after select(), maybe after read(), elsewhere?
361 */
362 handle_interrupt (signum);
363 /*kill (getpid (), SIGABRT); trying to enforce core dump - not working */
364 }
365
366 void
catch_signals()367 catch_signals ()
368 {
369 #if defined (SIGRTMIN) && defined (SIGRTMAX)
370 int i;
371 for (i = SIGRTMIN; i <= SIGRTMAX; i ++) {
372 signal (i, catch_interrupt);
373 }
374 #endif
375
376 #ifdef SIGABRT
377 signal (SIGABRT, catch_crash);
378 #endif
379 #ifdef SIGSEGV
380 signal (SIGSEGV, catch_crash);
381 #endif
382 #ifdef SIGBUS
383 signal (SIGBUS, catch_crash);
384 #endif
385 #ifdef SIGFPE
386 signal (SIGFPE, catch_crash);
387 #endif
388 #ifdef SIGILL
389 signal (SIGILL, catch_crash);
390 #endif
391
392 #ifdef SIGHUP
393 signal (SIGHUP, catch_interrupt);
394 #endif
395 #ifdef SIGTRAP
396 signal (SIGTRAP, catch_interrupt);
397 #endif
398 #ifdef SIGEMT
399 signal (SIGEMT, catch_interrupt);
400 #endif
401 #ifdef SIGSYS
402 signal (SIGSYS, catch_interrupt);
403 #endif
404 #ifdef SIGPIPE
405 signal (SIGPIPE, catch_interrupt);
406 #endif
407 #ifdef SIGALRM
408 signal (SIGALRM, catch_interrupt);
409 #endif
410 #ifdef SIGTERM
411 signal (SIGTERM, catch_interrupt);
412 #endif
413 #ifdef SIGXCPU
414 signal (SIGXCPU, catch_interrupt);
415 #endif
416 #ifdef SIGXFSZ
417 signal (SIGXFSZ, catch_interrupt);
418 #endif
419 #ifdef SIGVTALRM
420 signal (SIGVTALRM, catch_interrupt);
421 #endif
422 #ifdef SIGPROF
423 signal (SIGPROF, catch_interrupt);
424 #endif
425 #ifdef SIGPWR
426 signal (SIGPWR, catch_interrupt);
427 #endif
428
429 #ifdef SIGIO
430 /* or should this rather be ignored? */
431 signal (SIGIO, catch_interrupt);
432 #else
433 #ifdef SIGPOLL
434 signal (SIGPOLL, catch_interrupt);
435 #endif
436 #endif
437 #ifdef SIGLOST
438 /* linux man 7 signal says "SIGIO and SIGLOST have the same value."
439 but on cygwin, they have different values
440 */
441 signal (SIGLOST, catch_interrupt);
442 #endif
443
444 #ifdef SIGUSR1
445 signal (SIGUSR1, catch_interrupt);
446 #endif
447 #ifdef SIGUSR2
448 signal (SIGUSR2, catch_interrupt);
449 #endif
450 #ifdef SIGUSR3
451 signal (SIGUSR3, catch_interrupt);
452 #endif
453 }
454
455 #ifdef SIGWINCH
456 /*
457 * Catch the SIGWINCH signal sent to mined.
458 */
459 static
460 void
catchwinch(dummy)461 catchwinch (dummy)
462 int dummy;
463 {
464 winchg = True;
465 interrupted = True;
466 trace_winchg (("catching winchg\n"));
467
468 /* workaround for interference of WINCH and FOCUSin handling */
469 window_focus = True;
470
471 /* This is now performed in __readchar () to prevent display garbage
472 in case this interrupts occurs during display output operations which
473 get screen size related values changed while relying on them.
474 if (waitingforinput) {
475 RDwinchg ();
476 }
477 */
478
479 signal (SIGWINCH, catchwinch); /* reinstall the signal */
480 kill (getppid (), SIGWINCH); /* propagate to parent (e.g. shell) */
481 }
482 #endif
483
484 #ifdef SIGQUIT
485 /*
486 * Catch the SIGQUIT signal (^\) sent to mined. It turns on the quitflag.
487 */
488 static
489 void
catchquit(dummy)490 catchquit (dummy)
491 int dummy;
492 {
493 #ifdef UNUSED /* Should not be needed with new __readchar () */
494 /* Was previously needed on Sun but showed bad effects on Iris. */
495 static char quitchar = '\0';
496 if (waitingforinput) {
497 /* simulate input to enable immediate break also during input */
498 (void) ioctl (input_fd, TIOCSTI, & quitchar);
499 }
500 #endif
501 quit = True;
502 signal (SIGQUIT, catchquit); /* reinstall the signal */
503 }
504 #endif
505
506 #ifdef SIGBREAK
507 /*
508 * Catch the SIGBREAK signal (control-Break) and turn on the quitflag.
509 */
510 static
511 void
catchbreak(dummy)512 catchbreak (dummy)
513 int dummy;
514 {
515 quit = True;
516 signal (SIGBREAK, catchbreak); /* do we need this ? */
517 }
518 #else
519 # ifdef msdos
520 static
521 int
controlbreak()522 controlbreak ()
523 {
524 quit = True;
525 return 1; /* continue program execution */
526 }
527 # endif
528 #endif
529
530 #ifdef SIGINT
531 /*
532 * Catch the SIGINT signal (^C) sent if it cannot be ignored by tty driver
533 */
534 static
535 void
catchint(dummy)536 catchint (dummy)
537 int dummy;
538 {
539 intr_char = True;
540 signal (SIGINT, catchint); /* reinstall the signal */
541 }
542 #endif
543
544 #ifdef SIGTSTP
545 /**
546 Catch external TSTP signal to try to reset terminal modes
547 */
548 static
549 void
catchtstp(dummy)550 catchtstp (dummy)
551 int dummy;
552 {
553 interrupted = True;
554 /* for now, do nothing, effectively ignoring the external signal */
555 signal (SIGTSTP, catchtstp); /* reinstall the signal */
556 }
557 #endif
558
559 #ifdef SIGCONT
560 /**
561 Catch CONT signal to refresh screen
562 */
563 static
564 void
catchcont(dummy)565 catchcont (dummy)
566 int dummy;
567 {
568 /* trigger screen refresh */
569 winchg = True;
570 interrupted = True;
571 continued = True;
572 signal (SIGCONT, catchcont); /* reinstall the signal */
573 }
574 #endif
575
576
577 #ifdef SIGTSTP
578 #ifdef __ANDROID__
579 FLAG cansuspendmyself = False;
580 #else
581 FLAG cansuspendmyself = True;
582 #endif
583 #else
584 FLAG cansuspendmyself = False;
585 #endif
586
587 void
suspendmyself()588 suspendmyself ()
589 {
590 #ifdef SIGTSTP
591 signal (SIGTSTP, SIG_DFL); /* uninstall catch of external TSTP */
592 kill (getpid (), SIGTSTP);
593 signal (SIGTSTP, catchtstp); /* reinstall the signal */
594 #endif
595 }
596
597
598 /*======================================================================*\
599 |* Unix terminal capabilities *|
600 \*======================================================================*/
601
602 #if defined (unix) || defined (ANSI) || defined (vms)
603
604 #ifndef CURSES
605
606 static FLAG avoid_tputs = False;
607
608 #ifdef __CYGWIN__avoiding_tputs
609 /* workaround: tputs not working anymore if terminfo not installed,
610 esp. when running stand-alone (without cygwin environment) */
611 #warning deprecated workaround replaced by dynamic alternative
612 #define termputstr(str, aff) putstring (str)
613 #else
614 #ifdef vms
615 #define termputstr(str, aff) putescape (str)
616 #else
617 #ifdef ANSI
618 #define termputstr(str, aff) putstring (str)
619 #else
620
621 extern int tputs _((char *, int, intfunc));
622 /*#define termputstr(str, aff) (void) tputs (str, aff, (intfunc) __putchar)*/
623 static
624 void
termputstr(str,aff)625 termputstr (str, aff)
626 char * str;
627 int aff;
628 {
629 if (avoid_tputs) {
630 putstring (str);
631 } else {
632 (void) tputs (str, aff, (intfunc) __putchar);
633 }
634 }
635
636 #endif
637 #endif
638 #endif
639
640 static char
641 * cCL, * cCE, * cCD, * cEC, * cSR, * cAL, * cDL, * cCS, * cSC, * cRC,
642 * cCM, * cSO, * cSE, * cVS, * cVE, * cVI,
643 * cTI, * cTE, * cKS, * cKE,
644 * cAS, * cAE, * cEA, * cdisableEA, * cAC, * cS2, * cS3,
645 * cME, * cMR, * cMH, * cMD, * cUL, * cBL, * cAF, * cAB;
646
647 #endif
648
649 static char * cMouseEventAnyOn = "\033[?1003h";
650 static char * cMouseEventAnyOff = "\033[?1003l";
651 static char * cMouseEventBtnOn = "\033[?1002h";
652 #ifndef CURSES
653 static char * cMouseEventBtnOff = "\033[?1002l";
654 static char * cMouseButtonOn = "\033[?1000h";
655 static char * cMouseButtonOff = "\033[?1000l";
656 static char * cMouseX10On = "\033[?9h";
657 static char * cMouseX10Off = "\033[?9l";
658
659 static char * cMouseExtendedOn = "\033[?1005h";
660 static char * cMouseExtendedOff = "\033[?1005l";
661 static char * cMouse1015On = "\033[?1015h";
662 static char * cMouse1015Off = "\033[?1015l";
663
664 static char * cMouseFocusOn = "\033[?1004h";
665 static char * cMouseFocusOff = "\033[?1004l";
666 static char * cAmbigOn = "\033[?7700h";
667 static char * cAmbigOff = "\033[?7700l";
668 #endif
669
670 #endif /* defined (unix) || defined (vms) */
671
672
673 #ifdef unix
674
675 /**
676 termcap/termlib API and storage
677 */
678 #if ! defined (ANSI) && ! defined (CURSES)
679 #define TERMAPI
680 #define TERMCAP /* disable to use termlib/terminfo API */
681 #endif
682
683 #ifdef CURSES
684 #define TERMAPI
685 #undef TERMCAP
686 #endif
687
688 #ifdef __EMX__
689 #define TERMCAP
690 #endif
691
692
693 #ifdef __CYGWIN__avoiding_tputs
694 #warning deprecated workaround replaced by dynamic alternative
695 /* strip "$<2>" delay suffixes if not using tputs */
tstrfix(tc,tstr)696 static char * tstrfix (tc, tstr)
697 char * tc;
698 char * tstr;
699 {
700 if (tstr) {
701 char * junk = strchr (tstr, '$');
702 if (junk && * (junk + 1) == '<') {
703 char * fixtstr = malloc (junk - tstr + 1);
704 * fixtstr = '\0';
705 strncat (fixtstr, tstr, junk - tstr);
706 return fixtstr;
707 }
708 }
709 return tstr;
710 }
711 #else
712 #define tstrfix(tc, tstr) tstr
713 #endif
714
715 #ifdef TERMAPI
716 #ifdef TERMCAP
717 /* termcap API */
718 #define term_setup(TERM) (tgetent (term_rawbuf, TERM) == 1)
719 #define term_getstr(tc, ti) tstrfix (tc, tgetstr (tc, & term_capbufpoi))
720 #define term_getnum(tc, ti) tgetnum (tc)
721 #define term_getflag(tc, ti) tgetflag (tc)
722
723 #else /* #ifdef TERMCAP */
724 /* terminfo API */
725 #define term_setup(TERM) (setterm (TERM) == 0)
726 #define term_getstr(tc, ti) tstrfix (tc, tigetstr (ti))
727 #define term_getnum(tc, ti) tigetnum (ti)
728 #define term_getflag(tc, ti) tigetflag (ti)
729
730 #endif /* #else TERMCAP */
731 #endif
732
733
734 #ifndef CURSES
735
736 #ifdef TERMCAP
737
738 extern int tgetent _((char * rawbuf, char * TERM));
739 extern char * tgetstr _((char *, char * * capbufpoi));
740 extern int tgetnum _((char *));
741 extern int tgetflag _((char *));
742
743 #define term_capbuflen 1024
744 static char term_capbuf [term_capbuflen];
745 static char * term_capbufpoi = term_capbuf;
746
747 #else /* #ifdef TERMCAP */
748
749 #ifdef BSD
750 extern int setterm _((char * TERM));
751 #else
752 extern int setupterm _((char * TERM, int , int *));
753 #define setterm(TERM) setupterm (TERM, 1, 0)
754 #endif
755 extern char * tigetstr _((char *));
756 extern int tigetnum _((char *));
757 extern int tigetflag _((char *));
758
759 #endif /* #else TERMCAP */
760
761
762 extern char * tgoto _((char *, int, int));
763
764 #define aff1 0
765 #define affmax YMAX
766
767 #endif /* #ifndef CURSES */
768
769
770 #define dont_debug_terminfo
771
772 #ifndef ANSI
773
774 #define fkeymap_terminfo_len 155
775 struct fkeyentry fkeymap_terminfo [fkeymap_terminfo_len + 1] = {
776 {NIL_PTR}
777 };
778 static int fkeymap_terminfo_i = 0;
779
780 static
781 void
add_keymap_entry(cap,f,shift_state)782 add_keymap_entry (cap, f, shift_state)
783 char * cap;
784 voidfunc f;
785 unsigned char shift_state;
786 {
787 if (fkeymap_terminfo_i < fkeymap_terminfo_len) {
788 fkeymap_terminfo [fkeymap_terminfo_i].fk = cap;
789 fkeymap_terminfo [fkeymap_terminfo_i].fp = f;
790 fkeymap_terminfo [fkeymap_terminfo_i].fkeyshift = shift_state;
791 fkeymap_terminfo_i ++;
792 fkeymap_terminfo [fkeymap_terminfo_i].fk = NIL_PTR;
793 }
794 }
795
796
797 static
798 char *
add_terminfo_entry(tc,ti,f,shift_state)799 add_terminfo_entry (tc, ti, f, shift_state)
800 char * tc;
801 char * ti;
802 voidfunc f;
803 unsigned char shift_state;
804 {
805 if (f) {
806 char * cap = term_getstr (tc, ti);
807 if (cap) {
808 add_keymap_entry (cap, f, shift_state);
809 #ifdef debug_terminfo
810 printf ("termcap %s / terminfo %s : <^[%s> [shift %X]\n", tc, ti, cap + 1, shift_state);
811 #endif
812 return cap;
813 }
814 }
815 return 0;
816 }
817
818 static
819 void
add_terminfo_entries()820 add_terminfo_entries ()
821 {
822 char * caphome;
823 char * capend;
824 caphome = add_terminfo_entry ("K1", "ka1", HOMEkey, 0); /* upper left of keypad */
825 (void) add_terminfo_entry ("K3", "ka3", PGUPkey, 0); /* upper right of keypad */
826 (void) add_terminfo_entry ("K2", "kb2", HOP, 0); /* center of keypad */
827 capend = add_terminfo_entry ("K4", "kc1", ENDkey, 0); /* lower left of keypad */
828 (void) add_terminfo_entry ("K5", "kc3", PGDNkey, 0); /* lower right of keypad */
829
830 if (caphome && capend) {
831 /* if keypad keys are explicitly defined, use them to assign HOME/END;
832 if home/begin/home_down/end key definitions refer to different keys,
833 map "small" keypad functions to them;
834 if they happen to refer to the same keys, the first setting
835 will have precedence
836 */
837 (void) add_terminfo_entry ("kh", "khome", smallHOMEkey, 0); /* home key */
838 (void) add_terminfo_entry ("kH", "kll", smallENDkey, 0); /* lower-left key (home down) */
839 (void) add_terminfo_entry ("@1", "kbeg", smallHOMEkey, 0); /* begin key */
840 (void) add_terminfo_entry ("@7", "kend", smallENDkey, 0); /* end key */
841 (void) add_terminfo_entry ("#2", "kHOM", HOMEkey, shift_mask); /* shifted home key */
842 (void) add_terminfo_entry ("&9", "kBEG", HOMEkey, shift_mask); /* shifted begin key */
843 (void) add_terminfo_entry ("*7", "kEND", ENDkey, shift_mask); /* shifted end key */
844 } else {
845 /* if keypad keys are not explicitly defined,
846 assign HOME/END to home/begin and home_down/end keys
847 */
848 (void) add_terminfo_entry ("kh", "khome", HOMEkey, 0); /* home key */
849 (void) add_terminfo_entry ("kH", "kll", ENDkey, 0); /* lower-left key (home down) */
850 (void) add_terminfo_entry ("@1", "kbeg", HOMEkey, 0); /* begin key */
851 (void) add_terminfo_entry ("@7", "kend", ENDkey, 0); /* end key */
852 (void) add_terminfo_entry ("#2", "kHOM", smallHOMEkey, shift_mask); /* shifted home key */
853 (void) add_terminfo_entry ("&9", "kBEG", smallHOMEkey, shift_mask); /* shifted begin key */
854 (void) add_terminfo_entry ("*7", "kEND", smallENDkey, shift_mask); /* shifted end key */
855 }
856
857 (void) add_terminfo_entry ("kb", "kbs", DPC, 0); /* backspace key */
858 (void) add_terminfo_entry ("kB", "kcbt", MPW, 0); /* back-tab key */
859 (void) add_terminfo_entry ("@2", "kcan", 0, 0); /* cancel key */
860 (void) add_terminfo_entry ("ka", "ktbc", 0, 0); /* clear-all-tabs key */
861 (void) add_terminfo_entry ("kC", "kclr", 0, 0); /* clear-screen or erase key */
862 (void) add_terminfo_entry ("@3", "kclo", 0, 0); /* close key */
863 (void) add_terminfo_entry ("@4", "kcmd", HOP, 0); /* command key */
864 (void) add_terminfo_entry ("@5", "kcpy", COPY, 0); /* copy key */
865 (void) add_terminfo_entry ("@6", "kcrt", 0, 0); /* create key */
866 (void) add_terminfo_entry ("kt", "kctab", 0, 0); /* clear-tab key */
867 (void) add_terminfo_entry ("kD", "kdch1", DELkey, 0); /* delete-character key */
868 (void) add_terminfo_entry ("kL", "kdl1", 0, 0); /* delete-line key */
869 (void) add_terminfo_entry ("kd", "kcud1", DNkey, 0); /* down-arrow key */
870 (void) add_terminfo_entry ("kM", "krmir", 0, 0); /* sent by rmir or smir in insert mode */
871 (void) add_terminfo_entry ("@8", "kent", SNL, 0); /* enter/send key */
872 (void) add_terminfo_entry ("kE", "kel", 0, 0); /* clear-to-end-of-line key */
873 (void) add_terminfo_entry ("kS", "ked", 0, 0); /* clear-to-end-of-screen key */
874 (void) add_terminfo_entry ("@9", "kext", 0, 0); /* exit key */
875
876 (void) add_terminfo_entry ("k0", "kf0", F10, 0); /* F0 function key */
877 (void) add_terminfo_entry ("k1", "kf1", F1, 0); /* F1 function key */
878 (void) add_terminfo_entry ("k2", "kf2", F2, 0); /* F2 function key */
879 (void) add_terminfo_entry ("k3", "kf3", F3, 0); /* F3 function key */
880 (void) add_terminfo_entry ("k4", "kf4", F4, 0); /* F4 function key */
881 (void) add_terminfo_entry ("k5", "kf5", F5, 0); /* F5 function key */
882 (void) add_terminfo_entry ("k6", "kf6", F6, 0); /* F6 function key */
883 (void) add_terminfo_entry ("k7", "kf7", F7, 0); /* F7 function key */
884 (void) add_terminfo_entry ("k8", "kf8", F8, 0); /* F8 function key */
885 (void) add_terminfo_entry ("k9", "kf9", F9, 0); /* F9 function key */
886 (void) add_terminfo_entry ("k;", "kf10", F10, 0); /* F10 function key */
887
888 #ifdef shift_f_keys
889 there is no uniform mapping of actual shifted function keys
890 to terminfo F11..F63 names, so better leave these entries out
891 (void) add_terminfo_entry ("F1", "kf11", F11, 0); /* F11 function key */
892 (void) add_terminfo_entry ("F2", "kf12", F12, 0); /* F12 function key */
893 (void) add_terminfo_entry ("F3", "kf13", F1, shift_mask); /* F13 function key */
894 (void) add_terminfo_entry ("F4", "kf14", F2, shift_mask); /* F14 function key */
895 (void) add_terminfo_entry ("F5", "kf15", F3, shift_mask); /* F15 function key */
896 (void) add_terminfo_entry ("F6", "kf16", F4, shift_mask); /* F16 function key */
897 (void) add_terminfo_entry ("F7", "kf17", F5, shift_mask); /* F17 function key */
898 (void) add_terminfo_entry ("F8", "kf18", F6, shift_mask); /* F18 function key */
899 (void) add_terminfo_entry ("F9", "kf19", F7, shift_mask); /* F19 function key */
900 (void) add_terminfo_entry ("FA", "kf20", F8, shift_mask); /* F20 function key */
901 (void) add_terminfo_entry ("FB", "kf21", F9, shift_mask); /* F21 function key */
902 (void) add_terminfo_entry ("FC", "kf22", F10, shift_mask); /* F22 function key */
903 (void) add_terminfo_entry ("FD", "kf23", F11, shift_mask); /* F23 function key */
904 (void) add_terminfo_entry ("FE", "kf24", F12, shift_mask); /* F24 function key */
905 (void) add_terminfo_entry ("FF", "kf25", F1, ctrl_mask); /* F25 function key */
906 (void) add_terminfo_entry ("FG", "kf26", F2, ctrl_mask); /* F26 function key */
907 (void) add_terminfo_entry ("FH", "kf27", F3, ctrl_mask); /* F27 function key */
908 (void) add_terminfo_entry ("FI", "kf28", F4, ctrl_mask); /* F28 function key */
909 (void) add_terminfo_entry ("FJ", "kf29", F5, ctrl_mask); /* F29 function key */
910 (void) add_terminfo_entry ("FK", "kf30", F6, ctrl_mask); /* F30 function key */
911 (void) add_terminfo_entry ("FL", "kf31", F7, ctrl_mask); /* F31 function key */
912 (void) add_terminfo_entry ("FM", "kf32", F8, ctrl_mask); /* F32 function key */
913 (void) add_terminfo_entry ("FN", "kf33", F9, ctrl_mask); /* F33 function key */
914 (void) add_terminfo_entry ("FO", "kf34", F10, ctrl_mask); /* F34 function key */
915 (void) add_terminfo_entry ("FP", "kf35", F11, ctrl_mask); /* F35 function key */
916 (void) add_terminfo_entry ("FQ", "kf36", F12, ctrl_mask); /* F36 function key */
917 (void) add_terminfo_entry ("FR", "kf37", F1, ctrlshift_mask); /* F37 function key */
918 (void) add_terminfo_entry ("FS", "kf38", F2, ctrlshift_mask); /* F38 function key */
919 (void) add_terminfo_entry ("FT", "kf39", F3, ctrlshift_mask); /* F39 function key */
920 (void) add_terminfo_entry ("FU", "kf40", F4, ctrlshift_mask); /* F40 function key */
921 (void) add_terminfo_entry ("FV", "kf41", F5, ctrlshift_mask); /* F41 function key */
922 (void) add_terminfo_entry ("FW", "kf42", F6, ctrlshift_mask); /* F42 function key */
923 (void) add_terminfo_entry ("FX", "kf43", F7, ctrlshift_mask); /* F43 function key */
924 (void) add_terminfo_entry ("FY", "kf44", F8, ctrlshift_mask); /* F44 function key */
925 (void) add_terminfo_entry ("FZ", "kf45", F9, ctrlshift_mask); /* F45 function key */
926 (void) add_terminfo_entry ("Fa", "kf46", F10, ctrlshift_mask); /* F46 function key */
927 (void) add_terminfo_entry ("Fb", "kf47", F11, ctrlshift_mask); /* F47 function key */
928 (void) add_terminfo_entry ("Fc", "kf48", F12, ctrlshift_mask); /* F48 function key */
929 (void) add_terminfo_entry ("Fd", "kf49", F1, alt_mask); /* F49 function key */
930 (void) add_terminfo_entry ("Fe", "kf50", F2, alt_mask); /* F50 function key */
931 (void) add_terminfo_entry ("Ff", "kf51", F3, alt_mask); /* F51 function key */
932 (void) add_terminfo_entry ("Fg", "kf52", F4, alt_mask); /* F52 function key */
933 (void) add_terminfo_entry ("Fh", "kf53", F5, alt_mask); /* F53 function key */
934 (void) add_terminfo_entry ("Fi", "kf54", F6, alt_mask); /* F54 function key */
935 (void) add_terminfo_entry ("Fj", "kf55", F7, alt_mask); /* F55 function key */
936 (void) add_terminfo_entry ("Fk", "kf56", F8, alt_mask); /* F56 function key */
937 (void) add_terminfo_entry ("Fl", "kf57", F9, alt_mask); /* F57 function key */
938 (void) add_terminfo_entry ("Fm", "kf58", F10, alt_mask); /* F58 function key */
939 (void) add_terminfo_entry ("Fn", "kf59", F11, alt_mask); /* F59 function key */
940 (void) add_terminfo_entry ("Fo", "kf60", F12, alt_mask); /* F60 function key */
941 (void) add_terminfo_entry ("Fp", "kf61", F1, altshift_mask); /* F61 function key */
942 (void) add_terminfo_entry ("Fq", "kf62", F2, altshift_mask); /* F62 function key */
943 (void) add_terminfo_entry ("Fr", "kf63", F3, altshift_mask); /* F63 function key */
944 #endif
945
946 (void) add_terminfo_entry ("@0", "kfnd", FIND, 0); /* find key */
947 (void) add_terminfo_entry ("%1", "khlp", HELP, 0); /* help key */
948 (void) add_terminfo_entry ("kI", "kich1", INSkey, 0); /* insert-character key */
949 (void) add_terminfo_entry ("kA", "kil1", 0, 0); /* insert-line key */
950 (void) add_terminfo_entry ("kl", "kcub1", LFkey, 0); /* left-arrow key */
951 (void) add_terminfo_entry ("%2", "kmrk", MARK, 0); /* mark key */
952 (void) add_terminfo_entry ("%3", "kmsg", 0, 0); /* message key */
953 (void) add_terminfo_entry ("%4", "kmov", 0, 0); /* move key */
954 (void) add_terminfo_entry ("%5", "knxt", 0, 0); /* next key */
955 (void) add_terminfo_entry ("kN", "knp", PGDNkey, 0); /* next-page key */
956 (void) add_terminfo_entry ("%6", "kopn", EDIT, 0); /* open key */
957 (void) add_terminfo_entry ("%7", "kopt", QUICKMENU, 0); /* options key */
958 (void) add_terminfo_entry ("kP", "kpp", PGUPkey, 0); /* previous-page key */
959 (void) add_terminfo_entry ("%8", "kprv", 0, 0); /* previous key */
960 (void) add_terminfo_entry ("%9", "kprt", PRINT, 0); /* print key */
961 (void) add_terminfo_entry ("%0", "krdo", COPY, 0); /* redo key */
962 (void) add_terminfo_entry ("&1", "kref", 0, 0); /* reference key */
963 (void) add_terminfo_entry ("&2", "krfr", 0, 0); /* refresh key */
964 (void) add_terminfo_entry ("&3", "krpl", GR, 0); /* replace key */
965 (void) add_terminfo_entry ("&4", "krst", 0, 0); /* restart key */
966 (void) add_terminfo_entry ("&5", "kres", AGAIN, 0); /* resume key */
967 (void) add_terminfo_entry ("kr", "kcuf1", RTkey, 0); /* right-arrow key */
968 (void) add_terminfo_entry ("&6", "ksav", WT, 0); /* save key */
969 (void) add_terminfo_entry ("&0", "kCAN", 0, shift_mask); /* shifted cancel key */
970 (void) add_terminfo_entry ("*1", "kCMD", HOP, shift_mask); /* shifted command key */
971 (void) add_terminfo_entry ("*2", "kCPY", COPY, shift_mask); /* shifted copy key */
972 (void) add_terminfo_entry ("*3", "kCRT", 0, shift_mask); /* shifted create key */
973 (void) add_terminfo_entry ("*4", "kDC", DELkey, shift_mask); /* shifted delete-character key */
974 (void) add_terminfo_entry ("*5", "kDL", 0, shift_mask); /* shifted delete-line key */
975 (void) add_terminfo_entry ("*6", "kslt", MARK, 0); /* select key */
976 (void) add_terminfo_entry ("*8", "kEOL", 0, shift_mask); /* shifted clear-to-end-of-line key */
977 (void) add_terminfo_entry ("*9", "kEXT", 0, shift_mask); /* shifted exit key */
978 (void) add_terminfo_entry ("kF", "kind", SD, 0); /* scroll-forward key */
979 (void) add_terminfo_entry ("*0", "kFND", FIND, shift_mask); /* shifted find key */
980 (void) add_terminfo_entry ("#1", "kHLP", HELP, shift_mask); /* shifted help key */
981 (void) add_terminfo_entry ("#3", "kIC", INSkey, shift_mask); /* shifted insert-character key */
982 (void) add_terminfo_entry ("#4", "kLFT", LFkey, shift_mask); /* shifted left-arrow key */
983 (void) add_terminfo_entry ("%a", "kMSG", 0, shift_mask); /* shifted message key */
984 (void) add_terminfo_entry ("%b", "kMOV", 0, shift_mask); /* shifted move key */
985 (void) add_terminfo_entry ("%c", "kNXT", PGDNkey, shift_mask); /* shifted next key */
986 (void) add_terminfo_entry ("%d", "kOPT", handleFlagmenus, shift_mask); /* shifted options key */
987 (void) add_terminfo_entry ("%e", "kPRV", PGUPkey, shift_mask); /* shifted previous key */
988 (void) add_terminfo_entry ("%f", "kPRT", PRINT, shift_mask); /* shifted print key */
989 (void) add_terminfo_entry ("kR", "kri", SU, 0); /* scroll-backward key */
990 (void) add_terminfo_entry ("%g", "kRDO", COPY, shift_mask); /* shifted redo key */
991 (void) add_terminfo_entry ("%h", "kRPL", REPL, shift_mask); /* shifted replace key */
992 (void) add_terminfo_entry ("%i", "kRIT", RTkey, shift_mask); /* shifted right-arrow key */
993 (void) add_terminfo_entry ("%j", "kRES", AGAIN, shift_mask); /* shifted resume key */
994 (void) add_terminfo_entry ("!1", "kSAV", WTU, shift_mask); /* shifted save key */
995 (void) add_terminfo_entry ("!2", "kSPD", SUSP, shift_mask); /* shifted suspend key */
996 (void) add_terminfo_entry ("kT", "khts", 0, 0); /* set-tab key */
997 (void) add_terminfo_entry ("!3", "kUND", UNDO, shift_mask); /* shifted undo key */
998 (void) add_terminfo_entry ("&7", "kspd", SUSP, 0); /* suspend key */
999 (void) add_terminfo_entry ("&8", "kund", UNDO, 0); /* undo key */
1000 (void) add_terminfo_entry ("ku", "kcuu1", UPkey, 0); /* up-arrow key */
1001 (void) add_terminfo_entry ("Km", "kmous", DIRECTxterm, 0); /* Mouse event has occurred */
1002 }
1003
1004 #endif /* #else ANSI */
1005
1006 #endif /* #ifdef unix */
1007
1008
1009 #ifdef ANSI
1010 struct fkeyentry fkeymap_terminfo [1] = {
1011 {NIL_PTR}
1012 };
1013 #endif
1014
1015
1016 /*======================================================================*\
1017 |* TTY and terminal mode switcher *|
1018 \*======================================================================*/
1019
1020 static void start_screen_mode _((int kb));
1021 static void end_screen_mode _((void));
1022 static void setup_terminal _((void));
1023 static void reset_terminal _((void));
1024
1025
1026 #ifdef CURSES
1027
1028 #define use_newterm /* otherwise, redirection to stdout doesn't work */
1029
1030 #ifdef __EMX__ /* __PDCURSES__ ? */
1031 #undef use_newterm
1032 #endif
1033 #ifdef msdos
1034 #undef use_newterm
1035 #endif
1036 #ifdef vms
1037 #undef use_newterm
1038 #endif
1039
1040 static FLAG screen_acquired = False;
1041 static void configure_screen _((void));
1042 # ifdef use_newterm
1043 static SCREEN * myscreen;
1044 extern FILE * fdopen ();
1045 # endif
1046
1047 #endif
1048
1049
1050 #ifdef TERMIO
1051 static FLAG old_termprops_not_saved = True;
1052 #endif
1053 #ifdef SGTTY
1054 static FLAG old_termprops_not_saved = True;
1055 #endif
1056
1057 static FLAG init_done = False;
1058
1059 /* the termios ISIG flag suppresses signal generation on
1060 tty input of INTR, QUIT, SUSP, or DSUSP associated keys */
1061 #define dont_use_ISIG
1062
1063 #ifdef TERMIO
1064 #ifdef debug_termios
1065 static
1066 void
dump_termios(tios)1067 dump_termios (tios)
1068 struct termios * tios;
1069 {
1070 int i;
1071 printf ("iflag %04X\n", tios->c_iflag);
1072 printf ("oflag %04X\n", tios->c_oflag);
1073 printf ("cflag %04X\n", tios->c_cflag);
1074 printf ("lflag %04X\n", tios->c_lflag);
1075 printf ("line %02X\n", tios->c_line);
1076 for (i = 0; i < NCCS; i ++) {
1077 printf ("cc[%d] %02X\n", i, tios->c_cc [i]);
1078 }
1079 }
1080 #endif
1081 #endif
1082
1083 /*
1084 * Set (True) or Restore (False) tty raw mode.
1085 * Also set signal characters (except for ^\) to UNDEF. ^\ is caught.
1086 */
1087 void
raw_mode(to_raw_state)1088 raw_mode (to_raw_state)
1089 FLAG to_raw_state;
1090 {
1091 #ifdef TERMIO
1092 static struct termios old_termio;
1093 struct termios new_termio;
1094 #ifdef TCGETS
1095 # define gettermio(fd, iopoi) ioctl (fd, TCGETS, iopoi)
1096 # ifdef TCSETSW
1097 # define settermio(fd, iopoi) ioctl (fd, TCSETSW, iopoi)
1098 # else
1099 # define settermio(fd, iopoi) ioctl (fd, TCSETS, iopoi)
1100 # endif
1101 #else
1102 # define gettermio(fd, iopoi) tcgetattr (fd, iopoi)
1103 # ifdef TCSADRAIN
1104 # define settermio(fd, iopoi) tcsetattr (fd, TCSADRAIN, iopoi)
1105 # else
1106 # define settermio(fd, iopoi) tcsetattr (fd, TCSANOW, iopoi)
1107 # endif
1108 #endif
1109 #endif /* TERMIO */
1110
1111 #ifdef SGTTY
1112 static struct sgttyb old_tty;
1113 struct sgttyb new_tty;
1114 static int oldlmode;
1115 int lmode;
1116 static struct tchars old_tchars;
1117 static struct ltchars old_ltchars;
1118
1119 /* correspondence between the tchars/ltchars characters of the sgtty
1120 interface and the c_cc characters of the termios interface (codes vary):
1121 sgtty termio sgtty termio
1122 struct tchars struct ltchars
1123 t_intrc VINTR t_suspc VSUSP
1124 t_quitc VQUIT t_dsuspc VDSUSP
1125 t_startc VSTART t_rprntc VREPRINT
1126 t_stopc VSTOP t_flushc VDISCARD
1127 t_eofc VEOF (VMIN) t_werasc VWERASE
1128 t_brkc VEOL (VTIME) t_lnextc VLNEXT
1129 */
1130 #define NDEF '\377'
1131 static struct tchars new_tchars = {NDEF, 0, NDEF, NDEF, NDEF, NDEF};
1132 static struct tchars new_QStchars = {NDEF, 0, '\021', '\023', NDEF, NDEF};
1133 static struct ltchars new_ltchars = {NDEF, NDEF, NDEF, NDEF, NDEF, NDEF};
1134
1135 new_tchars.t_quitc = quit_char;
1136 new_QStchars.t_quitc = quit_char;
1137 #endif /* SGTTY */
1138
1139
1140 if (to_raw_state == False) {
1141 isscreenmode = False;
1142
1143 /* Reset screen */
1144
1145 reset_terminal ();
1146 end_screen_mode ();
1147
1148 #ifndef CURSES
1149 flush ();
1150 #endif
1151
1152
1153 /* Reset tty */
1154 #ifdef CURSES
1155 savetty ();
1156 endwin ();
1157 # ifdef vms
1158 (void) system ("set terminal /ttsync /nopasthru");
1159 # endif
1160 #else
1161 #ifdef vms
1162 ttclose ();
1163 #endif
1164 #endif
1165
1166 #ifdef TERMIO
1167 if (settermio (tty_fd, & old_termio) < 0) {
1168 /*printf ("settermio failed: %s\n", serror ());*/
1169 }
1170 /* one byte of output swallowed here on SunOS */
1171 #endif
1172 #ifdef SGTTY
1173 (void) ioctl (tty_fd, TIOCSETP, & old_tty);
1174 (void) ioctl (tty_fd, TIOCSETC, & old_tchars);
1175 /* one byte of output swallowed here on SunOS */
1176 (void) ioctl (tty_fd, TIOCSLTC, & old_ltchars);
1177 (void) ioctl (tty_fd, TIOCLSET, & oldlmode);
1178 #endif
1179
1180 /* output a byte that SunOS may swallow: */
1181 (void) write (output_fd, " \r", 2);
1182
1183 #if defined (TIOCEXCL) && defined (TIOCNXCL)
1184 /* release tty lock */
1185 (void) ioctl (tty_fd, TIOCNXCL);
1186 #endif
1187
1188 return;
1189 }
1190
1191
1192 else /* (to_raw_state == True) */ {
1193 if (isscreenmode) {
1194 /* first terminal mode initialization is delayed
1195 and de-coupled from tty configuration */
1196 start_screen_mode (1);
1197 setup_terminal ();
1198 init_done = True;
1199 return;
1200 }
1201
1202 /* first call: don't rely on checkwinsize() yet! */
1203
1204 isscreenmode = True;
1205
1206 /* Init tty */
1207 #ifdef CURSES
1208 # ifdef vms
1209 (void) system ("set terminal /pasthru /nottsync");
1210 # endif
1211
1212 if (screen_acquired == False) {
1213 # ifdef use_newterm
1214 FILE * ttyin = fdopen (input_fd, "r");
1215 FILE * ttyout = fdopen (output_fd, "w");
1216 myscreen = newterm (NIL_PTR, ttyout, ttyin);
1217 if (! myscreen) {
1218 printf ("Cannot open terminal: %s\n", envvar ("TERM"));
1219 exit (-1);
1220 }
1221 # else
1222 initscr ();
1223 # endif
1224
1225 add_terminfo_entries ();
1226
1227 screen_acquired = True;
1228 configure_screen ();
1229 } else {
1230 resetty ();
1231 }
1232
1233 getwinsize ();
1234 #else
1235 #ifdef vms
1236 ttopen ();
1237 #endif
1238 #endif
1239
1240 #ifdef TERMIO
1241 # ifdef ioctl_twice
1242 if (old_termprops_not_saved) {
1243 /* Save old tty settings */
1244 if (gettermio (tty_fd, & old_termio) < 0) {
1245 /*printf ("gettermio failed: %s\n", serror ());*/
1246 }
1247
1248 /* Determine configured erase character */
1249 erase_char = old_termio.c_cc [VERASE];
1250 /*kill_char = old_termio.c_cc [VKILL];*/
1251
1252 old_termprops_not_saved = False;
1253 }
1254 # endif
1255
1256 if (gettermio (tty_fd, & new_termio) < 0) {
1257 /*printf ("gettermio failed: %s\n", serror ());*/
1258 }
1259
1260 # ifndef ioctl_twice
1261 if (old_termprops_not_saved) {
1262 /* Save old tty settings */
1263 memcpy (& old_termio, & new_termio, sizeof (struct termios));
1264
1265 /* Determine configured erase character */
1266 erase_char = old_termio.c_cc [VERASE];
1267 /*kill_char = old_termio.c_cc [VKILL];*/
1268
1269 old_termprops_not_saved = False;
1270 }
1271 # endif
1272
1273 if (controlQS == False) {
1274 new_termio.c_iflag &= ~(ISTRIP|IXON|IXOFF);
1275 } else {
1276 new_termio.c_iflag &= ~(ISTRIP);
1277 }
1278 new_termio.c_oflag &= ~OPOST;
1279 new_termio.c_cflag &= ~(PARENB|CSIZE);
1280 new_termio.c_cflag |= CS8;
1281 new_termio.c_lflag &= ~(ICANON|ECHO
1282 #ifdef use_ISIG
1283 #ifdef ISIG
1284 |ISIG
1285 #endif
1286 #endif
1287 );
1288 new_termio.c_iflag &= ~ICRNL; /* pass through ^M */
1289 #define NDEF '\000'
1290 new_termio.c_cc [VMIN] = 1;
1291 #ifdef selectread
1292 new_termio.c_cc [VTIME] = 0;
1293 #else
1294 /* let read loop monitor WINCH */
1295 new_termio.c_cc [VTIME] = 3; /* 3 is good trade-off */
1296 #endif
1297 new_termio.c_cc [VQUIT] = quit_char; /* don't use ISIG! */
1298 new_termio.c_cc [VINTR] = NDEF;
1299 new_termio.c_cc [VSUSP] = NDEF;
1300 #ifdef VSTOP
1301 new_termio.c_cc [VSTOP] = NDEF; /* or/also use IXOFF? */
1302 #endif
1303 #ifdef VDISCARD
1304 new_termio.c_cc [VDISCARD] = NDEF;
1305 #endif
1306 #ifdef VDSUSP
1307 new_termio.c_cc [VDSUSP] = NDEF;
1308 #endif
1309 #ifdef VLNEXT
1310 new_termio.c_cc [VLNEXT] = NDEF;
1311 #endif
1312 if (settermio (tty_fd, & new_termio) < 0) {
1313 /*printf ("settermio failed: %s\n", serror ());*/
1314 }
1315 #endif /* TERMIO */
1316 #ifdef SGTTY
1317 if (old_termprops_not_saved) {
1318 /* Save old tty settings */
1319 (void) ioctl (tty_fd, TIOCGETP, & old_tty);
1320 (void) ioctl (tty_fd, TIOCGETC, & old_tchars);
1321 (void) ioctl (tty_fd, TIOCGLTC, & old_ltchars);
1322 (void) ioctl (tty_fd, TIOCLGET, & oldlmode);
1323
1324 /* Determine configured erase character */
1325 erase_char = old_tty.sg_erase;
1326 /*kill_char = old_tty.sg_kill;*/
1327
1328 old_termprops_not_saved = False;
1329 }
1330
1331 /* Set line mode */
1332 /* If this feature should not be available on some system,
1333 RAW must be used instead of CBREAK below to enable 8 bit output */
1334 lmode = oldlmode;
1335 lmode |= LPASS8; /* enable 8 bit characters on input in CBREAK mode */
1336 lmode |= LLITOUT; /* enable 8 bit characters on output in CBREAK mode;
1337 this may not be necessary in newer Unixes, e.g. SunOS 4;
1338 output handling is slightly complicated by LITOUT */
1339 (void) ioctl (tty_fd, TIOCLSET, & lmode);
1340 /* Set tty to CBREAK (or RAW) mode */
1341 new_tty = old_tty;
1342 new_tty.sg_flags &= ~ECHO;
1343 new_tty.sg_flags |= CBREAK;
1344 (void) ioctl (tty_fd, TIOCSETP, & new_tty);
1345 /* Unset signal chars */
1346 if (controlQS == False) {
1347 /* leave quit_char */
1348 (void) ioctl (tty_fd, TIOCSETC, & new_tchars);
1349 } else {
1350 /* leave quit_char, ^Q, ^S */
1351 (void) ioctl (tty_fd, TIOCSETC, & new_QStchars);
1352 }
1353 (void) ioctl (tty_fd, TIOCSLTC, & new_ltchars); /* Leaves nothing */
1354 #endif /* SGTTY */
1355
1356 #if defined (TIOCEXCL) && defined (TIOCNXCL)
1357 /* prevent from other processes spoiling the editing screen;
1358 acquire tty lock
1359 - does not lock against root processes writing to tty
1360 - does not work on cygwin (as of 1.7.30)
1361 */
1362 (void) ioctl (tty_fd, TIOCEXCL);
1363 #endif
1364
1365
1366 /* Init screen */
1367 if (init_done) { /* postpone on first invocation of raw_mode */
1368 /* keyboard modes */
1369 start_screen_mode (1);
1370 /* specific terminal modes */
1371 setup_terminal ();
1372 }
1373 /* do not postpone actual screen mode */
1374 start_screen_mode (0);
1375
1376 #ifdef CURSES
1377 refresh ();
1378 /* Determine configured erase character */
1379 erase_char = erasechar ();
1380 /*kill_char = killchar ();*/
1381 #else
1382 flush ();
1383 #endif
1384
1385 /* Setup specific signal handlers */
1386 #ifdef SIGQUIT
1387 signal (SIGQUIT, catchquit); /* Catch quit_char */
1388 #endif
1389 #ifdef SIGBREAK
1390 signal (SIGBREAK, catchbreak); /* control-Break (e.g. OS/2) */
1391 #else
1392 # ifdef msdos_suppressbreak
1393 ctrlbrk (controlbreak); /* completely useless, stupid Turbo-C! */
1394 # endif
1395 #endif
1396 #ifdef SIGINT
1397 signal (SIGINT, catchint); /* Catch INTR char (^C) */
1398 #endif
1399 #ifdef SIGWINCH
1400 signal (SIGWINCH, catchwinch); /* Catch window size changes */
1401 #endif
1402 #ifdef SIGTSTP
1403 signal (SIGTSTP, catchtstp);
1404 #endif
1405 #ifdef SIGCONT
1406 signal (SIGCONT, catchcont);
1407 #endif
1408 }
1409 }
1410
1411
1412 /*======================================================================*\
1413 |* Terminal mode setup *|
1414 \*======================================================================*/
1415
1416 /**
1417 temporarily disable modifyOtherKeys for shifted letters
1418 */
1419 void
disable_modify_keys(dis)1420 disable_modify_keys (dis)
1421 FLAG dis;
1422 {
1423 #ifdef unix
1424 if (use_modifyOtherKeys && xterm_version > 0) {
1425 if (dis) {
1426 putescape ("\033[>4m");
1427 } else {
1428 putescape ("\033[>4;2m");
1429 }
1430 flush ();
1431 }
1432 #endif
1433 }
1434
1435
1436 FLAG redefined_ansi2 = False;
1437
1438 #if defined (unix) || defined (ANSI) || defined (vms)
1439
1440 FLAG redefined_ansi3 = False;
1441 FLAG redefined_ansi7 = False;
1442 FLAG redefined_curscolr = False;
1443
1444 char set_ansi2 [27];
1445 char restore_ansi2 [27];
1446 char set_ansi3 [27];
1447 char restore_ansi3 [27];
1448 char set_ansi7 [27];
1449 char restore_ansi7 [27];
1450 char set_curscolr [27];
1451 char restore_curscolr [27];
1452
1453 static void
setup_terminal()1454 setup_terminal ()
1455 {
1456 /* set redefined ANSI colors */
1457 if (redefined_ansi7) {
1458 putescape (set_ansi7);
1459 }
1460 if (redefined_ansi2) {
1461 putescape (set_ansi2);
1462 }
1463 if (redefined_ansi3) {
1464 putescape (set_ansi3);
1465 }
1466 if (redefined_curscolr) {
1467 putescape (set_curscolr);
1468 }
1469
1470 /* set special keyboard modes */
1471 if (use_modifyOtherKeys) {
1472 putescape ("\033[>4;2m");
1473 }
1474
1475 /* screen style */
1476 if (cursor_style) {
1477 static char cs [15];
1478 build_string (cs, "\033[%d q", cursor_style);
1479 putescape (cs);
1480 }
1481
1482 /* specific terminal configuration */
1483 if (configure_xterm_keyboard && xterm_version > 0) {
1484 putescape ("\033[?1037s"); /* save DEC mode value */
1485 /* send DEL from the editing‐keypad Delete key */
1486 putescape ("\033[?1037h");
1487 if (xterm_version < 122) {
1488 putescape ("\033[?1034s"); /* save DEC mode value */
1489 /* send ESC when Meta modifies a key (eightBitInput: false) */
1490 putescape ("\033[?1034l");
1491 } else {
1492 putescape ("\033[?1036s"); /* save DEC mode value */
1493 /* send ESC when Meta modifies a key (metaSendsEscape: true) */
1494 putescape ("\033[?1036h");
1495 }
1496 }
1497 #ifdef mintty_scrollbar_workaround
1498 if (mintty_version > 0) {
1499 putescape ("\033[?30l"); /* disable scrollbar to facilitate mouse wheel */
1500 # ifdef debug_terminal_resize
1501 printf ("disabling scrollbar\n");
1502 # endif
1503 }
1504 #endif
1505 if (mintty_version >= 403) {
1506 /* this mode interferes with fkeymap_rxvt
1507 if inappropriately TERM=rxvt in mintty (workaround in mined1.c) */
1508 putescape ("\033[?7727h"); /* application escape key mode: ESC sends ^[O[ */
1509 }
1510 if (mintty_version >= 501) {
1511 putescape ("\033[?7783h"); /* shortcut override on */
1512 }
1513 }
1514
1515 static void
reset_terminal()1516 reset_terminal ()
1517 {
1518 /* restore redefined ANSI colors */
1519 if (redefined_ansi7) {
1520 putescape (restore_ansi7);
1521 }
1522 if (redefined_ansi2) {
1523 putescape (restore_ansi2);
1524 }
1525 if (redefined_ansi3) {
1526 putescape (restore_ansi3);
1527 }
1528 if (redefined_curscolr) {
1529 putescape (restore_curscolr);
1530 }
1531
1532 /* reset special keyboard modes */
1533 if (use_modifyOtherKeys) {
1534 #ifdef reset_modifyOtherKeys
1535 if (mintty_version == 400) {
1536 putescape ("\033[>4;0m");
1537 } else {
1538 putescape ("\033[>4m");
1539 }
1540 #else
1541 putescape ("\033[>4m");
1542 #endif
1543 }
1544
1545 /* screen style */
1546 if (cursor_style) {
1547 putescape ("\033[0 q");
1548 }
1549
1550 /* restore specific terminal modes */
1551 if (configure_xterm_keyboard && xterm_version > 0) {
1552 putescape ("\033[?1037r"); /* restore DEC mode value */
1553 if (xterm_version < 122) {
1554 putescape ("\033[?1034r"); /* restore DEC mode value */
1555 } else {
1556 putescape ("\033[?1036r"); /* restore DEC mode value */
1557 }
1558 }
1559 #ifdef mintty_scrollbar_workaround
1560 if (mintty_version > 0) {
1561 putescape ("\033[?30h"); /* enable scrollbar if it was enabled */
1562 # ifdef debug_terminal_resize
1563 printf ("enabling scrollbar\n");
1564 # endif
1565 }
1566 #endif
1567 if (mintty_version >= 403) {
1568 putescape ("\033[?7727l"); /* reset application escape key mode */
1569 }
1570 if (mintty_version >= 501) {
1571 putescape ("\033[?7783l"); /* shortcut override off */
1572 }
1573 }
1574
1575 #else
1576
1577 static void
setup_terminal()1578 setup_terminal ()
1579 {
1580 }
1581
1582 static void
reset_terminal()1583 reset_terminal ()
1584 {
1585 }
1586
1587 #endif
1588
1589
1590 /*======================================================================*\
1591 |* Escape code I/O routine *|
1592 \*======================================================================*/
1593
1594 #ifdef CURSES
1595 void
_putescape(s)1596 _putescape (s)
1597 char * s;
1598 {
1599 /* synchronize with buffered screen output */
1600 flush ();
1601 /* bypass curses for escape sequence */
1602 if (write (output_fd, s, strlen (s)) <= 0) {
1603 /* terminal write error; cannot do anything */
1604 }
1605 }
1606 #else
1607 #define _putescape(s) putstring (s)
1608 #endif
1609
1610 void
putescape(s)1611 putescape (s)
1612 char * s;
1613 {
1614 if (screen_version > 0) {
1615 /* pass through transparently to host terminal: */
1616 _putescape ("\033P");
1617 _putescape (s);
1618 _putescape ("\033\\");
1619 } else {
1620 _putescape (s);
1621 }
1622 }
1623
1624
1625 /*======================================================================*\
1626 |* Menu borders *|
1627 \*======================================================================*/
1628
1629 /* block graphics mapping
1630 note: VGA (PC) encoding also used on Linux console!
1631 VT100 VGA curses
1632 j D9 ACS_LRCORNER
1633 k BF ACS_URCORNER
1634 l DA ACS_ULCORNER
1635 m C0 ACS_LLCORNER
1636 n ACS_PLUS
1637 o ACS_S1
1638 p ACS_S3
1639 q C4 ACS_HLINE
1640 r ACS_S7
1641 s ACS_S9
1642 t C3 ACS_LTEE
1643 u B4 ACS_RTEE
1644 v C1 ACS_BTEE
1645 w C2 ACS_TTEE
1646 x B3 ACS_VLINE
1647 */
1648
1649 /**
1650 ASCII block graphics mapping
1651 +-+-+
1652 +-+-+
1653 | | |
1654 +-+-+
1655 */
1656 static
1657 char *
asciiblockchar(c)1658 asciiblockchar (c)
1659 character c;
1660 {
1661 if (menu_border_style == 'r') {
1662 switch (c) {
1663 case 'j': return "/"; /* LR */
1664 case 'k': return "\\"; /* UR */
1665 case 'l': return "/"; /* UL */
1666 case 'm': return "\\"; /* LL */
1667 case 'n': return "+"; /* crossing (not used) */
1668 case 'q': if (cjk_width_data_version) {
1669 return "--"; /* hor. line */
1670 } else {
1671 return "-"; /* hor. line */
1672 }
1673 case 't': return "+"; /* left tee */
1674 case 'u': return "+"; /* right tee */
1675 case 'v': return "+"; /* bottom tee */
1676 case 'w': return "+"; /* top tee */
1677 case 'x': return "|"; /* vert. line */
1678 case 'f':
1679 case 'g': /* scrolling indication */
1680 if (utf8_screen) {
1681 return "¦";
1682 } else if (cjk_term || mapped_term) {
1683 return "|";
1684 } else {
1685 return "�";
1686 }
1687 default: return "";
1688 }
1689 } else {
1690 switch (c) {
1691 case 'j': return "+"; /* LR */
1692 case 'k': return "+"; /* UR */
1693 case 'l': return "+"; /* UL */
1694 case 'm': return "+"; /* LL */
1695 case 'n': return "+"; /* crossing (not used) */
1696 case 'q': if (cjk_width_data_version) {
1697 return "--"; /* hor. line */
1698 } else {
1699 return "-"; /* hor. line */
1700 }
1701 case 't': return "+"; /* left tee */
1702 case 'u': return "+"; /* right tee */
1703 case 'v': return "+"; /* bottom tee */
1704 case 'w': return "+"; /* top tee */
1705 case 'x': return "|"; /* vert. line */
1706 case 'f':
1707 case 'g': /* scrolling indication */
1708 if (utf8_screen) {
1709 return "¦";
1710 } else if (cjk_term || mapped_term) {
1711 return "|";
1712 } else {
1713 return "�";
1714 }
1715 default: return "";
1716 }
1717 }
1718 }
1719
1720 #ifndef CURSES
1721
1722 /**
1723 VGA (PC/DOS) block graphics mapping
1724 */
1725 static
1726 character
vgablockchar(c)1727 vgablockchar (c)
1728 character c;
1729 {
1730 if (menu_border_style == 'd') {
1731 switch (c) {
1732 case 'j': return 0xBC; /* LR */
1733 case 'k': return 0xBB; /* UR */
1734 case 'l': return 0xC9; /* UL */
1735 case 'm': return 0xC8; /* LL */
1736 case 'n': return 0xCE; /* crossing (not used) */
1737 case 'q': return 0xCD; /* hor. line */
1738 case 't': return 0xCC; /* left tee */
1739 case 'u': return 0xB9; /* right tee */
1740 case 'v': return 0xCA; /* bottom tee */
1741 case 'w': return 0xCB; /* top tee */
1742 case 'x': return 0xBA; /* vert. line */
1743 case 'f': /* scrolling indication up */
1744 case 'g': /* scrolling indication down */
1745 return '';
1746 #ifdef choose_scrolling_indicators
1747 return ''; /* diamond */
1748 return 0xBA; /* double line */
1749 return ''; /* arrow up */
1750 return ''; /* arrow down */
1751 return 0xB2; /* box */
1752 #endif
1753 default: return c;
1754 }
1755 } else {
1756 switch (c) {
1757 case 'j': return 0xD9; /* LR */
1758 case 'k': return 0xBF; /* UR */
1759 case 'l': return 0xDA; /* UL */
1760 case 'm': return 0xC0; /* LL */
1761 case 'n': return 0xC5; /* crossing (not used) */
1762 case 'q': return 0xC4; /* hor. line */
1763 case 't': return 0xC3; /* left tee */
1764 case 'u': return 0xB4; /* right tee */
1765 case 'v': return 0xC1; /* bottom tee */
1766 case 'w': return 0xC2; /* top tee */
1767 case 'x': return 0xB3; /* vert. line */
1768 case 'f': /* scrolling indication up */
1769 return ''; /* arrow up */
1770 case 'g': /* scrolling indication down */
1771 return ''; /* arrow down */
1772 #ifdef choose_scrolling_indicators
1773 return ''; /* arrow up */
1774 return ''; /* arrow down */
1775 return ''; /* diamond */
1776 return 0xBA; /* double line */
1777 return 0xB2; /* box */
1778 #endif
1779 default: return c;
1780 }
1781 }
1782 }
1783
1784 #if defined (unix) || defined (vms)
1785
1786 /**
1787 block graphics mapping using termcap "ac" / terminfo "acsc" capability,
1788 or VT100 block graphics by default
1789 */
1790 static
1791 char *
acblockchar(c)1792 acblockchar (c)
1793 character c;
1794 {
1795 character cout = '\0';
1796 static char sout [3];
1797 char * spoi = sout;
1798
1799 if (c == 'f' || c == 'g') {
1800 c = '`'; /* choose one of '`' 'a' '|' 'f' */
1801 }
1802
1803 if (* cAC) {
1804 int i;
1805 for (i = 0; i < strlen (cAC); i += 2) {
1806 if (cAC [i] == c) {
1807 cout = cAC [i + 1];
1808 break;
1809 }
1810 }
1811 if (cout == '\0') {
1812 /*don't return asciiblockchar (c) while in graphics mode*/
1813 /*don't skip wide handling below anyway*/
1814 cout = c;
1815 }
1816 } else {
1817 cout = c;
1818 }
1819
1820 * spoi ++ = cout;
1821 if (c == 'q' && cjk_width_data_version && cjk_term) {
1822 * spoi ++ = cout;
1823 }
1824 * spoi = '\0';
1825 return sout;
1826 }
1827
1828 #endif
1829
1830 #endif
1831
1832 /**
1833 Unicode block graphics mapping
1834 ┌─┬─┐ ╭─┬─╮
1835 ├─┼─┤ ├─┼─┤
1836 │ │ │ │ │ │
1837 └─┴─┘ ╰─┴─╯
1838 ┏━┳━┓ ╔═╦═╗
1839 ┣━╋━┫ ╠═╬═╣
1840 ┃ ┃ ┃ ║ ║ ║
1841 ┗━┻━┛ ╚═╩═╝
1842 */
1843 static
1844 char *
unicodeblockchar(c)1845 unicodeblockchar (c)
1846 character c;
1847 {
1848 if (use_ascii_graphics) {
1849 return asciiblockchar (c);
1850 } else {
1851 if (menu_border_style == 'f') {
1852 switch (c) {
1853 case 'j': return "┛"; /* LR */
1854 case 'k': return "┓"; /* UR */
1855 case 'l': return "┏"; /* UL */
1856 case 'm': return "┗"; /* LL */
1857 case 'n': return "╋"; /* crossing (not used) */
1858 case 'q': return "━"; /* hor. line */
1859 case 't': return "┣"; /* left tee */
1860 case 'u': return "┫"; /* right tee */
1861 case 'v': return "┻"; /* bottom tee */
1862 case 'w': return "┳"; /* top tee */
1863 case 'x': return "┃"; /* vert. line */
1864 case 'f': /* scroll indication up */
1865 case 'g': /* scroll indication down */
1866 return menu_cont_fatmarker;
1867 #ifdef choose_scrolling_indicators
1868 return "⬆";
1869 return "⬇";
1870 #endif
1871 default: return "";
1872 }
1873 } else if (menu_border_style == 'd') {
1874 switch (c) {
1875 case 'j': return "╝"; /* LR */
1876 case 'k': return "╗"; /* UR */
1877 case 'l': return "╔"; /* UL */
1878 case 'm': return "╚"; /* LL */
1879 case 'n': return "╬"; /* crossing (not used) */
1880 case 'q': return "═"; /* hor. line */
1881 case 't': return "╠"; /* left tee */
1882 case 'u': return "╣"; /* right tee */
1883 case 'v': return "╩"; /* bottom tee */
1884 case 'w': return "╦"; /* top tee */
1885 case 'x': return "║"; /* vert. line */
1886 case 'f': /* scroll indication up */
1887 case 'g': /* scroll indication down */
1888 return "║"; /* scrolling indication */
1889 #ifdef choose_scrolling_indicators
1890 return "⇑";
1891 return "⇓";
1892 #endif
1893 default: return "";
1894 }
1895 } else if (menu_border_style == 'r') {
1896 switch (c) {
1897 case 'j': return "╯"; /* LR */
1898 case 'k': return "╮"; /* UR */
1899 case 'l': return "╭"; /* UL */
1900 case 'm': return "╰"; /* LL */
1901 case 'n': return "┼"; /* crossing (not used) */
1902 case 'q': return "─"; /* hor. line */
1903 case 't': return "├"; /* left tee */
1904 case 'u': return "┤"; /* right tee */
1905 case 'v': return "┴"; /* bottom tee */
1906 case 'w': return "┬"; /* top tee */
1907 case 'x': return "│"; /* vert. line */
1908 case 'f': /* scroll indication up */
1909 case 'g': /* scroll indication down */
1910 return menu_cont_marker; /* scroll indication */
1911 #ifdef choose_scrolling_indicators
1912 return "↑";
1913 return "↓";
1914 return "⇡";
1915 return "⇣";
1916 #endif
1917 default: return "";
1918 }
1919 } else {
1920 switch (c) {
1921 case 'j': return "┘"; /* LR */
1922 case 'k': return "┐"; /* UR */
1923 case 'l': return "┌"; /* UL */
1924 case 'm': return "└"; /* LL */
1925 case 'n': return "┼"; /* crossing (not used) */
1926 case 'q': return "─"; /* hor. line */
1927 case 't': return "├"; /* left tee */
1928 case 'u': return "┤"; /* right tee */
1929 case 'v': return "┴"; /* bottom tee */
1930 case 'w': return "┬"; /* top tee */
1931 case 'x': return "│"; /* vert. line */
1932 case 'f': /* scroll indication up */
1933 case 'g': /* scroll indication down */
1934 return menu_cont_marker; /* scroll indication */
1935 #ifdef choose_scrolling_indicators
1936 return "↑";
1937 return "↓";
1938 return "⇡";
1939 return "⇣";
1940 #endif
1941 default: return "";
1942 }
1943 }
1944 }
1945 }
1946
1947
1948 /*======================================================================*\
1949 |* Mouse mode control *|
1950 \*======================================================================*/
1951
1952 #if defined (unix) || defined (ANSI) || defined (vms)
1953
1954 /**
1955 Adapt mouse mode to menu state (menu opened?)
1956 While a menu is open, mouse movement should be reported separately.
1957 */
1958 void
menu_mouse_mode(menu)1959 menu_mouse_mode (menu)
1960 FLAG menu;
1961 {
1962 if (! use_mouse) {
1963 return;
1964 }
1965
1966 #ifdef debug_mouse
1967 printf ("menu_mouse_mode %d\n", menu);
1968 #endif
1969
1970 if (menu) {
1971 if (in_menu_mouse_mode == False) {
1972 #ifndef CURSES_mouse
1973 if (use_mouse_button_event_tracking) {
1974 /* activate button-event tracking */
1975 putescape (cMouseEventBtnOn);
1976 if (use_mouse_anymove_inmenu) {
1977 /* activate any-event tracking */
1978 putescape (cMouseEventAnyOn);
1979 }
1980 }
1981 #endif
1982 /* hide cursor for menu display if reverse mode available
1983 for menu item marking
1984 */
1985 if (can_reverse_mode) {
1986 disp_cursor (False);
1987 }
1988 }
1989 } else {
1990 if (in_menu_mouse_mode) {
1991 #ifndef CURSES_mouse
1992 if (use_mouse_button_event_tracking) {
1993 if (use_mouse_anymove_inmenu && ! use_mouse_anymove_always) {
1994 /* deactivate any-event tracking */
1995 putescape (cMouseEventAnyOff);
1996 }
1997 /* reactivate button-event tracking */
1998 putescape (cMouseEventBtnOn);
1999 if (use_mouse_anymove_always) {
2000 /* upgrade to any-event tracking */
2001 putescape (cMouseEventAnyOn);
2002 }
2003 }
2004 #endif
2005 /* turn cursor visible again;
2006 (was turned invisible only if reverse mode available)
2007 */
2008 if (can_reverse_mode) {
2009 disp_cursor (True);
2010 }
2011 }
2012 }
2013 in_menu_mouse_mode = menu;
2014 }
2015
2016 /**
2017 Enable/disable xterm button event reporting mode.
2018 */
2019 void
mouse_button_event_mode(report)2020 mouse_button_event_mode (report)
2021 FLAG report;
2022 {
2023 if (! use_mouse_button_event_tracking) {
2024 return;
2025 }
2026
2027 #ifdef debug_mouse
2028 printf ("mouse_button_event_mode %d\n", report);
2029 #endif
2030
2031 #ifndef CURSES_mouse
2032 if (report) {
2033 /* activate button-event tracking */
2034 putescape (cMouseEventBtnOn);
2035 is_mouse_button_event_mode_enabled = True;
2036 } else if (is_mouse_button_event_mode_enabled) {
2037 #ifdef switch_button_event_tracking
2038 putescape (cMouseEventBtnOff);
2039 flush ();
2040 #endif
2041 is_mouse_button_event_mode_enabled = False;
2042 }
2043 #endif
2044 }
2045
2046 /**
2047 Switch normal/alternate screen buffer.
2048 */
2049 void
screen_buffer(alt)2050 screen_buffer (alt)
2051 FLAG alt;
2052 {
2053 #ifdef CURSES
2054 if (alt) {
2055 putescape ("[?47h");
2056 } else {
2057 putescape ("[?47l");
2058 }
2059 flush ();
2060 #else
2061 if (alt) {
2062 termputstr (cTI, aff1);
2063 } else {
2064 termputstr (cTE, aff1);
2065 }
2066 #endif
2067 }
2068
2069 #endif
2070
2071 #ifdef CURSES
2072
2073 /*======================================================================*\
2074 |* Curses *|
2075 \*======================================================================*/
2076
2077
2078 #define TRUE (char) 1
2079 #define FALSE (char) 0
2080 extern int curs_readchar _((void));
2081
2082
2083 /* colour definitions from curses.h
2084 // #define COLOR_BLACK 0
2085 // #define COLOR_RED 1
2086 // #define COLOR_GREEN 2
2087 // #define COLOR_YELLOW 3
2088 // #define COLOR_BLUE 4
2089 // #define COLOR_MAGENTA 5
2090 // #define COLOR_CYAN 6
2091 // #define COLOR_WHITE 7
2092 */
2093 /* colour pair index definitions */
2094 #define ctrlcolor 0
2095 #define menucolor 0
2096 #define diagcolor 0
2097
2098 #define markcolor 1
2099 #define emphcolor markcolor
2100 #define menuborder markcolor
2101 #define menuheader markcolor
2102 #define scrollfgcolor 2
2103 #define specialcolor 3
2104 #define selcolor 4
2105 #define menuitem 5
2106 #define HTMLcolor 6
2107 #define HTMLcomment 7
2108 #define HTMLjsp 8
2109 #define XMLattrib 9
2110 #define XMLvalue 10
2111 #define colour8_base 11
2112
2113 #if NCURSES_VERSION_MAJOR >= 5
2114 #define use_default_colour
2115 #endif
2116 #if NCURSES_VERSION_MAJOR == 4
2117 # if NCURSES_VERSION_MINOR >= 2
2118 #define use_default_colour
2119 # endif
2120 #endif
2121
2122 #ifdef use_default_colour
2123 #define COLOR_fg -1
2124 #define COLOR_bg -1
2125 #else
2126 #define COLOR_fg COLOR_WHITE
2127 #define COLOR_bg COLOR_BLACK
2128 #endif
2129
2130 static
2131 void
init_colours()2132 init_colours ()
2133 {
2134 start_color ();
2135 #ifdef use_default_colour
2136 use_default_colors ();
2137 #endif
2138 if (! has_colors ()) {
2139 bw_term = True;
2140 }
2141
2142 /* This produces silly warnings if compiled with gcc option -Wconversion
2143 ("passing arg ... with different width due to prototype")
2144 although all parameters are short.
2145 */
2146 #ifndef vms
2147 init_pair (markcolor, COLOR_RED, COLOR_bg);
2148 init_pair (scrollfgcolor, COLOR_CYAN, COLOR_BLUE);
2149 init_pair (specialcolor, COLOR_CYAN, COLOR_bg);
2150 init_pair (selcolor, COLOR_BLUE, COLOR_bg);
2151
2152 init_pair (menuitem, COLOR_BLACK, COLOR_YELLOW);
2153 init_pair (HTMLcomment, COLOR_BLUE, COLOR_YELLOW);
2154 init_pair (HTMLcolor, COLOR_CYAN, COLOR_bg);
2155 init_pair (HTMLjsp, COLOR_BLUE, COLOR_bg);
2156 init_pair (XMLattrib, COLOR_RED, COLOR_bg);
2157 init_pair (XMLvalue, COLOR_MAGENTA, COLOR_bg);
2158
2159 init_pair (colour8_base + 0, COLOR_BLACK, COLOR_bg);
2160 init_pair (colour8_base + 1, COLOR_RED, COLOR_bg);
2161 init_pair (colour8_base + 2, COLOR_GREEN, COLOR_bg);
2162 init_pair (colour8_base + 3, COLOR_YELLOW, COLOR_bg);
2163 init_pair (colour8_base + 4, COLOR_BLUE, COLOR_bg);
2164 init_pair (colour8_base + 5, COLOR_MAGENTA, COLOR_bg);
2165 init_pair (colour8_base + 6, COLOR_CYAN, COLOR_bg);
2166 init_pair (colour8_base + 7, COLOR_WHITE, COLOR_bg);
2167 #endif
2168 }
2169
2170
2171 void
__putchar(c)2172 __putchar (c)
2173 register character c;
2174 {
2175 addch (c);
2176 }
2177
2178 void
putblockchar(c)2179 putblockchar (c)
2180 register character c;
2181 {
2182 if (menu_border_style == 'P' && c != 'q') {
2183 return;
2184 } else if (menu_border_style == 'p' && c != 'q') {
2185 putstring (" ");
2186 return;
2187 }
2188
2189 if (use_normalchars_boxdrawing) {
2190 addstr (unicodeblockchar (c));
2191 } else {
2192 #ifdef vms
2193 addstr (asciiblockchar (c));
2194 #else
2195 switch (c) {
2196 case 'j': addch (ACS_LRCORNER); break;
2197 case 'k': addch (ACS_URCORNER); break;
2198 case 'l': addch (ACS_ULCORNER); break;
2199 case 'm': addch (ACS_LLCORNER); break;
2200 case 'n': addch (ACS_PLUS); break;
2201 case 'q': addch (ACS_HLINE); break;
2202 case 't': addch (ACS_LTEE); break;
2203 case 'u': addch (ACS_RTEE); break;
2204 case 'v': addch (ACS_BTEE); break;
2205 case 'w': addch (ACS_TTEE); break;
2206 case 'x': addch (ACS_VLINE); break;
2207 case 'f':
2208 case 'g': addch (ACS_DIAMOND); break;
2209 default: addch (' ');
2210 }
2211 #endif
2212 }
2213 }
2214
2215 void
ring_bell()2216 ring_bell ()
2217 {
2218 beep ();
2219 }
2220
2221 void
putstring(str)2222 putstring (str)
2223 register char * str;
2224 {
2225 addstr (str);
2226 }
2227
2228 void
flush()2229 flush ()
2230 {
2231 refresh ();
2232 }
2233
2234 void
clear_screen()2235 clear_screen ()
2236 {
2237 clear ();
2238 }
2239
2240 void
clear_eol()2241 clear_eol ()
2242 {
2243 clrtoeol ();
2244 }
2245
2246 void
erase_chars(n)2247 erase_chars (n)
2248 register int n;
2249 {
2250 while (n -- > 0) {
2251 __putchar (' ');
2252 }
2253 }
2254
2255 void
scroll_forward()2256 scroll_forward ()
2257 {
2258 scroll (stdscr);
2259 }
2260
2261 void
scroll_reverse()2262 scroll_reverse ()
2263 { /* only to be called if can_add_line or cursor is at top of screen */
2264 insertln ();
2265 }
2266
2267 void
add_line(y)2268 add_line (y)
2269 register int y;
2270 { /* only to be called if can_add_line == True */
2271 move (y + MENU, 0);
2272 insertln ();
2273 }
2274
2275 void
delete_line(y)2276 delete_line (y)
2277 register int y;
2278 {
2279 move (y + MENU, 0);
2280 deleteln ();
2281 }
2282
2283 void
set_cursor(x,y)2284 set_cursor (x, y)
2285 register int x;
2286 register int y;
2287 {
2288 /*current_cursor_y = y;*/
2289 move (y + MENU, x);
2290 }
2291
2292 void
reverse_on()2293 reverse_on ()
2294 {
2295 standout ();
2296 }
2297
2298 void
reverse_off()2299 reverse_off ()
2300 {
2301 standend ();
2302 }
2303
2304
2305 static
2306 void
configure_screen()2307 configure_screen ()
2308 {
2309 #ifdef __PDCURSES__
2310 keypad (stdscr, TRUE);
2311 #endif
2312
2313 #ifdef KEY_MOUSE
2314
2315 # ifdef __PDCURSES__
2316 (void) mouse_set (ALL_MOUSE_EVENTS);
2317 # else
2318 # ifdef NCURSES_VERSION
2319 (void) mousemask (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED
2320 # ifdef BUTTON_SHIFT
2321 | BUTTON_SHIFT
2322 # endif
2323 # ifdef ALL_MOUSE_EVENTS
2324 | ALL_MOUSE_EVENTS
2325 # endif
2326 # ifdef REPORT_MOUSE_POSITION
2327 | REPORT_MOUSE_POSITION
2328 # endif
2329 , /*(mmask_t)*/ (unsigned long) 0);
2330 # endif
2331 # endif
2332 #endif
2333
2334 init_colours ();
2335
2336 #define use_cbreak
2337
2338 #ifdef vms
2339 crmode ();
2340 #else
2341 # ifdef use_cbreak
2342 /* not sufficient to suppress ^S processing on Unix in pipe ?! */
2343 /* but now also VSTOP is explicitly removed */
2344 cbreak ();
2345 # else
2346 raw ();
2347 # endif
2348 nonl ();
2349 #endif
2350
2351 meta (stdscr, TRUE); /* should force 8-bit-cleanness but doesn't work */
2352 noecho ();
2353 scrollok (stdscr, FALSE);
2354
2355 #if defined (unix) && ! defined (ultrix)
2356 # ifndef __EMX__
2357 idlok (stdscr, TRUE);
2358 # endif
2359 # ifndef sun
2360 typeahead (input_fd);
2361 # endif
2362 #endif
2363 }
2364
2365 static
2366 void
start_screen_mode(kb)2367 start_screen_mode (kb)
2368 int kb;
2369 {
2370 /* for curses, see configure_screen () above */
2371 }
2372
2373 static
2374 void
end_screen_mode()2375 end_screen_mode ()
2376 {
2377 }
2378
2379
2380 static
2381 void
get_term_cap(TERMname)2382 get_term_cap (TERMname)
2383 char * TERMname;
2384 {
2385 #ifdef SETLOCALE
2386 setlocale (LC_ALL, "");
2387 #endif
2388
2389 YMAX = LINES - 1 - MENU; /* # of lines */
2390 XMAX = COLS - 1; /* # of columns */
2391 /* getwinsize (); */
2392 }
2393
2394 void
altcset_on()2395 altcset_on ()
2396 {
2397 attron (A_ALTCHARSET);
2398 }
2399
2400 void
altcset_off()2401 altcset_off ()
2402 {
2403 attroff (A_ALTCHARSET);
2404 }
2405
2406 void
disp_cursor(visible)2407 disp_cursor (visible)
2408 FLAG visible;
2409 {
2410 if (visible) {
2411 curs_set (1);
2412 } else {
2413 curs_set (0);
2414 }
2415 }
2416
2417 void
set_screen_mode(m)2418 set_screen_mode (m)
2419 int m;
2420 {}
2421
2422 void
maximize_restore_screen()2423 maximize_restore_screen ()
2424 {
2425 }
2426
2427 void
switch_textmode_height(cycle)2428 switch_textmode_height (cycle)
2429 FLAG cycle;
2430 {}
2431
2432 void
resize_font(inc)2433 resize_font (inc)
2434 int inc;
2435 {
2436 if (mintty_version >= 503) {
2437 if (inc > 0) { /* increase font size */
2438 putescape ("]7770;+1");
2439 } else if (inc < 0) { /* decrease font size */
2440 putescape ("]7770;-1");
2441 } else { /* reset to default */
2442 putescape ("]7770;");
2443 }
2444 } else if (xterm_version >= 203 /* best guess */) {
2445 if (inc > 0) { /* increase font size */
2446 putescape ("]50;#+1");
2447 } else if (inc < 0) { /* decrease font size */
2448 putescape ("]50;#-1");
2449 } else { /* reset to default */
2450 putescape ("]50;#");
2451 }
2452 }
2453 }
2454
2455 static
2456 void
resize_screen(l,c)2457 resize_screen (l, c)
2458 int l;
2459 int c;
2460 {
2461 static char s [22];
2462 build_string (s, "\033[8;%d;%dt", l, c);
2463 putescape (s);
2464 }
2465
2466 static
2467 void
resize_vt(sb,keep_columns)2468 resize_vt (sb, keep_columns)
2469 FLAG sb;
2470 FLAG keep_columns;
2471 {
2472 if (keep_columns == True) {
2473 /* change number of lines (VT420) */
2474 int lines = YMAX + 1 + MENU;
2475 static int vtlines [] = {24, 36, 48, 72, 144};
2476 int i;
2477 static char s [15];
2478 if (sb == SMALLER) {
2479 for (i = arrlen (vtlines) - 1; i >= 0; i --) {
2480 if (lines > vtlines [i]) {
2481 build_string (s, "\033[%dt", vtlines [i]);
2482 putescape (s);
2483 YMAX = vtlines [i] - 1 - MENU;
2484 return;
2485 }
2486 }
2487 } else {
2488 for (i = 0; i < arrlen (vtlines); i ++) {
2489 if (lines < vtlines [i]) {
2490 build_string (s, "\033[%dt", vtlines [i]);
2491 putescape (s);
2492 YMAX = vtlines [i] - 1 - MENU;
2493 return;
2494 }
2495 }
2496 }
2497 } else {
2498 /* switch 80/132 columns */
2499 if (sb == SMALLER) {
2500 putescape ("\033[?40h\033[?3l");
2501 XMAX = 79;
2502 } else {
2503 putescape ("\033[?40h\033[?3h");
2504 XMAX = 131;
2505 }
2506 }
2507 }
2508
2509 void
resize_the_screen(sb,keep_columns)2510 resize_the_screen (sb, keep_columns)
2511 FLAG sb;
2512 FLAG keep_columns;
2513 {
2514 if (decterm_version > 0) {
2515 resize_vt (sb, keep_columns);
2516 } else {
2517 int ldif = 6;
2518 int coldif = 13;
2519 if (sb == SMALLER) {
2520 ldif = - ldif;
2521 coldif = - coldif;
2522 }
2523 if (keep_columns == True) {
2524 coldif = 0;
2525 } else if (keep_columns == NOT_VALID) {
2526 ldif = 0;
2527 }
2528
2529 resize_screen (YMAX + 1 + MENU + ldif, XMAX + 1 + coldif);
2530 }
2531 }
2532
2533 #else /* #ifdef CURSES */
2534
2535
2536 /*======================================================================*\
2537 non-curses
2538 \*======================================================================*/
2539
2540
2541 #ifndef msdos
2542 void
ring_bell()2543 ring_bell ()
2544 {
2545 putchar ('\07');
2546 }
2547 #endif
2548
2549
2550 /*======================================================================*\
2551 |* Basic buffered screen output *|
2552 \*======================================================================*/
2553
2554 /* screen buffer length should be sufficient to keep one full window;
2555 not essential, though, on very large screen
2556 */
2557 #define screenbuflen 22222
2558
2559 static char screenbuf [screenbuflen + 1];
2560 static unsigned int screenbuf_count = 0;
2561
2562 #define dont_debug_write
2563
2564 #ifdef debug_write
2565 static
print_buf(s,len)2566 void print_buf (s, len)
2567 char * s;
2568 int len;
2569 {
2570 while (len > 0) {
2571 if ((* s & 0xE0) == 0) {
2572 printf ("^%c", * s + 0x40);
2573 } else {
2574 printf ("%c", * s);
2575 }
2576 s ++;
2577 len --;
2578 }
2579 }
2580 #endif
2581
2582 /*
2583 * Flush the screen buffer
2584 */
2585 static
2586 int
flush_screenbuf()2587 flush_screenbuf ()
2588 {
2589 if (screenbuf_count == 0) { /* There is nothing to flush */
2590 return FINE;
2591 }
2592
2593 #ifdef conio
2594 cputs (screenbuf);
2595 #else
2596 #ifdef BorlandC
2597 screenbuf [screenbuf_count] = '\0';
2598 /* don't ask me why that crazy compiler doesn't work with write () below */
2599 printf ("%s", screenbuf);
2600 #else
2601 {
2602 char * writepoi = screenbuf;
2603 int written = 0;
2604 int none_count = 0;
2605 /* int less_count = 0; */
2606
2607 #ifdef debug_write
2608 printf ("writing %d: ", screenbuf_count);
2609 print_buf (writepoi, screenbuf_count);
2610 printf ("\n");
2611 if (tty_closed) {
2612 printf ("(tty closed) - not written\n");
2613 sleep (1);
2614 }
2615 #endif
2616
2617 if (tty_closed) {
2618 screenbuf_count = 0;
2619 return ERRORS;
2620 }
2621
2622 while (screenbuf_count > 0) {
2623 #ifdef vms_async_output
2624 /* no noticeable speed improvement */
2625 written = ttputs (writepoi, screenbuf_count);
2626 #else
2627 written = write (output_fd, writepoi, screenbuf_count);
2628 #endif
2629 #ifdef debug_write
2630 printf ("written %d (errno %d: %s)\n", written, geterrno (), serror ());
2631 #endif
2632 if (written == -1) {
2633 if (geterrno () == EINTR && winchg) {
2634 /* try again */
2635 } else {
2636 tty_closed = True;
2637 panicio ("Terminal write error", serror ());
2638 screenbuf_count = 0;
2639 return ERRORS;
2640 }
2641 } else if (written == 0) {
2642 none_count ++;
2643 if (none_count > 20) {
2644 panicio ("Terminal write error", serror ());
2645 screenbuf_count = 0;
2646 return ERRORS;
2647 }
2648 } else {
2649 screenbuf_count -= written;
2650 writepoi += written;
2651 }
2652 }
2653 }
2654 #endif
2655 #endif
2656
2657 screenbuf_count = 0;
2658 return FINE;
2659 }
2660
2661 void
flush()2662 flush ()
2663 {
2664 (void) flush_screenbuf ();
2665 }
2666
2667 /*
2668 * putoutchar does a buffered output to screen.
2669 */
2670 static
2671 int
putoutchar(c)2672 putoutchar (c)
2673 character c;
2674 {
2675 if (c == '\n') {
2676 if (putoutchar ('\r') == ERRORS) {
2677 return ERRORS;
2678 }
2679 }
2680 if (translate_output) {
2681 if ((c & '\200') != '\0') {
2682 char clow = (c & '\177');
2683 altcset_on ();
2684 if ((int) clow < translen) {
2685 putoutchar (transout [(int) clow]);
2686 } else {
2687 putoutchar (clow);
2688 }
2689 altcset_off ();
2690 return FINE;
2691 }
2692 }
2693 if (screen_version > 0 && screen_version < 400 && c >= 0x80 && c < 0xA0) {
2694 /* embed C1 control characters (workaround for 'screen' bug) */
2695 putoutchar ('\033');
2696 putoutchar ('P');
2697 screenbuf [screenbuf_count ++] = c;
2698 if (screenbuf_count == screenbuflen) {
2699 (void) flush_screenbuf ();
2700 }
2701 putoutchar ('\033');
2702 putoutchar ('\\');
2703 return FINE;
2704 }
2705 screenbuf [screenbuf_count ++] = c;
2706 if (screenbuf_count == screenbuflen) {
2707 return flush_screenbuf ();
2708 }
2709
2710 #define dont_debug_all_output
2711 #ifdef debug_all_output
2712 if (c == '\033') {
2713 printf ("^[");
2714 } else {
2715 printf ("%c", c);
2716 }
2717 #endif
2718 #ifdef debug_flush_output
2719 flush ();
2720 #endif
2721
2722 return FINE;
2723 }
2724
2725 /*
2726 * Putoutstring writes the given string out to the terminal.
2727 * (buffered via misused screen buffer!)
2728 putstring (str) does putoutstring (str) unless with curses or conio
2729 */
2730 static
2731 void
putoutstring(text)2732 putoutstring (text)
2733 register char * text;
2734 {
2735 while (* text != '\0') {
2736 (void) putoutchar (* text ++);
2737 }
2738 }
2739
2740 void
__putchar(c)2741 __putchar (c)
2742 register character c;
2743 {
2744 #ifdef conio
2745 putch (c);
2746 #else
2747 putoutchar (c);
2748 #endif
2749 }
2750
2751 void
putstring(str)2752 putstring (str)
2753 register char * str;
2754 {
2755 #ifdef conio
2756 cputs (str);
2757 #else
2758 putoutstring (str);
2759 #endif
2760 }
2761
2762 /**
2763 Output a menu border character. Decide which style to use,
2764 block graphics (VT100 or VGA), Unicode graphics, ASCII graphics.
2765 This and it's setup is a mess and could do with some revision.
2766 */
2767 void
putblockchar(c)2768 putblockchar (c)
2769 register character c;
2770 {
2771 if (menu_border_style == 'P' && c != 'q') {
2772 return;
2773 } else if (menu_border_style == 'p' && c != 'q') {
2774 putstring (" ");
2775 return;
2776 }
2777
2778 #ifdef conio
2779 if (use_ascii_graphics) {
2780 putstring (asciiblockchar (c));
2781 } else {
2782 putchar (vgablockchar (c));
2783 }
2784 #else
2785 if (use_ascii_graphics) {
2786 putoutstring (asciiblockchar (c));
2787 } else if (use_vga_block_graphics) {
2788 putoutchar (vgablockchar (c));
2789 } else if (use_normalchars_boxdrawing) {
2790 putoutstring (unicodeblockchar (c));
2791 } else if (use_pc_block_graphics) {
2792 putoutchar (vgablockchar (c));
2793 } else {
2794 # if defined (unix) || defined (vms)
2795 putoutstring (acblockchar (c));
2796 # else
2797 putoutstring (asciiblockchar (c));
2798 # endif
2799 }
2800 #endif
2801 }
2802
2803
2804 /*======================================================================*\
2805 |* Screen control functions *|
2806 \*======================================================================*/
2807
2808 #if defined (unix) || defined (ANSI)
2809
2810 void
clear_screen()2811 clear_screen ()
2812 {
2813 termputstr (cCL, affmax);
2814 }
2815
2816 void
clear_eol()2817 clear_eol ()
2818 {
2819 if (can_clear_eol) {
2820 termputstr (cCE, aff1);
2821 }
2822 }
2823
2824 void
erase_chars(n)2825 erase_chars (n)
2826 register int n;
2827 {
2828 #ifdef ANSI
2829 static char s [15];
2830 build_string (s, "\033[%dX", n);
2831 termputstr (s, aff1);
2832 #else
2833 termputstr (tgoto (cEC, 0, n), aff1);
2834 #endif
2835 }
2836
2837 void
scroll_forward()2838 scroll_forward ()
2839 {
2840 set_cursor (0, YMAX);
2841 termputstr ("\n", affmax);
2842 }
2843
2844 void
scroll_reverse()2845 scroll_reverse ()
2846 { /* only to be called if can_add_line or cursor is at top of screen */
2847 if (can_add_line) {
2848 add_line (0);
2849 } else {
2850 termputstr (cSR, affmax);
2851 }
2852 }
2853
2854 static
2855 void
scrolling_region(yb,ye)2856 scrolling_region (yb, ye)
2857 register int yb;
2858 register int ye;
2859 {
2860 #ifdef ANSI
2861 static char s [22];
2862 build_string (s, "\033[%d;%dr", yb + 1, ye + 1);
2863 termputstr (s, aff1);
2864 #else
2865 termputstr (tgoto (cCS, ye, yb), aff1);
2866 #endif
2867 }
2868
2869 void
add_line(y)2870 add_line (y)
2871 register int y;
2872 { /* only to be called if can_add_line == True */
2873 if (cAL) {
2874 set_cursor (0, y);
2875 termputstr (cAL, affmax);
2876 } else {
2877 set_cursor (0, y);
2878 termputstr (cSC, aff1);
2879 scrolling_region (MENU + y, MENU + YMAX);
2880 termputstr (cRC, aff1);
2881 termputstr (cSR, affmax);
2882 scrolling_region (0, MENU + YMAX);
2883 termputstr (cRC, aff1);
2884 }
2885 }
2886
2887 void
delete_line(y)2888 delete_line (y)
2889 register int y;
2890 {
2891 if (cDL) {
2892 set_cursor (0, y);
2893 termputstr (cDL, affmax);
2894 } else {
2895 set_cursor (0, y);
2896 termputstr (cSC, aff1);
2897 scrolling_region (MENU + y, MENU + YMAX);
2898 set_cursor (0, YMAX);
2899 termputstr ("\n", affmax);
2900 scrolling_region (0, MENU + YMAX);
2901 termputstr (cRC, aff1);
2902 }
2903 }
2904
2905 void
set_cursor(x,y)2906 set_cursor (x, y)
2907 register int x;
2908 register int y;
2909 {
2910 #ifdef ANSI
2911 static char s [22];
2912 #endif
2913
2914 if (screen_version > 0) {
2915 /* flush cursor position (workaround for 'screen' bug) */
2916 #ifdef ANSI
2917 termputstr ("\033[1;1H", aff1);
2918 #else
2919 termputstr (tgoto (cCM, 0, 0), aff1);
2920 #endif
2921 }
2922
2923 /*current_cursor_y = y;*/
2924 #ifdef ANSI
2925 build_string (s, "\033[%d;%dH", y + 1 + MENU, x + 1);
2926 termputstr (s, aff1);
2927 #else
2928 termputstr (tgoto (cCM, x, y + MENU), aff1);
2929 #endif
2930 }
2931
2932 #define dont_use_standout /* might add underline, e.g. within 'screen' */
2933
2934 void
reverse_on()2935 reverse_on ()
2936 {
2937 #ifdef use_standout
2938 termputstr (cSO, aff1);
2939 #else
2940 termputstr (cMR, aff1);
2941 #endif
2942 }
2943
2944 void
reverse_off()2945 reverse_off ()
2946 {
2947 #ifdef use_standout
2948 termputstr (cSE, aff1);
2949 #else
2950 termputstr (cME, aff1);
2951 #endif
2952 }
2953
2954 void
altcset_on()2955 altcset_on ()
2956 {
2957 if (use_pc_block_graphics) {
2958 termputstr (cS2, aff1);
2959 } else {
2960 termputstr (cAS, aff1);
2961 }
2962 }
2963
2964 void
altcset_off()2965 altcset_off ()
2966 {
2967 if (use_pc_block_graphics) {
2968 termputstr (cS3, aff1);
2969 } else {
2970 termputstr (cAE, aff1);
2971 }
2972 }
2973
2974 #endif /* #if defined (unix) || defined (ANSI) */
2975
2976 #if defined (unix) && ! defined (ANSI)
2977
2978 static
2979 void
get_terminfo(TERMname)2980 get_terminfo (TERMname)
2981 char * TERMname;
2982 {
2983 /* get screen size */
2984 YMAX = term_getnum ("li", "lines") - 1 - MENU; /* # of lines */
2985 XMAX = term_getnum ("co", "cols") - 1; /* # of columns */
2986 getwinsize ();
2987
2988 /* get screen control escape sequences */
2989 cCL = term_getstr ("cl", "clear"); /* clear screen */
2990 cCE = term_getstr ("ce", "el"); /* clear to end of line */
2991 cCD = term_getstr ("cd", "ed"); /* clear to end of screen */
2992 cCM = term_getstr ("cm", "cup"); /* move cursor */
2993
2994 cEC = term_getstr ("ec", "ech"); /* erase characters */
2995 cSR = term_getstr ("sr", "ri"); /* scroll down */
2996 cAL = term_getstr ("al", "il1"); /* add line */
2997 cDL = term_getstr ("dl", "dl1"); /* delete line */
2998 cCS = term_getstr ("cs", "csr"); /* change scrolling region */
2999 cSC = term_getstr ("sc", "sc"); /* save cursor \ needed with VT100 */
3000 cRC = term_getstr ("rc", "rc"); /* restore cursor / for add/delete line */
3001
3002 cME = term_getstr ("me", "sgr0"); /* turn off all attributes */
3003 cMR = term_getstr ("mr", "rev"); /* reverse */
3004 cMD = term_getstr ("md", "bold"); /* bold / extra bright */
3005 cMH = term_getstr ("mh", "dim"); /* dim / half-bright */
3006 cUL = term_getstr ("us", "smul"); /* underline */
3007 cBL = term_getstr ("mb", "blink"); /* blink */
3008 cSO = term_getstr ("so", "smso"); /* standout mode */
3009 cSE = term_getstr ("se", "rmso"); /* end standout mode */
3010
3011 cVS = term_getstr ("vs", "cvvis"); /* visual cursor */
3012 cVE = term_getstr ("ve", "cnorm"); /* normal cursor */
3013 cVI = term_getstr ("vi", "civis"); /* invisible cursor */
3014 cTI = term_getstr ("ti", "smcup"); /* positioning mode */
3015 cTE = term_getstr ("te", "rmcup"); /* end " */
3016 cKS = term_getstr ("ks", "smkx"); /* keypad mode */
3017 cKE = term_getstr ("ke", "rmkx"); /* end " */
3018 cAS = term_getstr ("as", "smacs"); /* alternate character set */
3019 cAE = term_getstr ("ae", "rmacs"); /* end " */
3020 cEA = term_getstr ("eA", "enacs"); /* enable " */
3021 cAC = term_getstr ("ac", "acsc"); /* block graphics code mapping */
3022 cS2 = term_getstr ("S2", "smpch"); /* PC character set */
3023 cS3 = term_getstr ("S3", "rmpch"); /* end " */
3024
3025 cAF = term_getstr ("AF", "setaf"); /* select foreground colour */
3026 cAB = term_getstr ("AB", "setab"); /* select background colour */
3027 if (term_getnum ("Co", "colors") == 0 && ! cAF) {
3028 bw_term = True;
3029 }
3030 standout_glitch = term_getflag ("xs", "xhp"); /* standout glitch */
3031
3032 /* add function key escape sequences */
3033 add_terminfo_entries ();
3034 }
3035
3036 #endif /* #if defined (unix) || defined (ANSI) */
3037
3038
3039 #if defined (vms) || defined (ANSI)
3040
3041 static
3042 FLAG
term_setup(TERMname)3043 term_setup (TERMname)
3044 char * TERMname;
3045 {
3046 return False;
3047 }
3048
3049 static
3050 void
get_terminfo(TERMname)3051 get_terminfo (TERMname)
3052 char * TERMname;
3053 {
3054 }
3055
3056 #endif
3057
3058
3059 #if defined (unix) || defined (ANSI) || defined (vms)
3060
3061 void
disp_cursor(visible)3062 disp_cursor (visible)
3063 FLAG visible;
3064 {
3065 if (visible) {
3066 /* first turn it "normal" in case "very visible" does
3067 not work, then try "very visible"
3068 */
3069 termputstr (cVE, affmax);
3070 termputstr (cVS, affmax);
3071 } else {
3072 termputstr (cVI, affmax);
3073 }
3074 }
3075
3076 static
3077 void
set_term_defaults(TERMname)3078 set_term_defaults (TERMname)
3079 char * TERMname;
3080 {
3081 /* set common ANSI sequences */
3082 cCL = "[H[J"; /* clear screen */
3083 cCE = "[K"; /* clear to end of line */
3084 cCD = "[J"; /* clear to end of screen */
3085 cCM = "[%i%p1%d;%p2%dH"; /* move cursor */
3086 cCS = NIL_PTR; /* change scrolling region */
3087 cEC = NIL_PTR; /* erase characters */
3088 cSR = NIL_PTR; /* scroll down */
3089 cAL = NIL_PTR; /* add line */
3090 cDL = NIL_PTR; /* delete line */
3091 cSC = NIL_PTR; /* save cursor position */
3092 cRC = NIL_PTR; /* restore cursor position */
3093
3094 cVS = NIL_PTR; /* visual cursor */
3095 cVE = NIL_PTR; /* normal cursor */
3096 cVI = NIL_PTR; /* invisible cursor */
3097 cTI = NIL_PTR; /* positioning mode */
3098 cTE = NIL_PTR; /* end " */
3099 cKS = NIL_PTR; /* keypad mode */
3100 cKE = NIL_PTR; /* end " */
3101
3102 cME = "[0m"; /* turn off all attributes */
3103 cMR = "[7m"; /* reverse */
3104 cMD = "[1m"; /* bold */
3105 cMH = NIL_PTR; /* dim */
3106 cUL = "[4m"; /* underline */
3107 cBL = "[5m"; /* blink */
3108 cSO = "[7m"; /* standout mode */
3109 cSE = "[0m";; /* end standout */
3110 cAF = NIL_PTR; /* set foreground colour */
3111 cAB = NIL_PTR; /* set background colour */
3112 cAS = NIL_PTR; /* alternate character set */
3113 cAE = NIL_PTR; /* end " */
3114 cEA = NIL_PTR; /* enable " */
3115 cAC = NIL_PTR; /* block graphics code mapping */
3116 cS2 = NIL_PTR; /* PC character set */
3117 cS3 = NIL_PTR; /* end " */
3118 #ifdef __CYGWIN__
3119 if (strisprefix ("interix", TERMname)) {
3120 /* running cygwin version in interix terminal,
3121 cygwin console terminal emulation is applicable
3122 */
3123 TERMname = "cygwin";
3124 }
3125 #endif
3126 if (streq (TERMname, "cygwin")) {
3127 cEC = "[%dX"; /* erase characters */
3128 cSR = "M"; /* scroll down */
3129 cAL = "[L"; /* add line */
3130 cDL = "[M"; /* delete line */
3131 cSC = "7"; /* save cursor position */
3132 cRC = "8"; /* restore cursor position */
3133
3134 cTI = "7[?47h[2J"; /* positioning mode */
3135 cTE = "[2J[?47l8"; /* end " */
3136
3137 cSE = "[27m"; /* end standout */
3138 cS2 = "[11m"; /* PC character set */
3139 cS3 = "[10m"; /* end " */
3140 } else if (strisprefix ("xterm", TERMname)) {
3141 cCS = "[%i%p1%d;%p2%dr"; /* change scrolling region */
3142 cEC = "[%dX"; /* erase characters */
3143 cSR = "M"; /* scroll down */
3144 cAL = "[L"; /* add line */
3145 cDL = "[M"; /* delete line */
3146 cSC = "7"; /* save cursor position */
3147 cRC = "8"; /* restore cursor position */
3148
3149 cVS = "[?12;25h"; /* visual cursor */
3150 cVE = "[?12l[?25h"; /* normal cursor */
3151 cVI = "[?25l"; /* invisible cursor */
3152 #ifdef newer_xterm_may_use
3153 /* xterm_version >= 90, not detected yet at this time */
3154 cTI = "[?1049h"; /* positioning mode */
3155 cTE = "[?1049l"; /* end " */
3156 #else
3157 cTI = "7[?47h[2J"; /* positioning mode */
3158 cTE = "[2J[?47l8"; /* end " */
3159 #endif
3160 cKS = "[?1h="; /* keypad mode */
3161 cKE = "[?1l>"; /* end " */
3162
3163 cSE = "[27m"; /* end standout */
3164 cAS = "(0"; /* alternate character set */
3165 cAE = "(B"; /* end " */
3166 } else if (strisprefix ("rxvt", TERMname)) {
3167 cCS = "[%i%p1%d;%p2%dr"; /* change scrolling region */
3168 cSR = "M"; /* scroll down */
3169 cAL = "[L"; /* add line */
3170 cDL = "[M"; /* delete line */
3171 cSC = "7"; /* save cursor position */
3172 cRC = "8"; /* restore cursor position */
3173
3174 cVE = "[?25h"; /* normal cursor */
3175 cVI = "[?25l"; /* invisible cursor */
3176 cTI = "7[?47h[2J"; /* positioning mode */
3177 cTE = "[2J[?47l8"; /* end " */
3178 cKS = "="; /* keypad mode */
3179 cKE = ">"; /* end " */
3180
3181 cSE = "[27m"; /* end standout */
3182 cAS = ""; /* alternate character set */
3183 cAE = ""; /* end " */
3184 cEA = "(B)0"; /* enable " */
3185 } else if (strisprefix ("vt", TERMname)
3186 && ! streq ("vt52", TERMname)
3187 && ! strisprefix ("vt50", TERMname)
3188 ) {
3189 cCS = "[%i%p1%d;%p2%dr"; /* change scrolling region */
3190 cSR = "M"; /* scroll down */
3191 cSC = "7"; /* save cursor position */
3192 cRC = "8"; /* restore cursor position */
3193 if (TERMname [2] > '1' || strisprefix ("vt102", TERMname)) {
3194 cAL = "[L"; /* add line */
3195 cDL = "[M"; /* delete line */
3196 }
3197
3198 cKS = "[?1h="; /* keypad mode */
3199 cKE = "[?1l>"; /* end " */
3200
3201 cSE = "[m"; /* end standout */
3202 cAS = ""; /* alternate character set */
3203 cAE = ""; /* end " */
3204 cEA = "(B)0"; /* enable " */
3205 } else if (strisprefix ("linux", TERMname)) {
3206 cCS = "[%i%p1%d;%p2%dr"; /* change scrolling region */
3207 cEC = "[%dX"; /* erase characters */
3208 cSR = "M"; /* scroll down */
3209 cAL = "[L"; /* add line */
3210 cDL = "[M"; /* delete line */
3211 cSC = "7"; /* save cursor position */
3212 cRC = "8"; /* restore cursor position */
3213
3214 cVS = "[?25h[?8c"; /* visual cursor */
3215 cVE = "[?25h[?0c"; /* normal cursor */
3216 cVI = "[?25l[?1c"; /* invisible cursor */
3217
3218 cSE = "[27m"; /* end standout */
3219 cS2 = "[11m"; /* PC character set */
3220 cS3 = "[10m"; /* end " */
3221 } else if (strisprefix ("screen", TERMname)) {
3222 cCS = "[%i%p1%d;%p2%dr"; /* change scrolling region */
3223 cSR = "M"; /* scroll down */
3224 cAL = "[L"; /* add line */
3225 cDL = "[M"; /* delete line */
3226 cSC = "7"; /* save cursor position */
3227 cRC = "8"; /* restore cursor position */
3228
3229 cVS = "[34l"; /* visual cursor */
3230 cVE = "[34h[?25h"; /* normal cursor */
3231 cVI = "[?25l"; /* invisible cursor */
3232 cTI = "[?1049h"; /* positioning mode */
3233 cTE = "[?1049l"; /* end " */
3234 cKS = "[?1h="; /* keypad mode */
3235 cKE = "[?1l>"; /* end " */
3236
3237 cSO = "[3m"; /* standout */
3238 cSE = "[23m"; /* end standout */
3239 cAS = ""; /* alternate character set */
3240 cAE = ""; /* end " */
3241 } else if (strisprefix ("interix", TERMname)) {
3242 cSR = "[T"; /* scroll down */
3243 cAL = "[L"; /* add line */
3244 cDL = "[M"; /* delete line */
3245 cSC = "[s"; /* save cursor position */
3246 cRC = "[u"; /* restore cursor position */
3247
3248 cTI = "[s[1b"; /* positioning mode */
3249 cTE = "[2b[u\r[K"; /* end " */
3250
3251 cSE = "[m"; /* end standout */
3252 } else {
3253 errprintf ("Unknown terminal %s - trying minimal ANSI terminal settings\n", TERMname);
3254 #ifndef ANSI
3255 sleep (1);
3256 #endif
3257 }
3258 }
3259
3260
3261 #define dont_debug_termcap
3262
3263 #ifdef debug_termcap
3264 /**
3265 Debug termcap control strings.
3266 */
3267 static
3268 void
print_termcapstr(s,namecap,nameinfo)3269 print_termcapstr (s, namecap, nameinfo)
3270 char * s;
3271 char * namecap;
3272 char * nameinfo;
3273 {
3274 printf ("%s (%s): ", namecap, nameinfo);
3275 if (s) {
3276 while (* s) {
3277 if ((* s & 0xE0) == 0) {
3278 printf ("^%c", * s + 0x40);
3279 } else {
3280 printf ("%c", * s);
3281 }
3282 s ++;
3283 }
3284 } else {
3285 printf ("(NULL)");
3286 }
3287 printf ("\n");
3288 }
3289 #endif
3290
3291 static
3292 void
get_term_cap(TERMname)3293 get_term_cap (TERMname)
3294 char * TERMname;
3295 {
3296 #ifdef TERMCAP
3297 char term_rawbuf [2048];
3298 #endif
3299
3300 char * check;
3301
3302 if (! term_setup (TERMname)) {
3303 avoid_tputs = True;
3304 /* support some terminals even without termcap/terminfo available,
3305 especially for cygwin stand-alone version;
3306 first set minimal set of ANSI sequences
3307 */
3308 YMAX = 23 - MENU;
3309 XMAX = 79;
3310 getwinsize ();
3311 set_term_defaults (TERMname);
3312 } else {
3313 get_terminfo (TERMname);
3314 }
3315 #ifdef debug_termcap
3316 print_termcapstr (cCL, "cl", "clear"); /* clear screen */
3317 print_termcapstr (cCE, "ce", "el"); /* clear to end of line */
3318 print_termcapstr (cCD, "cd", "ed"); /* clear to end of screen */
3319 print_termcapstr (cCM, "cm", "cup"); /* move cursor */
3320
3321 print_termcapstr (cEC, "ec", "ech"); /* erase characters */
3322 print_termcapstr (cSR, "sr", "ri"); /* scroll down */
3323 print_termcapstr (cAL, "al", "il1"); /* add line */
3324 print_termcapstr (cDL, "dl", "dl1"); /* delete line */
3325 print_termcapstr (cCS, "cs", "csr"); /* change scrolling region */
3326 print_termcapstr (cSC, "sc", "sc"); /* save cursor \ needed with VT100 */
3327 print_termcapstr (cRC, "rc", "rc"); /* restore cursor / for add/delete line */
3328
3329 print_termcapstr (cME, "me", "sgr0"); /* turn off all attributes */
3330 print_termcapstr (cMR, "mr", "rev"); /* reverse */
3331 print_termcapstr (cMD, "md", "bold"); /* bold / extra bright */
3332 print_termcapstr (cMH, "mh", "dim"); /* dim / half-bright */
3333 print_termcapstr (cUL, "us", "smul"); /* underline */
3334 print_termcapstr (cBL, "mb", "blink"); /* blink */
3335 print_termcapstr (cSO, "so", "smso"); /* standout mode */
3336 print_termcapstr (cSE, "se", "rmso"); /* end standout mode */
3337
3338 print_termcapstr (cVS, "vs", "cvvis"); /* visual cursor */
3339 print_termcapstr (cVE, "ve", "cnorm"); /* normal cursor */
3340 print_termcapstr (cVI, "vi", "civis"); /* invisible cursor */
3341 print_termcapstr (cTI, "ti", "smcup"); /* positioning mode */
3342 print_termcapstr (cTE, "te", "rmcup"); /* end " */
3343 print_termcapstr (cKS, "ks", "smkx"); /* keypad mode */
3344 print_termcapstr (cKE, "ke", "rmkx"); /* end " */
3345 print_termcapstr (cAS, "as", "smacs"); /* alternate character set */
3346 print_termcapstr (cAE, "ae", "rmacs"); /* end " */
3347 print_termcapstr (cEA, "eA", "enacs"); /* enable " */
3348 print_termcapstr (cAC, "ac", "acsc"); /* block graphics code mapping */
3349 print_termcapstr (cS2, "S2", "smpch"); /* PC character set */
3350 print_termcapstr (cS3, "S3", "rmpch"); /* end " */
3351
3352 print_termcapstr (cAF, "AF", "setaf"); /* select foreground colour */
3353 print_termcapstr (cAB, "AB", "setab"); /* select background colour */
3354 #endif
3355
3356 #ifdef TERMCAP
3357 if (term_capbufpoi > term_capbuf + term_capbuflen) {
3358 panic ("Terminal control strings don't fit", NIL_PTR);
3359 }
3360 #endif
3361
3362 /* derive and fix properties */
3363 if (!cSR) {
3364 cSR = cAL;
3365 }
3366
3367 if (cAL || (cSR && cCS)) {
3368 can_add_line = True;
3369 } else {
3370 can_add_line = False;
3371 }
3372 if (cSR) {
3373 can_scroll_reverse = True;
3374 } else {
3375 can_scroll_reverse = False;
3376 }
3377 if (cDL || cCS) {
3378 can_delete_line = True;
3379 } else {
3380 can_delete_line = False;
3381 }
3382 if (cCE) {
3383 can_clear_eol = True;
3384 } else {
3385 can_clear_eol = False;
3386 }
3387 if (cCD) {
3388 can_clear_eos = True;
3389 } else {
3390 can_clear_eos = False;
3391 }
3392 if (cEC) {
3393 can_erase_chars = True;
3394 } else {
3395 can_erase_chars = False;
3396 }
3397 if (cVI) {
3398 can_hide_cursor = True;
3399 }
3400 if (cMH) {
3401 can_dim = True;
3402 }
3403
3404 #define denull(c) if (c == NIL_PTR) c = ""
3405
3406 denull (cSO);
3407 denull (cSE);
3408 denull (cTI);
3409 denull (cTE);
3410 denull (cVS);
3411 denull (cVE);
3412 denull (cVI);
3413 denull (cAS);
3414 denull (cAE);
3415 denull (cEA);
3416 denull (cAC);
3417 denull (cS2);
3418 denull (cS3);
3419 denull (cKS);
3420 denull (cKE);
3421 denull (cME);
3422 denull (cMR);
3423 denull (cMH);
3424 denull (cUL);
3425 denull (cBL);
3426 denull (cMD);
3427 denull (cAF);
3428 denull (cAB);
3429
3430 /* if the terminal has no explicit "reverse" control, use standout instead */
3431 if (* cMR == '\0') {
3432 cMR = cSO;
3433 cME = cSE;
3434 }
3435 if (* cMR == '\0') {
3436 can_reverse_mode = False;
3437 }
3438
3439 /* verify minimal feature set */
3440 if (!cCL || !cCM /* || !cSO || !cSE */ ) {
3441 panic ("Sorry, terminal features are insufficient for mined", NIL_PTR);
3442 }
3443
3444 /* check if terminal accepts ANSI control sequence patterns */
3445 check = cME;
3446 if (* check == '\0') {
3447 check = cSE;
3448 }
3449 if (strcontains (check, "\033[") && strchr (check, 'm') != NIL_PTR) {
3450 ansi_esc = True;
3451 } else {
3452 ansi_esc = False;
3453 }
3454
3455 /* set mouse mode controls */
3456 if (! ansi_esc) {
3457 /* disable xterm mouse escape sequences */
3458 cMouseX10On = "";
3459 cMouseX10Off = "";
3460 cMouseButtonOn = "";
3461 cMouseButtonOff = "";
3462 cMouseEventBtnOn = "";
3463 cMouseEventBtnOff = "";
3464 cMouseEventAnyOn = "";
3465 cMouseEventAnyOff = "";
3466 cMouseExtendedOn = "";
3467 cMouseExtendedOff = "";
3468 cMouseFocusOn = "";
3469 cMouseFocusOff = "";
3470 cAmbigOn = "";
3471 cAmbigOff = "";
3472 }
3473
3474 if (* cAS == '\0') {
3475 if (use_vt100_block_graphics) {
3476 cAS = "";
3477 cAE = "";
3478 }
3479 }
3480 if (strcontains (TERMname, "linux") && use_vt100_block_graphics) {
3481 cAS = "";
3482 cAE = "";
3483 }
3484 #ifdef terminal_already_detected
3485 /* which is not the case... */
3486 if (mintty_version >= 400) {
3487 cS2 = "[11m";
3488 cS3 = "[10m";
3489 }
3490 #endif
3491 if (* cAS == '\0') {
3492 can_alt_cset = False;
3493 }
3494 if (* cEA == '\0' && * cAS == ''
3495 && (strisprefix ("xterm", TERMname)
3496 || strisprefix ("rxvt", TERMname)
3497 || strisprefix ("konsole", TERMname)
3498 || strisprefix ("screen", TERMname)
3499 )) {
3500 /* workaround for missing eA capability in terminfo / /etc/termcap */
3501 cEA = "\033(B\033)0";
3502 }
3503 if (strcontains (cEA, "\033)0")) {
3504 /* workaround for missing disable alternate charset capability */
3505 /* restore normal G1 character set on exit */
3506 cdisableEA = "\033)B";
3507 } else {
3508 cdisableEA = "";
3509 }
3510 if (* cS2 != '\0' && * cS3 != '\0') {
3511 use_pc_block_graphics = True;
3512 }
3513
3514 if ((* cTI == '\0'
3515 || * (cTI + 1) == '@' /* workaround for bug in Solaris terminfo */
3516 ) && strisprefix ("xterm", TERMname)
3517 ) {
3518 cTI = "7[?47h[2J"; /* positioning mode */
3519 cTE = "[2J[?47l8"; /* end " */
3520 }
3521
3522 if (* cKS == '\0' && ansi_esc) {
3523 /* escape sequence to enable application keypad;
3524 include ESC= / ESC> for terminals that don't understand
3525 ESC[?66;1h (e.g. linux console)
3526 */
3527 if (strcontains (TERMname, "linux")) {
3528 cKS = "\033=";
3529 cKE = "\033>";
3530 } else {
3531 cKS = "\033=\033[?66;1h";
3532 cKE = "\033>\033[?66;1l";
3533 }
3534 }
3535
3536 if (* cAF == '\0' && ansi_esc) {
3537 cAF = "\033[3%dm";
3538 cAB = "\033[4%dm";
3539 }
3540
3541 if (* cVI == '\0' && ansi_esc) {
3542 cVI = "\033[?25l";
3543 if (* cVE == '\0') {
3544 cVE = "\033[?25h";
3545 }
3546 }
3547 }
3548
3549
3550 /**
3551 the two invocation modes (kb or not) and their usage are a mess
3552 (also setup_terminal is used in addition)
3553 - but never touch a running system...
3554 */
3555 static
3556 void
start_screen_mode(kb)3557 start_screen_mode (kb)
3558 int kb;
3559 {
3560 if (decterm_version > 0) { /* setup DEC locator reports */
3561 cMouseX10On = "";
3562 cMouseX10Off = "";
3563 cMouseButtonOn = "\033[1'z\033[1'{\033[3'{";
3564 cMouseButtonOff = "\033[0'z";
3565 cMouseEventBtnOn = "";
3566 cMouseEventBtnOff = "";
3567 cMouseEventAnyOn = "";
3568 cMouseEventAnyOff = "";
3569 cMouseExtendedOn = "";
3570 cMouseExtendedOff = "";
3571 }
3572
3573 if (kb) {
3574 /* adjust control sequences */
3575 if (! init_done) {
3576 /* if termcap/terminfo defines combined control sequences that
3577 set/reset both application cursor keys and application
3578 keypad mode, reduce them to application cursor keys only in
3579 order to maintain distinguishable control-keypad-keys
3580 */
3581 if (! use_appl_keypad) {
3582 if (strncmp (cKS, "\033[?1h", 5) == 0) {
3583 cKS = "\033[?1h";
3584 }
3585 if (strncmp (cKE, "\033[?1l", 5) == 0) {
3586 cKE = "\033[?1l";
3587 }
3588 }
3589 if (! use_appl_cursor) {
3590 if (strncmp (cKS, "\033[?1h", 5) == 0) {
3591 cKS += 5;
3592 }
3593 if (strncmp (cKE, "\033[?1l", 5) == 0) {
3594 cKE += 5;
3595 }
3596 }
3597 }
3598
3599 /* set keyboard modes */
3600 termputstr (cKS, affmax);
3601
3602 if (xterm_version >= 280) {
3603 /* enable modifyKeyboard resource */
3604 putescape ("\033[>0;15m");
3605 /* and then enable VT220 Keyboard with Application Keypad mode */
3606 putescape ("\033[?1061h\033[?66h");
3607 }
3608
3609 /* set mouse modes */
3610 if (use_mouse) {
3611 #ifdef debug_mouse
3612 printf ("starting mouse mode\n");
3613 #endif
3614 putescape (cMouseX10On); /* activate mouse reporting */
3615 putescape (cMouseButtonOn);
3616 putescape (cMouseEventBtnOn);
3617 if (use_mouse_anymove_always) {
3618 putescape (cMouseEventAnyOn);
3619 }
3620 if (use_mouse_1015) {
3621 /* numeric encoding of mouse coordinates */
3622 putescape (cMouse1015On);
3623 } else if (use_mouse_extended) {
3624 /* UTF-8 encoding of mouse coordinates */
3625 putescape (cMouseExtendedOn);
3626 }
3627 putescape (cMouseFocusOn); /* activate focus reports */
3628 putescape (cAmbigOn); /* activate ambiguous width change reports */
3629 }
3630 } else {
3631 /* set screen modes */
3632 termputstr (cTI, affmax);
3633 termputstr (cVS, affmax);
3634
3635 /* Reset scrolling region in case terminal is bigger than assumed;
3636 terminal misconfiguration effect was observed after
3637 * window size changes of Sun windows
3638 * remote login to VMS
3639 * explicit misconfiguration with stty
3640 */
3641 if (cCS) {
3642 /* YMAX as derived from tty may not yet been adjusted
3643 to actual terminal size (in case of inconsistence);
3644 checkwinsize() would have to have been called before!
3645 Possibly a reason to move this into the section above
3646 for start_screen_mode (1) but then we're getting other
3647 effects due to the cursor movement...
3648 */
3649 /*scrolling_region (0, MENU + YMAX);*/
3650 scrolling_region (-1, -1);
3651 }
3652
3653 #ifndef CURSES
3654 /* enable alternate character set */
3655 termputstr (cEA, aff1);
3656 #endif
3657 }
3658 }
3659
3660 static
3661 void
end_screen_mode()3662 end_screen_mode ()
3663 {
3664 /* reset mouse modes */
3665 if (use_mouse) {
3666 putescape (cMouseFocusOff);
3667 putescape (cAmbigOff);
3668 if (use_mouse_1015) {
3669 putescape (cMouse1015Off);
3670 } else if (use_mouse_extended) {
3671 putescape (cMouseExtendedOff);
3672 }
3673 putescape (cMouseEventBtnOff);
3674 putescape (cMouseButtonOff);
3675 putescape (cMouseX10Off);
3676 #ifdef debug_mouse
3677 printf ("ended mouse mode\n");
3678 #endif
3679 }
3680 /* if mouse was released quickly after, e.g., QUIT command,
3681 swallow mouse release report already sent */
3682 #ifndef vms_slow_lookahead
3683 if (char_ready_within (50, NIL_PTR)) {
3684 (void) _readchar_nokeymap ();
3685 }
3686 #endif
3687
3688 /* reset keyboard modes */
3689 termputstr (cKE, affmax);
3690
3691 if (xterm_version >= 280) {
3692 /* reset modifyKeyboard resource */
3693 putescape ("\033[>0m");
3694 /* and then disable VT220 Keyboard with Application Keypad mode */
3695 putescape ("\033[?1061l\033[?66l");
3696 }
3697
3698 /* reset screen modes */
3699 termputstr (cVE, affmax);
3700 termputstr (cTE, affmax);
3701
3702 #ifndef CURSES
3703 /* disable alternate character set */
3704 termputstr (cdisableEA, aff1);
3705 #endif
3706
3707 flush ();
3708 }
3709
3710 #endif /* defined (unix) || defined (vms) */
3711
3712
3713 #ifdef vms
3714
3715 void
add_terminfo_entries()3716 add_terminfo_entries ()
3717 {
3718 }
3719
3720 #endif
3721
3722
3723 #ifdef msdos
3724
3725 #ifdef __TURBOC__
3726 #define peekbyte peekb
3727 #define peekword peek
3728 #endif
3729 #ifdef __DJGPP__
3730 #define peekbyte _farpeekb
3731 #define peekword _farpeekw
3732 #include <sys/farptr.h>
3733 #endif
3734
3735 #ifdef conio
3736 #include <conio.h>
3737
3738 static struct text_info scrinfo;
3739
3740 #ifdef __TURBOC__
3741 static FLAG use_peek = NOT_VALID; /* determine on first demand */
3742 #else
3743 static FLAG use_peek = False; /* peek doesn't seem to work with djgpp */
3744 #endif
3745
3746 /**
3747 Retrieve screen size from BIOS
3748 BIOS data:
3749 40:4A word video columns
3750 can also be determined with INT10h, function 0Fh
3751 40:84 byte video lines - 1 (EGA/VGA required)
3752 40:85 word character height (pixels) (EGA/VGA required)
3753 can also be determined with INT10h, function 11h/30h
3754 */
3755 void
getwinsize()3756 getwinsize ()
3757 {
3758 int bioslines;
3759 int bioscols;
3760 if (use_peek == NOT_VALID) {
3761 gettextinfo (& scrinfo);
3762 /* check whether this is reliable (EGA or VGA only): */
3763 bioslines = peekbyte (0x40, 0x84) + 1;
3764 use_peek = scrinfo.screenheight == bioslines;
3765 }
3766 if (use_peek) {
3767 bioslines = peekbyte (0x40, 0x84) + 1;
3768 bioscols = peekword (0x40, 0x4A);
3769 } else {
3770 #ifdef __DJGPP__
3771 /* make sure changed size is detected (e.g. using vgamax) */
3772 gppconio_init ();
3773 #endif
3774 gettextinfo (& scrinfo);
3775 bioslines = scrinfo.screenheight;
3776 bioscols = scrinfo.screenwidth;
3777 }
3778
3779 YMAX = bioslines - 1 - MENU;
3780 XMAX = bioscols - 1;
3781 }
3782
3783 #endif /* #ifdef conio */
3784
3785 static int wincheck = 1;
3786
3787 #ifdef __TURBOC__ /* try to improve Turbo-C getch behaviour */
3788
3789 /*
3790 * getch () reads in a character from keyboard. We seem to need our
3791 * own low-level input routine since (at least with Turbo-C) the use
3792 * of getch () from conio.h makes the runtime system switch to normal
3793 * text mode on startup so that extended text modes could not be used.
3794 * This is really a very stupid chicane of Turbo-C.
3795 */
3796 int
dosgetch()3797 dosgetch ()
3798 {
3799 union REGS regs;
3800 int result;
3801
3802 #ifdef getchBIOS
3803 /* Don't use; for some reason, this crap doesn't work.
3804 And if it's tweaked to work, it doesn't provide keypad keys.
3805 And it doesn't even help to avoid ^S/^Q/^C/^P handling either.
3806 */
3807 static int BIOSgetch = -1;
3808 if (BIOSgetch == -1) {
3809 struct SREGS segs;
3810 regs.h.ah = 0xC0;
3811 int86x (0x15, & regs, & regs, & segs);
3812 if (regs.x.cflag == 0 && peekbyte (segs.es, regs.x.bx + 6) & 0x40) {
3813 regs.h.ah = 9;
3814 int86 (0x16, & regs, & regs);
3815 if (regs.h.al & 0x40) {
3816 BIOSgetch = 0x20;
3817 } else if (regs.h.al & 0x20) {
3818 BIOSgetch = 0x10;
3819 } else {
3820 BIOSgetch = 0x00;
3821 }
3822 } else {
3823 BIOSgetch = 0x00;
3824 }
3825 }
3826
3827 regs.h.ah = BIOSgetch;
3828 int86 (0x16, & regs, & regs);
3829 #else
3830 regs.h.ah = 0x07;
3831 intdos (& regs, & regs);
3832 #endif
3833
3834 result = regs.h.al;
3835
3836 return result;
3837 }
3838
3839 #endif /* __TURBOC__ */
3840
3841 void
ring_bell()3842 ring_bell ()
3843 {
3844 union REGS regs;
3845
3846 regs.h.ah = 0x0E;
3847 regs.h.al = 7;
3848 regs.h.bh = 0;
3849 regs.h.bl = 0;
3850 int86 (0x10, & regs, & regs);
3851 }
3852
3853 void
set_video_lines(r)3854 set_video_lines (r)
3855 /* 0/1/2: 200/350/400 lines */
3856 int r;
3857 {
3858 union REGS regs;
3859
3860 regs.h.ah = 0x12;
3861 regs.h.bl = 0x30;
3862 regs.h.al = r;
3863
3864 int86 (0x10, & regs, & regs);
3865 }
3866
3867 int font_height = 16;
3868 void
set_font_height(r)3869 set_font_height (r)
3870 /* set font height in character pixels, <= 32 */
3871 int r;
3872 {
3873 #ifdef __TURBOC__
3874 #define useintr
3875 #endif
3876
3877 #ifdef useintr
3878 struct REGPACK regs;
3879
3880 regs.r_ax = 0x1130;
3881 regs.r_bx = 0;
3882 intr (0x10, & regs);
3883 regs.r_ax = 0x1110;
3884 regs.r_bx = r << 8;
3885 regs.r_cx = 256;
3886 regs.r_dx = 0;
3887 /*
3888 regs.r_bp = 0;
3889 regs.r_es = 0;
3890 */
3891 intr (0x10, & regs);
3892 #else
3893 union REGS regs;
3894
3895 regs.h.ah = 0x11;
3896 regs.h.al = 0x10;
3897 regs.h.bh = r;
3898 font_height = r;
3899 regs.h.bl = 0;
3900 regs.x.cx = 256;
3901 regs.x.dx = 0;
3902 /* regs.x.bp = 0; ignored by Turbo-C's int86 function */
3903 /* regs.x.es = 0; not in structure but accepted by rotten C */
3904 int86 (0x10, & regs, & regs);
3905 #endif
3906 }
3907
3908 void
set_grafmode_height(r,l)3909 set_grafmode_height (r, l)
3910 /* 0/1/2: font height 8/14/16 ; 1/2/3/n: 14/25/43/n lines */
3911 int r;
3912 int l;
3913 {
3914 union REGS regs;
3915
3916 regs.h.ah = 0x11;
3917 if (r == 0) {
3918 regs.h.al = 0x23;
3919 } else if (r == 1) {
3920 regs.h.al = 0x22;
3921 } else {
3922 regs.h.al = 0x24;
3923 }
3924 if (l <= 0) {
3925 regs.h.bl = 1;
3926 } else if (l <= 3) {
3927 regs.h.bl = l;
3928 } else {
3929 regs.h.bl = 0;
3930 regs.h.dl = l;
3931 }
3932
3933 int86 (0x10, & regs, & regs);
3934 }
3935
3936 void
set_fontbank(f)3937 set_fontbank (f)
3938 /* 0..7 */
3939 int f;
3940 {
3941 union REGS regs;
3942
3943 regs.h.ah = 0x11;
3944 regs.h.al = 0x03;
3945 regs.h.bl = (f & 3) * 5 + (f & 4) * 12;
3946
3947 int86 (0x10, & regs, & regs);
3948 }
3949
3950 #ifdef conio
3951 static unsigned char norm_attr; /* default character colours */
3952 static unsigned char inverse_attr;
3953
3954 void
clear_screen()3955 clear_screen ()
3956 {
3957 clrscr ();
3958 }
3959
3960 void
clear_eol()3961 clear_eol ()
3962 {
3963 clreol ();
3964 }
3965
3966 void
erase_chars(n)3967 erase_chars (n)
3968 register int n;
3969 {
3970 while (n -- > 0) {
3971 putchar (' ');
3972 }
3973 }
3974
3975 void
scroll_forward()3976 scroll_forward ()
3977 {
3978 set_cursor (0, YMAX);
3979 putchar ('\n');
3980 }
3981
3982 void
scroll_reverse()3983 scroll_reverse ()
3984 { /* only to be called if can_add_line or cursor is at top of screen */
3985 insline ();
3986 }
3987
3988 void
add_line(y)3989 add_line (y)
3990 register int y;
3991 { /* only to be called if can_add_line == True */
3992 set_cursor (0, y);
3993 insline ();
3994 }
3995
3996 void
delete_line(y)3997 delete_line (y)
3998 register int y;
3999 {
4000 set_cursor (0, y);
4001 delline ();
4002 }
4003
4004 void
set_cursor(x,y)4005 set_cursor (x, y)
4006 {
4007 /*current_cursor_y = y;*/
4008 gotoxy (x + 1, y + 1 + MENU);
4009 }
4010
4011 void
reverse_on()4012 reverse_on ()
4013 {
4014 textattr (inverse_attr);
4015 /*highvideo ();*/
4016 }
4017
4018 void
reverse_off()4019 reverse_off ()
4020 {
4021 textattr (norm_attr);
4022 /*normvideo ();*/
4023 }
4024
4025 void
altcset_on()4026 altcset_on ()
4027 {}
4028
4029 void
altcset_off()4030 altcset_off ()
4031 {}
4032
4033 static
4034 void
start_screen_mode(kb)4035 start_screen_mode (kb)
4036 int kb;
4037 {}
4038
4039 static
4040 void
end_screen_mode()4041 end_screen_mode ()
4042 {}
4043
4044 void
menu_mouse_mode(menu)4045 menu_mouse_mode (menu)
4046 FLAG menu;
4047 {
4048 in_menu_mouse_mode = menu;
4049 }
4050
4051 void
screen_buffer(alt)4052 screen_buffer (alt)
4053 FLAG alt;
4054 {
4055 }
4056
4057 void
get_term(TERM)4058 get_term (TERM)
4059 char * TERM;
4060 {
4061 getwinsize ();
4062
4063 norm_attr = scrinfo.normattr;
4064 inverse_attr = ((norm_attr & 0x0F) << 4) | (norm_attr >> 4);
4065 }
4066
4067 #endif /* #ifdef conio */
4068
4069 #endif /* #ifdef msdos */
4070
4071
4072 /**************************************************************************
4073 * screen mode setting functions, alternatively by MSDOS BIOS calls or
4074 * ANSI sequences
4075 */
4076
4077 static int textmode_height = 2;
4078
4079 #ifdef msdos
4080
4081 void
set_screen_mode(m)4082 set_screen_mode (m)
4083 int m;
4084 {
4085 union REGS regs;
4086
4087 if (m >= 0) {
4088 regs.h.ah = 0x00;
4089 regs.h.al = m;
4090 int86 (0x10, & regs, & regs);
4091 }
4092 }
4093
4094 void
set_textmode_height(r)4095 set_textmode_height (r)
4096 /* 0/1/2: font height 8/14/16 */
4097 int r;
4098 {
4099 union REGS regs;
4100
4101 regs.h.ah = 0x11;
4102 regs.h.bl = 0;
4103 textmode_height = r;
4104 if (r == 0) {
4105 regs.h.al = 0x12;
4106 } else if (r == 1) {
4107 regs.h.al = 0x11;
4108 } else {
4109 regs.h.al = 0x14;
4110 }
4111
4112 int86 (0x10, & regs, & regs);
4113 }
4114
4115 #else /* #ifdef msdos - else use ANSI driver: */
4116
4117 int screen_mode = 3 /* just an assumption, cannot be determined */;
4118
4119 void
set_screen_mode(m)4120 set_screen_mode (m)
4121 int m;
4122 {
4123 char resize_str [8];
4124
4125 if (m >= 0) {
4126 if (m != 50 && m != 43) {
4127 screen_mode = m;
4128 }
4129 build_string (resize_str, "\033[=%dh", m);
4130 putescape (resize_str);
4131 }
4132 }
4133
4134 void
set_textmode_height(r)4135 set_textmode_height (r)
4136 /* 0/1/2: font height 8/14/16 */
4137 int r;
4138 {
4139 textmode_height = r;
4140 if (r == 0) {
4141 set_screen_mode (50);
4142 } else if (r == 1) {
4143 set_screen_mode (43);
4144 } else {
4145 set_screen_mode (screen_mode);
4146 }
4147 }
4148
4149 #endif
4150
4151 void
switch_textmode_height(cycle)4152 switch_textmode_height (cycle)
4153 /* True: cycle through font heights 8/14/16
4154 False: switch between font heights 8/16 */
4155 FLAG cycle;
4156 {
4157 if (textmode_height >= 2) {
4158 set_textmode_height (0);
4159 } else if (cycle) {
4160 set_textmode_height (textmode_height + 1);
4161 } else {
4162 set_textmode_height (2);
4163 }
4164 }
4165
4166
4167 #define djconiox
4168 #ifdef djconio
4169
4170 int ltab [] = {25, 28, 35, 40, 43, 50};
4171
4172 void
maximize_restore_screen()4173 maximize_restore_screen ()
4174 {
4175 }
4176
4177 void
resize_font(inc)4178 resize_font (inc)
4179 int inc;
4180 {
4181 }
4182
4183 void
resize_the_screen(sb,keep_columns)4184 resize_the_screen (sb, keep_columns)
4185 FLAG sb;
4186 FLAG keep_columns;
4187 {
4188 /* char resize_str [8]; */
4189 int lins = YMAX + 1 + MENU;
4190 int i;
4191
4192 if (sb == BIGGER) {
4193 i = 0;
4194 while (i < arrlen (ltab) && ltab [i] <= lins) {
4195 i ++;
4196 }
4197 if (i == arrlen (ltab)) {
4198 i = 0;
4199 }
4200 } else {
4201 i = arrlen (ltab) - 1;
4202 while (i >= 0 && ltab [i] >= lins) {
4203 i --;
4204 }
4205 if (i < 0) {
4206 i = arrlen (ltab) - 1;
4207 }
4208 }
4209 _set_screen_lines (ltab [i]);
4210 }
4211
4212 #else /* #ifdef djconio */
4213
4214 #ifdef msdos
4215
4216 #include "dosvideo.t"
4217
4218 void
maximize_restore_screen()4219 maximize_restore_screen ()
4220 {
4221 }
4222
4223 void
resize_font(inc)4224 resize_font (inc)
4225 int inc;
4226 {
4227 }
4228
4229 void
resize_the_screen(sb,keep_columns)4230 resize_the_screen (sb, keep_columns)
4231 FLAG sb;
4232 FLAG keep_columns;
4233 {
4234 if (keep_columns && ((sb == SMALLER && textmode_height > 0)
4235 || (sb == BIGGER && textmode_height < 2)))
4236 {
4237 if (sb == SMALLER) {
4238 set_textmode_height (textmode_height - 1);
4239 } else {
4240 set_textmode_height (textmode_height + 1);
4241 }
4242 }
4243 else
4244 {
4245 int newtotal = 0;
4246 int newmode = -1;
4247 int totalchars = (XMAX + 1) * (YMAX + 1 + MENU);
4248 int i = 0;
4249 while (modetab [i].mode >= 0) {
4250 int curtotal = modetab [i].cols * modetab [i].lins;
4251 if (((sb == SMALLER && curtotal < totalchars && curtotal > newtotal) ||
4252 (sb == BIGGER && curtotal > totalchars && (newtotal == 0 || curtotal < newtotal)))
4253 && (keep_columns == False || modetab [i].cols == XMAX + 1))
4254 {
4255 newtotal = curtotal;
4256 newmode = modetab [i].mode;
4257 }
4258 i ++;
4259 }
4260 if (newmode >= 0) {
4261 set_screen_mode (newmode);
4262 if (keep_columns) {
4263 if (sb == BIGGER) {
4264 set_textmode_height (0);
4265 } else {
4266 set_textmode_height (2);
4267 }
4268 }
4269 }
4270 }
4271 }
4272
4273 #else /* #ifdef msdos */
4274
4275 static FLAG maximised = False;
4276
4277 void
maximize_restore_screen()4278 maximize_restore_screen ()
4279 {
4280 if (maximised) {
4281 putescape ("\033[9;0t");
4282 maximised = False;
4283 } else {
4284 /*putescape ("\033[9;1t");*/
4285 putescape ("\033[9;2t"); /* mintty: true full screen */
4286 maximised = True;
4287 }
4288 }
4289
4290 void
resize_font(inc)4291 resize_font (inc)
4292 int inc;
4293 {
4294 if (mintty_version >= 503) {
4295 if (inc > 0) { /* increase font size */
4296 putescape ("]7770;+1");
4297 } else if (inc < 0) { /* decrease font size */
4298 putescape ("]7770;-1");
4299 } else { /* reset to default */
4300 putescape ("]7770;");
4301 }
4302 } else if (xterm_version >= 203 /* best guess */) {
4303 if (inc > 0) { /* increase font size */
4304 putescape ("]50;#+1");
4305 } else if (inc < 0) { /* decrease font size */
4306 putescape ("]50;#-1");
4307 } else { /* reset to default */
4308 putescape ("]50;#");
4309 }
4310 }
4311 }
4312
4313 static
4314 void
resize_screen(l,c)4315 resize_screen (l, c)
4316 int l;
4317 int c;
4318 {
4319 static char s [22];
4320 build_string (s, "\033[8;%d;%dt", l, c);
4321 putescape (s);
4322 }
4323
4324 static
4325 void
resize_vt(sb,keep_columns)4326 resize_vt (sb, keep_columns)
4327 FLAG sb;
4328 FLAG keep_columns;
4329 {
4330 if (keep_columns == True) {
4331 /* change number of lines (VT420) */
4332 int lines = YMAX + 1 + MENU;
4333 static int vtlines [] = {24, 36, 48, 72, 144};
4334 int i;
4335 static char s [15];
4336 if (sb == SMALLER) {
4337 for (i = arrlen (vtlines) - 1; i >= 0; i --) {
4338 if (lines > vtlines [i]) {
4339 build_string (s, "\033[%dt", vtlines [i]);
4340 putescape (s);
4341 YMAX = vtlines [i] - 1 - MENU;
4342 return;
4343 }
4344 }
4345 } else {
4346 for (i = 0; i < arrlen (vtlines); i ++) {
4347 if (lines < vtlines [i]) {
4348 build_string (s, "\033[%dt", vtlines [i]);
4349 putescape (s);
4350 YMAX = vtlines [i] - 1 - MENU;
4351 return;
4352 }
4353 }
4354 }
4355 } else {
4356 /* switch 80/132 columns */
4357 if (sb == SMALLER) {
4358 putescape ("\033[?40h\033[?3l");
4359 XMAX = 79;
4360 } else {
4361 putescape ("\033[?40h\033[?3h");
4362 XMAX = 131;
4363 }
4364 }
4365 }
4366
4367 void
resize_the_screen(sb,keep_columns)4368 resize_the_screen (sb, keep_columns)
4369 FLAG sb;
4370 FLAG keep_columns;
4371 {
4372 if (decterm_version > 0) {
4373 resize_vt (sb, keep_columns);
4374 } else {
4375 int ldif = 6;
4376 int coldif = 13;
4377 if (sb == SMALLER) {
4378 ldif = - ldif;
4379 coldif = - coldif;
4380 }
4381 if (keep_columns == True) {
4382 coldif = 0;
4383 } else if (keep_columns == NOT_VALID) {
4384 ldif = 0;
4385 }
4386
4387 resize_screen (YMAX + 1 + MENU + ldif, XMAX + 1 + coldif);
4388 }
4389 }
4390
4391 #endif
4392
4393 #endif /* #else djconio */
4394
4395
4396 #endif /* #else CURSES */
4397
4398
4399 /*======================================================================*\
4400 |* OS special *|
4401 \*======================================================================*/
4402
4403 #ifdef msdos
4404
4405 unsigned int
get_codepage()4406 get_codepage ()
4407 {
4408 union REGS regs;
4409
4410 #ifndef __TURBOC__
4411 __dpmi_regs mregs;
4412 short parblock [2];
4413
4414 mregs.x.ax = 0x440C;
4415 mregs.x.bx = 1; /* device handle */
4416 mregs.x.cx = 0x036A; /* 3: CON, 0x6A: query selected code page */
4417 mregs.x.ds = __tb >> 4;
4418 mregs.x.dx = __tb & 0x0F;
4419 mregs.x.flags |= 1; /* preset to detect unimplemented call */
4420 __dpmi_int (0x21, & mregs);
4421 if ((mregs.x.flags & 1) == 0) {
4422 dosmemget (__tb, 4, parblock);
4423 return parblock [1];
4424 }
4425 #endif
4426
4427 /* 2F/AD02 -> BX=codepage
4428 works with NLSFUNC driver, otherwise returns BX=FFFF, CY set
4429 */
4430 regs.x.ax = 0xAD02;
4431 regs.x.cflag = 1; /* preset to detect unimplemented call */
4432 regs.x.bx = 0; /* preset to detect unset result register */
4433 int86 (0x2F, & regs, & regs);
4434 if (regs.x.cflag == 0 && regs.x.bx > 1) {
4435 return regs.x.bx;
4436 }
4437
4438 regs.x.ax = 0x6601;
4439 regs.x.cflag = 1; /* preset to detect unimplemented call */
4440 regs.x.bx = 0; /* preset to detect unset result register */
4441 int86 (0x21, & regs, & regs);
4442 if (regs.x.cflag == 0) {
4443 return regs.x.bx;
4444 }
4445
4446 return 0;
4447 }
4448
4449 #endif
4450
4451
4452 /*======================================================================*\
4453 |* OS input *|
4454 \*======================================================================*/
4455
4456 #define dont_debug_select
4457
4458
4459 /*
4460 * Read a character from the operating system and handle interrupts.
4461 * Concerning problems due to the interference of read operations and
4462 * incoming signals (QUIT, WINCH) see the comments at readchar ().
4463 */
4464
4465 #ifdef cygwin_hup_hang_fix
4466
4467 static
4468 void
catch_alarm(signum)4469 catch_alarm (signum)
4470 int signum;
4471 {
4472 }
4473
4474 /**
4475 Call this before select () to rescue it from hanging...
4476 Update: with current cygwin (1.7.15) there doesn't seem to be a need
4477 to care about hanging select after terminated terminal anymore...
4478 */
4479 static
4480 void
ialarm(msec)4481 ialarm (msec)
4482 int msec;
4483 {
4484 struct itimerval timeout;
4485 timeout.it_value.tv_sec = msec / 1000;
4486 timeout.it_value.tv_usec = (msec % 1000) * 1000;
4487 timeout.it_interval.tv_sec = 0;
4488 timeout.it_interval.tv_usec = 0;
4489
4490 signal (SIGALRM, catch_alarm);
4491 setitimer (ITIMER_REAL, & timeout, (struct itimerval *) 0);
4492 }
4493
4494 #endif
4495
4496
4497 #ifdef TERMIO
4498 #define buffered_TERMIO
4499 #endif
4500 #ifdef _getch_
4501 #undef buffered_TERMIO
4502 #endif
4503 #undef buffered_TERMIO /* works, but doesn't improve terminal pasting */
4504
4505 #ifdef buffered_TERMIO
4506 #define cbuflen 22
4507 static char cbuf [cbuflen];
4508 static int cbufi = 0;
4509 static int cbufn = 0;
4510 #endif
4511
4512 /*
4513 * Is a character available within msec milliseconds from file handle?
4514 */
4515 int
inputreadyafter(msec)4516 inputreadyafter (msec)
4517 int msec;
4518 {
4519 #ifdef buffered_TERMIO
4520 if (cbufi < cbufn) {
4521 return 1;
4522 }
4523 #endif
4524
4525 if (tty_closed) {
4526 #ifdef debug_select
4527 printf ("(tty closed) select -> 0\n");
4528 #endif
4529 return 0;
4530 } else {
4531
4532 #ifdef selectpeek
4533
4534 #ifdef FD_SET
4535 fd_set readfds; /* causes mined not to work in pipe mode */
4536 #else
4537 int readfds; /* gives compiler warnings on System V without casting */
4538 #endif
4539
4540 struct timeval timeoutstru;
4541 register int nfds;
4542
4543 timeoutstru.tv_sec = msec / 1000;
4544 timeoutstru.tv_usec = (msec % 1000) * 1000;
4545
4546 #ifdef FD_SET
4547 FD_ZERO (& readfds);
4548 FD_SET (input_fd, & readfds);
4549 #else
4550 readfds = 1 << input_fd;
4551 #endif
4552
4553 #ifdef debug_select
4554 printf ("inputreadyafter %d: select %04lX\n", msec, readfds);
4555 #endif
4556
4557 if (msec < 0) {
4558 nfds = select (input_fd + 1, & readfds, 0, 0, 0);
4559 } else {
4560 nfds = select (input_fd + 1, & readfds, 0, 0, & timeoutstru);
4561 }
4562
4563 #ifdef debug_select
4564 printf (" ... -> #=%d\n", nfds);
4565 #endif
4566
4567 return nfds;
4568
4569 #else /* #ifdef selectpeek */
4570
4571 #ifdef CURSES
4572 int key;
4573 int timerms = 0;
4574 #define timestep 10
4575
4576 nodelay (stdscr, TRUE);
4577 while (timerms < msec && (key = curs_readchar ()) == ERR) {
4578 napms (timestep);
4579 timerms += timestep;
4580 }
4581 nodelay (stdscr, FALSE);
4582 if (key == ERR) {
4583 return 0;
4584 } else {
4585 ungetch (key);
4586 return 1;
4587 }
4588 #else
4589 #ifdef msdos
4590 if (mousegetch (msec) == -1) {
4591 return 0;
4592 } else {
4593 return 1;
4594 }
4595 #else
4596 #ifdef vms
4597 return tthaschar (msec);
4598 #else
4599 if (msec < 500
4600 && msec > 30 /* or flush_keyboard would block */
4601 ) {
4602 return 1;
4603 } else {
4604 return 0;
4605 }
4606 #endif
4607 #endif
4608 #endif
4609
4610 #endif /* #else selectpeek */
4611 }
4612 }
4613
4614
4615 /*
4616 * Read a char from operating system, handle interrupts if possible,
4617 * handle window size changes if possible.
4618 */
4619
4620 #define dont_debug__readchar
4621
4622 #ifdef debug__readchar
4623 #define trace__readchar(params) printf params
4624 #else
4625 #define trace__readchar(params)
4626 #endif
4627
4628 #ifdef selectread
4629
4630 static
4631 int
strange(err)4632 strange (err)
4633 char * err;
4634 {
4635 ring_bell ();
4636 error2 ("Interrupted while reading from terminal: ", err);
4637 sleep (1);
4638 ring_bell ();
4639 return quit_char;
4640 }
4641
4642 static
4643 int
__readchar_reporting_winchg(report_winchg)4644 __readchar_reporting_winchg (report_winchg)
4645 FLAG report_winchg;
4646 {
4647 #ifdef FD_SET
4648 fd_set readfds;
4649 fd_set exceptfds;
4650 #else
4651 int readfds;
4652 int exceptfds; /* comments see above */
4653 #endif
4654
4655 int selret;
4656
4657 #ifndef _getch_
4658 character c;
4659 register int n;
4660 #endif
4661
4662 #ifdef buffered_TERMIO
4663 if (cbufi < cbufn) {
4664 return cbuf [cbufi ++];
4665 }
4666 #endif
4667
4668 if (tty_closed) {
4669 trace__readchar (("(tty closed) read -> quit\n"));
4670 quit = True;
4671 return quit_char;
4672 }
4673
4674 select_getch:
4675
4676 trace__readchar (("-> __readchar\n"));
4677 do {
4678 trace__readchar (("__readchar do\n"));
4679 if (winchg) {
4680 trace_winchg (("__readchar -> winchg -> RDwin\n"));
4681
4682 if (isscreenmode && continued) {
4683 continued = False;
4684 /* recover from SIGSTOP */
4685 raw_mode (False);
4686 raw_mode (True);
4687 }
4688
4689 trace__readchar (("< RDwin\n"));
4690 RDwinchg ();
4691 trace__readchar (("> RDwin\n"));
4692 }
4693
4694 /* the following would be obsolete with ISIG (termios)
4695 which is, however, not used anymore as it also suppresses ^\ interrupt;
4696 on the other hand, it is obsolete with setting VINTR to NDEF as well
4697 */
4698 #ifdef __CYGWIN__
4699 #define control_C_unsure
4700 #endif
4701 #ifdef CURSES
4702 #define control_C_unsure
4703 #endif
4704
4705 #ifdef control_C_unsure
4706 if (intr_char) {
4707 intr_char = False;
4708 return '\003';
4709 }
4710 #endif
4711
4712 #ifdef FD_SET
4713 FD_ZERO (& readfds);
4714 FD_SET (input_fd, & readfds);
4715 FD_ZERO (& exceptfds);
4716 FD_SET (input_fd, & exceptfds);
4717 #else
4718 readfds = 1 << input_fd;
4719 exceptfds = readfds;
4720 #endif
4721
4722 selret = select (input_fd + 1, & readfds, 0, & exceptfds, 0);
4723 trace__readchar (("select -> %d [%X %X] (errno %d: %s)\n", selret, readfds, exceptfds, geterrno (), serror ()));
4724
4725 #ifdef FD_SET
4726 if (selret > 0 && FD_ISSET (input_fd, & readfds)) {
4727 #else
4728 if (selret > 0 && readfds != 0) {
4729 #endif
4730 #ifdef _getch_
4731 return getch ();
4732 #else /* #ifdef _getch_ */
4733 #ifdef buffered_TERMIO
4734 cbufn = read (input_fd, & cbuf, cbuflen);
4735 if (cbufn > 0) {
4736 n = 1;
4737 c = cbuf [0];
4738 cbufi = 1;
4739 } else {
4740 n = cbufn;
4741 }
4742 #else
4743 n = read (input_fd, & c, 1);
4744 #endif
4745 if (n == 1) {
4746 trace__readchar (("read: %02X\n", c));
4747 return c;
4748 } else if ((n == 0) || (geterrno () != EINTR)) {
4749 trace__readchar (("read -> %d (errno %d: %s)\n", n, geterrno (), serror ()));
4750 tty_closed = True;
4751 panicio ("Terminal read error", serror ());
4752 } else {
4753 trace__readchar (("read -> strange\n"));
4754 return strange (serror ());
4755 }
4756 #endif /* #else _getch_ */
4757 } else {
4758 if (quit) {
4759 trace__readchar (("select -> quit\n"));
4760 return quit_char;
4761
4762 } else if (winchg) {
4763 trace_winchg (("select -> winchg\n"));
4764 trace__readchar (("select -> winchg\n"));
4765 if (report_winchg) {
4766 trace_winchg (("-> return RDwin\n"));
4767 /* raise WINCH exception */
4768 keyproc = RDwin;
4769 return (int) FUNcmd;
4770 }
4771
4772 } else if (intr_char) {
4773 trace__readchar (("select -> intr_char\n"));
4774 intr_char = False;
4775 return '\003';
4776
4777 } else if (hup) {
4778 trace__readchar (("select -> hup -> repeat\n"));
4779 hup = False;
4780 goto select_getch;
4781
4782 } else {
4783 trace__readchar (("select -> strange\n"));
4784 return strange ("exception");
4785 }
4786 }
4787 } while (1);
4788 /* NOTREACHED */
4789 }
4790
4791 #else /* #ifdef selectread */
4792
4793 static
4794 int
__readchar_reporting_winchg(report_winchg)4795 __readchar_reporting_winchg (report_winchg)
4796 FLAG report_winchg;
4797 {
4798 #ifdef _getch_
4799
4800 int c;
4801
4802 if (tty_closed) {
4803 trace__readchar (("(tty closed) read -> quit\n"));
4804 quit = True;
4805 return quit_char;
4806 }
4807
4808 #ifdef dosmouse
4809 c = mousegetch (-1); /* no timeout */
4810 {
4811 union REGS regs;
4812 regs.h.ah = 2;
4813 int86 (0x16, & regs, & regs);
4814 if (c == FUNcmd) {
4815 if (regs.h.al & 0x3) {
4816 mouse_shift |= shift_button;
4817 }
4818 if (regs.h.al & 0x4) {
4819 mouse_shift |= control_button;
4820 }
4821 if (regs.h.al & 0x8) {
4822 mouse_shift |= alt_button;
4823 }
4824 } else {
4825 if (regs.h.al & 0x3) {
4826 keyshift |= shift_mask;
4827 }
4828 if (regs.h.al & 0x4) {
4829 if (c == 0 || c >= ' ') {
4830 keyshift |= ctrl_mask;
4831 }
4832 /* else: don't add another ctrl flag to ctrl keys */
4833 }
4834 if (regs.h.al & 0x8) {
4835 keyshift |= alt_mask;
4836 }
4837 }
4838 }
4839 #else
4840 c = getch ();
4841 #endif
4842
4843 #ifdef conio
4844 if (wincheck) {
4845 int oldymax = YMAX;
4846 int oldxmax = XMAX;
4847 getwinsize ();
4848 if (YMAX != oldymax || XMAX != oldxmax) {
4849 winchg = True;
4850 interrupted = True;
4851 trace_winchg (("getch -> winchg\n"));
4852 /* in MSDOS, RDwin calls getch,
4853 so it cannot be called directly here */
4854 }
4855 }
4856 #endif
4857
4858 if (intr_char) {
4859 /* turn SIGINT signal into intr character */
4860 /* Note: doesn't seem to be necessary */
4861 intr_char = False;
4862 c = '\003';
4863 }
4864
4865 #else /* #ifdef _getch_ */
4866
4867 #ifdef vms
4868 int ret;
4869 #endif
4870 character c;
4871
4872 if (tty_closed) {
4873 trace__readchar (("(tty closed) read -> quit\n"));
4874 quit = True;
4875 return quit_char;
4876 }
4877
4878 #ifdef vms
4879
4880 ret = ttgetchar ();
4881 if (ret == VMS$ERROR) {
4882 tty_closed = True;
4883 panicio ("Terminal read error", serror ());
4884 }
4885 c = ret;
4886
4887 #else
4888
4889 #ifdef debug_select
4890 printf ("__readchar_reporting_winchg ...\n");
4891 #endif
4892
4893 read_getch:
4894
4895 if (read (input_fd, & c, 1) != 1 && quit == False) {
4896 #ifdef debug_select
4897 printf (" ... != 1\n");
4898 #endif
4899
4900 if (geterrno () == EINTR || geterrno () == EAGAIN) {
4901 if (winchg) {
4902 if (report_winchg) {
4903 trace_winchg (("__readchar_reporting_winchg -> winchg\n"));
4904 /* raise WINCH exception */
4905 keyproc = RDwin;
4906 return (int) FUNcmd;
4907 } else { /* handle WINCH */
4908 trace_winchg (("__readchar -> winchg -> RDwin\n"));
4909
4910 if (isscreenmode && continued) {
4911 continued = False;
4912 /* recover from SIGSTOP */
4913 raw_mode (False);
4914 raw_mode (True);
4915 }
4916
4917 trace__readchar (("< RDwin\n"));
4918 RDwinchg ();
4919 trace__readchar (("> RDwin\n"));
4920
4921 goto read_getch;
4922 }
4923 } else {
4924 goto read_getch;
4925 }
4926 } else {
4927 tty_closed = True;
4928 panicio ("Terminal read error", serror ());
4929 }
4930 }
4931 #ifdef debug_select
4932 printf (" ... OK\n");
4933 #endif
4934
4935 #endif /* #else vms */
4936
4937 #endif /* #else _getch_ */
4938
4939 if (quit) {
4940 /* turn SIGQUIT or SIGBREAK signals into quit character */
4941 /* Note: doesn't seem to work */
4942 c = quit_char;
4943 }
4944
4945 return c;
4946 }
4947
4948 #endif /* #else selectread */
4949
4950 #define dont_debug___readchar
4951
4952 static
4953 int
__readchar_reporting_winchg_trace(reporting_winchg)4954 __readchar_reporting_winchg_trace (reporting_winchg)
4955 FLAG reporting_winchg;
4956 {
4957 int ch = __readchar_reporting_winchg (reporting_winchg);
4958 #ifdef debug_qio
4959 char log [2];
4960 log [0] = ch;
4961 log [1] = 0;
4962 debuglog ("__readchar", log, "");
4963 #endif
4964 #ifdef debug___readchar
4965 if ((char) ch >= ' ')
4966 printf ("__readchar %02X '%c'\n", ch, ch);
4967 else
4968 printf ("__readchar %02X\n", ch);
4969 #endif
4970
4971 return ch;
4972 }
4973
4974 int
__readchar()4975 __readchar ()
4976 {
4977 return __readchar_reporting_winchg_trace (False);
4978 }
4979
4980 int
__readchar_report_winchg()4981 __readchar_report_winchg ()
4982 {
4983 return __readchar_reporting_winchg_trace (True);
4984 }
4985
4986
4987 /*======================================================================*\
4988 |* Enquire terminal properties *|
4989 \*======================================================================*/
4990
4991 #ifdef vms
4992
4993 void
get_term(TERM)4994 get_term (TERM)
4995 char * TERM;
4996 {
4997 ttopen ();
4998 get_term_cap ("vt100");
4999 }
5000
5001 void
getwinsize()5002 getwinsize ()
5003 {
5004 YMAX = ttrows - 1 - MENU; /* # of lines */
5005 XMAX = ttcols - 1; /* # of columns */
5006 }
5007
5008 #else
5009
5010 #if defined (unix) || defined (ANSI)
5011
5012 /*
5013 * Get current window size
5014 If this does not work (e.g. on SCO Caldera Linux, or VMS (remote login),
5015 or likely whenever a real terminal is connected),
5016 the issue will be caught and handled by checkwinsize() by querying the terminal.
5017 */
5018 void
getwinsize()5019 getwinsize ()
5020 {
5021 #ifdef TIOCGWINSZ
5022 struct winsize winsiz;
5023 static int get_winsz = 1; /* check only once; on SunOS there was a
5024 bug that after initial result values 0 0
5025 (size not known to SunOS), further calls
5026 would return erratic random values.
5027 */
5028
5029 if (get_winsz) {
5030 (void) ioctl (output_fd, TIOCGWINSZ, & winsiz);
5031 if (winsiz.ws_row != 0) {
5032 YMAX = winsiz.ws_row - 1 - MENU;
5033 }
5034 if (winsiz.ws_col != 0) {
5035 XMAX = winsiz.ws_col - 1;
5036 } else {
5037 get_winsz = 0;
5038 }
5039 }
5040 #else
5041 #ifdef TIOCGSIZE
5042 struct ttysize ttysiz;
5043
5044 (void) ioctl (output_fd, TIOCGSIZE, & ttysiz);
5045 if (ttysiz.ts_lines != 0) {
5046 YMAX = ttysiz.ts_lines - 1 - MENU;
5047 }
5048 if (ttysiz.ts_cols != 0) {
5049 XMAX = ttysiz.ts_cols - 1;
5050 }
5051 #else
5052 #ifdef WIOCGETD
5053 struct uwdata uwdat;
5054
5055 (void) ioctl (output_fd, WIOCGETD, & uwdat);
5056 if (uwdat.uw_height > 0) {
5057 YMAX = uwdat.uw_height / uwdat.uw_vs - 1 - MENU;
5058 }
5059 if (uwdat.uw_width > 0) {
5060 XMAX = uwdat.uw_width / uwdat.uw_hs - 1;
5061 }
5062 #else
5063 #warning [41m system does not support terminal size retrieval (but terminal is queried) [0m
5064 /* leave previous size assumption */
5065 return;
5066 #endif
5067 #endif
5068 #endif
5069
5070 #ifdef CURSES
5071 # if defined (__PDCURSES__) || defined (NCURSES_VERSION)
5072 if (init_done) {
5073 resize_term (YMAX + 1 + MENU, XMAX + 1);
5074 }
5075 # endif
5076 #endif
5077
5078 trace_winchg (("getwinsize: %d * %d\n", XMAX + 1, YMAX + 1 + MENU));
5079 }
5080
5081 /*
5082 * Get terminal information
5083 */
5084 void
get_term(TERMname)5085 get_term (TERMname)
5086 char * TERMname;
5087 {
5088 if (TERMname == NIL_PTR) {
5089 #ifdef __EMX__
5090 TERMname = "ansi";
5091 #else
5092 panic ("Terminal not specified", NIL_PTR);
5093 #endif
5094 }
5095
5096 get_term_cap (TERMname);
5097 if (strisprefix ("xterm", TERMname)) {
5098 title_string_pattern = "\033]2;%s\007\033]1;%s\007";
5099 } else if (strisprefix ("rxvt", TERMname)) {
5100 title_string_pattern = "\033]2;%s\007\033]1;%s\007";
5101 #ifndef CURSES
5102 } else if (streq (TERMname, "cygwin")) {
5103 title_string_pattern = "\033]2;%s\007\033]1;%s\007";
5104 if (explicit_border_style) {
5105 use_vga_block_graphics = False;
5106 } else {
5107 use_vt100_block_graphics = False;
5108 use_pc_block_graphics = True;
5109 }
5110 #endif
5111 #ifndef __MINGW32__
5112 } else if (strncmp (TERMname, "sun", 3) == 0 && ! streq (ttyname (output_fd), "/dev/console")) {
5113 title_string_pattern = "\033]l%s\033\\\033]L%s\033\\";
5114 #endif
5115 } else if (strisprefix ("aixterm", TERMname)) {
5116 title_string_pattern = "\033]2;%s\007\033]1;%s\007";
5117 } else if (strisprefix ("dtterm", TERMname)) {
5118 title_string_pattern = "\033]2;%s\007\033]1;%s\007";
5119 } else if (strisprefix ("iris-", TERMname)) {
5120 title_string_pattern = "\033P1.y%s\033\\\033P3.y%s\033\\";
5121 } else if (strisprefix ("hpterm", TERMname)) {
5122 title_string_pattern = "\033&f0k%dD%s\033&f-1k%dD%s";
5123 } else {
5124 title_string_pattern = "";
5125 }
5126
5127 if (! ansi_esc) {
5128 use_mouse_button_event_tracking = False;
5129 }
5130
5131 /*
5132 build_string (text_buffer, "Terminal is %s, %d * %d.\n", TERMname, YMAX+1, XMAX+1);
5133 putstring (text_buffer);
5134 */
5135 }
5136
5137 #endif /* #ifdef unix || ANSI */
5138
5139 #endif /* #else vms */
5140
5141
5142 /*======================================================================*\
5143 |* Screen attribute control *|
5144 \*======================================================================*/
5145
5146 #define dont_debug_disp_colour
5147
5148 static
5149 int
rgb(col,for_256_colours)5150 rgb (col, for_256_colours)
5151 int col;
5152 FLAG for_256_colours;
5153 {
5154 if (col < 16) {
5155 if (col >= 8) {
5156 col -= 8;
5157 }
5158 switch (col) {
5159 case 0: /* black */
5160 return 0x000000;
5161 case 1: /* red */
5162 return 0xFF0000;
5163 case 2: /* green */
5164 return 0x00FF00;
5165 case 3: /* yellow */
5166 return 0xFFFF00;
5167 case 4: /* blue */
5168 return 0x0000FF;
5169 case 5: /* magenta */
5170 return 0xFF00FF;
5171 case 6: /* cyan */
5172 return 0x00FFFF;
5173 case 7: /* white */
5174 return 0xFFFFFF;
5175 default: return 0;
5176 }
5177 } else if (for_256_colours || col >= 88) {
5178 /* 256 colours: 16 VGA + 6×6×6 colour cube + 24 gray shades */
5179 if (col >= 232) {
5180 int gray = (col - 231) * 256 / 25;
5181 return gray << 16 | gray << 8 | gray;
5182 } else {
5183 int r, g, b;
5184 col -= 16; /* clear VGA offset */
5185 r = col / 36;
5186 g = (col % 36) / 6;
5187 b = col % 6;
5188 r *= 0x33;
5189 g *= 0x33;
5190 b *= 0x33;
5191 return r << 16 | g << 8 | b;
5192 }
5193 } else {
5194 /* 88 colours: 16 VGA + 4×4×4 colour cube + 8 gray shades */
5195 if (col >= 80) {
5196 int gray = (col - 79) * 256 / 9;
5197 return gray << 16 | gray << 8 | gray;
5198 } else {
5199 int r, g, b;
5200 col -= 16; /* clear VGA offset */
5201 r = col / 16;
5202 g = (col % 16) / 4;
5203 b = col % 4;
5204 r *= 0x55;
5205 g *= 0x55;
5206 b *= 0x55;
5207 return r << 16 | g << 8 | b;
5208 }
5209 }
5210 }
5211
5212 static
5213 int
R(rgb0)5214 R (rgb0)
5215 int rgb0;
5216 {
5217 return rgb0 >> 16;
5218 }
5219
5220 static
5221 int
G(rgb0)5222 G (rgb0)
5223 int rgb0;
5224 {
5225 return (rgb0 >> 8) & 0xFF;
5226 }
5227
5228 static
5229 int
B(rgb0)5230 B (rgb0)
5231 int rgb0;
5232 {
5233 return rgb0 & 0xFF;
5234 }
5235
5236 static
5237 unsigned int
dist(rgb1,rgb2)5238 dist (rgb1, rgb2)
5239 int rgb1, rgb2;
5240 {
5241 int dr = R (rgb1) - R (rgb2);
5242 int dg = G (rgb1) - G (rgb2);
5243 int db = B (rgb1) - B (rgb2);
5244 return dr * dr + dg * dg + db * db;
5245 }
5246
5247 static
5248 int
map8(col,for_256_colours)5249 map8 (col, for_256_colours)
5250 int col;
5251 FLAG for_256_colours;
5252 {
5253 unsigned int d = (unsigned int) -1; /* max unsigned int */
5254 int i;
5255 int rgb_col = rgb (col, for_256_colours);
5256 int repl_col = -1;
5257
5258 if (col >= 244) {
5259 return 7;
5260 } else if (col >= 232) {
5261 return 0;
5262 }
5263 for (i = 0; i < 8; i ++) {
5264 unsigned int dist_col = dist (rgb (i, for_256_colours), rgb_col);
5265 if (dist_col < d) {
5266 d = dist_col;
5267 repl_col = i;
5268 }
5269 #ifdef debug_disp_colour
5270 printf (" %06X %06X dist %d col %d\n", rgb_col, rgb (i, for_256_colours), dist_col, repl_col);
5271 #endif
5272 }
5273 if (repl_col == 0) {
5274 return 4; /* replace black with blue */
5275 }
5276 if (repl_col == 7) {
5277 return 3; /* replace white with yellow */
5278 }
5279 return repl_col;
5280 }
5281
5282
5283 #ifdef CURSES
5284
5285 void
disp_colour(c,for_256_colours)5286 disp_colour (c, for_256_colours)
5287 int c;
5288 FLAG for_256_colours;
5289 {
5290 attrset (COLOR_PAIR (colour8_base + map8 (c, for_256_colours)));
5291 if (dark_term) {
5292 attron (A_BOLD);
5293 }
5294 }
5295
5296 void
emph_on()5297 emph_on ()
5298 {
5299 attrset (COLOR_PAIR (emphcolor));
5300 if (dark_term) {
5301 attron (A_BOLD);
5302 }
5303 }
5304
5305 void
mark_on()5306 mark_on ()
5307 {
5308 if (colour_token >= 0) {
5309 disp_colour (colour_token, UNSURE);
5310 colour_token = -1;
5311 } else if (nonempty (markansi)) {
5312 attrset (COLOR_PAIR (markcolor));
5313 } else if (! dark_term) {
5314 attrset (A_DIM);
5315 }
5316 if (dark_term) {
5317 attron (A_BOLD);
5318 }
5319 }
5320
5321 void
mark_off()5322 mark_off ()
5323 {
5324 standend ();
5325 }
5326
5327
5328 void
bold_on()5329 bold_on ()
5330 {
5331 attrset (A_BOLD);
5332 }
5333
5334 void
bold_off()5335 bold_off ()
5336 {
5337 standend ();
5338 }
5339
5340 void
underline_on()5341 underline_on ()
5342 {
5343 attrset (A_UNDERLINE);
5344 }
5345
5346 void
underline_off()5347 underline_off ()
5348 {
5349 standend ();
5350 }
5351
5352 void
blink_on()5353 blink_on ()
5354 {
5355 attrset (A_BLINK);
5356 }
5357
5358 void
blink_off()5359 blink_off ()
5360 {
5361 standend ();
5362 }
5363
5364 void
disp_normal()5365 disp_normal ()
5366 {
5367 standend ();
5368 }
5369
5370 void
disp_selected(bg,border)5371 disp_selected (bg, border)
5372 FLAG bg;
5373 FLAG border;
5374 /* for selected menu item */
5375 {
5376 /* | selected item |
5377 left border: bg && border (if graphic)
5378 selected item: bg && ! border
5379 right border: ! bg && border (if graphic)
5380 */
5381 if (avoid_reverse_colour) {
5382 /* workaround for buggy cygwin reverse bold colour handling */
5383 if (bg) {
5384 if (border) {
5385 attrset (COLOR_PAIR (selcolor));
5386 } else {
5387 reverse_off ();
5388 attrset (COLOR_PAIR (selcolor) | A_REVERSE | A_BOLD);
5389 }
5390 } else {
5391 attrset ((border ? COLOR_PAIR (selcolor) : COLOR_PAIR (selcolor) | A_REVERSE));
5392 }
5393 } else {
5394 if (nonempty (selansi)) {
5395 attrset ((border ? COLOR_PAIR (selcolor) : COLOR_PAIR (selcolor) | A_REVERSE)
5396 | (bg ? A_REVERSE : 0)
5397 | (dark_term ? A_BOLD : 0)
5398 );
5399 } else {
5400 standout ();
5401 }
5402 }
5403 }
5404
5405
5406 void
unidisp_on()5407 unidisp_on ()
5408 /* for non-displayable or illegal Unicode characters */
5409 {
5410 if (nonempty (uniansi)) {
5411 /*attrset (COLOR_PAIR (unicolor));*/
5412 attrset (COLOR_PAIR (specialcolor) | A_REVERSE);
5413 } else {
5414 standout ();
5415 }
5416 }
5417
5418 void
unidisp_off()5419 unidisp_off ()
5420 {
5421 standend ();
5422 }
5423
5424
5425 void
specialdisp_on()5426 specialdisp_on ()
5427 /* for Unicode line end indications */
5428 {
5429 if (nonempty (specialansi)) {
5430 attrset (COLOR_PAIR (specialcolor));
5431 } else {
5432 standout ();
5433 }
5434 }
5435
5436 void
specialdisp_off()5437 specialdisp_off ()
5438 {
5439 standend ();
5440 }
5441
5442
5443 void
combiningdisp_on()5444 combiningdisp_on ()
5445 /* for Unicode combining character indication in separated display mode */
5446 {
5447 if (nonempty (combiningansi)) {
5448 /*attrset (COLOR_PAIR (combiningcolor));*/
5449 attrset (COLOR_PAIR (specialcolor) | A_REVERSE);
5450 } else {
5451 standout ();
5452 }
5453 }
5454
5455 void
combiningdisp_off()5456 combiningdisp_off ()
5457 {
5458 standend ();
5459 }
5460
5461
5462 void
ctrldisp_on()5463 ctrldisp_on ()
5464 {
5465 if (nonempty (ctrlansi)) {
5466 attrset (COLOR_PAIR (ctrlcolor));
5467 } else {
5468 standout ();
5469 }
5470 }
5471
5472 void
ctrldisp_off()5473 ctrldisp_off ()
5474 {
5475 standend ();
5476 }
5477
5478
5479 void
dispHTML_code()5480 dispHTML_code ()
5481 {
5482 if (nonempty (HTMLansi)) {
5483 attrset (COLOR_PAIR (HTMLcolor));
5484 } else {
5485 standout ();
5486 }
5487 }
5488
5489 void
dispHTML_comment()5490 dispHTML_comment ()
5491 {
5492 if (nonempty (HTMLansi)) {
5493 attrset (COLOR_PAIR (HTMLcomment));
5494 } else {
5495 standout ();
5496 }
5497 }
5498
5499 void
dispHTML_jsp()5500 dispHTML_jsp ()
5501 {
5502 if (nonempty (HTMLansi)) {
5503 attrset (COLOR_PAIR (HTMLjsp));
5504 } else {
5505 standout ();
5506 }
5507 }
5508
5509 void
dispXML_attrib()5510 dispXML_attrib ()
5511 {
5512 if (nonempty (XMLattribansi)) {
5513 attrset (COLOR_PAIR (XMLattrib));
5514 } else {
5515 standout ();
5516 }
5517 }
5518
5519 void
dispXML_value()5520 dispXML_value ()
5521 {
5522 if (nonempty (XMLvalueansi)) {
5523 attrset (COLOR_PAIR (XMLvalue));
5524 } else {
5525 standout ();
5526 }
5527 }
5528
5529 void
dispHTML_off()5530 dispHTML_off ()
5531 {
5532 standend ();
5533 }
5534
5535
5536 void
menudisp_on()5537 menudisp_on ()
5538 {
5539 if (nonempty (menuansi)) {
5540 attrset (COLOR_PAIR (menucolor));
5541 } else {
5542 standout ();
5543 }
5544 }
5545
5546 void
menudisp_off()5547 menudisp_off ()
5548 {
5549 standend ();
5550 }
5551
5552 void
diagdisp_on()5553 diagdisp_on ()
5554 {
5555 if (nonempty (diagansi)) {
5556 attrset (COLOR_PAIR (diagcolor));
5557 } else {
5558 standout ();
5559 }
5560 }
5561
5562 void
diagdisp_off()5563 diagdisp_off ()
5564 {
5565 standend ();
5566 }
5567
5568
5569 void
disp_scrollbar_foreground()5570 disp_scrollbar_foreground ()
5571 {
5572 if (nonempty (scrollbgansi)) {
5573 attrset (COLOR_PAIR (scrollfgcolor));
5574 } else {
5575 standout ();
5576 }
5577 }
5578
5579 void
disp_scrollbar_background()5580 disp_scrollbar_background ()
5581 {
5582 if (nonempty (scrollbgansi)) {
5583 attrset (COLOR_PAIR (scrollfgcolor) | A_REVERSE);
5584 }
5585 }
5586
5587 void
disp_scrollbar_off()5588 disp_scrollbar_off ()
5589 {
5590 standend ();
5591 }
5592
5593
5594 void
menuborder_on()5595 menuborder_on ()
5596 {
5597 if (! use_normalchars_boxdrawing) {
5598 altcset_on ();
5599 }
5600 #ifdef use_default_colour
5601 attrset (COLOR_PAIR (menuborder) | (bold_border ? A_BOLD : 0));
5602 #endif
5603 in_menu_border = True;
5604 }
5605
5606 void
menuborder_off()5607 menuborder_off ()
5608 {
5609 standend ();
5610 if (! use_normalchars_boxdrawing) {
5611 altcset_off ();
5612 }
5613 in_menu_border = False;
5614 }
5615
5616 void
menuitem_on()5617 menuitem_on ()
5618 {
5619 #ifdef use_default_colour
5620 attrset (COLOR_PAIR (menuitem) /* | A_BOLD */);
5621 #endif
5622 }
5623
5624 void
menuitem_off()5625 menuitem_off ()
5626 {
5627 standend ();
5628 }
5629
5630 void
menuheader_on()5631 menuheader_on ()
5632 {
5633 if (! use_normalchars_boxdrawing) {
5634 altcset_off ();
5635 }
5636 if (avoid_reverse_colour) {
5637 /* workaround for buggy cygwin reverse bold colour handling */
5638 disp_normal ();
5639 attrset (COLOR_PAIR (menuheader));
5640 } else {
5641 attrset (COLOR_PAIR (menuheader) | A_BOLD | A_REVERSE);
5642 }
5643 in_menu_border = False;
5644 }
5645
5646 void
menuheader_off()5647 menuheader_off ()
5648 {
5649 standend ();
5650 in_menu_border = False;
5651 }
5652
5653 #else /* #ifdef CURSES */
5654
5655
5656 #ifdef conio
5657
5658 void
disp_colour(c,for_256_colours)5659 disp_colour (c, for_256_colours)
5660 int c;
5661 FLAG for_256_colours;
5662 {
5663 switch (map8 (c, for_256_colours)) {
5664 case 0: textcolor (BLACK); break;
5665 case 1: textcolor (RED); break;
5666 case 2: textcolor (GREEN); break;
5667 case 3: textcolor (YELLOW); break;
5668 case 4: textcolor (BLUE); break;
5669 case 5: textcolor (MAGENTA); break;
5670 case 6: textcolor (CYAN); break;
5671 case 7: textcolor (WHITE); break;
5672 }
5673 if (dark_term) {
5674 highvideo ();
5675 }
5676 }
5677
5678 void
emph_on()5679 emph_on ()
5680 {
5681 /* check emphansi ? */
5682 textcolor (RED);
5683 if (dark_term) {
5684 highvideo ();
5685 }
5686 }
5687
5688 void
mark_on()5689 mark_on ()
5690 {
5691 /* check markansi ? */
5692 if (colour_token >= 0) {
5693 disp_colour (colour_token, UNSURE);
5694 colour_token = -1;
5695 } else {
5696 textcolor (RED);
5697 }
5698 if (dark_term) {
5699 highvideo ();
5700 }
5701 }
5702
5703 void
mark_off()5704 mark_off ()
5705 {
5706 normvideo ();
5707 }
5708
5709
5710 void
bold_on()5711 bold_on ()
5712 {
5713 highvideo ();
5714 }
5715
5716 void
bold_off()5717 bold_off ()
5718 {
5719 normvideo ();
5720 }
5721
5722 void
underline_on()5723 underline_on ()
5724 {
5725 highvideo ();
5726 }
5727
5728 void
underline_off()5729 underline_off ()
5730 {
5731 normvideo ();
5732 }
5733
5734 void
blink_on()5735 blink_on ()
5736 {
5737 #ifdef __DJGPP__
5738 blinkvideo ();
5739 #else
5740 highvideo ();
5741 #endif
5742 }
5743
5744 void
blink_off()5745 blink_off ()
5746 {
5747 normvideo ();
5748 }
5749
5750 void
disp_normal()5751 disp_normal ()
5752 {
5753 normvideo ();
5754 }
5755
5756 void
disp_selected(bg,border)5757 disp_selected (bg, border)
5758 FLAG bg;
5759 FLAG border;
5760 {
5761 /* check selansi ? */
5762 if (bg) {
5763 if (dark_term) {
5764 highvideo ();
5765 } else {
5766 normvideo ();
5767 }
5768 textbackground (BLUE);
5769 if (! border) {
5770 textcolor (YELLOW);
5771 }
5772 } else {
5773 textcolor (BLUE);
5774 }
5775 }
5776
5777
5778 void
unidisp_on()5779 unidisp_on ()
5780 /* for non-displayable or illegal Unicode characters */
5781 {
5782 /* check uniansi ? */
5783 textbackground (CYAN);
5784 }
5785
5786 void
unidisp_off()5787 unidisp_off ()
5788 {
5789 normvideo ();
5790 }
5791
5792
5793 void
specialdisp_on()5794 specialdisp_on ()
5795 /* for Unicode line end indications */
5796 {
5797 textcolor (CYAN);
5798 }
5799
5800 void
specialdisp_off()5801 specialdisp_off ()
5802 {
5803 normvideo ();
5804 }
5805
5806
5807 void
combiningdisp_on()5808 combiningdisp_on ()
5809 /* for Unicode combining character indication in separated display mode */
5810 {
5811 textbackground (CYAN);
5812 textcolor (BLACK);
5813 }
5814
5815 void
combiningdisp_off()5816 combiningdisp_off ()
5817 {
5818 normvideo ();
5819 }
5820
5821
5822 void
ctrldisp_on()5823 ctrldisp_on ()
5824 {
5825 reverse_on ();
5826 }
5827
5828 void
ctrldisp_off()5829 ctrldisp_off ()
5830 {
5831 reverse_off ();
5832 }
5833
5834
5835 void
dispHTML_code()5836 dispHTML_code ()
5837 {
5838 textcolor (LIGHTBLUE);
5839 }
5840
5841 void
dispXML_attrib()5842 dispXML_attrib ()
5843 {
5844 textcolor (RED);
5845 }
5846
5847 void
dispXML_value()5848 dispXML_value ()
5849 {
5850 textcolor (MAGENTA);
5851 }
5852
5853 void
dispHTML_comment()5854 dispHTML_comment ()
5855 {
5856 textcolor (LIGHTBLUE);
5857 textbackground (YELLOW);
5858 }
5859
5860 void
dispHTML_jsp()5861 dispHTML_jsp ()
5862 {
5863 textcolor (CYAN);
5864 textbackground (BLACK);
5865 }
5866
5867 void
dispHTML_off()5868 dispHTML_off ()
5869 {
5870 normvideo ();
5871 }
5872
5873
5874 void
menudisp_on()5875 menudisp_on ()
5876 {
5877 reverse_on ();
5878 }
5879
5880 void
menudisp_off()5881 menudisp_off ()
5882 {
5883 reverse_off ();
5884 }
5885
5886 void
diagdisp_on()5887 diagdisp_on ()
5888 {
5889 reverse_on ();
5890 }
5891
5892 void
diagdisp_off()5893 diagdisp_off ()
5894 {
5895 reverse_off ();
5896 }
5897
5898
5899 void
disp_scrollbar_foreground()5900 disp_scrollbar_foreground ()
5901 {
5902 /* textattr (CYAN); */
5903 textbackground (BLUE);
5904 }
5905
5906 void
disp_scrollbar_background()5907 disp_scrollbar_background ()
5908 {
5909 /* textattr (BLUE); */
5910 textbackground (CYAN);
5911 }
5912
5913 void
disp_scrollbar_off()5914 disp_scrollbar_off ()
5915 {
5916 normvideo ();
5917 }
5918
5919
5920 void
menuborder_on()5921 menuborder_on ()
5922 {
5923 if (! use_normalchars_boxdrawing) {
5924 altcset_on ();
5925 }
5926 textattr (RED);
5927 if (bold_border) {
5928 highvideo ();
5929 }
5930 in_menu_border = True;
5931 }
5932
5933 void
menuborder_off()5934 menuborder_off ()
5935 {
5936 normvideo ();
5937 textattr (norm_attr);
5938 if (! use_normalchars_boxdrawing) {
5939 altcset_off ();
5940 }
5941 in_menu_border = False;
5942 }
5943
5944 void
menuitem_on()5945 menuitem_on ()
5946 {
5947 textbackground (YELLOW);
5948 /* highvideo (); */
5949 }
5950
5951 void
menuitem_off()5952 menuitem_off ()
5953 {
5954 textattr (norm_attr);
5955 }
5956
5957 void
menuheader_on()5958 menuheader_on ()
5959 {
5960 if (! use_normalchars_boxdrawing) {
5961 altcset_off ();
5962 }
5963 /*reverse_on ();*/
5964 textbackground (RED);
5965 textcolor (LIGHTGRAY);
5966 in_menu_border = False;
5967 }
5968
5969 void
menuheader_off()5970 menuheader_off ()
5971 {
5972 textattr (norm_attr);
5973 in_menu_border = False;
5974 }
5975
5976 #else /* #ifdef conio */
5977
5978
5979 static
5980 FLAG
putansistring(s)5981 putansistring (s)
5982 char * s;
5983 {
5984 if (ansi_esc && nonempty (s)) {
5985 if (suppress_colour && (* s == '3' || * s == '4')) {
5986 /* e.g. for Android Terminal Emulator */
5987 if (s == scrollfgansi) {
5988 return False;
5989 } else if (s == scrollbgansi) {
5990 return True;
5991 } else if (strstr (s, ";1")) {
5992 putansistring ("1");
5993 return False;
5994 } else if (strstr (s, ";7")) {
5995 putansistring ("7");
5996 return False;
5997 } else {
5998 return False;
5999 }
6000 }
6001 putescape ("\033[");
6002 putescape (s);
6003 putescape ("m");
6004 return True;
6005 } else {
6006 return False;
6007 }
6008 }
6009
6010 void
disp_colour(c,for_256_colours)6011 disp_colour (c, for_256_colours)
6012 int c;
6013 FLAG for_256_colours;
6014 {
6015 char ctrl [19];
6016 int col8 = map8 (c, for_256_colours);
6017
6018 if (c < 8) {
6019 build_string (ctrl, "3%d", c);
6020 } else if (c < 16) {
6021 build_string (ctrl, "9%d", c - 8);
6022 } else {
6023 if (colours_256 || colours_88) {
6024 build_string (ctrl, "38;5;%d", c);
6025 } else {
6026 build_string (ctrl, "3%d", col8);
6027 }
6028 }
6029 #ifdef debug_disp_colour
6030 printf ("disp_colour %d put <%s>\n", c, ctrl);
6031 #endif
6032 (void) putansistring (ctrl);
6033
6034 if (col8 == 0 || col8 == 1 || col8 == 4) {
6035 /* black, red, blue */
6036 if (dark_term) {
6037 bold_on ();
6038 }
6039 } else {
6040 if (! dark_term) {
6041 bold_on ();
6042 }
6043 }
6044 }
6045
6046 void
emph_on()6047 emph_on ()
6048 {
6049 if (dark_term) {
6050 bold_on ();
6051 }
6052 (void) putansistring (emphansi);
6053 }
6054
6055 void
mark_on()6056 mark_on ()
6057 {
6058 if (dark_term) {
6059 bold_on ();
6060 } else {
6061 #if defined (unix) || defined (vms)
6062 if (can_dim && ! screen_version && ansi_esc &&
6063 (! cMH || ! * cMH)) {
6064 cMH = "[2m";
6065 }
6066 termputstr (cMH, aff1);
6067 #endif
6068 }
6069 if (colour_token >= 0) {
6070 disp_colour (colour_token, UNSURE);
6071 colour_token = -1;
6072 } else {
6073 (void) putansistring (markansi);
6074 }
6075 }
6076
6077 void
mark_off()6078 mark_off ()
6079 {
6080 if (! putansistring ("0")) {
6081 termputstr (cME, aff1);
6082 }
6083 }
6084
6085 void
bold_on()6086 bold_on ()
6087 {
6088 if (use_bold) {
6089 termputstr (cMD, aff1);
6090 }
6091 }
6092
6093 void
bold_off()6094 bold_off ()
6095 {
6096 if (use_bold) {
6097 termputstr (cME, aff1);
6098 }
6099 }
6100
6101 void
underline_on()6102 underline_on ()
6103 {
6104 termputstr (cUL, aff1);
6105 }
6106
6107 void
underline_off()6108 underline_off ()
6109 {
6110 termputstr (cME, aff1);
6111 }
6112
6113 void
blink_on()6114 blink_on ()
6115 {
6116 termputstr (cBL, aff1);
6117 }
6118
6119 void
blink_off()6120 blink_off ()
6121 {
6122 termputstr (cME, aff1);
6123 }
6124
6125 void
disp_normal()6126 disp_normal ()
6127 {
6128 if (screen_version > 0) {
6129 /* workaround to reset attributes passed by transparently */
6130 reverse_on ();
6131 reverse_off ();
6132 }
6133 termputstr (cME, aff1);
6134 }
6135
6136 static
6137 char *
reverse_colour(ansi)6138 reverse_colour (ansi)
6139 char * ansi;
6140 {
6141 static char revansi [3];
6142 if (ansi [0] == '3') {
6143 revansi [0] = '4';
6144 } else {
6145 revansi [0] = '3';
6146 }
6147 revansi [1] = ansi [1];
6148 revansi [2] = 0;
6149 return revansi;
6150 }
6151
6152 void
disp_selected(bg,border)6153 disp_selected (bg, border)
6154 FLAG bg;
6155 FLAG border;
6156 {
6157 /* | selected item |
6158 left border: bg && border (if graphic)
6159 selected item: bg && ! border
6160 right border: ! bg && border (if graphic)
6161 */
6162 if (avoid_reverse_colour) {
6163 /* workaround for buggy cygwin reverse bold colour handling */
6164 if (bg) {
6165 if (border) {
6166 (void) putansistring (selansi);
6167 reverse_on ();
6168 } else {
6169 reverse_off ();
6170 (void) putansistring (reverse_colour (selansi));
6171 (void) putansistring (reverse_colour (selfgansi));
6172 bold_on ();
6173 }
6174 } else {
6175 (void) putansistring (selansi);
6176 if (! border) {
6177 (void) putansistring (selfgansi);
6178 }
6179 }
6180 } else {
6181 (void) putansistring (selansi);
6182 if (! border) {
6183 (void) putansistring (selfgansi);
6184 }
6185 if (bg) {
6186 reverse_on ();
6187 }
6188 }
6189 }
6190
6191
6192 void
unidisp_on()6193 unidisp_on ()
6194 /* for non-displayable or illegal Unicode characters */
6195 {
6196 if (! putansistring (uniansi)) {
6197 reverse_on ();
6198 }
6199 }
6200
6201 void
unidisp_off()6202 unidisp_off ()
6203 {
6204 if (nonempty (uniansi)) {
6205 if (! putansistring ("0")) {
6206 reverse_off ();
6207 }
6208 } else {
6209 reverse_off ();
6210 }
6211 }
6212
6213
6214 void
specialdisp_on()6215 specialdisp_on ()
6216 /* for Unicode line end indications */
6217 {
6218 if (! putansistring (specialansi)) {
6219 reverse_on ();
6220 }
6221 }
6222
6223 void
specialdisp_off()6224 specialdisp_off ()
6225 {
6226 if (nonempty (specialansi)) {
6227 if (! putansistring ("0")) {
6228 reverse_off ();
6229 }
6230 } else {
6231 reverse_off ();
6232 }
6233 }
6234
6235
6236 void
combiningdisp_on()6237 combiningdisp_on ()
6238 /* for Unicode combining character indication in separated display mode */
6239 {
6240 if (! putansistring (combiningansi)) {
6241 reverse_on ();
6242 }
6243 }
6244
6245 void
combiningdisp_off()6246 combiningdisp_off ()
6247 {
6248 if (nonempty (combiningansi)) {
6249 if (! putansistring ("0")) {
6250 reverse_off ();
6251 }
6252 } else {
6253 reverse_off ();
6254 }
6255 }
6256
6257
6258 void
ctrldisp_on()6259 ctrldisp_on ()
6260 {
6261 if (! putansistring (ctrlansi)) {
6262 reverse_on ();
6263 }
6264 }
6265
6266 void
ctrldisp_off()6267 ctrldisp_off ()
6268 {
6269 if (nonempty (ctrlansi)) {
6270 if (! putansistring ("0")) {
6271 reverse_off ();
6272 }
6273 } else {
6274 reverse_off ();
6275 }
6276 }
6277
6278
6279 void
dispHTML_code()6280 dispHTML_code ()
6281 {
6282 if (! putansistring (HTMLansi)) {
6283 mark_on ();
6284 }
6285 }
6286
6287 void
dispXML_attrib()6288 dispXML_attrib ()
6289 {
6290 if (! putansistring (XMLattribansi)) {
6291 if (! putansistring ("31")) {
6292 mark_on ();
6293 }
6294 }
6295 }
6296
6297 void
dispXML_value()6298 dispXML_value ()
6299 {
6300 if (! putansistring (XMLvalueansi)) {
6301 if (! putansistring ("35")) {
6302 mark_on ();
6303 }
6304 }
6305 }
6306
6307 void
dispHTML_comment()6308 dispHTML_comment ()
6309 {
6310 char ctrl [19];
6311
6312 if (nonempty (HTMLansi)) {
6313 if (fg_yellowish) {
6314 build_string (ctrl, "%s;44;33", HTMLansi);
6315 } else {
6316 build_string (ctrl, "%s;43", HTMLansi);
6317 }
6318 if (! putansistring (ctrl)) {
6319 mark_on ();
6320 }
6321 } else {
6322 mark_on ();
6323 }
6324 }
6325
6326 void
dispHTML_jsp()6327 dispHTML_jsp ()
6328 {
6329 if (nonempty (HTMLansi)) {
6330 /*(void) putansistring ("36");*/
6331 if (! putansistring ("36;40")) {
6332 mark_on ();
6333 }
6334 } else {
6335 mark_on ();
6336 }
6337 }
6338
6339 void
dispHTML_off()6340 dispHTML_off ()
6341 {
6342 if (nonempty (HTMLansi)) {
6343 if (! putansistring ("0")) {
6344 mark_off ();
6345 }
6346 } else {
6347 mark_off ();
6348 }
6349 }
6350
6351
6352 void
menudisp_on()6353 menudisp_on ()
6354 {
6355 if (! putansistring (menuansi)) {
6356 reverse_on ();
6357 }
6358 }
6359
6360 void
menudisp_off()6361 menudisp_off ()
6362 {
6363 if (nonempty (menuansi)) {
6364 if (! putansistring ("0")) {
6365 reverse_off ();
6366 }
6367 } else {
6368 reverse_off ();
6369 }
6370 }
6371
6372 void
diagdisp_on()6373 diagdisp_on ()
6374 {
6375 if (! putansistring (diagansi)) {
6376 reverse_on ();
6377 }
6378 }
6379
6380 void
diagdisp_off()6381 diagdisp_off ()
6382 {
6383 if (nonempty (diagansi)) {
6384 if (! putansistring ("0")) {
6385 reverse_off ();
6386 }
6387 } else {
6388 reverse_off ();
6389 }
6390 }
6391
6392
6393 void
disp_scrollbar_foreground()6394 disp_scrollbar_foreground ()
6395 {
6396 if (suppress_colour) {
6397 reverse_off ();
6398 } else if (nonempty (scrollfgansi)) {
6399 if (! putansistring (scrollfgansi)) {
6400 reverse_on ();
6401 }
6402 } else {
6403 (void) putansistring (scrollbgansi);
6404 reverse_on ();
6405 }
6406 }
6407
6408 void
disp_scrollbar_background()6409 disp_scrollbar_background ()
6410 {
6411 if (suppress_colour) {
6412 reverse_on ();
6413 } else {
6414 reverse_off ();
6415 if (! putansistring (scrollbgansi)) {
6416 termputstr (cSO, aff1);
6417 }
6418 }
6419 }
6420
6421 void
disp_scrollbar_off()6422 disp_scrollbar_off ()
6423 {
6424 if (nonempty (scrollbgansi)) {
6425 if (! putansistring ("0")) {
6426 reverse_off ();
6427 }
6428 } else {
6429 reverse_off ();
6430 }
6431 }
6432
6433
6434 void
menuborder_on()6435 menuborder_on ()
6436 {
6437 if (! use_normalchars_boxdrawing) {
6438 altcset_on ();
6439 }
6440 if (bold_border) {
6441 bold_on ();
6442 }
6443 (void) putansistring (borderansi);
6444 in_menu_border = True;
6445 }
6446
6447 void
menuborder_off()6448 menuborder_off ()
6449 {
6450 (void) putansistring ("0");
6451 if (! use_normalchars_boxdrawing) {
6452 altcset_off ();
6453 }
6454 in_menu_border = False;
6455 }
6456
6457 void
menuitem_on()6458 menuitem_on ()
6459 {
6460 if (use_bgcolor) {
6461 /* try to keep it visible on old buggy hanterm: */
6462 /* - hopefully not needed anymore; */
6463 /* - interferes unpleasantly with buggy
6464 bold/colour combination on gnome-terminal/konsole */
6465 /* bold_on (); */
6466
6467 if (! putansistring (fg_yellowish ? "44;33" : "43;30")) {
6468 reverse_on ();
6469 }
6470 } else {
6471 if (! putansistring ("0;1")) {
6472 reverse_on ();
6473 }
6474 }
6475 }
6476
6477 void
menuitem_off()6478 menuitem_off ()
6479 {
6480 if (! putansistring ("0")) {
6481 reverse_off ();
6482 }
6483 }
6484
6485 void
menuheader_on()6486 menuheader_on ()
6487 {
6488 if (! use_normalchars_boxdrawing) {
6489 altcset_off ();
6490 }
6491 if (avoid_reverse_colour) {
6492 /* workaround for buggy cygwin reverse bold colour handling */
6493 disp_normal ();
6494 if (dark_term) {
6495 (void) putansistring ("37");
6496 }
6497 (void) putansistring (reverse_colour (borderansi));
6498 } else {
6499 if (dark_term) {
6500 bold_on ();
6501 }
6502 /* Note: menu border colour is already switched on */
6503 if (! putansistring ("7")) {
6504 reverse_on ();
6505 }
6506 }
6507 in_menu_border = False;
6508 }
6509
6510 void
menuheader_off()6511 menuheader_off ()
6512 {
6513 if (! putansistring ("0")) {
6514 reverse_off ();
6515 }
6516 in_menu_border = False;
6517 }
6518
6519 #endif /* #else conio */
6520
6521
6522 #endif /* #else CURSES */
6523
6524
6525 /*======================================================================*\
6526 |* DOS mouse API *|
6527 \*======================================================================*/
6528
6529 #ifdef dosmouse
6530 #include "dosmouse.c"
6531 #endif
6532
6533
6534 /*======================================================================*\
6535 |* End *|
6536 \*======================================================================*/
6537