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 | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh 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 $Revision: 1.54 $";
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 */
504 #if !defined(TERMCAP)
505 #define TERMCAP "/etc/termcap"
509 int length; /* length of string sent by key */
510 char *string; /* string sent by key */
511 int value; /* CURSES value of key (9-bit) */
515 struct KEYS *element;
516 struct KEY_STACK *next;
519 struct KEY_STACK *KEY_TOS = NULL;
520 struct KEY_STACK *KEY_POINT;
524 | Not all systems have good terminal information, so we will define
525 | keyboard information here for the most widely used terminal type,
530 struct KEYS vt100[] =
532 { 3, "\033[A", 0403 }, /* key up */
533 { 3, "\033[C", 0405 }, /* key right */
534 { 3, "\033[D", 0404 }, /* key left */
536 { 4, "\033[6~", 0522 }, /* key next page */
537 { 4, "\033[5~", 0523 }, /* key prev page */
538 { 3, "\033[[", 0550 }, /* key end */
539 { 3, "\033[@", 0406 }, /* key home */
540 { 4, "\033[2~", 0513 }, /* key insert char */
542 { 3, "\033[y", 0410 }, /* key F0 */
543 { 3, "\033[P", 0411 }, /* key F1 */
544 { 3, "\033[Q", 0412 }, /* key F2 */
545 { 3, "\033[R", 0413 }, /* key F3 */
546 { 3, "\033[S", 0414 }, /* key F4 */
547 { 3, "\033[t", 0415 }, /* key F5 */
548 { 3, "\033[u", 0416 }, /* key F6 */
549 { 3, "\033[v", 0417 }, /* key F7 */
550 { 3, "\033[l", 0420 }, /* key F8 */
551 { 3, "\033[w", 0421 }, /* key F9 */
552 { 3, "\033[x", 0422 }, /* key F10 */
554 { 5, "\033[10~", 0410 }, /* key F0 */
555 { 5, "\033[11~", 0411 }, /* key F1 */
556 { 5, "\033[12~", 0412 }, /* key F2 */
557 { 5, "\033[13~", 0413 }, /* key F3 */
558 { 5, "\033[14~", 0414 }, /* key F4 */
559 { 5, "\033[15~", 0415 }, /* key F5 */
560 { 5, "\033[17~", 0416 }, /* key F6 */
561 { 5, "\033[18~", 0417 }, /* key F7 */
562 { 5, "\033[19~", 0420 }, /* key F8 */
563 { 5, "\033[20~", 0421 }, /* key F9 */
564 { 5, "\033[21~", 0422 }, /* key F10 */
565 { 5, "\033[23~", 0423 }, /* key F11 */
566 { 5, "\033[24~", 0424 }, /* key F12 */
567 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
568 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
569 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
570 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
571 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
574 | The following are the same keys as above, but with
575 | a different character following the escape char.
578 { 3, "\033OA", 0403 }, /* key up */
579 { 3, "\033OC", 0405 }, /* key right */
580 { 3, "\033OD", 0404 }, /* key left */
581 { 3, "\033OB", 0402 }, /* key down */
582 { 4, "\033O6~", 0522 }, /* key next page */
583 { 4, "\033O5~", 0523 }, /* key prev page */
584 { 3, "\033O[", 0550 }, /* key end */
585 { 3, "\033O@", 0406 }, /* key home */
586 { 4, "\033O2~", 0513 }, /* key insert char */
588 { 3, "\033Oy", 0410 }, /* key F0 */
589 { 3, "\033OP", 0411 }, /* key F1 */
590 { 3, "\033OQ", 0412 }, /* key F2 */
591 { 3, "\033OR", 0413 }, /* key F3 */
592 { 3, "\033OS", 0414 }, /* key F4 */
593 { 3, "\033Ot", 0415 }, /* key F5 */
594 { 3, "\033Ou", 0416 }, /* key F6 */
595 { 3, "\033Ov", 0417 }, /* key F7 */
596 { 3, "\033Ol", 0420 }, /* key F8 */
597 { 3, "\033Ow", 0421 }, /* key F9 */
598 { 3, "\033Ox", 0422 }, /* key F10 */
600 { 5, "\033O10~", 0410 }, /* key F0 */
601 { 5, "\033O11~", 0411 }, /* key F1 */
602 { 5, "\033O12~", 0412 }, /* key F2 */
603 { 5, "\033O13~", 0413 }, /* key F3 */
604 { 5, "\033O14~", 0414 }, /* key F4 */
605 { 5, "\033O15~", 0415 }, /* key F5 */
606 { 5, "\033O17~", 0416 }, /* key F6 */
607 { 5, "\033O18~", 0417 }, /* key F7 */
608 { 5, "\033O19~", 0420 }, /* key F8 */
609 { 5, "\033O20~", 0421 }, /* key F9 */
610 { 5, "\033O21~", 0422 }, /* key F10 */
611 { 5, "\033O23~", 0423 }, /* key F11 */
612 { 5, "\033O24~", 0424 }, /* key F12 */
613 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
614 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
615 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
616 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
617 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
619 { 0, "", 0 } /* end */
624 struct Parameters *next;
628 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
629 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
630 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
631 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
632 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
633 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
634 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
635 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
636 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
637 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
638 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
639 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
640 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
643 int attributes_set[9];
645 static int nc_attributes = 0; /* global attributes for new_curse to observe */
648 struct termio Terminal;
649 struct termio Saved_tty;
651 struct sgttyb Terminal;
652 struct sgttyb Saved_tty;
659 char *String_table[1024];
663 static char nc_scrolling_ability = FALSE;
665 char *terminfo_path[] = {
667 "/usr/share/lib/terminfo",
668 "/usr/share/terminfo",
674 #if defined(__STDC__) || defined(__cplusplus)
678 #endif /* __STDC__ */
680 int tc_Get_int P_((int));
681 void CAP_PARSE P_((void));
682 void Find_term P_((void));
691 extern char *fgets();
692 extern char *malloc();
693 extern char *getenv();
694 FILE *fopen(); /* declaration for open function */
695 #endif /* HAS_STDLIB */
696 #endif /* __STDC__ */
701 | Copy the contents of one window to another.
705 copy_window(origin, destination)
706 WINDOW *origin, *destination;
709 struct _line *orig, *dest;
711 orig = origin->first_line;
712 dest = destination->first_line;
715 row < (min(origin->Num_lines, destination->Num_lines));
719 column < (min(origin->Num_cols, destination->Num_cols));
722 dest->row[column] = orig->row[column];
723 dest->attributes[column] = orig->attributes[column];
725 dest->changed = orig->changed;
726 dest->scroll = orig->scroll;
727 dest->last_char = min(orig->last_char, destination->Num_cols);
728 orig = orig->next_screen;
729 dest = dest->next_screen;
731 destination->LX = min((destination->Num_cols - 1), origin->LX);
732 destination->LY = min((destination->Num_lines - 1), origin->LY);
733 destination->Attrib = origin->Attrib;
734 destination->scroll_up = origin->scroll_up;
735 destination->scroll_down = origin->scroll_down;
736 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
747 signal(SIGWINCH, reinitscr);
749 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
751 if (ws.ws_row == LINES && ws.ws_col == COLS)
758 #endif /* TIOCGWINSZ */
759 local_virt = newwin(LINES, COLS, 0, 0);
760 local_std = newwin(LINES, COLS, 0, 0);
761 local_cur = newwin(LINES, COLS, 0, 0);
762 copy_window(virtual_scr, local_virt);
763 copy_window(stdscr, local_std);
764 copy_window(curscr, local_cur);
768 virtual_scr = local_virt;
772 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
773 interrupt_flag = TRUE;
775 #endif /* SIGWINCH */
778 initscr() /* initialize terminal for operations */
783 char *columns_string;
789 printf("starting initscr \n");fflush(stdout);
795 #endif /* BSD_SELECT */
803 value = ioctl(0, TCGETA, &Terminal);
804 if (Terminal.c_cflag & PARENB)
806 if (Terminal.c_cflag & PARENB)
811 if ((Terminal.c_cflag & CS8) == CS8)
815 else if ((Terminal.c_cflag & CS7) == CS7)
817 else if ((Terminal.c_cflag & CS6) == CS6)
821 value = Terminal.c_cflag & 037;
823 case 01: speed = 50.0;
825 case 02: speed = 75.0;
827 case 03: speed = 110.0;
829 case 04: speed = 134.5;
831 case 05: speed = 150.0;
833 case 06: speed = 200.0;
835 case 07: speed = 300.0;
837 case 010: speed = 600.0;
839 case 011: speed = 900.0;
841 case 012: speed = 1200.0;
843 case 013: speed = 1800.0;
845 case 014: speed = 2400.0;
847 case 015: speed = 3600.0;
849 case 016: speed = 4800.0;
851 case 017: speed = 7200.0;
853 case 020: speed = 9600.0;
855 case 021: speed = 19200.0;
857 case 022: speed = 38400.0;
859 default: speed = 0.0;
862 value = ioctl(0, TIOCGETP, &Terminal);
863 if (Terminal.sg_flags & EVENP)
865 else if (Terminal.sg_flags & ODDP)
867 value = Terminal.sg_ospeed;
869 case 01: speed = 50.0;
871 case 02: speed = 75.0;
873 case 03: speed = 110.0;
875 case 04: speed = 134.5;
877 case 05: speed = 150.0;
879 case 06: speed = 200.0;
881 case 07: speed = 300.0;
883 case 010: speed = 600.0;
885 case 011: speed = 1200.0;
887 case 012: speed = 1800.0;
889 case 013: speed = 2400.0;
891 case 014: speed = 4800.0;
893 case 015: speed = 9600.0;
895 default: speed = 0.0;
898 chars_per_millisecond = (0.001 * speed) / 8.0;
899 TERMINAL_TYPE = getenv("TERM");
900 if (TERMINAL_TYPE == NULL)
902 printf("unknown terminal type\n");
907 TERM_PATH = getenv("TERMINFO");
908 if (TERM_PATH != NULL)
910 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
911 Term_File_name = malloc(Data_Line_len);
912 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
913 Fildes = open(Term_File_name, O_RDONLY);
916 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
917 Fildes = open(Term_File_name, O_RDONLY);
921 while ((Fildes == -1) && (terminfo_path[counter] != NULL))
923 TERM_PATH = terminfo_path[counter];
924 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
925 Term_File_name = malloc(Data_Line_len);
926 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
927 Fildes = open(Term_File_name, O_RDONLY);
930 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
931 Fildes = open(Term_File_name, O_RDONLY);
937 free(Term_File_name);
938 Term_File_name = NULL;
941 TERM_INFO = INFO_PARSE();
944 | termcap information can be in the TERMCAP env variable, if so
945 | use that, otherwise check the /etc/termcap file
947 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
949 if (*Term_File_name != '/')
950 Term_File_name = TERMCAP;
954 Term_File_name = TERMCAP;
956 if ((TFP = fopen(Term_File_name, "r")) == NULL)
958 printf("unable to open %s file \n", TERMCAP);
961 for (value = 0; value < 1024; value++)
962 String_table[value] = NULL;
963 for (value = 0; value < 128; value++)
965 for (value = 0; value < 128; value++)
967 Data_Line = malloc(512);
968 if (pointer && *pointer != '/')
970 TERM_data_ptr = pointer;
979 if (String_table[pc__] == NULL)
980 String_table[pc__] = "\0";
981 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
983 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
988 LINES = Numbers[li__];
989 COLS = Numbers[co__];
990 if ((lines_string = getenv("LINES")) != NULL)
992 value = atoi(lines_string);
996 if ((columns_string = getenv("COLUMNS")) != NULL)
998 value = atoi(columns_string);
1004 | get the window size
1006 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1014 virtual_scr = newwin(LINES, COLS, 0, 0);
1015 stdscr = newwin(LINES, COLS, 0, 0);
1016 curscr = newwin(LINES, COLS, 0, 0);
1017 wmove(stdscr, 0, 0);
1019 Repaint_screen = TRUE;
1021 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1025 | reset size of windows and LINES and COLS if term window
1028 signal(SIGWINCH, reinitscr);
1029 #endif /* SIGWINCH */
1032 | check if scrolling is available
1035 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1036 (String_table[dl__])) || ((String_table[cs__])
1037 && (String_table[sr__]));
1043 Get_int() /* get a two-byte integer from the terminfo file */
1049 Low_byte = *((unsigned char *) TERM_data_ptr++);
1050 High_byte = *((unsigned char *) TERM_data_ptr++);
1054 Low_byte = High_byte;
1057 if ((High_byte == 255) && (Low_byte == 255))
1060 return(Low_byte + (High_byte * 256));
1064 INFO_PARSE() /* parse off the data in the terminfo data file */
1067 int magic_number = 0;
1072 int Num_strings = 0;
1073 int string_table_len = 0;
1076 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1077 Data_Line_len = read(Fildes, Data_Line, 10240);
1078 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1083 magic_number = Get_int();
1085 | if magic number not right, reverse byte order and check again
1087 if (magic_number != 282)
1092 magic_number = Get_int();
1093 if (magic_number != 282)
1097 | get the number of each type in the terminfo data file
1099 Num_names = Get_int();
1100 Num_bools = Get_int();
1101 Num_ints = Get_int();
1102 Num_strings = Get_int();
1103 string_table_len = Get_int();
1104 Strings = malloc(string_table_len);
1105 while (Num_names > 0)
1114 Booleans[counter++] = *TERM_data_ptr++;
1116 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1122 Numbers[counter] = Get_int();
1125 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1126 memcpy(Strings, temp_ptr, string_table_len);
1131 if ((offset=Get_int()) != -1)
1133 if (String_table[counter] == NULL)
1134 String_table[counter] = Strings + offset;
1137 String_table[counter] = NULL;
1144 #endif /* ifndef CAP */
1147 AtoI() /* convert ascii text to integers */
1152 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1154 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1161 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1166 struct KEY_STACK *Spoint;
1171 while (key_def <= kf63__)
1173 if (key_def == ke__)
1175 else if (key_def == (K5__ + 1))
1177 else if (key_def == (kcbt__ + 1))
1179 else if (key_def == (kUND__ + 1))
1181 if (String_table[key_def] != NULL)
1183 if (KEY_TOS == NULL)
1184 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1188 while (Spoint->next != NULL)
1189 Spoint = Spoint->next;
1190 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1191 Spoint = Spoint->next;
1193 Spoint->next = NULL;
1194 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1195 Spoint->element->string = String_table[key_def];
1196 Spoint->element->length = strlen(String_table[key_def]);
1197 Spoint->element->value = Key_vals[Counter];
1198 Klen = strlen(Spoint->element->string);
1199 if (Klen > Max_Key_len)
1202 | Some terminal types accept keystrokes of the form
1203 | \E[A and \EOA, substituting '[' for 'O'. Make a
1204 | duplicate of such key strings (since the
1205 | database will only have one version) so new_curse
1206 | can understand both.
1208 if ((Spoint->element->length > 1) &&
1209 ((String_table[key_def][1] == '[') ||
1210 (String_table[key_def][1] == 'O')))
1212 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1213 Spoint = Spoint->next;
1214 Spoint->next = NULL;
1215 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1216 Spoint->element->length = strlen(String_table[key_def]);
1217 Spoint->element->string = malloc(Spoint->element->length + 1);
1218 strcpy(Spoint->element->string, String_table[key_def]);
1219 Spoint->element->value = Key_vals[Counter];
1220 Klen = strlen(Spoint->element->string);
1221 if (Klen > Max_Key_len)
1224 if (String_table[key_def][1] == '[')
1225 Spoint->element->string[1] = 'O';
1227 Spoint->element->string[1] = '[';
1236 | insert information about keys for a vt100 terminal
1244 struct KEY_STACK *Spoint;
1247 while (Spoint->next != NULL)
1248 Spoint = Spoint->next;
1249 for (counter = 0; vt100[counter].length != 0; counter++)
1251 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1252 Spoint = Spoint->next;
1253 Spoint->next = NULL;
1254 Spoint->element = &vt100[counter];
1255 Klen = strlen(Spoint->element->string);
1256 if (Klen > Max_Key_len)
1263 String_Get(param) /* read the string */
1272 while (*TERM_data_ptr != '=')
1274 Temp = ++TERM_data_ptr;
1276 while ((*Temp != ':') && (*Temp != (char)NULL))
1281 if (Counter == 1) /* no data */
1283 String = Temp = malloc(Counter);
1284 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1286 if (*TERM_data_ptr == '\\')
1289 if (*TERM_data_ptr == 'n')
1291 else if (*TERM_data_ptr == 't')
1293 else if (*TERM_data_ptr == 'b')
1295 else if (*TERM_data_ptr == 'r')
1297 else if (*TERM_data_ptr == 'f')
1299 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1300 *Temp = '\033'; /* escape */
1301 else if (*TERM_data_ptr == '\\')
1303 else if (*TERM_data_ptr == '\'')
1305 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1308 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1310 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1311 TERM_data_ptr++; /* ? */
1319 else if (*TERM_data_ptr == '^')
1322 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1323 *Temp = *TERM_data_ptr - '@';
1324 else if (*TERM_data_ptr == '?')
1330 *Temp++ = *TERM_data_ptr++;
1337 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1344 tc_Get_int(param) /* read the integer */
1351 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1359 while (*TERM_data_ptr != ':')
1366 Find_term() /* find terminal description in termcap file */
1371 Ftemp = Name = malloc(strlen(TERMINAL_TYPE) + 2);
1372 strcpy(Name, TERMINAL_TYPE);
1373 while (*Ftemp != (char)NULL)
1376 *Ftemp = (char)NULL;
1378 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1379 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1381 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1383 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1385 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1386 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1388 if (*TERM_data_ptr == '|')
1391 *TERM_data_ptr = (char)NULL;
1397 printf("terminal type %s not found\n", TERMINAL_TYPE);
1403 CAP_PARSE() /* parse off the data in the termcap data file */
1410 while (*TERM_data_ptr != (char)NULL)
1412 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1414 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1417 Booleans[offset] = TRUE;
1422 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1424 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1427 Numbers[offset] = tc_Get_int(Numbers[offset]);
1433 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1435 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1438 String_table[offset] = String_Get(String_table[offset]);
1443 if (!strncmp(TERM_data_ptr, "tc=", 3))
1444 tc_ = String_Get(NULL);
1445 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1447 if (*TERM_data_ptr == ':')
1450 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1453 TERMINAL_TYPE = tc_;
1462 #endif /* ifdef CAP */
1465 Screenalloc(columns)
1471 tmp = (struct _line *) malloc(sizeof (struct _line));
1472 tmp->row = malloc(columns + 1);
1473 tmp->attributes = malloc(columns + 1);
1474 tmp->prev_screen = NULL;
1475 tmp->next_screen = NULL;
1476 for (i = 0; i < columns; i++)
1479 tmp->attributes[i] = (char) NULL;
1481 tmp->scroll = tmp->changed = FALSE;
1482 tmp->row[0] = (char) NULL;
1483 tmp->attributes[0] = (char) NULL;
1484 tmp->row[columns] = (char) NULL;
1485 tmp->attributes[columns] = (char) NULL;
1490 WINDOW *newwin(lines, cols, start_l, start_c)
1491 int lines, cols; /* number of lines and columns to be in window */
1492 int start_l, start_c; /* starting line and column to be inwindow */
1495 struct _line *temp_screen;
1498 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1499 Ntemp->SR = start_l;
1500 Ntemp->SC = start_c;
1501 Ntemp->Num_lines = lines;
1502 Ntemp->Num_cols = cols;
1505 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1506 Ntemp->SCROLL_CLEAR = FALSE;
1507 Ntemp->Attrib = FALSE;
1508 Ntemp->first_line = temp_screen = Screenalloc(cols);
1509 Ntemp->first_line->number = 0;
1510 Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
1512 Ntemp->line_array[0] = Ntemp->first_line;
1514 for (i = 1; i < lines; i++)
1516 temp_screen->next_screen = Screenalloc(cols);
1517 temp_screen->next_screen->number = i;
1518 temp_screen->next_screen->prev_screen = temp_screen;
1519 temp_screen = temp_screen->next_screen;
1520 Ntemp->line_array[i] = temp_screen;
1522 Ntemp->first_line->prev_screen = NULL;
1523 temp_screen->next_screen = NULL;
1529 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1531 int p_list[]; /* stack of values */
1532 int place; /* place keeper of top of stack */
1534 char *Otemp; /* temporary string pointer to parse output */
1544 p1 = p_list[--place];
1545 p2 = p_list[--place];
1549 if ((*Otemp >= '0') && (*Otemp <= '9'))
1551 delay = atoi(Otemp);
1552 while ((*Otemp >= '0') && (*Otemp <= '9'))
1557 while (*Otemp != (char)NULL)
1562 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1566 else if (*Otemp == '2')
1568 else if (*Otemp == '3')
1570 else if (*Otemp == '+')
1576 else if (*Otemp == '.')
1581 else if (*Otemp == '>')
1592 else if (*Otemp == 'r')
1598 else if (*Otemp == 'i')
1603 else if (*Otemp == '%')
1605 else if (*Otemp == 'n')
1610 else if (*Otemp == 'B')
1612 p1 = (16 * (p1/10)) + (p1 % 10);
1613 p2 = (16 * (p2/10)) + (p2 % 10);
1615 else if (*Otemp == 'D')
1617 p1 = (p1 - 2 * (p1 % 16));
1618 p2 = (p2 - 2 * (p2 % 16));
1627 chars = delay * chars_per_millisecond;
1629 if ((chars - delay) > 0.0)
1631 for (; delay > 0; delay--)
1632 putchar(*String_table[pc__]);
1639 char *Otemp; /* temporary string pointer to parse output */
1645 Operation(Temp_Stack, place) /* handle conditional operations */
1654 temp = Temp_Stack[--place];
1657 else if (!strncmp(Otemp, "2d", 2))
1659 temp = Temp_Stack[--place];
1660 printf("%2d", temp);
1664 else if (!strncmp(Otemp, "3d", 2))
1666 temp = Temp_Stack[--place];
1667 printf("%0d", temp);
1671 else if (!strncmp(Otemp, "02d", 3))
1673 temp = Temp_Stack[--place];
1674 printf("%02d", temp);
1679 else if (!strncmp(Otemp, "03d", 3))
1681 temp = Temp_Stack[--place];
1682 printf("%03d", temp);
1687 else if (*Otemp == '+')
1690 temp = Temp_Stack[--place];
1691 temp += Temp_Stack[--place];
1692 Temp_Stack[place++] = temp;
1694 else if (*Otemp == '-')
1697 temp = Temp_Stack[--place];
1698 temp -= Temp_Stack[--place];
1699 Temp_Stack[place++] = temp;
1701 else if (*Otemp == '*')
1704 temp = Temp_Stack[--place];
1705 temp *= Temp_Stack[--place];
1706 Temp_Stack[place++] = temp;
1708 else if (*Otemp == '/')
1711 temp = Temp_Stack[--place];
1712 temp /= Temp_Stack[--place];
1713 Temp_Stack[place++] = temp;
1715 else if (*Otemp == 'm')
1718 temp = Temp_Stack[--place];
1719 temp %= Temp_Stack[--place];
1720 Temp_Stack[place++] = temp;
1722 else if (*Otemp == '&')
1725 temp = Temp_Stack[--place];
1726 temp &= Temp_Stack[--place];
1727 Temp_Stack[place++] = temp;
1729 else if (*Otemp == '|')
1732 temp = Temp_Stack[--place];
1733 temp |= Temp_Stack[--place];
1734 Temp_Stack[place++] = temp;
1736 else if (*Otemp == '^')
1739 temp = Temp_Stack[--place];
1740 temp ^= Temp_Stack[--place];
1741 Temp_Stack[place++] = temp;
1743 else if (*Otemp == '=')
1746 temp = Temp_Stack[--place];
1747 temp = (temp == Temp_Stack[--place]);
1748 Temp_Stack[place++] = temp;
1750 else if (*Otemp == '>')
1753 temp = Temp_Stack[--place];
1754 temp = temp > Temp_Stack[--place];
1755 Temp_Stack[place++] = temp;
1757 else if (*Otemp == '<')
1760 temp = Temp_Stack[--place];
1761 temp = temp < Temp_Stack[--place];
1762 Temp_Stack[place++] = temp;
1764 else if (*Otemp == 'c')
1767 putchar(Temp_Stack[--place]);
1769 else if (*Otemp == 'i')
1775 else if (*Otemp == '%')
1780 else if (*Otemp == '!')
1782 temp = ! Temp_Stack[--place];
1783 Temp_Stack[place++] = temp;
1786 else if (*Otemp == '~')
1788 temp = ~Temp_Stack[--place];
1789 Temp_Stack[place++] = temp;
1792 else if (*Otemp == 'p')
1795 Temp_Stack[place++] = p[*Otemp - '0'];
1798 else if (*Otemp == 'P')
1801 Temp_Stack[place++] = variable[*Otemp - 'a'];
1804 else if (*Otemp == 'g')
1807 variable[*Otemp - 'a'] = Temp_Stack[--place];
1810 else if (*Otemp == '\'')
1813 Temp_Stack[place++] = *Otemp;
1817 else if (*Otemp == '{')
1821 Temp_Stack[place++] = temp;
1822 while (*Otemp != '}')
1830 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1840 int Cond_Stack[128];
1863 for (temp = 1; (place != 0); temp++)
1865 p[temp] = p_list[--place];
1870 while (*Otemp != (char) NULL)
1875 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1885 | find the end of the
1886 | conditional statement
1888 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1894 Cond_place = Operation(Cond_Stack, Cond_place);
1898 | if condition is true
1900 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1910 else /* condition is false */
1913 | find 'else' or end
1916 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1919 | if an 'else' found
1921 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1927 | check for 'then' part
1929 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1934 if (*tchar == (char) NULL)
1941 | if end of if found,
1945 else if (!strncmp(tchar, "%;", 2))
1954 | if end of if found,
1958 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1964 else /* Otemp == NULL */
1978 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1980 if (*Otemp != (char) NULL)
1992 Top_of_stack = Operation(Stack, Top_of_stack);
1995 else if (!strncmp(Otemp, "$<", 2))
1999 delay = atoi(Otemp);
2000 while (*Otemp != '>')
2003 chars = delay * chars_per_millisecond;
2005 if ((chars - delay) > 0.0)
2007 if (String_table[pc__] == NULL)
2010 temp = *String_table[pc__];
2011 for (; delay > 0; delay--)
2025 wmove(window, row, column) /* move cursor to indicated position in window */
2029 if ((row < window->Num_lines) && (column < window->Num_cols))
2031 window->LX = column;
2037 clear_line(line, column, cols)
2044 if (column > line->last_char)
2046 for (j = line->last_char; j < column; j++)
2049 line->attributes[j] = (char) NULL;
2052 line->last_char = column;
2053 line->row[column] = (char) NULL;
2054 line->attributes[column] = (char) NULL;
2055 line->changed = TRUE;
2059 werase(window) /* clear the specified window */
2065 window->SCROLL_CLEAR = CLEAR;
2066 window->scroll_up = window->scroll_down = 0;
2067 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2068 clear_line(tmp, 0, window->Num_cols);
2072 wclrtoeol(window) /* erase from current cursor position to end of line */
2078 window->SCROLL_CLEAR = CHANGE;
2079 column = window->LX;
2081 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2082 tmp = tmp->next_screen;
2083 clear_line(tmp, column, window->Num_cols);
2087 wrefresh(window) /* flush all previous output */
2090 wnoutrefresh(window);
2095 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2096 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2098 if (temp->number == -1)
2099 fprintf(stderr, "line moved ");
2101 fprintf(stderr, "scroll_x is set: ");
2102 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2104 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2105 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2106 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2108 if (temp->number == -1)
2109 fprintf(stderr, "line moved ");
2111 fprintf(stderr, "scroll_x is set: ");
2112 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2114 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2115 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2116 fprintf(stderr, "line=%s|\n", temp->row);
2120 virtual_scr->SCROLL_CLEAR = FALSE;
2121 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2129 struct _line *user_line;
2130 int line_counter = 0;
2132 for (line_counter = 0, user_line = window->first_line;
2133 line_counter < window->Num_lines; line_counter++)
2135 user_line->changed = TRUE;
2137 window->SCROLL_CLEAR = TRUE;
2141 wnoutrefresh(window)
2144 struct _line *user_line;
2145 struct _line *virtual_line;
2146 int line_counter = 0;
2150 if (window->SR >= virtual_scr->Num_lines)
2152 user_line = window->first_line;
2153 virtual_line = virtual_scr->first_line;
2154 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2155 virtual_scr->LX = window->LX + window->SC;
2156 virtual_scr->LY = window->LY + window->SR;
2157 virtual_scr->scroll_up = window->scroll_up;
2158 virtual_scr->scroll_down = window->scroll_down;
2159 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2161 for (line_counter = 0; line_counter < window->SR; line_counter++)
2163 virtual_line = virtual_line->next_screen;
2165 for (line_counter = 0; (line_counter < window->Num_lines)
2166 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2169 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2171 for (user_col = 0, virt_col = window->SC;
2172 (virt_col < virtual_scr->Num_cols)
2173 && (user_col < user_line->last_char);
2174 virt_col++, user_col++)
2176 virtual_line->row[virt_col] = user_line->row[user_col];
2177 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2179 for (user_col = user_line->last_char,
2180 virt_col = window->SC + user_line->last_char;
2181 (virt_col < virtual_scr->Num_cols)
2182 && (user_col < window->Num_cols);
2183 virt_col++, user_col++)
2185 virtual_line->row[virt_col] = ' ';
2186 virtual_line->attributes[virt_col] = (char) NULL;
2189 if (virtual_scr->Num_cols != window->Num_cols)
2191 if (virtual_line->last_char < (user_line->last_char + window->SC))
2193 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2194 virtual_line->row[virtual_line->last_char] = ' ';
2195 virtual_line->last_char =
2196 min(virtual_scr->Num_cols,
2197 (user_line->last_char + window->SC));
2201 virtual_line->last_char = user_line->last_char;
2202 virtual_line->row[virtual_line->last_char] = (char) NULL;
2203 virtual_line->changed = user_line->changed;
2204 virtual_line = virtual_line->next_screen;
2205 user_line = user_line->next_screen;
2207 window->SCROLL_CLEAR = FALSE;
2208 window->scroll_up = window->scroll_down = 0;
2209 last_window_refreshed = window;
2213 flushinp() /* flush input */
2218 ungetch(c) /* push a character back on input */
2222 in_buff[bufp++] = c;
2237 tv.tv_usec = 500000; /* half a second */
2239 Time_Out = FALSE; /* just in case */
2241 ret_val = select(nfds, &fds, 0, 0, &tv);
2244 | if ret_val is less than zero, there was no input
2245 | otherwise, get a character and return it
2254 return(read(0, &temp, 1)? temp : -1);
2259 wgetch(window) /* get character from specified window */
2270 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2272 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2273 #else /* BSD_SELECT */
2275 in_value = ((bufp > 0) ? in_buff[--bufp] :
2276 (read(0, &temp, 1)> 0) ? temp : -1);
2281 old_arg = fcntl(0, F_GETFL, 0);
2282 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2284 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2287 fcntl(0, F_SETFL, old_arg);
2292 #endif /* BSD_SELECT */
2297 if ((Parity) && (Num_bits < 8))
2298 /* strip eighth bit if parity in use */
2301 else if (interrupt_flag)
2303 interrupt_flag = FALSE;
2304 in_value = wgetch(window);
2307 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2308 in_value = Get_key(in_value);
2314 Clear(arg) /* notify that time out has occurred */
2319 fprintf(stderr, "inside Clear()\n");
2323 #endif /* BSD_SELECT */
2326 Get_key(first_char) /* try to decode key sequence */
2327 int first_char; /* first character of sequence */
2335 struct termio Gterminal;
2337 struct sgttyb Gterminal;
2339 struct KEY_STACK *St_point;
2340 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2342 #endif /* BSD_SELECT */
2346 string[Count++] = first_char;
2347 string[Count] = (char) NULL;
2350 signal(SIGALRM, Clear);
2352 #endif /* BSD_SELECT */
2355 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2356 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2357 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2361 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2363 in_char = wgetch(stdscr);
2365 fprintf(stderr, "back in GetKey()\n");
2370 string[Count++] = in_char;
2371 string[Count] = (char) NULL;
2373 while ((St_point != NULL) && (!Found))
2375 if (!strcmp(string, St_point->element->string))
2378 St_point = St_point->next;
2385 #endif /* BSD_SELECT */
2387 /* value = ioctl(0, TCSETA, &Terminal);*/
2389 value = ioctl(0, TIOCSETP, &Terminal);
2390 /* value = fcntl(0, F_SETFL, old_arg);*/
2395 return(St_point->element->value);
2401 if ((string[--Count] != -1) &&
2402 ((unsigned char) (string[Count]) != 255))
2405 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2407 ungetch(string[Count]);
2415 waddch(window, c) /* output the character in the specified window */
2420 int shift; /* number of spaces to shift if a tab */
2421 struct _line *tmpline;
2424 /*printf("starting waddch \n");fflush(stdout);*/
2426 column = window->LX;
2429 shift = (column + 1) % 8;
2437 waddch(window, ' ');
2440 else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
2442 if ((c == '~') && (Booleans[hz__]))
2445 if (( c != '\b') && (c != '\n') && (c != '\r'))
2447 tmpline = window->line_array[window->LY];
2448 tmpline->row[column] = c;
2449 tmpline->attributes[column] = window->Attrib;
2450 tmpline->changed = TRUE;
2451 if (column >= tmpline->last_char)
2453 if (column > tmpline->last_char)
2454 for (j = tmpline->last_char; j < column; j++)
2456 tmpline->row[j] = ' ';
2457 tmpline->attributes[j] = (char) NULL;
2459 tmpline->row[column + 1] = (char) NULL;
2460 tmpline->attributes[column + 1] = (char) NULL;
2461 tmpline->last_char = column + 1;
2467 window->LX = window->Num_cols;
2476 if (window->LX >= window->Num_cols)
2480 if (window->LY >= window->Num_lines)
2482 window->LY = window->Num_lines - 1;
2483 /* window->LY = row;
2484 wmove(window, 0, 0);
2486 wmove(window, row, 0);*/
2489 window->SCROLL_CLEAR = CHANGE;
2493 winsertln(window) /* insert a blank line into the specified window */
2500 window->scroll_down += 1;
2501 window->SCROLL_CLEAR = SCROLL;
2502 column = window->LX;
2504 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2505 tmp = tmp->next_screen;
2506 if (tmp->prev_screen != NULL)
2507 tmp->prev_screen->next_screen = NULL;
2509 clear_line(tmp1, 0, window->Num_cols);
2511 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2512 tmp = tmp->next_screen;
2513 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2515 tmp1->next_screen = tmp->next_screen;
2516 tmp->next_screen = tmp1;
2517 tmp->changed = TRUE;
2518 tmp->next_screen->prev_screen = tmp;
2520 else if (window->Num_lines > 1)
2522 if (tmp->prev_screen != NULL)
2523 tmp->prev_screen->next_screen = tmp1;
2524 tmp1->prev_screen = tmp->prev_screen;
2525 tmp->prev_screen = tmp1;
2526 tmp1->next_screen = tmp;
2527 tmp->changed = TRUE;
2530 if (window->LY == 0)
2531 window->first_line = tmp1;
2533 for (row = 0, tmp1 = window->first_line;
2534 row < window->Num_lines; row++)
2536 window->line_array[row] = tmp1;
2537 tmp1 = tmp1->next_screen;
2542 wdeleteln(window) /* delete a line in the specified window */
2547 struct _line *tmpline;
2549 if (window->Num_lines > 1)
2551 window->scroll_up += 1;
2552 window->SCROLL_CLEAR = SCROLL;
2553 column = window->LX;
2555 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2556 tmp = tmp->next_screen;
2557 if (window->LY == 0)
2558 window->first_line = tmp->next_screen;
2559 if (tmp->prev_screen != NULL)
2560 tmp->prev_screen->next_screen = tmp->next_screen;
2561 if (tmp->next_screen != NULL)
2563 tmp->next_screen->changed = TRUE;
2564 tmp->next_screen->scroll = UP;
2565 tmp->next_screen->prev_screen = tmp->prev_screen;
2568 clear_line(tmpline, 0, window->Num_cols);
2569 tmpline->number = -1;
2570 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2571 tmp = tmp->next_screen;
2574 tmp->next_screen = tmpline;
2575 tmp->next_screen->prev_screen = tmp;
2576 tmp->changed = TRUE;
2577 tmp = tmp->next_screen;
2581 tmp->next_screen = NULL;
2583 for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
2585 window->line_array[row] = tmp;
2586 tmp = tmp->next_screen;
2591 clear_line(window->first_line, 0, window->Num_cols);
2596 wclrtobot(window) /* delete from current position to end of the window */
2602 window->SCROLL_CLEAR |= CLEAR;
2603 column = window->LX;
2605 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2606 tmp = tmp->next_screen;
2607 clear_line(tmp, column, window->Num_cols);
2608 for (row = (window->LY + 1); row < window->Num_lines; row++)
2610 tmp = tmp->next_screen;
2611 clear_line(tmp, 0, window->Num_cols);
2613 wmove(window, row, column);
2617 wstandout(window) /* begin standout mode in window */
2620 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2621 window->Attrib |= A_STANDOUT;
2625 wstandend(window) /* end standout mode in window */
2628 window->Attrib &= ~A_STANDOUT;
2632 waddstr(window, string) /* write 'string' in window */
2638 for (wstring = string; *wstring != (char) NULL; wstring++)
2639 waddch(window, *wstring);
2643 clearok(window, flag) /* erase screen and redraw at next refresh */
2647 Repaint_screen = TRUE;
2652 echo() /* turn on echoing */
2657 Terminal.c_lflag |= ECHO; /* enable echo */
2658 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2660 Terminal.sg_flags |= ECHO; /* enable echo */
2661 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2666 noecho() /* turn off echoing */
2671 Terminal.c_lflag &= ~ECHO; /* disable echo */
2672 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2674 Terminal.sg_flags &= ~ECHO; /* disable echo */
2675 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2680 raw() /* set to read characters immediately */
2685 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2686 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2687 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2689 Terminal.c_lflag &= ~FLUSHO;
2692 Terminal.c_lflag &= ~PENDIN;
2695 Terminal.c_lflag &= ~IEXTEN;
2697 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2698 Terminal.c_cc[VTIME] = 0; /* timeout value */
2699 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2700 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2702 Terminal.sg_flags |= RAW; /* enable raw mode */
2703 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2708 noraw() /* set to normal character read mode */
2713 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2714 Terminal.c_lflag |= ISIG; /* enable signal checking */
2715 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2716 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2717 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2718 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2720 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2721 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2722 /* old_arg = fcntl(0, F_GETFL, 0);
2723 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2733 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2734 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2744 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2745 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2746 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2766 nodelay(window, flag)
2780 keypad(window, flag)
2785 String_Out(String_table[ks__], NULL, 0);
2787 String_Out(String_table[ke__], NULL, 0);
2791 savetty() /* save current tty stats */
2796 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2798 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2803 resetty() /* restore previous tty stats */
2808 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2810 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2815 endwin() /* end windows */
2817 keypad(stdscr, FALSE);
2818 initialized = FALSE;
2820 delwin(virtual_scr);
2825 /* old_arg = fcntl(0, F_GETFL, 0);
2826 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2832 delwin(window) /* delete the window structure */
2837 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2839 window->first_line = window->first_line->next_screen;
2840 free(window->first_line->prev_screen->row);
2841 free(window->first_line->prev_screen->attributes);
2842 free(window->first_line->prev_screen);
2844 if (window == last_window_refreshed)
2845 last_window_refreshed = 0;
2846 if (window->first_line != NULL)
2848 free(window->first_line->row);
2849 free(window->first_line->attributes);
2850 free(window->first_line);
2859 #else /* __STDC__ */
2861 wprintw(WINDOW *window, const char *format, ...)
2862 #endif /* __STDC__ */
2877 window = va_arg(ap, WINDOW *);
2878 format = va_arg(ap, char *);
2879 #else /* __STDC__ */
2880 va_start(ap, format);
2881 #endif /* __STDC__ */
2883 fpoint = (char *) format;
2884 while (*fpoint != (char) NULL)
2891 value = va_arg(ap, int);
2892 iout(window, value);
2894 else if (*fpoint == 'c')
2896 value = va_arg(ap, int);
2897 waddch(window, value);
2899 else if (*fpoint == 's')
2901 wtemp = va_arg(ap, char *);
2902 waddstr(window, wtemp);
2906 else if (*fpoint == '\\')
2910 waddch(window, '\n');
2911 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2914 while ((*fpoint >= '0') && (*fpoint <= '9'))
2916 value = (value * 8) + (*fpoint - '0');
2919 waddch(window, value);
2924 waddch(window, *fpoint++);
2928 #endif /* __STDC__ */
2932 iout(window, value) /* output characters */
2938 if ((i = value / 10) != 0)
2940 waddch(window, ((value % 10) + '0'));
2944 Comp_line(line1, line2) /* compare lines */
2945 struct _line *line1;
2946 struct _line *line2;
2953 if (line1->last_char != line2->last_char)
2958 att1 = line1->attributes;
2959 att2 = line2->attributes;
2961 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2964 if ((count1 == 1) && (c1[i] == (char) NULL) && (c2[i] == (char) NULL))
2965 count1 = 0; /* both lines blank */
2966 else if ((c1[i] == (char) NULL) && (c2[i] == (char) NULL))
2967 count1 = -1; /* equal */
2969 count1 = 1; /* lines unequal */
2974 Insert_line(row, end_row, window) /* insert line into screen */
2983 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2984 tmp = tmp->next_screen;
2985 if ((end_row + window->SR) == 0)
2986 curscr->first_line = curscr->first_line->next_screen;
2989 | find bottom line to delete
2991 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2992 tmp = tmp->next_screen;
2993 if (tmp->prev_screen != NULL)
2994 tmp->prev_screen->next_screen = tmp->next_screen;
2995 if (tmp->next_screen != NULL)
2996 tmp->next_screen->prev_screen = tmp->prev_screen;
2999 | clear deleted line
3001 clear_line(tmp, 0, window->Num_cols);
3003 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3004 tmp = tmp->next_screen;
3006 for (i = 0, tmp = top_of_win; i < row; i++)
3007 tmp = tmp->next_screen;
3008 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
3009 tmp->prev_screen->next_screen = tmp1;
3010 tmp1->prev_screen = tmp->prev_screen;
3011 tmp->prev_screen = tmp1;
3012 tmp1->next_screen = tmp;
3013 if ((row + window->SR) == 0)
3014 curscr->first_line = tmp1;
3015 if (tmp1->next_screen != NULL)
3016 tmp1 = tmp1->next_screen;
3018 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3020 Position(window, (window->SR + end_row), 0);
3021 String_Out(String_table[dl__], NULL, 0);
3023 Position(window, (window->SR + row), 0);
3024 if (String_table[al__] != NULL)
3025 String_Out(String_table[al__], NULL, 0);
3027 String_Out(String_table[sr__], NULL, 0);
3029 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3030 top_of_win = top_of_win->next_screen;
3036 Delete_line(row, end_row, window) /* delete a line on screen */
3047 tmp = curscr->first_line;
3048 while (i < window->SR)
3051 tmp = tmp->next_screen;
3054 | find line to delete
3057 if ((row + window->SR) == 0)
3058 curscr->first_line = top_of_win->next_screen;
3059 for (i = 0, tmp = top_of_win; i < row; i++)
3060 tmp = tmp->next_screen;
3061 if (tmp->prev_screen != NULL)
3062 tmp->prev_screen->next_screen = tmp->next_screen;
3063 if (tmp->next_screen != NULL)
3064 tmp->next_screen->prev_screen = tmp->prev_screen;
3065 tmp2 = tmp->next_screen;
3068 | clear deleted line
3070 clear_line(tmp1, 0, window->Num_cols);
3073 | find location to insert deleted line
3075 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3076 tmp = tmp->next_screen;
3078 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3079 tmp = tmp->next_screen;
3080 tmp1->next_screen = tmp;
3081 tmp1->prev_screen = tmp->prev_screen;
3082 if (tmp1->prev_screen != NULL)
3083 tmp1->prev_screen->next_screen = tmp1;
3084 tmp->prev_screen = tmp1;
3086 Position(window, (window->SR + row), 0);
3087 String_Out(String_table[dl__], NULL, 0);
3088 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3090 Position(window, (window->SR + end_row), 0);
3091 String_Out(String_table[al__], NULL, 0);
3093 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3095 Position(window, (window->SR + end_row), 0);
3099 if (row == (window->Num_lines-1))
3101 if ((row + window->SR) == 0)
3102 curscr->first_line = top_of_win = tmp2;
3107 CLEAR_TO_EOL(window, row, column)
3114 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3115 tmp1 = tmp1->next_screen;
3116 for (x = column; x<window->Num_cols; x++)
3119 tmp1->attributes[x] = (char) NULL;
3121 tmp1->row[column] = (char) NULL;
3122 tmp1->last_char = column;
3128 Position(window, row, column);
3131 if (String_table[ce__] != NULL)
3132 String_Out(String_table[ce__], NULL, 0);
3135 for (x = column; x < window->Num_cols; x++)
3143 check_delete(window, line, offset, pointer_new, pointer_old)
3146 struct _line *pointer_new, *pointer_old;
3158 new_lin = pointer_new->row;
3159 new_att = pointer_new->attributes;
3160 old_lin = pointer_old->row;
3161 old_att = pointer_old->attributes;
3162 end_old = end_new = offset;
3163 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))
3165 if (old_lin[end_old] != (char) NULL)
3168 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))
3170 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3172 if (new_lin[end_new+k] == (char) NULL)
3174 Position(window, line, (end_new+k));
3175 CLEAR_TO_EOL(window, line, (end_new+k));
3177 Position(window, line, offset);
3178 for (k = offset; k < end_old; k++)
3179 Char_del(old_lin, old_att, offset, window->Num_cols);
3180 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3182 pointer_old->last_char = offset;
3190 | Check if characters were inserted in the middle of a line, and if
3195 check_insert(window, line, offset, pointer_new, pointer_old)
3198 struct _line *pointer_new, *pointer_old;
3201 int end_old, end_new;
3212 new_lin = pointer_new->row;
3213 new_att = pointer_new->attributes;
3214 old_lin = pointer_old->row;
3215 old_att = pointer_old->attributes;
3216 end_old = end_new = offset;
3217 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))
3219 if (new_lin[end_new] != (char) NULL)
3222 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))
3225 | check for commonality between rest of lines (are the old
3226 | and new lines the same, except for a chunk in the middle?)
3227 | if the rest of the lines are common, do not insert text
3230 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]))
3232 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3234 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3236 Position(window, line, offset);
3238 if (String_table[ic__] == NULL)
3240 String_Out(String_table[im__], NULL, 0);
3243 for (k = offset; k < end_new; k++)
3246 String_Out(String_table[ic__], NULL, 0);
3247 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3250 String_Out(String_table[ei__], NULL, 0);
3251 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3253 pointer_old->last_char = offset;
3266 int begin_old, begin_new;
3267 int end_old, end_new;
3269 int from_top, tmp_ft, offset;
3283 struct _line *old1, *new1;
3292 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3294 window = virtual_scr;
3296 if ((nc_attributes & A_NC_BIG5) != 0)
3301 if (String_table[cl__])
3302 String_Out(String_table[cl__], NULL, 0);
3306 while (from_top < LINES)
3308 Position(curscr, from_top, 0);
3309 if (String_table[ce__] != NULL)
3310 String_Out(String_table[ce__], NULL, 0);
3313 for (j = 0; j < window->Num_cols; j++)
3319 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3321 Position(curscr, from_top, 0);
3322 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3324 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3329 Position(curscr, from_top, j);
3333 Repaint_screen = FALSE;
3338 top_of_win = curscr->first_line;
3340 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3341 from_top < window->Num_lines; from_top++)
3343 virtual_lines[from_top] = TRUE;
3344 if ((similar = Comp_line(curr, virt)) > 0)
3346 virtual_lines[from_top] = FALSE;
3349 curr = curr->next_screen;
3350 virt = virt->next_screen;
3354 virt = window->first_line;
3358 | if the window has lines that are different, check for scrolling
3364 for (first_same = window->Num_lines;
3365 (first_same > from_top) && (virtual_lines[first_same - 1]);
3369 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3372 while ((from_top < first_same) && nc_scrolling_ability)
3373 /* check entire lines for diffs */
3376 if (from_top >= last_same)
3378 for (last_same = from_top;
3379 (last_same < window->Num_lines) &&
3380 (virtual_lines[last_same] == FALSE);
3384 if (!virtual_lines[from_top])
3388 | check for lines deleted (scroll up)
3390 for (tmp_ft = from_top+1, old = curr->next_screen;
3391 ((window->scroll_up) && (diff) &&
3392 (tmp_ft < last_same) &&
3393 (!virtual_lines[tmp_ft]));
3396 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3399 | Find the bottom of the
3400 | area that should be
3403 for (bottom = tmp_ft, old1 = old,
3404 new1 = virt, count1 = 0;
3405 (bottom < window->Num_lines) &&
3406 (Comp_line(old1, new1) <= 0);
3407 bottom++, old1 = old1->next_screen,
3408 new1 = new1->next_screen,
3413 if (String_table[cs__]) /* scrolling region */
3416 list[0] = min((bottom - 1), (window->Num_lines - 1));
3417 String_Out(String_table[cs__], list, 2);
3418 Curr_y = Curr_x = -1;
3421 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3423 old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
3427 if (String_table[cs__]) /* scrolling region */
3430 list[0] = LINES - 1;
3431 String_Out(String_table[cs__], list, 2);
3432 Curr_y = Curr_x = -1;
3435 top_of_win = curscr->first_line;
3437 for (offset = 0; offset < from_top; offset++)
3438 curr = curr->next_screen;
3439 for (offset = from_top, old=curr, new=virt;
3440 offset < window->Num_lines;
3441 old=old->next_screen, new=new->next_screen,
3444 similar = Comp_line(old, new);
3445 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3450 old = old->next_screen;
3453 | check for lines inserted (scroll down)
3455 for (tmp_ft = from_top-1, old = curr->prev_screen;
3456 ((window->scroll_down) && (tmp_ft >= 0) &&
3458 (!virtual_lines[tmp_ft]));
3461 if (Comp_line(old, virt) == -1)
3464 | Find the bottom of the
3465 | area that should be
3468 for (bottom = from_top, old1 = old,
3469 new1 = virt, count1 = 0;
3470 (bottom < window->Num_lines) &&
3471 (Comp_line(old1, new1) <= 0);
3472 bottom++, old1 = old1->next_screen,
3473 new1 = new1->next_screen,
3478 if (String_table[cs__]) /* scrolling region */
3481 list[0] = min((bottom - 1), (window->Num_lines - 1));
3482 String_Out(String_table[cs__], list, 2);
3483 Curr_y = Curr_x = -1;
3486 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3488 old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
3492 if (String_table[cs__]) /* scrolling region */
3495 list[0] = LINES - 1;
3496 String_Out(String_table[cs__], list, 2);
3497 Curr_y = Curr_x = -1;
3500 top_of_win = curscr->first_line;
3502 for (offset = 0; offset < from_top; offset++)
3503 curr = curr->next_screen;
3504 for (offset = from_top, old=curr, new=virt;
3505 offset < window->Num_lines;
3506 old=old->next_screen, new=new->next_screen,
3509 similar = Comp_line(old, new);
3510 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3515 old = old->prev_screen;
3519 curr = curr->next_screen;
3520 virt = virt->next_screen;
3526 | Scrolling done, now need to insert, delete, or modify text
3530 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3531 curr = curr->next_screen;
3533 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)
3537 | If either 'insert mode' or 'insert char' are
3538 | available, enter the following 'if' statement,
3539 | else, need to simply rewrite the contents of the line
3540 | at the point where the contents of the line change.
3543 if (((String_table[ic__]) || (String_table[im__])) &&
3544 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3549 vrt_lin = virt->row;
3550 vrt_att = virt->attributes;
3551 cur_lin = curr->row;
3552 cur_att = curr->attributes;
3553 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3555 if ((STAND) && (Booleans[xs__]))
3557 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3559 if ((STAND) && (!vrt_att[j]))
3562 Position(window, from_top, j);
3569 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3572 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3574 Position(window, from_top, j);
3575 /* CLEAR_TO_EOL(window, from_top, j);*/
3579 if (vrt_lin[j] != (char) NULL)
3585 if ((first_time) && (virt->changed))
3587 if (curr->last_char <= virt->last_char)
3588 changed = check_insert(window, from_top, j, virt, curr);
3590 changed = check_delete(window, from_top, j, virt, curr);
3592 virt->changed = FALSE;
3594 changed = check_insert(window, from_top, j, virt, curr);
3595 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3597 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3601 Position(window, from_top, j);
3602 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3605 if ((vrt_lin[j] != (char) NULL))
3608 if ((STAND) && (!vrt_att[j]))
3611 Position(window, from_top, j);
3615 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3617 Position(window, from_top, j);
3618 CLEAR_TO_EOL(window, from_top, j);
3621 else /*if ((similar != -1) && (similar != 0))*/
3625 att1 = curr->attributes;
3627 att2 = virt->attributes;
3628 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3630 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3634 | if previous character is an eight bit
3635 | char, start redraw from that character
3638 if ((NC_chinese) && (highbitset(c1[j - 1])))
3642 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3644 Position(window, from_top, begin_old);
3645 CLEAR_TO_EOL(window, from_top, j);
3646 Position(window, from_top, begin_old);
3647 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3648 Char_out(c2[j], att2[j], c1, att1, j);
3651 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3653 Position(window, from_top, j);
3654 CLEAR_TO_EOL(window, from_top, j);
3660 Position(window, from_top, j);
3663 virt->number = from_top;
3665 Position(window, window->LY, window->LX);
3669 Position(window, row, col) /* position the cursor for output on the screen */
3680 pos_row = row + window->SR;
3681 pos_column = col + window->SC;
3682 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3684 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3687 list[place++] = pos_column;
3688 list[place++] = pos_row;
3689 String_Out(String_table[cm__], list, place);
3690 if ((STAND) && (!Booleans[ms__]))
3693 Curr_x = pos_column;
3699 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3707 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3709 line[one] = line[two];
3710 attrib[one] = attrib[two];
3712 String_Out(String_table[dc__], NULL, 0);
3716 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3727 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3729 for (two = one + 1; (two > offset); one--, two--)
3731 line[two] = line[one];
3732 attrib[two] = attrib[one];
3734 line[offset] = newc;
3735 attrib[offset] = newatt;
3736 Char_out(newc, newatt, line, attrib, offset);
3742 if (String_table[sa__])
3744 attributes_set[0] = 1;
3745 String_Out(String_table[sa__], attributes_set, 1);
3747 else if (String_table[so__])
3748 String_Out(String_table[so__], NULL, 0);
3754 if (String_table[me__])
3755 String_Out(String_table[me__], NULL, 0);
3756 else if (String_table[sa__])
3758 attributes_set[0] = 0;
3759 String_Out(String_table[sa__], attributes_set, 1);
3761 else if (String_table[se__])
3762 String_Out(String_table[se__], NULL, 0);
3766 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3775 if ((newatt) && (!STAND))
3780 else if ((STAND) && (!newatt))
3786 if ((newatt) && (STAND) && (Booleans[xs__]))
3791 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3794 line[offset] = newc;
3795 attrib[offset] = newatt;
3802 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3803 | hacks that notify new_curse to handle characters that have the high
3804 | bit set as the first of two bytes of a multi-byte string.
3812 nc_attributes |= flag;
3816 nc_clearattrib(flag)
3819 nc_attributes &= ~flag;