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 $
44 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
45 "All rights are reserved."};
47 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 $";
49 #include "new_curse.h"
60 #include <sys/types.h>
64 #include <sys/select.h> /* on AIX */
67 #endif /* BSD_SELECT */
84 #include <sys/ioctl.h>
89 static WINDOW *virtual_scr;
91 WINDOW *last_window_refreshed;
97 #define min(a, b) (a < b ? a : b)
98 #define highbitset(a) ((a) & 0x80)
101 #define String_Out(table, stack, place) Info_Out(table, stack, place)
103 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
106 #define bw__ 0 /* booleans */
109 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
112 #define gn__ 6 /* generic type terminal */
113 #define hc__ 7 /* hardcopy terminal */
119 #define mi__ 13 /* safe to move during insert mode */
120 #define ms__ 14 /* safe to move during standout mode */
124 #define hz__ 18 /* hazeltine glitch */
133 #define co__ 0 /* number of columns */ /* numbers */
134 #define it__ 1 /* spaces per tab */
135 #define li__ 2 /* number of lines */
137 #define sg__ 4 /* magic cookie glitch */
151 #define bt__ 0 /* back tab */ /* strings */
152 #define bl__ 1 /* bell */
153 #define cr__ 2 /* carriage return */
154 #define cs__ 3 /* change scroll region */
155 #define ct__ 4 /* clear all tab stops */
156 #define cl__ 5 /* clear screen and home cursor */
157 #define ce__ 6 /* clear to end of line */
158 #define cd__ 7 /* clear to end of display */
159 #define ch__ 8 /* set cursor column */
160 #define CC__ 9 /* term, settable cmd char in */
161 #define cm__ 10 /* screen rel cursor motion, row, column */
162 #define do__ 11 /* down one line */
163 #define ho__ 12 /* home cursor */
164 #define vi__ 13 /* make cursor invisible */
165 #define le__ 14 /* move cursor left one space */
166 #define CM__ 15 /* memory rel cursor addressing */
167 #define ve__ 16 /* make cursor appear normal */
168 #define nd__ 17 /* non-destructive space (cursor right) */
169 #define ll__ 18 /* last line, first col */
170 #define up__ 19 /* cursor up */
172 #define dc__ 21 /* delete character */
173 #define dl__ 22 /* delete line */
178 #define md__ 27 /* turn on bold */
180 #define dm__ 29 /* turn on delete mode */
181 #define mh__ 30 /* half bright mode */
182 #define im__ 31 /* insert mode */
186 #define so__ 35 /* enter standout mode */
193 #define ei__ 42 /* exit insert mode */
194 #define se__ 43 /* exit standout mode */
206 #define kb__ 55 /* backspace key */
238 #define ku__ 87 /* key up */
282 #define sa__ 131 /* sgr */
428 char *Boolean_names[] = {
429 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
430 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
433 char *Number_names[] = {
434 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
437 char *String_names[] = {
438 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
439 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
440 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
441 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
442 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
443 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
444 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
445 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
446 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
447 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
448 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
449 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
450 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
451 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
452 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
453 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
454 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
455 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
456 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
457 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
458 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
459 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
460 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
461 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
462 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
466 char *new_curse = "October 1987";
468 char in_buff[100]; /* buffer for ungetch */
469 int bufp; /* next free position in in_buff */
471 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
473 int Data_Line_len = 0;
474 int Max_Key_len; /* max length of a sequence sent by a key */
475 char *Data_Line = NULL;
476 char *TERM_PATH = NULL;
477 char *TERM_data_ptr = NULL;
478 char *Term_File_name = NULL; /* name of file containing terminal description */
479 FILE *TFP; /* file pointer to file with terminal des. */
480 int Fildes; /* file descriptor for terminfo file */
481 int STAND = FALSE; /* is standout mode activated? */
482 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
483 int Time_Out; /* set when time elapsed while trying to read function key */
484 int Curr_x; /* current x position on screen */
485 int Curr_y; /* current y position on the screen */
488 int Move_It; /* flag to move cursor if magic cookie glitch */
489 int initialized = FALSE; /* tells whether new_curse is initialized */
491 float chars_per_millisecond;
492 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
493 int Intr; /* storeage for interrupt character */
494 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
495 int Noblock; /* for BSD systems */
496 int Num_bits; /* number of bits per character */
497 int Flip_Bytes; /* some systems have byte order reversed */
498 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
505 int length; /* length of string sent by key */
506 char *string; /* string sent by key */
507 int value; /* CURSES value of key (9-bit) */
511 struct KEYS *element;
512 struct KEY_STACK *next;
515 struct KEY_STACK *KEY_TOS = NULL;
516 struct KEY_STACK *KEY_POINT;
520 | Not all systems have good terminal information, so we will define
521 | keyboard information here for the most widely used terminal type,
526 struct KEYS vt100[] =
528 { 3, "\033[A", 0403 }, /* key up */
529 { 3, "\033[C", 0405 }, /* key right */
530 { 3, "\033[D", 0404 }, /* key left */
532 { 4, "\033[6~", 0522 }, /* key next page */
533 { 4, "\033[5~", 0523 }, /* key prev page */
534 { 3, "\033[[", 0550 }, /* key end */
535 { 3, "\033[@", 0406 }, /* key home */
536 { 4, "\033[2~", 0513 }, /* key insert char */
538 { 3, "\033[y", 0410 }, /* key F0 */
539 { 3, "\033[P", 0411 }, /* key F1 */
540 { 3, "\033[Q", 0412 }, /* key F2 */
541 { 3, "\033[R", 0413 }, /* key F3 */
542 { 3, "\033[S", 0414 }, /* key F4 */
543 { 3, "\033[t", 0415 }, /* key F5 */
544 { 3, "\033[u", 0416 }, /* key F6 */
545 { 3, "\033[v", 0417 }, /* key F7 */
546 { 3, "\033[l", 0420 }, /* key F8 */
547 { 3, "\033[w", 0421 }, /* key F9 */
548 { 3, "\033[x", 0422 }, /* key F10 */
550 { 5, "\033[10~", 0410 }, /* key F0 */
551 { 5, "\033[11~", 0411 }, /* key F1 */
552 { 5, "\033[12~", 0412 }, /* key F2 */
553 { 5, "\033[13~", 0413 }, /* key F3 */
554 { 5, "\033[14~", 0414 }, /* key F4 */
555 { 5, "\033[15~", 0415 }, /* key F5 */
556 { 5, "\033[17~", 0416 }, /* key F6 */
557 { 5, "\033[18~", 0417 }, /* key F7 */
558 { 5, "\033[19~", 0420 }, /* key F8 */
559 { 5, "\033[20~", 0421 }, /* key F9 */
560 { 5, "\033[21~", 0422 }, /* key F10 */
561 { 5, "\033[23~", 0423 }, /* key F11 */
562 { 5, "\033[24~", 0424 }, /* key F12 */
563 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
564 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
565 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
566 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
567 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
570 | The following are the same keys as above, but with
571 | a different character following the escape char.
574 { 3, "\033OA", 0403 }, /* key up */
575 { 3, "\033OC", 0405 }, /* key right */
576 { 3, "\033OD", 0404 }, /* key left */
577 { 3, "\033OB", 0402 }, /* key down */
578 { 4, "\033O6~", 0522 }, /* key next page */
579 { 4, "\033O5~", 0523 }, /* key prev page */
580 { 3, "\033O[", 0550 }, /* key end */
581 { 3, "\033O@", 0406 }, /* key home */
582 { 4, "\033O2~", 0513 }, /* key insert char */
584 { 3, "\033Oy", 0410 }, /* key F0 */
585 { 3, "\033OP", 0411 }, /* key F1 */
586 { 3, "\033OQ", 0412 }, /* key F2 */
587 { 3, "\033OR", 0413 }, /* key F3 */
588 { 3, "\033OS", 0414 }, /* key F4 */
589 { 3, "\033Ot", 0415 }, /* key F5 */
590 { 3, "\033Ou", 0416 }, /* key F6 */
591 { 3, "\033Ov", 0417 }, /* key F7 */
592 { 3, "\033Ol", 0420 }, /* key F8 */
593 { 3, "\033Ow", 0421 }, /* key F9 */
594 { 3, "\033Ox", 0422 }, /* key F10 */
596 { 5, "\033O10~", 0410 }, /* key F0 */
597 { 5, "\033O11~", 0411 }, /* key F1 */
598 { 5, "\033O12~", 0412 }, /* key F2 */
599 { 5, "\033O13~", 0413 }, /* key F3 */
600 { 5, "\033O14~", 0414 }, /* key F4 */
601 { 5, "\033O15~", 0415 }, /* key F5 */
602 { 5, "\033O17~", 0416 }, /* key F6 */
603 { 5, "\033O18~", 0417 }, /* key F7 */
604 { 5, "\033O19~", 0420 }, /* key F8 */
605 { 5, "\033O20~", 0421 }, /* key F9 */
606 { 5, "\033O21~", 0422 }, /* key F10 */
607 { 5, "\033O23~", 0423 }, /* key F11 */
608 { 5, "\033O24~", 0424 }, /* key F12 */
609 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
610 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
611 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
612 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
613 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
615 { 0, "", 0 } /* end */
620 struct Parameters *next;
624 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
625 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
626 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
627 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
628 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
629 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
630 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
631 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
632 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
633 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
634 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
635 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
636 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
639 int attributes_set[9];
641 static int nc_attributes = 0; /* global attributes for new_curse to observe */
644 struct termio Terminal;
645 struct termio Saved_tty;
647 struct sgttyb Terminal;
648 struct sgttyb Saved_tty;
655 char *String_table[1024];
659 static char nc_scrolling_ability = FALSE;
663 #if __STDC__ || defined(__cplusplus)
667 #endif /* __STDC__ */
669 int tc_Get_int P_((int));
670 void CAP_PARSE P_((void));
671 void Find_term P_((void));
680 extern char *fgets();
681 extern char *malloc();
682 extern char *getenv();
683 FILE *fopen(); /* declaration for open function */
684 #endif /* HAS_STDLIB */
685 #endif /* __STDC__ */
690 | Copy the contents of one window to another.
694 copy_window(origin, destination)
695 WINDOW *origin, *destination;
698 struct _line *orig, *dest;
700 orig = origin->first_line;
701 dest = destination->first_line;
704 row < (min(origin->Num_lines, destination->Num_lines));
708 column < (min(origin->Num_cols, destination->Num_cols));
711 dest->row[column] = orig->row[column];
712 dest->attributes[column] = orig->attributes[column];
714 dest->changed = orig->changed;
715 dest->scroll = orig->scroll;
716 dest->last_char = min(orig->last_char, destination->Num_cols);
717 orig = orig->next_screen;
718 dest = dest->next_screen;
720 destination->LX = min((destination->Num_cols - 1), origin->LX);
721 destination->LY = min((destination->Num_lines - 1), origin->LY);
722 destination->Attrib = origin->Attrib;
723 destination->scroll_up = origin->scroll_up;
724 destination->scroll_down = origin->scroll_down;
725 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
736 signal(SIGWINCH, reinitscr);
738 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
740 if (ws.ws_row == LINES && ws.ws_col == COLS)
747 #endif /* TIOCGWINSZ */
748 local_virt = newwin(LINES, COLS, 0, 0);
749 local_std = newwin(LINES, COLS, 0, 0);
750 local_cur = newwin(LINES, COLS, 0, 0);
751 copy_window(virtual_scr, local_virt);
752 copy_window(stdscr, local_std);
753 copy_window(curscr, local_cur);
757 virtual_scr = local_virt;
761 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
762 interrupt_flag = TRUE;
764 #endif /* SIGWINCH */
767 initscr() /* initialize terminal for operations */
771 char *columns_string;
777 printf("starting initscr \n");fflush(stdout);
783 #endif /* BSD_SELECT */
791 value = ioctl(0, TCGETA, &Terminal);
792 if (Terminal.c_cflag & PARENB)
794 if (Terminal.c_cflag & PARENB)
799 if ((Terminal.c_cflag & CS8) == CS8)
803 else if ((Terminal.c_cflag & CS7) == CS7)
805 else if ((Terminal.c_cflag & CS6) == CS6)
809 value = Terminal.c_cflag & 037;
811 case 01: speed = 50.0;
813 case 02: speed = 75.0;
815 case 03: speed = 110.0;
817 case 04: speed = 134.5;
819 case 05: speed = 150.0;
821 case 06: speed = 200.0;
823 case 07: speed = 300.0;
825 case 010: speed = 600.0;
827 case 011: speed = 900.0;
829 case 012: speed = 1200.0;
831 case 013: speed = 1800.0;
833 case 014: speed = 2400.0;
835 case 015: speed = 3600.0;
837 case 016: speed = 4800.0;
839 case 017: speed = 7200.0;
841 case 020: speed = 9600.0;
843 case 021: speed = 19200.0;
845 case 022: speed = 38400.0;
847 default: speed = 0.0;
850 value = ioctl(0, TIOCGETP, &Terminal);
851 if (Terminal.sg_flags & EVENP)
853 else if (Terminal.sg_flags & ODDP)
855 value = Terminal.sg_ospeed;
857 case 01: speed = 50.0;
859 case 02: speed = 75.0;
861 case 03: speed = 110.0;
863 case 04: speed = 134.5;
865 case 05: speed = 150.0;
867 case 06: speed = 200.0;
869 case 07: speed = 300.0;
871 case 010: speed = 600.0;
873 case 011: speed = 1200.0;
875 case 012: speed = 1800.0;
877 case 013: speed = 2400.0;
879 case 014: speed = 4800.0;
881 case 015: speed = 9600.0;
883 default: speed = 0.0;
886 chars_per_millisecond = (0.001 * speed) / 8.0;
887 TERMINAL_TYPE = getenv("TERM");
888 if (TERMINAL_TYPE == NULL)
890 printf("unknown terminal type\n");
895 TERM_PATH = getenv("TERMINFO");
896 if (TERM_PATH != NULL)
898 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
899 Term_File_name = malloc(Data_Line_len);
900 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
901 Fildes = open(Term_File_name, O_RDONLY);
905 TERM_PATH = "/usr/lib/terminfo";
906 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
907 Term_File_name = malloc(Data_Line_len);
908 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
909 Fildes = open(Term_File_name, O_RDONLY);
913 TERM_PATH = "/usr/share/lib/terminfo";
914 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
915 Term_File_name = malloc(Data_Line_len);
916 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
917 Fildes = open(Term_File_name, O_RDONLY);
921 TERM_PATH = "/usr/share/terminfo";
922 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
923 Term_File_name = malloc(Data_Line_len);
924 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
925 Fildes = open(Term_File_name, O_RDONLY);
929 free(Term_File_name);
930 Term_File_name = NULL;
933 TERM_INFO = INFO_PARSE();
936 | termcap information can be in the TERMCAP env variable, if so
937 | use that, otherwise check the /etc/termcap file
939 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
941 if (*Term_File_name != '/')
942 Term_File_name = "/etc/termcap";
946 Term_File_name = "/etc/termcap";
948 if ((TFP = fopen(Term_File_name, "r")) == NULL)
950 printf("unable to open /etc/termcap file \n");
953 for (value = 0; value < 1024; value++)
954 String_table[value] = NULL;
955 for (value = 0; value < 128; value++)
957 for (value = 0; value < 128; value++)
959 Data_Line = malloc(512);
960 if (pointer && *pointer != '/')
962 TERM_data_ptr = pointer;
971 if (String_table[pc__] == NULL)
972 String_table[pc__] = "\0";
973 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
975 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
980 LINES = Numbers[li__];
981 COLS = Numbers[co__];
982 if ((lines_string = getenv("LINES")) != NULL)
984 value = atoi(lines_string);
988 if ((columns_string = getenv("COLUMNS")) != NULL)
990 value = atoi(columns_string);
996 | get the window size
998 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1006 virtual_scr = newwin(LINES, COLS, 0, 0);
1007 stdscr = newwin(LINES, COLS, 0, 0);
1008 curscr = newwin(LINES, COLS, 0, 0);
1009 wmove(stdscr, 0, 0);
1011 Repaint_screen = TRUE;
1013 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1017 | reset size of windows and LINES and COLS if term window
1020 signal(SIGWINCH, reinitscr);
1021 #endif /* SIGWINCH */
1024 | check if scrolling is available
1027 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1028 (String_table[dl__])) || ((String_table[cs__])
1029 && (String_table[sr__]));
1035 Get_int() /* get a two-byte integer from the terminfo file */
1041 Low_byte = *((unsigned char *) TERM_data_ptr++);
1042 High_byte = *((unsigned char *) TERM_data_ptr++);
1046 Low_byte = High_byte;
1049 if ((High_byte == 255) && (Low_byte == 255))
1052 return(Low_byte + (High_byte * 256));
1056 INFO_PARSE() /* parse off the data in the terminfo data file */
1059 int magic_number = 0;
1064 int Num_strings = 0;
1065 int string_table_len = 0;
1068 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1069 Data_Line_len = read(Fildes, Data_Line, 10240);
1070 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1075 magic_number = Get_int();
1077 | if magic number not right, reverse byte order and check again
1079 if (magic_number != 282)
1084 magic_number = Get_int();
1085 if (magic_number != 282)
1089 | get the number of each type in the terminfo data file
1091 Num_names = Get_int();
1092 Num_bools = Get_int();
1093 Num_ints = Get_int();
1094 Num_strings = Get_int();
1095 string_table_len = Get_int();
1096 Strings = malloc(string_table_len);
1097 while (Num_names > 0)
1106 Booleans[counter++] = *TERM_data_ptr++;
1108 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1114 Numbers[counter] = Get_int();
1117 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1118 memcpy(Strings, temp_ptr, string_table_len);
1123 if ((offset=Get_int()) != -1)
1125 if (String_table[counter] == NULL)
1126 String_table[counter] = Strings + offset;
1129 String_table[counter] = NULL;
1136 #endif /* ifndef CAP */
1139 AtoI() /* convert ascii text to integers */
1144 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1146 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1153 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1158 struct KEY_STACK *Spoint;
1163 while (key_def <= kf63__)
1165 if (key_def == ke__)
1167 else if (key_def == (K5__ + 1))
1169 else if (key_def == (kcbt__ + 1))
1171 else if (key_def == (kUND__ + 1))
1173 if (String_table[key_def] != NULL)
1175 if (KEY_TOS == NULL)
1176 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1180 while (Spoint->next != NULL)
1181 Spoint = Spoint->next;
1182 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1183 Spoint = Spoint->next;
1185 Spoint->next = NULL;
1186 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1187 Spoint->element->string = String_table[key_def];
1188 Spoint->element->length = strlen(String_table[key_def]);
1189 Spoint->element->value = Key_vals[Counter];
1190 Klen = strlen(Spoint->element->string);
1191 if (Klen > Max_Key_len)
1194 | Some terminal types accept keystrokes of the form
1195 | \E[A and \EOA, substituting '[' for 'O'. Make a
1196 | duplicate of such key strings (since the
1197 | database will only have one version) so new_curse
1198 | can understand both.
1200 if ((Spoint->element->length > 1) &&
1201 ((String_table[key_def][1] == '[') ||
1202 (String_table[key_def][1] == 'O')))
1204 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1205 Spoint = Spoint->next;
1206 Spoint->next = NULL;
1207 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1208 Spoint->element->length = strlen(String_table[key_def]);
1209 Spoint->element->string = malloc(Spoint->element->length + 1);
1210 strcpy(Spoint->element->string, String_table[key_def]);
1211 Spoint->element->value = Key_vals[Counter];
1212 Klen = strlen(Spoint->element->string);
1213 if (Klen > Max_Key_len)
1216 if (String_table[key_def][1] == '[')
1217 Spoint->element->string[1] = 'O';
1219 Spoint->element->string[1] = '[';
1228 | insert information about keys for a vt100 terminal
1236 struct KEY_STACK *Spoint;
1239 while (Spoint->next != NULL)
1240 Spoint = Spoint->next;
1241 for (counter = 0; vt100[counter].length != 0; counter++)
1243 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1244 Spoint = Spoint->next;
1245 Spoint->next = NULL;
1246 Spoint->element = &vt100[counter];
1247 Klen = strlen(Spoint->element->string);
1248 if (Klen > Max_Key_len)
1255 String_Get(param) /* read the string */
1264 while (*TERM_data_ptr != '=')
1266 Temp = ++TERM_data_ptr;
1268 while ((*Temp != ':') && (*Temp != (char)NULL))
1273 if (Counter == 1) /* no data */
1275 String = Temp = malloc(Counter);
1276 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1278 if (*TERM_data_ptr == '\\')
1281 if (*TERM_data_ptr == 'n')
1283 else if (*TERM_data_ptr == 't')
1285 else if (*TERM_data_ptr == 'b')
1287 else if (*TERM_data_ptr == 'r')
1289 else if (*TERM_data_ptr == 'f')
1291 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1292 *Temp = '\033'; /* escape */
1293 else if (*TERM_data_ptr == '\\')
1295 else if (*TERM_data_ptr == '\'')
1297 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1300 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1302 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1303 TERM_data_ptr++; /* ? */
1311 else if (*TERM_data_ptr == '^')
1314 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1315 *Temp = *TERM_data_ptr - '@';
1316 else if (*TERM_data_ptr == '?')
1322 *Temp++ = *TERM_data_ptr++;
1329 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1336 tc_Get_int(param) /* read the integer */
1343 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1351 while (*TERM_data_ptr != ':')
1358 Find_term() /* find terminal description in termcap file */
1363 Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
1364 strcpy(Name, TERMINAL_TYPE);
1365 while (*Ftemp != (char)NULL)
1368 *Ftemp = (char)NULL;
1370 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1371 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1373 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1375 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1377 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1378 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1380 if (*TERM_data_ptr == '|')
1383 *TERM_data_ptr = (char)NULL;
1389 printf("terminal type %s not found\n", TERMINAL_TYPE);
1395 CAP_PARSE() /* parse off the data in the termcap data file */
1402 while (*TERM_data_ptr != (char)NULL)
1404 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1406 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1409 Booleans[offset] = TRUE;
1414 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1416 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1419 Numbers[offset] = tc_Get_int(Numbers[offset]);
1425 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1427 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1430 String_table[offset] = String_Get(String_table[offset]);
1435 if (!strncmp(TERM_data_ptr, "tc=", 3))
1436 tc_ = String_Get(NULL);
1437 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1439 if (*TERM_data_ptr == ':')
1442 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1445 TERMINAL_TYPE = tc_;
1455 #endif /* ifdef CAP */
1458 Screenalloc(columns)
1464 tmp = (struct _line *) malloc(sizeof (struct _line));
1465 tmp->row = malloc(columns + 1);
1466 tmp->attributes = malloc(columns + 1);
1467 tmp->prev_screen = NULL;
1468 tmp->next_screen = NULL;
1469 for (i = 0; i < columns; i++)
1472 tmp->attributes[i] = (char) NULL;
1474 tmp->scroll = tmp->changed = FALSE;
1475 tmp->row[0] = (char) NULL;
1476 tmp->attributes[0] = (char) NULL;
1477 tmp->row[columns] = (char) NULL;
1478 tmp->attributes[columns] = (char) NULL;
1483 WINDOW *newwin(lines, cols, start_l, start_c)
1484 int lines, cols; /* number of lines and columns to be in window */
1485 int start_l, start_c; /* starting line and column to be inwindow */
1488 struct _line *temp_screen;
1491 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1492 Ntemp->SR = start_l;
1493 Ntemp->SC = start_c;
1494 Ntemp->Num_lines = lines;
1495 Ntemp->Num_cols = cols;
1498 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1499 Ntemp->SCROLL_CLEAR = FALSE;
1500 Ntemp->Attrib = FALSE;
1501 Ntemp->first_line = temp_screen = Screenalloc(cols);
1502 Ntemp->first_line->number = 0;
1503 for (i = 1; i < lines; i++)
1505 temp_screen->next_screen = Screenalloc(cols);
1506 temp_screen->next_screen->number = i;
1507 temp_screen->next_screen->prev_screen = temp_screen;
1508 temp_screen = temp_screen->next_screen;
1510 Ntemp->first_line->prev_screen = NULL;
1511 temp_screen->next_screen = NULL;
1517 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1519 int p_list[]; /* stack of values */
1520 int place; /* place keeper of top of stack */
1522 char *Otemp; /* temporary string pointer to parse output */
1532 p1 = p_list[--place];
1533 p2 = p_list[--place];
1537 if ((*Otemp >= '0') && (*Otemp <= '9'))
1539 delay = atoi(Otemp);
1540 while ((*Otemp >= '0') && (*Otemp <= '9'))
1545 while (*Otemp != (char)NULL)
1550 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1554 else if (*Otemp == '2')
1556 else if (*Otemp == '3')
1558 else if (*Otemp == '+')
1564 else if (*Otemp == '.')
1569 else if (*Otemp == '>')
1580 else if (*Otemp == 'r')
1586 else if (*Otemp == 'i')
1591 else if (*Otemp == '%')
1593 else if (*Otemp == 'n')
1598 else if (*Otemp == 'B')
1600 p1 = (16 * (p1/10)) + (p1 % 10);
1601 p2 = (16 * (p2/10)) + (p2 % 10);
1603 else if (*Otemp == 'D')
1605 p1 = (p1 - 2 * (p1 % 16));
1606 p2 = (p2 - 2 * (p2 % 16));
1615 chars = delay * chars_per_millisecond;
1617 if ((chars - delay) > 0.0)
1619 for (; delay > 0; delay--)
1620 putchar(*String_table[pc__]);
1627 char *Otemp; /* temporary string pointer to parse output */
1633 Operation(Temp_Stack, place) /* handle conditional operations */
1642 temp = Temp_Stack[--place];
1645 else if (!strncmp(Otemp, "2d", 2))
1647 temp = Temp_Stack[--place];
1648 printf("%2d", temp);
1652 else if (!strncmp(Otemp, "3d", 2))
1654 temp = Temp_Stack[--place];
1655 printf("%0d", temp);
1659 else if (!strncmp(Otemp, "02d", 3))
1661 temp = Temp_Stack[--place];
1662 printf("%02d", temp);
1667 else if (!strncmp(Otemp, "03d", 3))
1669 temp = Temp_Stack[--place];
1670 printf("%03d", temp);
1675 else if (*Otemp == '+')
1678 temp = Temp_Stack[--place];
1679 temp += Temp_Stack[--place];
1680 Temp_Stack[place++] = temp;
1682 else if (*Otemp == '-')
1685 temp = Temp_Stack[--place];
1686 temp -= Temp_Stack[--place];
1687 Temp_Stack[place++] = temp;
1689 else if (*Otemp == '*')
1692 temp = Temp_Stack[--place];
1693 temp *= Temp_Stack[--place];
1694 Temp_Stack[place++] = temp;
1696 else if (*Otemp == '/')
1699 temp = Temp_Stack[--place];
1700 temp /= Temp_Stack[--place];
1701 Temp_Stack[place++] = temp;
1703 else if (*Otemp == 'm')
1706 temp = Temp_Stack[--place];
1707 temp %= Temp_Stack[--place];
1708 Temp_Stack[place++] = temp;
1710 else if (*Otemp == '&')
1713 temp = Temp_Stack[--place];
1714 temp &= Temp_Stack[--place];
1715 Temp_Stack[place++] = temp;
1717 else if (*Otemp == '|')
1720 temp = Temp_Stack[--place];
1721 temp |= Temp_Stack[--place];
1722 Temp_Stack[place++] = temp;
1724 else if (*Otemp == '^')
1727 temp = Temp_Stack[--place];
1728 temp ^= Temp_Stack[--place];
1729 Temp_Stack[place++] = temp;
1731 else if (*Otemp == '=')
1734 temp = Temp_Stack[--place];
1735 temp = (temp == Temp_Stack[--place]);
1736 Temp_Stack[place++] = temp;
1738 else if (*Otemp == '>')
1741 temp = Temp_Stack[--place];
1742 temp = temp > Temp_Stack[--place];
1743 Temp_Stack[place++] = temp;
1745 else if (*Otemp == '<')
1748 temp = Temp_Stack[--place];
1749 temp = temp < Temp_Stack[--place];
1750 Temp_Stack[place++] = temp;
1752 else if (*Otemp == 'c')
1755 putchar(Temp_Stack[--place]);
1757 else if (*Otemp == 'i')
1763 else if (*Otemp == '%')
1768 else if (*Otemp == '!')
1770 temp = ! Temp_Stack[--place];
1771 Temp_Stack[place++] = temp;
1774 else if (*Otemp == '~')
1776 temp = ~Temp_Stack[--place];
1777 Temp_Stack[place++] = temp;
1780 else if (*Otemp == 'p')
1783 Temp_Stack[place++] = p[*Otemp - '0'];
1786 else if (*Otemp == 'P')
1789 Temp_Stack[place++] = variable[*Otemp - 'a'];
1792 else if (*Otemp == 'g')
1795 variable[*Otemp - 'a'] = Temp_Stack[--place];
1798 else if (*Otemp == '\'')
1801 Temp_Stack[place++] = *Otemp;
1805 else if (*Otemp == '{')
1809 Temp_Stack[place++] = temp;
1810 while (*Otemp != '}')
1818 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1828 int Cond_Stack[128];
1851 for (temp = 1; (place != 0); temp++)
1853 p[temp] = p_list[--place];
1858 while (*Otemp != (char) NULL)
1863 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1873 | find the end of the
1874 | conditional statement
1876 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1882 Cond_place = Operation(Cond_Stack, Cond_place);
1886 | if condition is true
1888 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1898 else /* condition is false */
1901 | find 'else' or end
1904 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1907 | if an 'else' found
1909 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1915 | check for 'then' part
1917 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1922 if (*tchar == (char) NULL)
1929 | if end of if found,
1933 else if (!strncmp(tchar, "%;", 2))
1942 | if end of if found,
1946 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1952 else /* Otemp == NULL */
1966 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1968 if (*Otemp != (char) NULL)
1980 Top_of_stack = Operation(Stack, Top_of_stack);
1983 else if (!strncmp(Otemp, "$<", 2))
1987 delay = atoi(Otemp);
1988 while (*Otemp != '>')
1991 chars = delay * chars_per_millisecond;
1993 if ((chars - delay) > 0.0)
1995 if (String_table[pc__] == NULL)
1998 temp = *String_table[pc__];
1999 for (; delay > 0; delay--)
2013 wmove(window, row, column) /* move cursor to indicated position in window */
2017 if ((row < window->Num_lines) && (column < window->Num_cols))
2019 window->LX = column;
2025 clear_line(line, column, cols)
2032 if (column > line->last_char)
2033 line->row[line->last_char] = ' ';
2034 line->last_char = column;
2035 line->row[column] = (char) NULL;
2036 line->attributes[column] = (char) NULL;
2037 line->changed = TRUE;
2038 for (j = column + 1; j < cols; j++)
2041 line->attributes[j] = (char) NULL;
2046 werase(window) /* clear the specified window */
2052 window->SCROLL_CLEAR = CLEAR;
2053 window->scroll_up = window->scroll_down = 0;
2054 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2055 clear_line(tmp, 0, window->Num_cols);
2059 wclrtoeol(window) /* erase from current cursor position to end of line */
2065 window->SCROLL_CLEAR = CHANGE;
2066 column = window->LX;
2068 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2069 tmp = tmp->next_screen;
2070 clear_line(tmp, column, window->Num_cols);
2074 wrefresh(window) /* flush all previous output */
2077 wnoutrefresh(window);
2082 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2083 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2085 if (temp->number == -1)
2086 fprintf(stderr, "line moved ");
2088 fprintf(stderr, "scroll_x is set: ");
2089 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2091 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2092 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2093 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2095 if (temp->number == -1)
2096 fprintf(stderr, "line moved ");
2098 fprintf(stderr, "scroll_x is set: ");
2099 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2101 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2102 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2103 fprintf(stderr, "line=%s|\n", temp->row);
2107 virtual_scr->SCROLL_CLEAR = FALSE;
2108 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2116 struct _line *user_line;
2117 int line_counter = 0;
2119 for (line_counter = 0, user_line = window->first_line;
2120 line_counter < window->Num_lines; line_counter++)
2122 user_line->changed = TRUE;
2124 window->SCROLL_CLEAR = TRUE;
2128 wnoutrefresh(window)
2131 struct _line *user_line;
2132 struct _line *virtual_line;
2133 int line_counter = 0;
2137 if (window->SR >= virtual_scr->Num_lines)
2139 user_line = window->first_line;
2140 virtual_line = virtual_scr->first_line;
2141 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2142 virtual_scr->LX = window->LX + window->SC;
2143 virtual_scr->LY = window->LY + window->SR;
2144 virtual_scr->scroll_up = window->scroll_up;
2145 virtual_scr->scroll_down = window->scroll_down;
2146 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2148 for (line_counter = 0; line_counter < window->SR; line_counter++)
2150 virtual_line = virtual_line->next_screen;
2152 for (line_counter = 0; (line_counter < window->Num_lines)
2153 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2156 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2158 for (user_col = 0, virt_col = window->SC;
2159 (virt_col < virtual_scr->Num_cols)
2160 && (user_col < window->Num_cols);
2161 virt_col++, user_col++)
2163 virtual_line->row[virt_col] = user_line->row[user_col];
2164 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2167 if (virtual_scr->Num_cols != window->Num_cols)
2169 if (virtual_line->last_char < (user_line->last_char + window->SC))
2171 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2172 virtual_line->row[virtual_line->last_char] = ' ';
2173 virtual_line->last_char =
2174 min(virtual_scr->Num_cols,
2175 (user_line->last_char + window->SC));
2177 else if (virtual_line->last_char > (user_line->last_char + window->SC))
2179 virtual_line->row[min(virtual_scr->Num_cols,
2180 (user_line->last_char + window->SC))] = ' ';
2184 virtual_line->last_char = user_line->last_char;
2185 virtual_line->row[virtual_line->last_char] = (char) NULL;
2186 virtual_line->changed = user_line->changed;
2187 virtual_line = virtual_line->next_screen;
2188 user_line = user_line->next_screen;
2190 window->SCROLL_CLEAR = FALSE;
2191 window->scroll_up = window->scroll_down = 0;
2192 last_window_refreshed = window;
2196 flushinp() /* flush input */
2201 ungetch(c) /* push a character back on input */
2205 in_buff[bufp++] = c;
2220 tv.tv_usec = 500000; /* half a second */
2222 Time_Out = FALSE; /* just in case */
2224 ret_val = select(nfds, &fds, 0, 0, &tv);
2227 | if ret_val is less than zero, there was no input
2228 | otherwise, get a character and return it
2237 return(read(0, &temp, 1)? temp : -1);
2242 wgetch(window) /* get character from specified window */
2253 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2255 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2256 #else /* BSD_SELECT */
2258 in_value = ((bufp > 0) ? in_buff[--bufp] :
2259 (read(0, &temp, 1)> 0) ? temp : -1);
2264 old_arg = fcntl(0, F_GETFL, 0);
2265 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2267 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2270 fcntl(0, F_SETFL, old_arg);
2275 #endif /* BSD_SELECT */
2280 if ((Parity) && (Num_bits < 8))
2281 /* strip eighth bit if parity in use */
2284 else if (interrupt_flag)
2286 interrupt_flag = FALSE;
2287 in_value = wgetch(window);
2290 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2291 in_value = Get_key(in_value);
2297 Clear(arg) /* notify that time out has occurred */
2302 fprintf(stderr, "inside Clear()\n");
2306 #endif /* BSD_SELECT */
2309 Get_key(first_char) /* try to decode key sequence */
2310 int first_char; /* first character of sequence */
2318 struct termio Gterminal;
2320 struct sgttyb Gterminal;
2322 struct KEY_STACK *St_point;
2323 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2325 #endif /* BSD_SELECT */
2329 string[Count++] = first_char;
2330 string[Count] = (char) NULL;
2333 signal(SIGALRM, Clear);
2335 #endif /* BSD_SELECT */
2338 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2339 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2340 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2344 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2346 in_char = wgetch(stdscr);
2348 fprintf(stderr, "back in GetKey()\n");
2353 string[Count++] = in_char;
2354 string[Count] = (char) NULL;
2356 while ((St_point != NULL) && (!Found))
2358 if (!strcmp(string, St_point->element->string))
2361 St_point = St_point->next;
2368 #endif /* BSD_SELECT */
2370 /* value = ioctl(0, TCSETA, &Terminal);*/
2372 value = ioctl(0, TIOCSETP, &Terminal);
2373 /* value = fcntl(0, F_SETFL, old_arg);*/
2378 return(St_point->element->value);
2384 if ((string[--Count] != -1) &&
2385 ((unsigned char) (string[Count]) != 255))
2388 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2390 ungetch(string[Count]);
2398 waddch(window, c) /* output the character in the specified window */
2403 int shift; /* number of spaces to shift if a tab */
2404 struct _line *tmpline;
2407 /*printf("starting waddch \n");fflush(stdout);*/
2410 column = window->LX;
2413 shift = (column + 1) % 8;
2421 waddch(window, ' ');
2424 else if ((column < window->Num_cols) && (row < window->Num_lines))
2426 if ((c == '~') && (Booleans[hz__]))
2429 if (( c != '\b') && (c != '\n') && (c != '\r'))
2432 tmpline = window->first_line;
2433 while (row < window->LY)
2436 tmpline = tmpline->next_screen;
2438 tmpline->row[column] = c;
2439 tmpline->attributes[column] = window->Attrib;
2440 tmpline->changed = TRUE;
2441 if (column >= tmpline->last_char)
2443 if (column > tmpline->last_char)
2444 tmpline->row[tmpline->last_char] = ' ';
2445 tmpline->row[column + 1] = (char) NULL;
2446 tmpline->attributes[column + 1] = (char) NULL;
2447 tmpline->last_char = column + 1;
2453 window->LX = window->Num_cols;
2462 if (window->LX >= window->Num_cols)
2466 if (window->LY >= window->Num_lines)
2468 window->LY = window->Num_lines - 1;
2469 /* window->LY = row;
2470 wmove(window, 0, 0);
2472 wmove(window, row, 0);*/
2475 window->SCROLL_CLEAR = CHANGE;
2479 winsertln(window) /* insert a blank line into the specified window */
2486 window->scroll_down += 1;
2487 window->SCROLL_CLEAR = SCROLL;
2488 column = window->LX;
2490 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2491 tmp = tmp->next_screen;
2492 if (tmp->prev_screen != NULL)
2493 tmp->prev_screen->next_screen = NULL;
2495 clear_line(tmp1, 0, window->Num_cols);
2497 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2498 tmp = tmp->next_screen;
2499 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2501 tmp1->next_screen = tmp->next_screen;
2502 tmp->next_screen = tmp1;
2503 tmp->changed = TRUE;
2504 tmp->next_screen->prev_screen = tmp;
2506 else if (window->Num_lines > 1)
2508 if (tmp->prev_screen != NULL)
2509 tmp->prev_screen->next_screen = tmp1;
2510 tmp1->prev_screen = tmp->prev_screen;
2511 tmp->prev_screen = tmp1;
2512 tmp1->next_screen = tmp;
2513 tmp->changed = TRUE;
2516 if (window->LY == 0)
2517 window->first_line = tmp1;
2521 wdeleteln(window) /* delete a line in the specified window */
2526 struct _line *tmpline;
2528 if (window->Num_lines > 1)
2530 window->scroll_up += 1;
2531 window->SCROLL_CLEAR = SCROLL;
2532 column = window->LX;
2534 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2535 tmp = tmp->next_screen;
2536 if (window->LY == 0)
2537 window->first_line = tmp->next_screen;
2538 if (tmp->prev_screen != NULL)
2539 tmp->prev_screen->next_screen = tmp->next_screen;
2540 if (tmp->next_screen != NULL)
2542 tmp->next_screen->changed = TRUE;
2543 tmp->next_screen->scroll = UP;
2544 tmp->next_screen->prev_screen = tmp->prev_screen;
2547 clear_line(tmpline, 0, window->Num_cols);
2548 tmpline->number = -1;
2549 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2550 tmp = tmp->next_screen;
2553 tmp->next_screen = tmpline;
2554 tmp->next_screen->prev_screen = tmp;
2555 tmp->changed = TRUE;
2556 tmp = tmp->next_screen;
2560 tmp->next_screen = NULL;
2564 clear_line(window->first_line, 0, window->Num_cols);
2569 wclrtobot(window) /* delete from current position to end of the window */
2575 window->SCROLL_CLEAR |= CLEAR;
2576 column = window->LX;
2578 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2579 tmp = tmp->next_screen;
2580 clear_line(tmp, column, window->Num_cols);
2581 for (row = (window->LY + 1); row < window->Num_lines; row++)
2583 tmp = tmp->next_screen;
2584 clear_line(tmp, 0, window->Num_cols);
2586 wmove(window, row, column);
2590 wstandout(window) /* begin standout mode in window */
2593 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2594 window->Attrib |= A_STANDOUT;
2598 wstandend(window) /* end standout mode in window */
2601 window->Attrib &= ~A_STANDOUT;
2605 waddstr(window, string) /* write 'string' in window */
2611 for (wstring = string; *wstring != (char) NULL; wstring++)
2612 waddch(window, *wstring);
2616 clearok(window, flag) /* erase screen and redraw at next refresh */
2620 Repaint_screen = TRUE;
2625 echo() /* turn on echoing */
2630 Terminal.c_lflag |= ECHO; /* enable echo */
2631 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2633 Terminal.sg_flags |= ECHO; /* enable echo */
2634 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2639 noecho() /* turn off echoing */
2644 Terminal.c_lflag &= ~ECHO; /* disable echo */
2645 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2647 Terminal.sg_flags &= ~ECHO; /* disable echo */
2648 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2653 raw() /* set to read characters immediately */
2658 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2659 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2660 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2662 Terminal.c_lflag &= ~FLUSHO;
2665 Terminal.c_lflag &= ~PENDIN;
2668 Terminal.c_lflag &= ~IEXTEN;
2670 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2671 Terminal.c_cc[VTIME] = 255; /* timeout value */
2672 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2673 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2675 Terminal.sg_flags |= RAW; /* enable raw mode */
2676 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2681 noraw() /* set to normal character read mode */
2686 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2687 Terminal.c_lflag |= ISIG; /* enable signal checking */
2688 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2689 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2690 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2691 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2693 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2694 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2695 /* old_arg = fcntl(0, F_GETFL, 0);
2696 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2706 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2707 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2717 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2718 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2719 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2739 nodelay(window, flag)
2753 keypad(window, flag)
2758 String_Out(String_table[ks__], NULL, 0);
2760 String_Out(String_table[ke__], NULL, 0);
2764 savetty() /* save current tty stats */
2769 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2771 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2776 resetty() /* restore previous tty stats */
2781 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2783 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2788 endwin() /* end windows */
2790 keypad(stdscr, FALSE);
2791 initialized = FALSE;
2793 delwin(virtual_scr);
2798 /* old_arg = fcntl(0, F_GETFL, 0);
2799 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2805 delwin(window) /* delete the window structure */
2810 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2812 window->first_line = window->first_line->next_screen;
2813 free(window->first_line->prev_screen->row);
2814 free(window->first_line->prev_screen->attributes);
2815 free(window->first_line->prev_screen);
2817 if (window == last_window_refreshed)
2818 last_window_refreshed = 0;
2819 if (window->first_line != NULL)
2821 free(window->first_line->row);
2822 free(window->first_line->attributes);
2823 free(window->first_line);
2832 #else /* __STDC__ */
2834 wprintw(WINDOW *window, const char *format, ...)
2835 #endif /* __STDC__ */
2850 window = va_arg(ap, WINDOW *);
2851 format = va_arg(ap, char *);
2852 #else /* __STDC__ */
2853 va_start(ap, format);
2854 #endif /* __STDC__ */
2856 fpoint = (char *) format;
2857 while (*fpoint != (char) NULL)
2864 value = va_arg(ap, int);
2865 iout(window, value);
2867 else if (*fpoint == 'c')
2869 value = va_arg(ap, int);
2870 waddch(window, value);
2872 else if (*fpoint == 's')
2874 wtemp = va_arg(ap, char *);
2875 waddstr(window, wtemp);
2879 else if (*fpoint == '\\')
2883 waddch(window, '\n');
2884 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2887 while ((*fpoint >= '0') && (*fpoint <= '9'))
2889 value = (value * 8) + (*fpoint - '0');
2892 waddch(window, value);
2897 waddch(window, *fpoint++);
2901 #endif /* __STDC__ */
2905 iout(window, value) /* output characters */
2911 if ((i = value / 10) != 0)
2913 waddch(window, ((value % 10) + '0'));
2917 Comp_line(line1, line2) /* compare lines */
2918 struct _line *line1;
2919 struct _line *line2;
2928 att1 = line1->attributes;
2929 att2 = line2->attributes;
2930 count2 = strlen(c1) + 1;
2931 count1 = strlen(c2) + 1;
2932 if (count1 > count2)
2938 if (count2 > (count1 + count1))
2941 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2944 if ((count1 == 1) && (count2 == 1))
2945 count1 = 0; /* both lines blank */
2946 else if (count2 == count1)
2947 count1 = -1; /* equal */
2949 count1 = count2 / count1; /* lines unequal */
2954 Insert_line(row, end_row, window) /* insert line into screen */
2963 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2964 tmp = tmp->next_screen;
2965 if ((end_row + window->SR) == 0)
2966 curscr->first_line = curscr->first_line->next_screen;
2969 | find bottom line to delete
2971 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2972 tmp = tmp->next_screen;
2973 if (tmp->prev_screen != NULL)
2974 tmp->prev_screen->next_screen = tmp->next_screen;
2975 if (tmp->next_screen != NULL)
2976 tmp->next_screen->prev_screen = tmp->prev_screen;
2979 | clear deleted line
2981 clear_line(tmp, 0, window->Num_cols);
2983 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2984 tmp = tmp->next_screen;
2986 for (i = 0, tmp = top_of_win; i < row; i++)
2987 tmp = tmp->next_screen;
2988 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
2989 tmp->prev_screen->next_screen = tmp1;
2990 tmp1->prev_screen = tmp->prev_screen;
2991 tmp->prev_screen = tmp1;
2992 tmp1->next_screen = tmp;
2993 if ((row + window->SR) == 0)
2994 curscr->first_line = tmp1;
2995 if (tmp1->next_screen != NULL)
2996 tmp1 = tmp1->next_screen;
2998 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3000 Position(window, (window->SR + end_row), 0);
3001 String_Out(String_table[dl__], NULL, 0);
3003 Position(window, (window->SR + row), 0);
3004 if (String_table[al__] != NULL)
3005 String_Out(String_table[al__], NULL, 0);
3007 String_Out(String_table[sr__], NULL, 0);
3009 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3010 top_of_win = top_of_win->next_screen;
3016 Delete_line(row, end_row, window) /* delete a line on screen */
3027 tmp = curscr->first_line;
3028 while (i < window->SR)
3031 tmp = tmp->next_screen;
3034 | find line to delete
3037 if ((row + window->SR) == 0)
3038 curscr->first_line = top_of_win->next_screen;
3039 for (i = 0, tmp = top_of_win; i < row; i++)
3040 tmp = tmp->next_screen;
3041 if (tmp->prev_screen != NULL)
3042 tmp->prev_screen->next_screen = tmp->next_screen;
3043 if (tmp->next_screen != NULL)
3044 tmp->next_screen->prev_screen = tmp->prev_screen;
3045 tmp2 = tmp->next_screen;
3048 | clear deleted line
3050 clear_line(tmp1, 0, window->Num_cols);
3053 | find location to insert deleted line
3055 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3056 tmp = tmp->next_screen;
3058 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3059 tmp = tmp->next_screen;
3060 tmp1->next_screen = tmp;
3061 tmp1->prev_screen = tmp->prev_screen;
3062 if (tmp1->prev_screen != NULL)
3063 tmp1->prev_screen->next_screen = tmp1;
3064 tmp->prev_screen = tmp1;
3066 Position(window, (window->SR + row), 0);
3067 String_Out(String_table[dl__], NULL, 0);
3068 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3070 Position(window, (window->SR + end_row), 0);
3071 String_Out(String_table[al__], NULL, 0);
3073 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3075 Position(window, (window->SR + end_row), 0);
3079 if (row == (window->Num_lines-1))
3081 if ((row + window->SR) == 0)
3082 curscr->first_line = top_of_win = tmp2;
3087 CLEAR_TO_EOL(window, row, column)
3094 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3095 tmp1 = tmp1->next_screen;
3096 for (x = column; x<window->Num_cols; x++)
3099 tmp1->attributes[x] = (char) NULL;
3101 tmp1->row[column] = (char) NULL;
3102 tmp1->last_char = column;
3108 Position(window, row, column);
3111 if (String_table[ce__] != NULL)
3112 String_Out(String_table[ce__], NULL, 0);
3115 for (x = column; x < window->Num_cols; x++)
3123 check_delete(window, line, offset, pointer_new, pointer_old)
3126 struct _line *pointer_new, *pointer_old;
3138 new_lin = pointer_new->row;
3139 new_att = pointer_new->attributes;
3140 old_lin = pointer_old->row;
3141 old_att = pointer_old->attributes;
3142 end_old = end_new = offset;
3143 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))
3145 if (old_lin[end_old] != (char) NULL)
3148 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))
3150 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3152 if (new_lin[end_new+k] == (char) NULL)
3154 Position(window, line, (end_new+k));
3155 CLEAR_TO_EOL(window, line, (end_new+k));
3157 Position(window, line, offset);
3158 for (k = offset; k < end_old; k++)
3159 Char_del(old_lin, old_att, offset, window->Num_cols);
3160 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3162 pointer_old->last_char = offset;
3170 | Check if characters were inserted in the middle of a line, and if
3175 check_insert(window, line, offset, pointer_new, pointer_old)
3178 struct _line *pointer_new, *pointer_old;
3181 int end_old, end_new;
3192 new_lin = pointer_new->row;
3193 new_att = pointer_new->attributes;
3194 old_lin = pointer_old->row;
3195 old_att = pointer_old->attributes;
3196 end_old = end_new = offset;
3197 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))
3199 if (new_lin[end_new] != (char) NULL)
3202 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))
3205 | check for commonality between rest of lines (are the old
3206 | and new lines the same, except for a chunk in the middle?)
3207 | if the rest of the lines are common, do not insert text
3210 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]))
3212 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3214 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3216 Position(window, line, offset);
3218 if (String_table[ic__] == NULL)
3220 String_Out(String_table[im__], NULL, 0);
3223 for (k = offset; k < end_new; k++)
3226 String_Out(String_table[ic__], NULL, 0);
3227 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3230 String_Out(String_table[ei__], NULL, 0);
3231 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3233 pointer_old->last_char = offset;
3246 int begin_old, begin_new;
3247 int end_old, end_new;
3249 int from_top, tmp_ft, offset;
3269 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3271 window = virtual_scr;
3273 if ((nc_attributes & A_NC_BIG5) != 0)
3278 if (String_table[cl__])
3279 String_Out(String_table[cl__], NULL, 0);
3283 while (from_top < LINES)
3285 Position(curscr, from_top, 0);
3286 if (String_table[ce__] != NULL)
3287 String_Out(String_table[ce__], NULL, 0);
3290 for (j = 0; j < window->Num_cols; j++)
3296 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3298 Position(curscr, from_top, 0);
3299 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3301 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3306 Position(curscr, from_top, j);
3310 Repaint_screen = FALSE;
3315 top_of_win = curscr->first_line;
3317 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3318 from_top < window->Num_lines; from_top++)
3320 virtual_lines[from_top] = TRUE;
3321 if ((similar = Comp_line(curr, virt)) > 0)
3323 virtual_lines[from_top] = FALSE;
3326 curr = curr->next_screen;
3327 virt = virt->next_screen;
3331 virt = window->first_line;
3335 | if the window has lines that are different, check for scrolling
3341 for (first_same = window->Num_lines;
3342 (first_same > from_top) && (virtual_lines[first_same - 1]);
3345 count1 = first_same - 1;
3347 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3350 while ((from_top < first_same) && nc_scrolling_ability)
3351 /* check entire lines for diffs */
3355 if (from_top >= last_same)
3357 for (last_same = from_top;
3358 (last_same < window->Num_lines) &&
3359 (virtual_lines[last_same] == FALSE);
3363 if (!virtual_lines[from_top])
3367 | check for lines deleted (scroll up)
3369 for (tmp_ft = from_top+1, old = curr->next_screen;
3370 ((window->scroll_up) && (diff) &&
3371 (tmp_ft < last_same) &&
3372 (!virtual_lines[tmp_ft]));
3375 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3377 if (String_table[cs__]) /* scrolling region */
3380 list[0] = min((last_same - 1), (window->Num_lines - 1));
3381 String_Out(String_table[cs__], list, 2);
3382 Curr_y = Curr_x = -1;
3385 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3387 old = Delete_line(from_top, min((last_same - 1), (window->Num_lines - 1)), window);
3391 if (String_table[cs__]) /* scrolling region */
3394 list[0] = LINES - 1;
3395 String_Out(String_table[cs__], list, 2);
3396 Curr_y = Curr_x = -1;
3399 top_of_win = curscr->first_line;
3401 for (offset = 0; offset < from_top; offset++)
3402 curr = curr->next_screen;
3403 for (offset = from_top, old=curr, new=virt;
3404 offset < window->Num_lines;
3405 old=old->next_screen, new=new->next_screen,
3408 similar = Comp_line(old, new);
3409 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3413 old = old->next_screen;
3416 | check for lines inserted (scroll down)
3418 for (tmp_ft = from_top-1, old = curr->prev_screen;
3419 ((window->scroll_down) && (tmp_ft >= 0) &&
3421 (!virtual_lines[tmp_ft]));
3424 if (Comp_line(old, virt) == -1)
3426 if (String_table[cs__]) /* scrolling region */
3429 list[0] = min((last_same - 1), (window->Num_lines - 1));
3430 String_Out(String_table[cs__], list, 2);
3431 Curr_y = Curr_x = -1;
3434 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3436 old = Insert_line(tmp_ft, min((last_same - 1), (window->Num_lines -1)), window);
3440 if (String_table[cs__]) /* scrolling region */
3443 list[0] = LINES - 1;
3444 String_Out(String_table[cs__], list, 2);
3445 Curr_y = Curr_x = -1;
3448 top_of_win = curscr->first_line;
3450 for (offset = 0; offset < from_top; offset++)
3451 curr = curr->next_screen;
3452 for (offset = from_top, old=curr, new=virt;
3453 offset < window->Num_lines;
3454 old=old->next_screen, new=new->next_screen,
3457 similar = Comp_line(old, new);
3458 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3462 old = old->prev_screen;
3466 curr = curr->next_screen;
3467 virt = virt->next_screen;
3473 | Scrolling done, now need to insert, delete, or modify text
3477 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3478 curr = curr->next_screen;
3480 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)
3484 | If either 'insert mode' or 'insert char' are
3485 | available, enter the following 'if' statement,
3486 | else, need to simply rewrite the contents of the line
3487 | at the point where the contents of the line change.
3490 if (((String_table[ic__]) || (String_table[im__])) &&
3491 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3496 vrt_lin = virt->row;
3497 vrt_att = virt->attributes;
3498 cur_lin = curr->row;
3499 cur_att = curr->attributes;
3500 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3502 if ((STAND) && (Booleans[xs__]))
3504 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3506 if ((STAND) && (!vrt_att[j]))
3509 Position(window, from_top, j);
3516 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3519 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3521 Position(window, from_top, j);
3522 /* CLEAR_TO_EOL(window, from_top, j);*/
3526 if (vrt_lin[j] != (char) NULL)
3532 if ((first_time) && (virt->changed))
3534 if (curr->last_char <= virt->last_char)
3535 changed = check_insert(window, from_top, j, virt, curr);
3537 changed = check_delete(window, from_top, j, virt, curr);
3539 virt->changed = FALSE;
3541 changed = check_insert(window, from_top, j, virt, curr);
3542 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3544 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3548 Position(window, from_top, j);
3549 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3552 if ((vrt_lin[j] != (char) NULL))
3555 if ((STAND) && (!vrt_att[j]))
3558 Position(window, from_top, j);
3562 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3564 Position(window, from_top, j);
3565 CLEAR_TO_EOL(window, from_top, j);
3568 else /*if ((similar != -1) && (similar != 0))*/
3572 att1 = curr->attributes;
3574 att2 = virt->attributes;
3575 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3577 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3581 | if previous character is an eight bit
3582 | char, start redraw from that character
3585 if ((NC_chinese) && (highbitset(c1[j - 1])))
3589 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3591 Position(window, from_top, begin_old);
3592 CLEAR_TO_EOL(window, from_top, j);
3593 Position(window, from_top, begin_old);
3594 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3595 Char_out(c2[j], att2[j], c1, att1, j);
3598 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3600 Position(window, from_top, j);
3601 CLEAR_TO_EOL(window, from_top, j);
3607 Position(window, from_top, j);
3610 virt->number = from_top;
3612 Position(window, window->LY, window->LX);
3616 Position(window, row, col) /* position the cursor for output on the screen */
3627 pos_row = row + window->SR;
3628 pos_column = col + window->SC;
3629 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3631 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3634 list[place++] = pos_column;
3635 list[place++] = pos_row;
3636 String_Out(String_table[cm__], list, place);
3637 if ((STAND) && (!Booleans[ms__]))
3640 Curr_x = pos_column;
3646 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3654 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3656 line[one] = line[two];
3657 attrib[one] = attrib[two];
3659 String_Out(String_table[dc__], NULL, 0);
3663 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3674 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3676 for (two = one + 1; (two > offset); one--, two--)
3678 line[two] = line[one];
3679 attrib[two] = attrib[one];
3681 line[offset] = newc;
3682 attrib[offset] = newatt;
3683 Char_out(newc, newatt, line, attrib, offset);
3689 if (String_table[sa__])
3691 attributes_set[0] = 1;
3692 String_Out(String_table[sa__], attributes_set, 1);
3694 else if (String_table[so__])
3695 String_Out(String_table[so__], NULL, 0);
3701 if (String_table[me__])
3702 String_Out(String_table[me__], NULL, 0);
3703 else if (String_table[sa__])
3705 attributes_set[0] = 0;
3706 String_Out(String_table[sa__], attributes_set, 1);
3708 else if (String_table[se__])
3709 String_Out(String_table[se__], NULL, 0);
3713 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3722 if ((newatt) && (!STAND))
3727 else if ((STAND) && (!newatt))
3733 if ((newatt) && (STAND) && (Booleans[xs__]))
3738 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3741 line[offset] = newc;
3742 attrib[offset] = newatt;
3749 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3750 | hacks that notify new_curse to handle characters that have the high
3751 | bit set as the first of two bytes of a multi-byte string.
3759 nc_attributes |= flag;
3763 nc_clearattrib(flag)
3766 nc_attributes &= ~flag;