4 | A subset of curses developed for use with ae.
6 | written by Hugh Mahon
8 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11 | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 | FITNESS FOR A PARTICULAR PURPOSE. Neither
13 | Hewlett-Packard nor Hugh Mahon shall be liable
14 | for errors contained herein, nor for
15 | incidental or consequential damages in
16 | connection with the furnishing, performance or
17 | use of this material. Neither Hewlett-Packard
18 | nor Hugh Mahon assumes any responsibility for
19 | the use or reliability of this software or
20 | documentation. This software and
21 | documentation is totally UNSUPPORTED. There
22 | is no support contract available. Hewlett-
23 | Packard has done NO Quality Assurance on ANY
24 | of the program or documentation. You may find
25 | the quality of the materials inferior to
26 | supported materials.
28 | This software is not a product of Hewlett-Packard, Co., or any
29 | other company. No support is implied or offered with this software.
30 | You've got the source, and you're on your own.
32 | This software may be distributed under the terms of Larry Wall's
33 | Artistic license, a copy of which is included in this distribution.
35 | This notice must be included with this software and any derivatives.
37 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
38 | All are rights reserved.
40 | $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $
41 | $DragonFly: src/usr.bin/ee/new_curse.c,v 1.2 2003/06/17 04:29:26 dillon Exp $
45 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
46 "All rights are reserved."};
48 char * new_curse_name= "@(#) new_curse.c $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $";
50 #include "new_curse.h"
61 #include <sys/types.h>
65 #include <sys/select.h> /* on AIX */
68 #endif /* BSD_SELECT */
85 #include <sys/ioctl.h>
90 static WINDOW *virtual_scr;
92 WINDOW *last_window_refreshed;
98 #define min(a, b) (a < b ? a : b)
99 #define highbitset(a) ((a) & 0x80)
102 #define String_Out(table, stack, place) Info_Out(table, stack, place)
104 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
107 #define bw__ 0 /* booleans */
110 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
113 #define gn__ 6 /* generic type terminal */
114 #define hc__ 7 /* hardcopy terminal */
120 #define mi__ 13 /* safe to move during insert mode */
121 #define ms__ 14 /* safe to move during standout mode */
125 #define hz__ 18 /* hazeltine glitch */
134 #define co__ 0 /* number of columns */ /* numbers */
135 #define it__ 1 /* spaces per tab */
136 #define li__ 2 /* number of lines */
138 #define sg__ 4 /* magic cookie glitch */
152 #define bt__ 0 /* back tab */ /* strings */
153 #define bl__ 1 /* bell */
154 #define cr__ 2 /* carriage return */
155 #define cs__ 3 /* change scroll region */
156 #define ct__ 4 /* clear all tab stops */
157 #define cl__ 5 /* clear screen and home cursor */
158 #define ce__ 6 /* clear to end of line */
159 #define cd__ 7 /* clear to end of display */
160 #define ch__ 8 /* set cursor column */
161 #define CC__ 9 /* term, settable cmd char in */
162 #define cm__ 10 /* screen rel cursor motion, row, column */
163 #define do__ 11 /* down one line */
164 #define ho__ 12 /* home cursor */
165 #define vi__ 13 /* make cursor invisible */
166 #define le__ 14 /* move cursor left one space */
167 #define CM__ 15 /* memory rel cursor addressing */
168 #define ve__ 16 /* make cursor appear normal */
169 #define nd__ 17 /* non-destructive space (cursor right) */
170 #define ll__ 18 /* last line, first col */
171 #define up__ 19 /* cursor up */
173 #define dc__ 21 /* delete character */
174 #define dl__ 22 /* delete line */
179 #define md__ 27 /* turn on bold */
181 #define dm__ 29 /* turn on delete mode */
182 #define mh__ 30 /* half bright mode */
183 #define im__ 31 /* insert mode */
187 #define so__ 35 /* enter standout mode */
194 #define ei__ 42 /* exit insert mode */
195 #define se__ 43 /* exit standout mode */
207 #define kb__ 55 /* backspace key */
239 #define ku__ 87 /* key up */
283 #define sa__ 131 /* sgr */
429 char *Boolean_names[] = {
430 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
431 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
434 char *Number_names[] = {
435 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
438 char *String_names[] = {
439 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
440 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
441 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
442 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
443 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
444 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
445 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
446 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
447 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
448 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
449 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
450 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
451 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
452 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
453 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
454 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
455 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
456 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
457 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
458 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
459 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
460 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
461 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
462 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
463 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
467 char *new_curse = "October 1987";
469 char in_buff[100]; /* buffer for ungetch */
470 int bufp; /* next free position in in_buff */
472 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
474 int Data_Line_len = 0;
475 int Max_Key_len; /* max length of a sequence sent by a key */
476 char *Data_Line = NULL;
477 char *TERM_PATH = NULL;
478 char *TERM_data_ptr = NULL;
479 char *Term_File_name = NULL; /* name of file containing terminal description */
480 FILE *TFP; /* file pointer to file with terminal des. */
481 int Fildes; /* file descriptor for terminfo file */
482 int STAND = FALSE; /* is standout mode activated? */
483 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
484 int Time_Out; /* set when time elapsed while trying to read function key */
485 int Curr_x; /* current x position on screen */
486 int Curr_y; /* current y position on the screen */
489 int Move_It; /* flag to move cursor if magic cookie glitch */
490 int initialized = FALSE; /* tells whether new_curse is initialized */
492 float chars_per_millisecond;
493 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
494 int Intr; /* storeage for interrupt character */
495 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
496 int Noblock; /* for BSD systems */
497 int Num_bits; /* number of bits per character */
498 int Flip_Bytes; /* some systems have byte order reversed */
499 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
506 int length; /* length of string sent by key */
507 char *string; /* string sent by key */
508 int value; /* CURSES value of key (9-bit) */
512 struct KEYS *element;
513 struct KEY_STACK *next;
516 struct KEY_STACK *KEY_TOS = NULL;
517 struct KEY_STACK *KEY_POINT;
521 | Not all systems have good terminal information, so we will define
522 | keyboard information here for the most widely used terminal type,
527 struct KEYS vt100[] =
529 { 3, "\033[A", 0403 }, /* key up */
530 { 3, "\033[C", 0405 }, /* key right */
531 { 3, "\033[D", 0404 }, /* key left */
533 { 4, "\033[6~", 0522 }, /* key next page */
534 { 4, "\033[5~", 0523 }, /* key prev page */
535 { 3, "\033[[", 0550 }, /* key end */
536 { 3, "\033[@", 0406 }, /* key home */
537 { 4, "\033[2~", 0513 }, /* key insert char */
539 { 3, "\033[y", 0410 }, /* key F0 */
540 { 3, "\033[P", 0411 }, /* key F1 */
541 { 3, "\033[Q", 0412 }, /* key F2 */
542 { 3, "\033[R", 0413 }, /* key F3 */
543 { 3, "\033[S", 0414 }, /* key F4 */
544 { 3, "\033[t", 0415 }, /* key F5 */
545 { 3, "\033[u", 0416 }, /* key F6 */
546 { 3, "\033[v", 0417 }, /* key F7 */
547 { 3, "\033[l", 0420 }, /* key F8 */
548 { 3, "\033[w", 0421 }, /* key F9 */
549 { 3, "\033[x", 0422 }, /* key F10 */
551 { 5, "\033[10~", 0410 }, /* key F0 */
552 { 5, "\033[11~", 0411 }, /* key F1 */
553 { 5, "\033[12~", 0412 }, /* key F2 */
554 { 5, "\033[13~", 0413 }, /* key F3 */
555 { 5, "\033[14~", 0414 }, /* key F4 */
556 { 5, "\033[15~", 0415 }, /* key F5 */
557 { 5, "\033[17~", 0416 }, /* key F6 */
558 { 5, "\033[18~", 0417 }, /* key F7 */
559 { 5, "\033[19~", 0420 }, /* key F8 */
560 { 5, "\033[20~", 0421 }, /* key F9 */
561 { 5, "\033[21~", 0422 }, /* key F10 */
562 { 5, "\033[23~", 0423 }, /* key F11 */
563 { 5, "\033[24~", 0424 }, /* key F12 */
564 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
565 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
566 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
567 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
568 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
571 | The following are the same keys as above, but with
572 | a different character following the escape char.
575 { 3, "\033OA", 0403 }, /* key up */
576 { 3, "\033OC", 0405 }, /* key right */
577 { 3, "\033OD", 0404 }, /* key left */
578 { 3, "\033OB", 0402 }, /* key down */
579 { 4, "\033O6~", 0522 }, /* key next page */
580 { 4, "\033O5~", 0523 }, /* key prev page */
581 { 3, "\033O[", 0550 }, /* key end */
582 { 3, "\033O@", 0406 }, /* key home */
583 { 4, "\033O2~", 0513 }, /* key insert char */
585 { 3, "\033Oy", 0410 }, /* key F0 */
586 { 3, "\033OP", 0411 }, /* key F1 */
587 { 3, "\033OQ", 0412 }, /* key F2 */
588 { 3, "\033OR", 0413 }, /* key F3 */
589 { 3, "\033OS", 0414 }, /* key F4 */
590 { 3, "\033Ot", 0415 }, /* key F5 */
591 { 3, "\033Ou", 0416 }, /* key F6 */
592 { 3, "\033Ov", 0417 }, /* key F7 */
593 { 3, "\033Ol", 0420 }, /* key F8 */
594 { 3, "\033Ow", 0421 }, /* key F9 */
595 { 3, "\033Ox", 0422 }, /* key F10 */
597 { 5, "\033O10~", 0410 }, /* key F0 */
598 { 5, "\033O11~", 0411 }, /* key F1 */
599 { 5, "\033O12~", 0412 }, /* key F2 */
600 { 5, "\033O13~", 0413 }, /* key F3 */
601 { 5, "\033O14~", 0414 }, /* key F4 */
602 { 5, "\033O15~", 0415 }, /* key F5 */
603 { 5, "\033O17~", 0416 }, /* key F6 */
604 { 5, "\033O18~", 0417 }, /* key F7 */
605 { 5, "\033O19~", 0420 }, /* key F8 */
606 { 5, "\033O20~", 0421 }, /* key F9 */
607 { 5, "\033O21~", 0422 }, /* key F10 */
608 { 5, "\033O23~", 0423 }, /* key F11 */
609 { 5, "\033O24~", 0424 }, /* key F12 */
610 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
611 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
612 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
613 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
614 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
616 { 0, "", 0 } /* end */
621 struct Parameters *next;
625 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
626 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
627 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
628 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
629 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
630 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
631 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
632 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
633 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
634 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
635 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
636 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
637 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
640 int attributes_set[9];
642 static int nc_attributes = 0; /* global attributes for new_curse to observe */
645 struct termio Terminal;
646 struct termio Saved_tty;
648 struct sgttyb Terminal;
649 struct sgttyb Saved_tty;
656 char *String_table[1024];
660 static char nc_scrolling_ability = FALSE;
664 #if __STDC__ || defined(__cplusplus)
668 #endif /* __STDC__ */
670 int tc_Get_int P_((int));
671 void CAP_PARSE P_((void));
672 void Find_term P_((void));
681 extern char *fgets();
682 extern char *malloc();
683 extern char *getenv();
684 FILE *fopen(); /* declaration for open function */
685 #endif /* HAS_STDLIB */
686 #endif /* __STDC__ */
691 | Copy the contents of one window to another.
695 copy_window(origin, destination)
696 WINDOW *origin, *destination;
699 struct _line *orig, *dest;
701 orig = origin->first_line;
702 dest = destination->first_line;
705 row < (min(origin->Num_lines, destination->Num_lines));
709 column < (min(origin->Num_cols, destination->Num_cols));
712 dest->row[column] = orig->row[column];
713 dest->attributes[column] = orig->attributes[column];
715 dest->changed = orig->changed;
716 dest->scroll = orig->scroll;
717 dest->last_char = min(orig->last_char, destination->Num_cols);
718 orig = orig->next_screen;
719 dest = dest->next_screen;
721 destination->LX = min((destination->Num_cols - 1), origin->LX);
722 destination->LY = min((destination->Num_lines - 1), origin->LY);
723 destination->Attrib = origin->Attrib;
724 destination->scroll_up = origin->scroll_up;
725 destination->scroll_down = origin->scroll_down;
726 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
737 signal(SIGWINCH, reinitscr);
739 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
741 if (ws.ws_row == LINES && ws.ws_col == COLS)
748 #endif /* TIOCGWINSZ */
749 local_virt = newwin(LINES, COLS, 0, 0);
750 local_std = newwin(LINES, COLS, 0, 0);
751 local_cur = newwin(LINES, COLS, 0, 0);
752 copy_window(virtual_scr, local_virt);
753 copy_window(stdscr, local_std);
754 copy_window(curscr, local_cur);
758 virtual_scr = local_virt;
762 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
763 interrupt_flag = TRUE;
765 #endif /* SIGWINCH */
768 initscr() /* initialize terminal for operations */
772 char *columns_string;
778 printf("starting initscr \n");fflush(stdout);
784 #endif /* BSD_SELECT */
792 value = ioctl(0, TCGETA, &Terminal);
793 if (Terminal.c_cflag & PARENB)
795 if (Terminal.c_cflag & PARENB)
800 if ((Terminal.c_cflag & CS8) == CS8)
804 else if ((Terminal.c_cflag & CS7) == CS7)
806 else if ((Terminal.c_cflag & CS6) == CS6)
810 value = Terminal.c_cflag & 037;
812 case 01: speed = 50.0;
814 case 02: speed = 75.0;
816 case 03: speed = 110.0;
818 case 04: speed = 134.5;
820 case 05: speed = 150.0;
822 case 06: speed = 200.0;
824 case 07: speed = 300.0;
826 case 010: speed = 600.0;
828 case 011: speed = 900.0;
830 case 012: speed = 1200.0;
832 case 013: speed = 1800.0;
834 case 014: speed = 2400.0;
836 case 015: speed = 3600.0;
838 case 016: speed = 4800.0;
840 case 017: speed = 7200.0;
842 case 020: speed = 9600.0;
844 case 021: speed = 19200.0;
846 case 022: speed = 38400.0;
848 default: speed = 0.0;
851 value = ioctl(0, TIOCGETP, &Terminal);
852 if (Terminal.sg_flags & EVENP)
854 else if (Terminal.sg_flags & ODDP)
856 value = Terminal.sg_ospeed;
858 case 01: speed = 50.0;
860 case 02: speed = 75.0;
862 case 03: speed = 110.0;
864 case 04: speed = 134.5;
866 case 05: speed = 150.0;
868 case 06: speed = 200.0;
870 case 07: speed = 300.0;
872 case 010: speed = 600.0;
874 case 011: speed = 1200.0;
876 case 012: speed = 1800.0;
878 case 013: speed = 2400.0;
880 case 014: speed = 4800.0;
882 case 015: speed = 9600.0;
884 default: speed = 0.0;
887 chars_per_millisecond = (0.001 * speed) / 8.0;
888 TERMINAL_TYPE = getenv("TERM");
889 if (TERMINAL_TYPE == NULL)
891 printf("unknown terminal type\n");
896 TERM_PATH = getenv("TERMINFO");
897 if (TERM_PATH != NULL)
899 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
900 Term_File_name = malloc(Data_Line_len);
901 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
902 Fildes = open(Term_File_name, O_RDONLY);
906 TERM_PATH = "/usr/lib/terminfo";
907 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
908 Term_File_name = malloc(Data_Line_len);
909 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
910 Fildes = open(Term_File_name, O_RDONLY);
914 TERM_PATH = "/usr/share/lib/terminfo";
915 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
916 Term_File_name = malloc(Data_Line_len);
917 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
918 Fildes = open(Term_File_name, O_RDONLY);
922 TERM_PATH = "/usr/share/terminfo";
923 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
924 Term_File_name = malloc(Data_Line_len);
925 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
926 Fildes = open(Term_File_name, O_RDONLY);
930 free(Term_File_name);
931 Term_File_name = NULL;
934 TERM_INFO = INFO_PARSE();
937 | termcap information can be in the TERMCAP env variable, if so
938 | use that, otherwise check the /etc/termcap file
940 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
942 if (*Term_File_name != '/')
943 Term_File_name = "/etc/termcap";
947 Term_File_name = "/etc/termcap";
949 if ((TFP = fopen(Term_File_name, "r")) == NULL)
951 printf("unable to open /etc/termcap file \n");
954 for (value = 0; value < 1024; value++)
955 String_table[value] = NULL;
956 for (value = 0; value < 128; value++)
958 for (value = 0; value < 128; value++)
960 Data_Line = malloc(512);
961 if (pointer && *pointer != '/')
963 TERM_data_ptr = pointer;
972 if (String_table[pc__] == NULL)
973 String_table[pc__] = "\0";
974 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
976 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
981 LINES = Numbers[li__];
982 COLS = Numbers[co__];
983 if ((lines_string = getenv("LINES")) != NULL)
985 value = atoi(lines_string);
989 if ((columns_string = getenv("COLUMNS")) != NULL)
991 value = atoi(columns_string);
997 | get the window size
999 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1007 virtual_scr = newwin(LINES, COLS, 0, 0);
1008 stdscr = newwin(LINES, COLS, 0, 0);
1009 curscr = newwin(LINES, COLS, 0, 0);
1010 wmove(stdscr, 0, 0);
1012 Repaint_screen = TRUE;
1014 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1018 | reset size of windows and LINES and COLS if term window
1021 signal(SIGWINCH, reinitscr);
1022 #endif /* SIGWINCH */
1025 | check if scrolling is available
1028 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1029 (String_table[dl__])) || ((String_table[cs__])
1030 && (String_table[sr__]));
1036 Get_int() /* get a two-byte integer from the terminfo file */
1042 Low_byte = *((unsigned char *) TERM_data_ptr++);
1043 High_byte = *((unsigned char *) TERM_data_ptr++);
1047 Low_byte = High_byte;
1050 if ((High_byte == 255) && (Low_byte == 255))
1053 return(Low_byte + (High_byte * 256));
1057 INFO_PARSE() /* parse off the data in the terminfo data file */
1060 int magic_number = 0;
1065 int Num_strings = 0;
1066 int string_table_len = 0;
1069 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1070 Data_Line_len = read(Fildes, Data_Line, 10240);
1071 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1076 magic_number = Get_int();
1078 | if magic number not right, reverse byte order and check again
1080 if (magic_number != 282)
1085 magic_number = Get_int();
1086 if (magic_number != 282)
1090 | get the number of each type in the terminfo data file
1092 Num_names = Get_int();
1093 Num_bools = Get_int();
1094 Num_ints = Get_int();
1095 Num_strings = Get_int();
1096 string_table_len = Get_int();
1097 Strings = malloc(string_table_len);
1098 while (Num_names > 0)
1107 Booleans[counter++] = *TERM_data_ptr++;
1109 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1115 Numbers[counter] = Get_int();
1118 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1119 memcpy(Strings, temp_ptr, string_table_len);
1124 if ((offset=Get_int()) != -1)
1126 if (String_table[counter] == NULL)
1127 String_table[counter] = Strings + offset;
1130 String_table[counter] = NULL;
1137 #endif /* ifndef CAP */
1140 AtoI() /* convert ascii text to integers */
1145 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1147 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1154 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1159 struct KEY_STACK *Spoint;
1164 while (key_def <= kf63__)
1166 if (key_def == ke__)
1168 else if (key_def == (K5__ + 1))
1170 else if (key_def == (kcbt__ + 1))
1172 else if (key_def == (kUND__ + 1))
1174 if (String_table[key_def] != NULL)
1176 if (KEY_TOS == NULL)
1177 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1181 while (Spoint->next != NULL)
1182 Spoint = Spoint->next;
1183 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1184 Spoint = Spoint->next;
1186 Spoint->next = NULL;
1187 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1188 Spoint->element->string = String_table[key_def];
1189 Spoint->element->length = strlen(String_table[key_def]);
1190 Spoint->element->value = Key_vals[Counter];
1191 Klen = strlen(Spoint->element->string);
1192 if (Klen > Max_Key_len)
1195 | Some terminal types accept keystrokes of the form
1196 | \E[A and \EOA, substituting '[' for 'O'. Make a
1197 | duplicate of such key strings (since the
1198 | database will only have one version) so new_curse
1199 | can understand both.
1201 if ((Spoint->element->length > 1) &&
1202 ((String_table[key_def][1] == '[') ||
1203 (String_table[key_def][1] == 'O')))
1205 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1206 Spoint = Spoint->next;
1207 Spoint->next = NULL;
1208 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1209 Spoint->element->length = strlen(String_table[key_def]);
1210 Spoint->element->string = malloc(Spoint->element->length + 1);
1211 strcpy(Spoint->element->string, String_table[key_def]);
1212 Spoint->element->value = Key_vals[Counter];
1213 Klen = strlen(Spoint->element->string);
1214 if (Klen > Max_Key_len)
1217 if (String_table[key_def][1] == '[')
1218 Spoint->element->string[1] = 'O';
1220 Spoint->element->string[1] = '[';
1229 | insert information about keys for a vt100 terminal
1237 struct KEY_STACK *Spoint;
1240 while (Spoint->next != NULL)
1241 Spoint = Spoint->next;
1242 for (counter = 0; vt100[counter].length != 0; counter++)
1244 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1245 Spoint = Spoint->next;
1246 Spoint->next = NULL;
1247 Spoint->element = &vt100[counter];
1248 Klen = strlen(Spoint->element->string);
1249 if (Klen > Max_Key_len)
1256 String_Get(param) /* read the string */
1265 while (*TERM_data_ptr != '=')
1267 Temp = ++TERM_data_ptr;
1269 while ((*Temp != ':') && (*Temp != (char)NULL))
1274 if (Counter == 1) /* no data */
1276 String = Temp = malloc(Counter);
1277 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1279 if (*TERM_data_ptr == '\\')
1282 if (*TERM_data_ptr == 'n')
1284 else if (*TERM_data_ptr == 't')
1286 else if (*TERM_data_ptr == 'b')
1288 else if (*TERM_data_ptr == 'r')
1290 else if (*TERM_data_ptr == 'f')
1292 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1293 *Temp = '\033'; /* escape */
1294 else if (*TERM_data_ptr == '\\')
1296 else if (*TERM_data_ptr == '\'')
1298 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1301 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1303 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1304 TERM_data_ptr++; /* ? */
1312 else if (*TERM_data_ptr == '^')
1315 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1316 *Temp = *TERM_data_ptr - '@';
1317 else if (*TERM_data_ptr == '?')
1323 *Temp++ = *TERM_data_ptr++;
1330 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1337 tc_Get_int(param) /* read the integer */
1344 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1352 while (*TERM_data_ptr != ':')
1359 Find_term() /* find terminal description in termcap file */
1364 Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
1365 strcpy(Name, TERMINAL_TYPE);
1366 while (*Ftemp != (char)NULL)
1369 *Ftemp = (char)NULL;
1371 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1372 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1374 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1376 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1378 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1379 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1381 if (*TERM_data_ptr == '|')
1384 *TERM_data_ptr = (char)NULL;
1390 printf("terminal type %s not found\n", TERMINAL_TYPE);
1396 CAP_PARSE() /* parse off the data in the termcap data file */
1403 while (*TERM_data_ptr != (char)NULL)
1405 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1407 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1410 Booleans[offset] = TRUE;
1415 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1417 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1420 Numbers[offset] = tc_Get_int(Numbers[offset]);
1426 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1428 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1431 String_table[offset] = String_Get(String_table[offset]);
1436 if (!strncmp(TERM_data_ptr, "tc=", 3))
1437 tc_ = String_Get(NULL);
1438 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1440 if (*TERM_data_ptr == ':')
1443 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1446 TERMINAL_TYPE = tc_;
1456 #endif /* ifdef CAP */
1459 Screenalloc(columns)
1465 tmp = (struct _line *) malloc(sizeof (struct _line));
1466 tmp->row = malloc(columns + 1);
1467 tmp->attributes = malloc(columns + 1);
1468 tmp->prev_screen = NULL;
1469 tmp->next_screen = NULL;
1470 for (i = 0; i < columns; i++)
1473 tmp->attributes[i] = (char) NULL;
1475 tmp->scroll = tmp->changed = FALSE;
1476 tmp->row[0] = (char) NULL;
1477 tmp->attributes[0] = (char) NULL;
1478 tmp->row[columns] = (char) NULL;
1479 tmp->attributes[columns] = (char) NULL;
1484 WINDOW *newwin(lines, cols, start_l, start_c)
1485 int lines, cols; /* number of lines and columns to be in window */
1486 int start_l, start_c; /* starting line and column to be inwindow */
1489 struct _line *temp_screen;
1492 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1493 Ntemp->SR = start_l;
1494 Ntemp->SC = start_c;
1495 Ntemp->Num_lines = lines;
1496 Ntemp->Num_cols = cols;
1499 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1500 Ntemp->SCROLL_CLEAR = FALSE;
1501 Ntemp->Attrib = FALSE;
1502 Ntemp->first_line = temp_screen = Screenalloc(cols);
1503 Ntemp->first_line->number = 0;
1504 for (i = 1; i < lines; i++)
1506 temp_screen->next_screen = Screenalloc(cols);
1507 temp_screen->next_screen->number = i;
1508 temp_screen->next_screen->prev_screen = temp_screen;
1509 temp_screen = temp_screen->next_screen;
1511 Ntemp->first_line->prev_screen = NULL;
1512 temp_screen->next_screen = NULL;
1518 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1520 int p_list[]; /* stack of values */
1521 int place; /* place keeper of top of stack */
1523 char *Otemp; /* temporary string pointer to parse output */
1533 p1 = p_list[--place];
1534 p2 = p_list[--place];
1538 if ((*Otemp >= '0') && (*Otemp <= '9'))
1540 delay = atoi(Otemp);
1541 while ((*Otemp >= '0') && (*Otemp <= '9'))
1546 while (*Otemp != (char)NULL)
1551 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1555 else if (*Otemp == '2')
1557 else if (*Otemp == '3')
1559 else if (*Otemp == '+')
1565 else if (*Otemp == '.')
1570 else if (*Otemp == '>')
1581 else if (*Otemp == 'r')
1587 else if (*Otemp == 'i')
1592 else if (*Otemp == '%')
1594 else if (*Otemp == 'n')
1599 else if (*Otemp == 'B')
1601 p1 = (16 * (p1/10)) + (p1 % 10);
1602 p2 = (16 * (p2/10)) + (p2 % 10);
1604 else if (*Otemp == 'D')
1606 p1 = (p1 - 2 * (p1 % 16));
1607 p2 = (p2 - 2 * (p2 % 16));
1616 chars = delay * chars_per_millisecond;
1618 if ((chars - delay) > 0.0)
1620 for (; delay > 0; delay--)
1621 putchar(*String_table[pc__]);
1628 char *Otemp; /* temporary string pointer to parse output */
1634 Operation(Temp_Stack, place) /* handle conditional operations */
1643 temp = Temp_Stack[--place];
1646 else if (!strncmp(Otemp, "2d", 2))
1648 temp = Temp_Stack[--place];
1649 printf("%2d", temp);
1653 else if (!strncmp(Otemp, "3d", 2))
1655 temp = Temp_Stack[--place];
1656 printf("%0d", temp);
1660 else if (!strncmp(Otemp, "02d", 3))
1662 temp = Temp_Stack[--place];
1663 printf("%02d", temp);
1668 else if (!strncmp(Otemp, "03d", 3))
1670 temp = Temp_Stack[--place];
1671 printf("%03d", temp);
1676 else if (*Otemp == '+')
1679 temp = Temp_Stack[--place];
1680 temp += Temp_Stack[--place];
1681 Temp_Stack[place++] = temp;
1683 else if (*Otemp == '-')
1686 temp = Temp_Stack[--place];
1687 temp -= Temp_Stack[--place];
1688 Temp_Stack[place++] = temp;
1690 else if (*Otemp == '*')
1693 temp = Temp_Stack[--place];
1694 temp *= Temp_Stack[--place];
1695 Temp_Stack[place++] = temp;
1697 else if (*Otemp == '/')
1700 temp = Temp_Stack[--place];
1701 temp /= Temp_Stack[--place];
1702 Temp_Stack[place++] = temp;
1704 else if (*Otemp == 'm')
1707 temp = Temp_Stack[--place];
1708 temp %= Temp_Stack[--place];
1709 Temp_Stack[place++] = temp;
1711 else if (*Otemp == '&')
1714 temp = Temp_Stack[--place];
1715 temp &= Temp_Stack[--place];
1716 Temp_Stack[place++] = temp;
1718 else if (*Otemp == '|')
1721 temp = Temp_Stack[--place];
1722 temp |= Temp_Stack[--place];
1723 Temp_Stack[place++] = temp;
1725 else if (*Otemp == '^')
1728 temp = Temp_Stack[--place];
1729 temp ^= Temp_Stack[--place];
1730 Temp_Stack[place++] = temp;
1732 else if (*Otemp == '=')
1735 temp = Temp_Stack[--place];
1736 temp = (temp == Temp_Stack[--place]);
1737 Temp_Stack[place++] = temp;
1739 else if (*Otemp == '>')
1742 temp = Temp_Stack[--place];
1743 temp = temp > Temp_Stack[--place];
1744 Temp_Stack[place++] = temp;
1746 else if (*Otemp == '<')
1749 temp = Temp_Stack[--place];
1750 temp = temp < Temp_Stack[--place];
1751 Temp_Stack[place++] = temp;
1753 else if (*Otemp == 'c')
1756 putchar(Temp_Stack[--place]);
1758 else if (*Otemp == 'i')
1764 else if (*Otemp == '%')
1769 else if (*Otemp == '!')
1771 temp = ! Temp_Stack[--place];
1772 Temp_Stack[place++] = temp;
1775 else if (*Otemp == '~')
1777 temp = ~Temp_Stack[--place];
1778 Temp_Stack[place++] = temp;
1781 else if (*Otemp == 'p')
1784 Temp_Stack[place++] = p[*Otemp - '0'];
1787 else if (*Otemp == 'P')
1790 Temp_Stack[place++] = variable[*Otemp - 'a'];
1793 else if (*Otemp == 'g')
1796 variable[*Otemp - 'a'] = Temp_Stack[--place];
1799 else if (*Otemp == '\'')
1802 Temp_Stack[place++] = *Otemp;
1806 else if (*Otemp == '{')
1810 Temp_Stack[place++] = temp;
1811 while (*Otemp != '}')
1819 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1829 int Cond_Stack[128];
1852 for (temp = 1; (place != 0); temp++)
1854 p[temp] = p_list[--place];
1859 while (*Otemp != (char) NULL)
1864 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1874 | find the end of the
1875 | conditional statement
1877 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1883 Cond_place = Operation(Cond_Stack, Cond_place);
1887 | if condition is true
1889 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1899 else /* condition is false */
1902 | find 'else' or end
1905 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1908 | if an 'else' found
1910 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1916 | check for 'then' part
1918 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1923 if (*tchar == (char) NULL)
1930 | if end of if found,
1934 else if (!strncmp(tchar, "%;", 2))
1943 | if end of if found,
1947 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1953 else /* Otemp == NULL */
1967 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1969 if (*Otemp != (char) NULL)
1981 Top_of_stack = Operation(Stack, Top_of_stack);
1984 else if (!strncmp(Otemp, "$<", 2))
1988 delay = atoi(Otemp);
1989 while (*Otemp != '>')
1992 chars = delay * chars_per_millisecond;
1994 if ((chars - delay) > 0.0)
1996 if (String_table[pc__] == NULL)
1999 temp = *String_table[pc__];
2000 for (; delay > 0; delay--)
2014 wmove(window, row, column) /* move cursor to indicated position in window */
2018 if ((row < window->Num_lines) && (column < window->Num_cols))
2020 window->LX = column;
2026 clear_line(line, column, cols)
2033 if (column > line->last_char)
2034 line->row[line->last_char] = ' ';
2035 line->last_char = column;
2036 line->row[column] = (char) NULL;
2037 line->attributes[column] = (char) NULL;
2038 line->changed = TRUE;
2039 for (j = column + 1; j < cols; j++)
2042 line->attributes[j] = (char) NULL;
2047 werase(window) /* clear the specified window */
2053 window->SCROLL_CLEAR = CLEAR;
2054 window->scroll_up = window->scroll_down = 0;
2055 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2056 clear_line(tmp, 0, window->Num_cols);
2060 wclrtoeol(window) /* erase from current cursor position to end of line */
2066 window->SCROLL_CLEAR = CHANGE;
2067 column = window->LX;
2069 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2070 tmp = tmp->next_screen;
2071 clear_line(tmp, column, window->Num_cols);
2075 wrefresh(window) /* flush all previous output */
2078 wnoutrefresh(window);
2083 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2084 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2086 if (temp->number == -1)
2087 fprintf(stderr, "line moved ");
2089 fprintf(stderr, "scroll_x is set: ");
2090 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2092 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2093 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2094 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2096 if (temp->number == -1)
2097 fprintf(stderr, "line moved ");
2099 fprintf(stderr, "scroll_x is set: ");
2100 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2102 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2103 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2104 fprintf(stderr, "line=%s|\n", temp->row);
2108 virtual_scr->SCROLL_CLEAR = FALSE;
2109 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2117 struct _line *user_line;
2118 int line_counter = 0;
2120 for (line_counter = 0, user_line = window->first_line;
2121 line_counter < window->Num_lines; line_counter++)
2123 user_line->changed = TRUE;
2125 window->SCROLL_CLEAR = TRUE;
2129 wnoutrefresh(window)
2132 struct _line *user_line;
2133 struct _line *virtual_line;
2134 int line_counter = 0;
2138 if (window->SR >= virtual_scr->Num_lines)
2140 user_line = window->first_line;
2141 virtual_line = virtual_scr->first_line;
2142 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2143 virtual_scr->LX = window->LX + window->SC;
2144 virtual_scr->LY = window->LY + window->SR;
2145 virtual_scr->scroll_up = window->scroll_up;
2146 virtual_scr->scroll_down = window->scroll_down;
2147 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2149 for (line_counter = 0; line_counter < window->SR; line_counter++)
2151 virtual_line = virtual_line->next_screen;
2153 for (line_counter = 0; (line_counter < window->Num_lines)
2154 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2157 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2159 for (user_col = 0, virt_col = window->SC;
2160 (virt_col < virtual_scr->Num_cols)
2161 && (user_col < window->Num_cols);
2162 virt_col++, user_col++)
2164 virtual_line->row[virt_col] = user_line->row[user_col];
2165 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2168 if (virtual_scr->Num_cols != window->Num_cols)
2170 if (virtual_line->last_char < (user_line->last_char + window->SC))
2172 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2173 virtual_line->row[virtual_line->last_char] = ' ';
2174 virtual_line->last_char =
2175 min(virtual_scr->Num_cols,
2176 (user_line->last_char + window->SC));
2178 else if (virtual_line->last_char > (user_line->last_char + window->SC))
2180 virtual_line->row[min(virtual_scr->Num_cols,
2181 (user_line->last_char + window->SC))] = ' ';
2185 virtual_line->last_char = user_line->last_char;
2186 virtual_line->row[virtual_line->last_char] = (char) NULL;
2187 virtual_line->changed = user_line->changed;
2188 virtual_line = virtual_line->next_screen;
2189 user_line = user_line->next_screen;
2191 window->SCROLL_CLEAR = FALSE;
2192 window->scroll_up = window->scroll_down = 0;
2193 last_window_refreshed = window;
2197 flushinp() /* flush input */
2202 ungetch(c) /* push a character back on input */
2206 in_buff[bufp++] = c;
2221 tv.tv_usec = 500000; /* half a second */
2223 Time_Out = FALSE; /* just in case */
2225 ret_val = select(nfds, &fds, 0, 0, &tv);
2228 | if ret_val is less than zero, there was no input
2229 | otherwise, get a character and return it
2238 return(read(0, &temp, 1)? temp : -1);
2243 wgetch(window) /* get character from specified window */
2254 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2256 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2257 #else /* BSD_SELECT */
2259 in_value = ((bufp > 0) ? in_buff[--bufp] :
2260 (read(0, &temp, 1)> 0) ? temp : -1);
2265 old_arg = fcntl(0, F_GETFL, 0);
2266 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2268 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2271 fcntl(0, F_SETFL, old_arg);
2276 #endif /* BSD_SELECT */
2281 if ((Parity) && (Num_bits < 8))
2282 /* strip eighth bit if parity in use */
2285 else if (interrupt_flag)
2287 interrupt_flag = FALSE;
2288 in_value = wgetch(window);
2291 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2292 in_value = Get_key(in_value);
2298 Clear(arg) /* notify that time out has occurred */
2303 fprintf(stderr, "inside Clear()\n");
2307 #endif /* BSD_SELECT */
2310 Get_key(first_char) /* try to decode key sequence */
2311 int first_char; /* first character of sequence */
2319 struct termio Gterminal;
2321 struct sgttyb Gterminal;
2323 struct KEY_STACK *St_point;
2324 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2326 #endif /* BSD_SELECT */
2330 string[Count++] = first_char;
2331 string[Count] = (char) NULL;
2334 signal(SIGALRM, Clear);
2336 #endif /* BSD_SELECT */
2339 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2340 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2341 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2345 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2347 in_char = wgetch(stdscr);
2349 fprintf(stderr, "back in GetKey()\n");
2354 string[Count++] = in_char;
2355 string[Count] = (char) NULL;
2357 while ((St_point != NULL) && (!Found))
2359 if (!strcmp(string, St_point->element->string))
2362 St_point = St_point->next;
2369 #endif /* BSD_SELECT */
2371 /* value = ioctl(0, TCSETA, &Terminal);*/
2373 value = ioctl(0, TIOCSETP, &Terminal);
2374 /* value = fcntl(0, F_SETFL, old_arg);*/
2379 return(St_point->element->value);
2385 if ((string[--Count] != -1) &&
2386 ((unsigned char) (string[Count]) != 255))
2389 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2391 ungetch(string[Count]);
2399 waddch(window, c) /* output the character in the specified window */
2404 int shift; /* number of spaces to shift if a tab */
2405 struct _line *tmpline;
2408 /*printf("starting waddch \n");fflush(stdout);*/
2411 column = window->LX;
2414 shift = (column + 1) % 8;
2422 waddch(window, ' ');
2425 else if ((column < window->Num_cols) && (row < window->Num_lines))
2427 if ((c == '~') && (Booleans[hz__]))
2430 if (( c != '\b') && (c != '\n') && (c != '\r'))
2433 tmpline = window->first_line;
2434 while (row < window->LY)
2437 tmpline = tmpline->next_screen;
2439 tmpline->row[column] = c;
2440 tmpline->attributes[column] = window->Attrib;
2441 tmpline->changed = TRUE;
2442 if (column >= tmpline->last_char)
2444 if (column > tmpline->last_char)
2445 tmpline->row[tmpline->last_char] = ' ';
2446 tmpline->row[column + 1] = (char) NULL;
2447 tmpline->attributes[column + 1] = (char) NULL;
2448 tmpline->last_char = column + 1;
2454 window->LX = window->Num_cols;
2463 if (window->LX >= window->Num_cols)
2467 if (window->LY >= window->Num_lines)
2469 window->LY = window->Num_lines - 1;
2470 /* window->LY = row;
2471 wmove(window, 0, 0);
2473 wmove(window, row, 0);*/
2476 window->SCROLL_CLEAR = CHANGE;
2480 winsertln(window) /* insert a blank line into the specified window */
2487 window->scroll_down += 1;
2488 window->SCROLL_CLEAR = SCROLL;
2489 column = window->LX;
2491 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2492 tmp = tmp->next_screen;
2493 if (tmp->prev_screen != NULL)
2494 tmp->prev_screen->next_screen = NULL;
2496 clear_line(tmp1, 0, window->Num_cols);
2498 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2499 tmp = tmp->next_screen;
2500 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2502 tmp1->next_screen = tmp->next_screen;
2503 tmp->next_screen = tmp1;
2504 tmp->changed = TRUE;
2505 tmp->next_screen->prev_screen = tmp;
2507 else if (window->Num_lines > 1)
2509 if (tmp->prev_screen != NULL)
2510 tmp->prev_screen->next_screen = tmp1;
2511 tmp1->prev_screen = tmp->prev_screen;
2512 tmp->prev_screen = tmp1;
2513 tmp1->next_screen = tmp;
2514 tmp->changed = TRUE;
2517 if (window->LY == 0)
2518 window->first_line = tmp1;
2522 wdeleteln(window) /* delete a line in the specified window */
2527 struct _line *tmpline;
2529 if (window->Num_lines > 1)
2531 window->scroll_up += 1;
2532 window->SCROLL_CLEAR = SCROLL;
2533 column = window->LX;
2535 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2536 tmp = tmp->next_screen;
2537 if (window->LY == 0)
2538 window->first_line = tmp->next_screen;
2539 if (tmp->prev_screen != NULL)
2540 tmp->prev_screen->next_screen = tmp->next_screen;
2541 if (tmp->next_screen != NULL)
2543 tmp->next_screen->changed = TRUE;
2544 tmp->next_screen->scroll = UP;
2545 tmp->next_screen->prev_screen = tmp->prev_screen;
2548 clear_line(tmpline, 0, window->Num_cols);
2549 tmpline->number = -1;
2550 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2551 tmp = tmp->next_screen;
2554 tmp->next_screen = tmpline;
2555 tmp->next_screen->prev_screen = tmp;
2556 tmp->changed = TRUE;
2557 tmp = tmp->next_screen;
2561 tmp->next_screen = NULL;
2565 clear_line(window->first_line, 0, window->Num_cols);
2570 wclrtobot(window) /* delete from current position to end of the window */
2576 window->SCROLL_CLEAR |= CLEAR;
2577 column = window->LX;
2579 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2580 tmp = tmp->next_screen;
2581 clear_line(tmp, column, window->Num_cols);
2582 for (row = (window->LY + 1); row < window->Num_lines; row++)
2584 tmp = tmp->next_screen;
2585 clear_line(tmp, 0, window->Num_cols);
2587 wmove(window, row, column);
2591 wstandout(window) /* begin standout mode in window */
2594 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2595 window->Attrib |= A_STANDOUT;
2599 wstandend(window) /* end standout mode in window */
2602 window->Attrib &= ~A_STANDOUT;
2606 waddstr(window, string) /* write 'string' in window */
2612 for (wstring = string; *wstring != (char) NULL; wstring++)
2613 waddch(window, *wstring);
2617 clearok(window, flag) /* erase screen and redraw at next refresh */
2621 Repaint_screen = TRUE;
2626 echo() /* turn on echoing */
2631 Terminal.c_lflag |= ECHO; /* enable echo */
2632 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2634 Terminal.sg_flags |= ECHO; /* enable echo */
2635 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2640 noecho() /* turn off echoing */
2645 Terminal.c_lflag &= ~ECHO; /* disable echo */
2646 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2648 Terminal.sg_flags &= ~ECHO; /* disable echo */
2649 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2654 raw() /* set to read characters immediately */
2659 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2660 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2661 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2663 Terminal.c_lflag &= ~FLUSHO;
2666 Terminal.c_lflag &= ~PENDIN;
2669 Terminal.c_lflag &= ~IEXTEN;
2671 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2672 Terminal.c_cc[VTIME] = 255; /* timeout value */
2673 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2674 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2676 Terminal.sg_flags |= RAW; /* enable raw mode */
2677 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2682 noraw() /* set to normal character read mode */
2687 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2688 Terminal.c_lflag |= ISIG; /* enable signal checking */
2689 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2690 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2691 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2692 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2694 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2695 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2696 /* old_arg = fcntl(0, F_GETFL, 0);
2697 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2707 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2708 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2718 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2719 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2720 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2740 nodelay(window, flag)
2754 keypad(window, flag)
2759 String_Out(String_table[ks__], NULL, 0);
2761 String_Out(String_table[ke__], NULL, 0);
2765 savetty() /* save current tty stats */
2770 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2772 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2777 resetty() /* restore previous tty stats */
2782 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2784 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2789 endwin() /* end windows */
2791 keypad(stdscr, FALSE);
2792 initialized = FALSE;
2794 delwin(virtual_scr);
2799 /* old_arg = fcntl(0, F_GETFL, 0);
2800 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2806 delwin(window) /* delete the window structure */
2811 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2813 window->first_line = window->first_line->next_screen;
2814 free(window->first_line->prev_screen->row);
2815 free(window->first_line->prev_screen->attributes);
2816 free(window->first_line->prev_screen);
2818 if (window == last_window_refreshed)
2819 last_window_refreshed = 0;
2820 if (window->first_line != NULL)
2822 free(window->first_line->row);
2823 free(window->first_line->attributes);
2824 free(window->first_line);
2833 #else /* __STDC__ */
2835 wprintw(WINDOW *window, const char *format, ...)
2836 #endif /* __STDC__ */
2851 window = va_arg(ap, WINDOW *);
2852 format = va_arg(ap, char *);
2853 #else /* __STDC__ */
2854 va_start(ap, format);
2855 #endif /* __STDC__ */
2857 fpoint = (char *) format;
2858 while (*fpoint != (char) NULL)
2865 value = va_arg(ap, int);
2866 iout(window, value);
2868 else if (*fpoint == 'c')
2870 value = va_arg(ap, int);
2871 waddch(window, value);
2873 else if (*fpoint == 's')
2875 wtemp = va_arg(ap, char *);
2876 waddstr(window, wtemp);
2880 else if (*fpoint == '\\')
2884 waddch(window, '\n');
2885 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2888 while ((*fpoint >= '0') && (*fpoint <= '9'))
2890 value = (value * 8) + (*fpoint - '0');
2893 waddch(window, value);
2898 waddch(window, *fpoint++);
2902 #endif /* __STDC__ */
2906 iout(window, value) /* output characters */
2912 if ((i = value / 10) != 0)
2914 waddch(window, ((value % 10) + '0'));
2918 Comp_line(line1, line2) /* compare lines */
2919 struct _line *line1;
2920 struct _line *line2;
2929 att1 = line1->attributes;
2930 att2 = line2->attributes;
2931 count2 = strlen(c1) + 1;
2932 count1 = strlen(c2) + 1;
2933 if (count1 > count2)
2939 if (count2 > (count1 + count1))
2942 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2945 if ((count1 == 1) && (count2 == 1))
2946 count1 = 0; /* both lines blank */
2947 else if (count2 == count1)
2948 count1 = -1; /* equal */
2950 count1 = count2 / count1; /* lines unequal */
2955 Insert_line(row, end_row, window) /* insert line into screen */
2964 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2965 tmp = tmp->next_screen;
2966 if ((end_row + window->SR) == 0)
2967 curscr->first_line = curscr->first_line->next_screen;
2970 | find bottom line to delete
2972 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2973 tmp = tmp->next_screen;
2974 if (tmp->prev_screen != NULL)
2975 tmp->prev_screen->next_screen = tmp->next_screen;
2976 if (tmp->next_screen != NULL)
2977 tmp->next_screen->prev_screen = tmp->prev_screen;
2980 | clear deleted line
2982 clear_line(tmp, 0, window->Num_cols);
2984 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2985 tmp = tmp->next_screen;
2987 for (i = 0, tmp = top_of_win; i < row; i++)
2988 tmp = tmp->next_screen;
2989 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
2990 tmp->prev_screen->next_screen = tmp1;
2991 tmp1->prev_screen = tmp->prev_screen;
2992 tmp->prev_screen = tmp1;
2993 tmp1->next_screen = tmp;
2994 if ((row + window->SR) == 0)
2995 curscr->first_line = tmp1;
2996 if (tmp1->next_screen != NULL)
2997 tmp1 = tmp1->next_screen;
2999 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3001 Position(window, (window->SR + end_row), 0);
3002 String_Out(String_table[dl__], NULL, 0);
3004 Position(window, (window->SR + row), 0);
3005 if (String_table[al__] != NULL)
3006 String_Out(String_table[al__], NULL, 0);
3008 String_Out(String_table[sr__], NULL, 0);
3010 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3011 top_of_win = top_of_win->next_screen;
3017 Delete_line(row, end_row, window) /* delete a line on screen */
3028 tmp = curscr->first_line;
3029 while (i < window->SR)
3032 tmp = tmp->next_screen;
3035 | find line to delete
3038 if ((row + window->SR) == 0)
3039 curscr->first_line = top_of_win->next_screen;
3040 for (i = 0, tmp = top_of_win; i < row; i++)
3041 tmp = tmp->next_screen;
3042 if (tmp->prev_screen != NULL)
3043 tmp->prev_screen->next_screen = tmp->next_screen;
3044 if (tmp->next_screen != NULL)
3045 tmp->next_screen->prev_screen = tmp->prev_screen;
3046 tmp2 = tmp->next_screen;
3049 | clear deleted line
3051 clear_line(tmp1, 0, window->Num_cols);
3054 | find location to insert deleted line
3056 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3057 tmp = tmp->next_screen;
3059 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3060 tmp = tmp->next_screen;
3061 tmp1->next_screen = tmp;
3062 tmp1->prev_screen = tmp->prev_screen;
3063 if (tmp1->prev_screen != NULL)
3064 tmp1->prev_screen->next_screen = tmp1;
3065 tmp->prev_screen = tmp1;
3067 Position(window, (window->SR + row), 0);
3068 String_Out(String_table[dl__], NULL, 0);
3069 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3071 Position(window, (window->SR + end_row), 0);
3072 String_Out(String_table[al__], NULL, 0);
3074 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3076 Position(window, (window->SR + end_row), 0);
3080 if (row == (window->Num_lines-1))
3082 if ((row + window->SR) == 0)
3083 curscr->first_line = top_of_win = tmp2;
3088 CLEAR_TO_EOL(window, row, column)
3095 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3096 tmp1 = tmp1->next_screen;
3097 for (x = column; x<window->Num_cols; x++)
3100 tmp1->attributes[x] = (char) NULL;
3102 tmp1->row[column] = (char) NULL;
3103 tmp1->last_char = column;
3109 Position(window, row, column);
3112 if (String_table[ce__] != NULL)
3113 String_Out(String_table[ce__], NULL, 0);
3116 for (x = column; x < window->Num_cols; x++)
3124 check_delete(window, line, offset, pointer_new, pointer_old)
3127 struct _line *pointer_new, *pointer_old;
3139 new_lin = pointer_new->row;
3140 new_att = pointer_new->attributes;
3141 old_lin = pointer_old->row;
3142 old_att = pointer_old->attributes;
3143 end_old = end_new = offset;
3144 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != (char) NULL) && (new_lin[end_old] != (char) NULL))
3146 if (old_lin[end_old] != (char) NULL)
3149 while ((old_lin[end_old+k] == new_lin[end_new+k]) && (new_att[end_new+k] == old_att[end_old+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
3151 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3153 if (new_lin[end_new+k] == (char) NULL)
3155 Position(window, line, (end_new+k));
3156 CLEAR_TO_EOL(window, line, (end_new+k));
3158 Position(window, line, offset);
3159 for (k = offset; k < end_old; k++)
3160 Char_del(old_lin, old_att, offset, window->Num_cols);
3161 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3163 pointer_old->last_char = offset;
3171 | Check if characters were inserted in the middle of a line, and if
3176 check_insert(window, line, offset, pointer_new, pointer_old)
3179 struct _line *pointer_new, *pointer_old;
3182 int end_old, end_new;
3193 new_lin = pointer_new->row;
3194 new_att = pointer_new->attributes;
3195 old_lin = pointer_old->row;
3196 old_att = pointer_old->attributes;
3197 end_old = end_new = offset;
3198 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != (char) NULL) && (old_lin[end_new] != (char) NULL))
3200 if (new_lin[end_new] != (char) NULL)
3203 while ((old_lin[end_old+k] == new_lin[end_new+k]) && (old_att[end_old+k] == new_att[end_new+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
3206 | check for commonality between rest of lines (are the old
3207 | and new lines the same, except for a chunk in the middle?)
3208 | if the rest of the lines are common, do not insert text
3211 while ((old_lin[old_off] != (char) NULL) && (new_lin[old_off] != (char) NULL) && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3213 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3215 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3217 Position(window, line, offset);
3219 if (String_table[ic__] == NULL)
3221 String_Out(String_table[im__], NULL, 0);
3224 for (k = offset; k < end_new; k++)
3227 String_Out(String_table[ic__], NULL, 0);
3228 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3231 String_Out(String_table[ei__], NULL, 0);
3232 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3234 pointer_old->last_char = offset;
3247 int begin_old, begin_new;
3248 int end_old, end_new;
3250 int from_top, tmp_ft, offset;
3270 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3272 window = virtual_scr;
3274 if ((nc_attributes & A_NC_BIG5) != 0)
3279 if (String_table[cl__])
3280 String_Out(String_table[cl__], NULL, 0);
3284 while (from_top < LINES)
3286 Position(curscr, from_top, 0);
3287 if (String_table[ce__] != NULL)
3288 String_Out(String_table[ce__], NULL, 0);
3291 for (j = 0; j < window->Num_cols; j++)
3297 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3299 Position(curscr, from_top, 0);
3300 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3302 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3307 Position(curscr, from_top, j);
3311 Repaint_screen = FALSE;
3316 top_of_win = curscr->first_line;
3318 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3319 from_top < window->Num_lines; from_top++)
3321 virtual_lines[from_top] = TRUE;
3322 if ((similar = Comp_line(curr, virt)) > 0)
3324 virtual_lines[from_top] = FALSE;
3327 curr = curr->next_screen;
3328 virt = virt->next_screen;
3332 virt = window->first_line;
3336 | if the window has lines that are different, check for scrolling
3342 for (first_same = window->Num_lines;
3343 (first_same > from_top) && (virtual_lines[first_same - 1]);
3346 count1 = first_same - 1;
3348 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3351 while ((from_top < first_same) && nc_scrolling_ability)
3352 /* check entire lines for diffs */
3356 if (from_top >= last_same)
3358 for (last_same = from_top;
3359 (last_same < window->Num_lines) &&
3360 (virtual_lines[last_same] == FALSE);
3364 if (!virtual_lines[from_top])
3368 | check for lines deleted (scroll up)
3370 for (tmp_ft = from_top+1, old = curr->next_screen;
3371 ((window->scroll_up) && (diff) &&
3372 (tmp_ft < last_same) &&
3373 (!virtual_lines[tmp_ft]));
3376 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3378 if (String_table[cs__]) /* scrolling region */
3381 list[0] = min((last_same - 1), (window->Num_lines - 1));
3382 String_Out(String_table[cs__], list, 2);
3383 Curr_y = Curr_x = -1;
3386 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3388 old = Delete_line(from_top, min((last_same - 1), (window->Num_lines - 1)), window);
3392 if (String_table[cs__]) /* scrolling region */
3395 list[0] = LINES - 1;
3396 String_Out(String_table[cs__], list, 2);
3397 Curr_y = Curr_x = -1;
3400 top_of_win = curscr->first_line;
3402 for (offset = 0; offset < from_top; offset++)
3403 curr = curr->next_screen;
3404 for (offset = from_top, old=curr, new=virt;
3405 offset < window->Num_lines;
3406 old=old->next_screen, new=new->next_screen,
3409 similar = Comp_line(old, new);
3410 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3414 old = old->next_screen;
3417 | check for lines inserted (scroll down)
3419 for (tmp_ft = from_top-1, old = curr->prev_screen;
3420 ((window->scroll_down) && (tmp_ft >= 0) &&
3422 (!virtual_lines[tmp_ft]));
3425 if (Comp_line(old, virt) == -1)
3427 if (String_table[cs__]) /* scrolling region */
3430 list[0] = min((last_same - 1), (window->Num_lines - 1));
3431 String_Out(String_table[cs__], list, 2);
3432 Curr_y = Curr_x = -1;
3435 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3437 old = Insert_line(tmp_ft, min((last_same - 1), (window->Num_lines -1)), window);
3441 if (String_table[cs__]) /* scrolling region */
3444 list[0] = LINES - 1;
3445 String_Out(String_table[cs__], list, 2);
3446 Curr_y = Curr_x = -1;
3449 top_of_win = curscr->first_line;
3451 for (offset = 0; offset < from_top; offset++)
3452 curr = curr->next_screen;
3453 for (offset = from_top, old=curr, new=virt;
3454 offset < window->Num_lines;
3455 old=old->next_screen, new=new->next_screen,
3458 similar = Comp_line(old, new);
3459 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3463 old = old->prev_screen;
3467 curr = curr->next_screen;
3468 virt = virt->next_screen;
3474 | Scrolling done, now need to insert, delete, or modify text
3478 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3479 curr = curr->next_screen;
3481 for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++, curr = curr->next_screen, virt = virt->next_screen)
3485 | If either 'insert mode' or 'insert char' are
3486 | available, enter the following 'if' statement,
3487 | else, need to simply rewrite the contents of the line
3488 | at the point where the contents of the line change.
3491 if (((String_table[ic__]) || (String_table[im__])) &&
3492 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3497 vrt_lin = virt->row;
3498 vrt_att = virt->attributes;
3499 cur_lin = curr->row;
3500 cur_att = curr->attributes;
3501 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3503 if ((STAND) && (Booleans[xs__]))
3505 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3507 if ((STAND) && (!vrt_att[j]))
3510 Position(window, from_top, j);
3517 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3520 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3522 Position(window, from_top, j);
3523 /* CLEAR_TO_EOL(window, from_top, j);*/
3527 if (vrt_lin[j] != (char) NULL)
3533 if ((first_time) && (virt->changed))
3535 if (curr->last_char <= virt->last_char)
3536 changed = check_insert(window, from_top, j, virt, curr);
3538 changed = check_delete(window, from_top, j, virt, curr);
3540 virt->changed = FALSE;
3542 changed = check_insert(window, from_top, j, virt, curr);
3543 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3545 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3549 Position(window, from_top, j);
3550 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3553 if ((vrt_lin[j] != (char) NULL))
3556 if ((STAND) && (!vrt_att[j]))
3559 Position(window, from_top, j);
3563 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3565 Position(window, from_top, j);
3566 CLEAR_TO_EOL(window, from_top, j);
3569 else /*if ((similar != -1) && (similar != 0))*/
3573 att1 = curr->attributes;
3575 att2 = virt->attributes;
3576 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3578 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3582 | if previous character is an eight bit
3583 | char, start redraw from that character
3586 if ((NC_chinese) && (highbitset(c1[j - 1])))
3590 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3592 Position(window, from_top, begin_old);
3593 CLEAR_TO_EOL(window, from_top, j);
3594 Position(window, from_top, begin_old);
3595 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3596 Char_out(c2[j], att2[j], c1, att1, j);
3599 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3601 Position(window, from_top, j);
3602 CLEAR_TO_EOL(window, from_top, j);
3608 Position(window, from_top, j);
3611 virt->number = from_top;
3613 Position(window, window->LY, window->LX);
3617 Position(window, row, col) /* position the cursor for output on the screen */
3628 pos_row = row + window->SR;
3629 pos_column = col + window->SC;
3630 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3632 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3635 list[place++] = pos_column;
3636 list[place++] = pos_row;
3637 String_Out(String_table[cm__], list, place);
3638 if ((STAND) && (!Booleans[ms__]))
3641 Curr_x = pos_column;
3647 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3655 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3657 line[one] = line[two];
3658 attrib[one] = attrib[two];
3660 String_Out(String_table[dc__], NULL, 0);
3664 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3675 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3677 for (two = one + 1; (two > offset); one--, two--)
3679 line[two] = line[one];
3680 attrib[two] = attrib[one];
3682 line[offset] = newc;
3683 attrib[offset] = newatt;
3684 Char_out(newc, newatt, line, attrib, offset);
3690 if (String_table[sa__])
3692 attributes_set[0] = 1;
3693 String_Out(String_table[sa__], attributes_set, 1);
3695 else if (String_table[so__])
3696 String_Out(String_table[so__], NULL, 0);
3702 if (String_table[me__])
3703 String_Out(String_table[me__], NULL, 0);
3704 else if (String_table[sa__])
3706 attributes_set[0] = 0;
3707 String_Out(String_table[sa__], attributes_set, 1);
3709 else if (String_table[se__])
3710 String_Out(String_table[se__], NULL, 0);
3714 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3723 if ((newatt) && (!STAND))
3728 else if ((STAND) && (!newatt))
3734 if ((newatt) && (STAND) && (Booleans[xs__]))
3739 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3742 line[offset] = newc;
3743 attrib[offset] = newatt;
3750 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3751 | hacks that notify new_curse to handle characters that have the high
3752 | bit set as the first of two bytes of a multi-byte string.
3760 nc_attributes |= flag;
3764 nc_clearattrib(flag)
3767 nc_attributes &= ~flag;