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.50 2001/01/19 02:53:40 hugh Exp hugh $
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.50 $";
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 defined(__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_;
1454 #endif /* ifdef CAP */
1457 Screenalloc(columns)
1463 tmp = (struct _line *) malloc(sizeof (struct _line));
1464 tmp->row = malloc(columns + 1);
1465 tmp->attributes = malloc(columns + 1);
1466 tmp->prev_screen = NULL;
1467 tmp->next_screen = NULL;
1468 for (i = 0; i < columns; i++)
1471 tmp->attributes[i] = (char) NULL;
1473 tmp->scroll = tmp->changed = FALSE;
1474 tmp->row[0] = (char) NULL;
1475 tmp->attributes[0] = (char) NULL;
1476 tmp->row[columns] = (char) NULL;
1477 tmp->attributes[columns] = (char) NULL;
1482 WINDOW *newwin(lines, cols, start_l, start_c)
1483 int lines, cols; /* number of lines and columns to be in window */
1484 int start_l, start_c; /* starting line and column to be inwindow */
1487 struct _line *temp_screen;
1490 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1491 Ntemp->SR = start_l;
1492 Ntemp->SC = start_c;
1493 Ntemp->Num_lines = lines;
1494 Ntemp->Num_cols = cols;
1497 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1498 Ntemp->SCROLL_CLEAR = FALSE;
1499 Ntemp->Attrib = FALSE;
1500 Ntemp->first_line = temp_screen = Screenalloc(cols);
1501 Ntemp->first_line->number = 0;
1502 Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
1504 Ntemp->line_array[0] = Ntemp->first_line;
1506 for (i = 1; i < lines; i++)
1508 temp_screen->next_screen = Screenalloc(cols);
1509 temp_screen->next_screen->number = i;
1510 temp_screen->next_screen->prev_screen = temp_screen;
1511 temp_screen = temp_screen->next_screen;
1512 Ntemp->line_array[i] = temp_screen;
1514 Ntemp->first_line->prev_screen = NULL;
1515 temp_screen->next_screen = NULL;
1521 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1523 int p_list[]; /* stack of values */
1524 int place; /* place keeper of top of stack */
1526 char *Otemp; /* temporary string pointer to parse output */
1536 p1 = p_list[--place];
1537 p2 = p_list[--place];
1541 if ((*Otemp >= '0') && (*Otemp <= '9'))
1543 delay = atoi(Otemp);
1544 while ((*Otemp >= '0') && (*Otemp <= '9'))
1549 while (*Otemp != (char)NULL)
1554 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1558 else if (*Otemp == '2')
1560 else if (*Otemp == '3')
1562 else if (*Otemp == '+')
1568 else if (*Otemp == '.')
1573 else if (*Otemp == '>')
1584 else if (*Otemp == 'r')
1590 else if (*Otemp == 'i')
1595 else if (*Otemp == '%')
1597 else if (*Otemp == 'n')
1602 else if (*Otemp == 'B')
1604 p1 = (16 * (p1/10)) + (p1 % 10);
1605 p2 = (16 * (p2/10)) + (p2 % 10);
1607 else if (*Otemp == 'D')
1609 p1 = (p1 - 2 * (p1 % 16));
1610 p2 = (p2 - 2 * (p2 % 16));
1619 chars = delay * chars_per_millisecond;
1621 if ((chars - delay) > 0.0)
1623 for (; delay > 0; delay--)
1624 putchar(*String_table[pc__]);
1631 char *Otemp; /* temporary string pointer to parse output */
1637 Operation(Temp_Stack, place) /* handle conditional operations */
1646 temp = Temp_Stack[--place];
1649 else if (!strncmp(Otemp, "2d", 2))
1651 temp = Temp_Stack[--place];
1652 printf("%2d", temp);
1656 else if (!strncmp(Otemp, "3d", 2))
1658 temp = Temp_Stack[--place];
1659 printf("%0d", temp);
1663 else if (!strncmp(Otemp, "02d", 3))
1665 temp = Temp_Stack[--place];
1666 printf("%02d", temp);
1671 else if (!strncmp(Otemp, "03d", 3))
1673 temp = Temp_Stack[--place];
1674 printf("%03d", temp);
1679 else if (*Otemp == '+')
1682 temp = Temp_Stack[--place];
1683 temp += Temp_Stack[--place];
1684 Temp_Stack[place++] = temp;
1686 else if (*Otemp == '-')
1689 temp = Temp_Stack[--place];
1690 temp -= Temp_Stack[--place];
1691 Temp_Stack[place++] = temp;
1693 else if (*Otemp == '*')
1696 temp = Temp_Stack[--place];
1697 temp *= Temp_Stack[--place];
1698 Temp_Stack[place++] = temp;
1700 else if (*Otemp == '/')
1703 temp = Temp_Stack[--place];
1704 temp /= Temp_Stack[--place];
1705 Temp_Stack[place++] = temp;
1707 else if (*Otemp == 'm')
1710 temp = Temp_Stack[--place];
1711 temp %= Temp_Stack[--place];
1712 Temp_Stack[place++] = temp;
1714 else if (*Otemp == '&')
1717 temp = Temp_Stack[--place];
1718 temp &= Temp_Stack[--place];
1719 Temp_Stack[place++] = temp;
1721 else if (*Otemp == '|')
1724 temp = Temp_Stack[--place];
1725 temp |= Temp_Stack[--place];
1726 Temp_Stack[place++] = temp;
1728 else if (*Otemp == '^')
1731 temp = Temp_Stack[--place];
1732 temp ^= Temp_Stack[--place];
1733 Temp_Stack[place++] = temp;
1735 else if (*Otemp == '=')
1738 temp = Temp_Stack[--place];
1739 temp = (temp == Temp_Stack[--place]);
1740 Temp_Stack[place++] = temp;
1742 else if (*Otemp == '>')
1745 temp = Temp_Stack[--place];
1746 temp = temp > Temp_Stack[--place];
1747 Temp_Stack[place++] = temp;
1749 else if (*Otemp == '<')
1752 temp = Temp_Stack[--place];
1753 temp = temp < Temp_Stack[--place];
1754 Temp_Stack[place++] = temp;
1756 else if (*Otemp == 'c')
1759 putchar(Temp_Stack[--place]);
1761 else if (*Otemp == 'i')
1767 else if (*Otemp == '%')
1772 else if (*Otemp == '!')
1774 temp = ! Temp_Stack[--place];
1775 Temp_Stack[place++] = temp;
1778 else if (*Otemp == '~')
1780 temp = ~Temp_Stack[--place];
1781 Temp_Stack[place++] = temp;
1784 else if (*Otemp == 'p')
1787 Temp_Stack[place++] = p[*Otemp - '0'];
1790 else if (*Otemp == 'P')
1793 Temp_Stack[place++] = variable[*Otemp - 'a'];
1796 else if (*Otemp == 'g')
1799 variable[*Otemp - 'a'] = Temp_Stack[--place];
1802 else if (*Otemp == '\'')
1805 Temp_Stack[place++] = *Otemp;
1809 else if (*Otemp == '{')
1813 Temp_Stack[place++] = temp;
1814 while (*Otemp != '}')
1822 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1832 int Cond_Stack[128];
1855 for (temp = 1; (place != 0); temp++)
1857 p[temp] = p_list[--place];
1862 while (*Otemp != (char) NULL)
1867 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1877 | find the end of the
1878 | conditional statement
1880 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1886 Cond_place = Operation(Cond_Stack, Cond_place);
1890 | if condition is true
1892 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1902 else /* condition is false */
1905 | find 'else' or end
1908 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1911 | if an 'else' found
1913 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1919 | check for 'then' part
1921 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1926 if (*tchar == (char) NULL)
1933 | if end of if found,
1937 else if (!strncmp(tchar, "%;", 2))
1946 | if end of if found,
1950 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1956 else /* Otemp == NULL */
1970 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1972 if (*Otemp != (char) NULL)
1984 Top_of_stack = Operation(Stack, Top_of_stack);
1987 else if (!strncmp(Otemp, "$<", 2))
1991 delay = atoi(Otemp);
1992 while (*Otemp != '>')
1995 chars = delay * chars_per_millisecond;
1997 if ((chars - delay) > 0.0)
1999 if (String_table[pc__] == NULL)
2002 temp = *String_table[pc__];
2003 for (; delay > 0; delay--)
2017 wmove(window, row, column) /* move cursor to indicated position in window */
2021 if ((row < window->Num_lines) && (column < window->Num_cols))
2023 window->LX = column;
2029 clear_line(line, column, cols)
2036 if (column > line->last_char)
2038 for (j = line->last_char; j < column; j++)
2041 line->attributes[j] = (char) NULL;
2044 line->last_char = column;
2045 line->row[column] = (char) NULL;
2046 line->attributes[column] = (char) NULL;
2047 line->changed = TRUE;
2051 werase(window) /* clear the specified window */
2057 window->SCROLL_CLEAR = CLEAR;
2058 window->scroll_up = window->scroll_down = 0;
2059 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2060 clear_line(tmp, 0, window->Num_cols);
2064 wclrtoeol(window) /* erase from current cursor position to end of line */
2070 window->SCROLL_CLEAR = CHANGE;
2071 column = window->LX;
2073 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2074 tmp = tmp->next_screen;
2075 clear_line(tmp, column, window->Num_cols);
2079 wrefresh(window) /* flush all previous output */
2082 wnoutrefresh(window);
2087 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2088 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2090 if (temp->number == -1)
2091 fprintf(stderr, "line moved ");
2093 fprintf(stderr, "scroll_x is set: ");
2094 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2096 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2097 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2098 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2100 if (temp->number == -1)
2101 fprintf(stderr, "line moved ");
2103 fprintf(stderr, "scroll_x is set: ");
2104 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2106 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2107 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2108 fprintf(stderr, "line=%s|\n", temp->row);
2112 virtual_scr->SCROLL_CLEAR = FALSE;
2113 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2121 struct _line *user_line;
2122 int line_counter = 0;
2124 for (line_counter = 0, user_line = window->first_line;
2125 line_counter < window->Num_lines; line_counter++)
2127 user_line->changed = TRUE;
2129 window->SCROLL_CLEAR = TRUE;
2133 wnoutrefresh(window)
2136 struct _line *user_line;
2137 struct _line *virtual_line;
2138 int line_counter = 0;
2142 if (window->SR >= virtual_scr->Num_lines)
2144 user_line = window->first_line;
2145 virtual_line = virtual_scr->first_line;
2146 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2147 virtual_scr->LX = window->LX + window->SC;
2148 virtual_scr->LY = window->LY + window->SR;
2149 virtual_scr->scroll_up = window->scroll_up;
2150 virtual_scr->scroll_down = window->scroll_down;
2151 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2153 for (line_counter = 0; line_counter < window->SR; line_counter++)
2155 virtual_line = virtual_line->next_screen;
2157 for (line_counter = 0; (line_counter < window->Num_lines)
2158 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2161 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2163 for (user_col = 0, virt_col = window->SC;
2164 (virt_col < virtual_scr->Num_cols)
2165 && (user_col < user_line->last_char);
2166 virt_col++, user_col++)
2168 virtual_line->row[virt_col] = user_line->row[user_col];
2169 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2171 for (user_col = user_line->last_char,
2172 virt_col = window->SC + user_line->last_char;
2173 (virt_col < virtual_scr->Num_cols)
2174 && (user_col < window->Num_cols);
2175 virt_col++, user_col++)
2177 virtual_line->row[virt_col] = ' ';
2178 virtual_line->attributes[virt_col] = (char) NULL;
2181 if (virtual_scr->Num_cols != window->Num_cols)
2183 if (virtual_line->last_char < (user_line->last_char + window->SC))
2185 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2186 virtual_line->row[virtual_line->last_char] = ' ';
2187 virtual_line->last_char =
2188 min(virtual_scr->Num_cols,
2189 (user_line->last_char + window->SC));
2193 virtual_line->last_char = user_line->last_char;
2194 virtual_line->row[virtual_line->last_char] = (char) NULL;
2195 virtual_line->changed = user_line->changed;
2196 virtual_line = virtual_line->next_screen;
2197 user_line = user_line->next_screen;
2199 window->SCROLL_CLEAR = FALSE;
2200 window->scroll_up = window->scroll_down = 0;
2201 last_window_refreshed = window;
2205 flushinp() /* flush input */
2210 ungetch(c) /* push a character back on input */
2214 in_buff[bufp++] = c;
2229 tv.tv_usec = 500000; /* half a second */
2231 Time_Out = FALSE; /* just in case */
2233 ret_val = select(nfds, &fds, 0, 0, &tv);
2236 | if ret_val is less than zero, there was no input
2237 | otherwise, get a character and return it
2246 return(read(0, &temp, 1)? temp : -1);
2251 wgetch(window) /* get character from specified window */
2262 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2264 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2265 #else /* BSD_SELECT */
2267 in_value = ((bufp > 0) ? in_buff[--bufp] :
2268 (read(0, &temp, 1)> 0) ? temp : -1);
2273 old_arg = fcntl(0, F_GETFL, 0);
2274 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2276 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2279 fcntl(0, F_SETFL, old_arg);
2284 #endif /* BSD_SELECT */
2289 if ((Parity) && (Num_bits < 8))
2290 /* strip eighth bit if parity in use */
2293 else if (interrupt_flag)
2295 interrupt_flag = FALSE;
2296 in_value = wgetch(window);
2299 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2300 in_value = Get_key(in_value);
2306 Clear(arg) /* notify that time out has occurred */
2311 fprintf(stderr, "inside Clear()\n");
2315 #endif /* BSD_SELECT */
2318 Get_key(first_char) /* try to decode key sequence */
2319 int first_char; /* first character of sequence */
2327 struct termio Gterminal;
2329 struct sgttyb Gterminal;
2331 struct KEY_STACK *St_point;
2332 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2334 #endif /* BSD_SELECT */
2338 string[Count++] = first_char;
2339 string[Count] = (char) NULL;
2342 signal(SIGALRM, Clear);
2344 #endif /* BSD_SELECT */
2347 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2348 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2349 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2353 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2355 in_char = wgetch(stdscr);
2357 fprintf(stderr, "back in GetKey()\n");
2362 string[Count++] = in_char;
2363 string[Count] = (char) NULL;
2365 while ((St_point != NULL) && (!Found))
2367 if (!strcmp(string, St_point->element->string))
2370 St_point = St_point->next;
2377 #endif /* BSD_SELECT */
2379 /* value = ioctl(0, TCSETA, &Terminal);*/
2381 value = ioctl(0, TIOCSETP, &Terminal);
2382 /* value = fcntl(0, F_SETFL, old_arg);*/
2387 return(St_point->element->value);
2393 if ((string[--Count] != -1) &&
2394 ((unsigned char) (string[Count]) != 255))
2397 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2399 ungetch(string[Count]);
2407 waddch(window, c) /* output the character in the specified window */
2412 int shift; /* number of spaces to shift if a tab */
2413 struct _line *tmpline;
2416 /*printf("starting waddch \n");fflush(stdout);*/
2418 column = window->LX;
2421 shift = (column + 1) % 8;
2429 waddch(window, ' ');
2432 else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
2434 if ((c == '~') && (Booleans[hz__]))
2437 if (( c != '\b') && (c != '\n') && (c != '\r'))
2439 tmpline = window->line_array[window->LY];
2440 tmpline->row[column] = c;
2441 tmpline->attributes[column] = window->Attrib;
2442 tmpline->changed = TRUE;
2443 if (column >= tmpline->last_char)
2445 if (column > tmpline->last_char)
2446 for (j = tmpline->last_char; j < column; j++)
2448 tmpline->row[j] = ' ';
2449 tmpline->attributes[j] = (char) NULL;
2451 tmpline->row[column + 1] = (char) NULL;
2452 tmpline->attributes[column + 1] = (char) NULL;
2453 tmpline->last_char = column + 1;
2459 window->LX = window->Num_cols;
2468 if (window->LX >= window->Num_cols)
2472 if (window->LY >= window->Num_lines)
2474 window->LY = window->Num_lines - 1;
2475 /* window->LY = row;
2476 wmove(window, 0, 0);
2478 wmove(window, row, 0);*/
2481 window->SCROLL_CLEAR = CHANGE;
2485 winsertln(window) /* insert a blank line into the specified window */
2492 window->scroll_down += 1;
2493 window->SCROLL_CLEAR = SCROLL;
2494 column = window->LX;
2496 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2497 tmp = tmp->next_screen;
2498 if (tmp->prev_screen != NULL)
2499 tmp->prev_screen->next_screen = NULL;
2501 clear_line(tmp1, 0, window->Num_cols);
2503 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2504 tmp = tmp->next_screen;
2505 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2507 tmp1->next_screen = tmp->next_screen;
2508 tmp->next_screen = tmp1;
2509 tmp->changed = TRUE;
2510 tmp->next_screen->prev_screen = tmp;
2512 else if (window->Num_lines > 1)
2514 if (tmp->prev_screen != NULL)
2515 tmp->prev_screen->next_screen = tmp1;
2516 tmp1->prev_screen = tmp->prev_screen;
2517 tmp->prev_screen = tmp1;
2518 tmp1->next_screen = tmp;
2519 tmp->changed = TRUE;
2522 if (window->LY == 0)
2523 window->first_line = tmp1;
2525 for (row = 0, tmp1 = window->first_line;
2526 row < window->Num_lines; row++)
2528 window->line_array[row] = tmp1;
2529 tmp1 = tmp1->next_screen;
2534 wdeleteln(window) /* delete a line in the specified window */
2539 struct _line *tmpline;
2541 if (window->Num_lines > 1)
2543 window->scroll_up += 1;
2544 window->SCROLL_CLEAR = SCROLL;
2545 column = window->LX;
2547 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2548 tmp = tmp->next_screen;
2549 if (window->LY == 0)
2550 window->first_line = tmp->next_screen;
2551 if (tmp->prev_screen != NULL)
2552 tmp->prev_screen->next_screen = tmp->next_screen;
2553 if (tmp->next_screen != NULL)
2555 tmp->next_screen->changed = TRUE;
2556 tmp->next_screen->scroll = UP;
2557 tmp->next_screen->prev_screen = tmp->prev_screen;
2560 clear_line(tmpline, 0, window->Num_cols);
2561 tmpline->number = -1;
2562 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2563 tmp = tmp->next_screen;
2566 tmp->next_screen = tmpline;
2567 tmp->next_screen->prev_screen = tmp;
2568 tmp->changed = TRUE;
2569 tmp = tmp->next_screen;
2573 tmp->next_screen = NULL;
2575 for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
2577 window->line_array[row] = tmp;
2578 tmp = tmp->next_screen;
2583 clear_line(window->first_line, 0, window->Num_cols);
2588 wclrtobot(window) /* delete from current position to end of the window */
2594 window->SCROLL_CLEAR |= CLEAR;
2595 column = window->LX;
2597 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2598 tmp = tmp->next_screen;
2599 clear_line(tmp, column, window->Num_cols);
2600 for (row = (window->LY + 1); row < window->Num_lines; row++)
2602 tmp = tmp->next_screen;
2603 clear_line(tmp, 0, window->Num_cols);
2605 wmove(window, row, column);
2609 wstandout(window) /* begin standout mode in window */
2612 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2613 window->Attrib |= A_STANDOUT;
2617 wstandend(window) /* end standout mode in window */
2620 window->Attrib &= ~A_STANDOUT;
2624 waddstr(window, string) /* write 'string' in window */
2630 for (wstring = string; *wstring != (char) NULL; wstring++)
2631 waddch(window, *wstring);
2635 clearok(window, flag) /* erase screen and redraw at next refresh */
2639 Repaint_screen = TRUE;
2644 echo() /* turn on echoing */
2649 Terminal.c_lflag |= ECHO; /* enable echo */
2650 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2652 Terminal.sg_flags |= ECHO; /* enable echo */
2653 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2658 noecho() /* turn off echoing */
2663 Terminal.c_lflag &= ~ECHO; /* disable echo */
2664 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2666 Terminal.sg_flags &= ~ECHO; /* disable echo */
2667 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2672 raw() /* set to read characters immediately */
2677 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2678 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2679 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2681 Terminal.c_lflag &= ~FLUSHO;
2684 Terminal.c_lflag &= ~PENDIN;
2687 Terminal.c_lflag &= ~IEXTEN;
2689 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2690 Terminal.c_cc[VTIME] = 0; /* timeout value */
2691 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2692 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2694 Terminal.sg_flags |= RAW; /* enable raw mode */
2695 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2700 noraw() /* set to normal character read mode */
2705 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2706 Terminal.c_lflag |= ISIG; /* enable signal checking */
2707 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2708 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2709 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2710 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2712 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2713 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2714 /* old_arg = fcntl(0, F_GETFL, 0);
2715 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2725 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2726 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2736 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2737 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2738 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2758 nodelay(window, flag)
2772 keypad(window, flag)
2777 String_Out(String_table[ks__], NULL, 0);
2779 String_Out(String_table[ke__], NULL, 0);
2783 savetty() /* save current tty stats */
2788 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2790 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2795 resetty() /* restore previous tty stats */
2800 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2802 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2807 endwin() /* end windows */
2809 keypad(stdscr, FALSE);
2810 initialized = FALSE;
2812 delwin(virtual_scr);
2817 /* old_arg = fcntl(0, F_GETFL, 0);
2818 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2824 delwin(window) /* delete the window structure */
2829 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2831 window->first_line = window->first_line->next_screen;
2832 free(window->first_line->prev_screen->row);
2833 free(window->first_line->prev_screen->attributes);
2834 free(window->first_line->prev_screen);
2836 if (window == last_window_refreshed)
2837 last_window_refreshed = 0;
2838 if (window->first_line != NULL)
2840 free(window->first_line->row);
2841 free(window->first_line->attributes);
2842 free(window->first_line);
2851 #else /* __STDC__ */
2853 wprintw(WINDOW *window, const char *format, ...)
2854 #endif /* __STDC__ */
2869 window = va_arg(ap, WINDOW *);
2870 format = va_arg(ap, char *);
2871 #else /* __STDC__ */
2872 va_start(ap, format);
2873 #endif /* __STDC__ */
2875 fpoint = (char *) format;
2876 while (*fpoint != (char) NULL)
2883 value = va_arg(ap, int);
2884 iout(window, value);
2886 else if (*fpoint == 'c')
2888 value = va_arg(ap, int);
2889 waddch(window, value);
2891 else if (*fpoint == 's')
2893 wtemp = va_arg(ap, char *);
2894 waddstr(window, wtemp);
2898 else if (*fpoint == '\\')
2902 waddch(window, '\n');
2903 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2906 while ((*fpoint >= '0') && (*fpoint <= '9'))
2908 value = (value * 8) + (*fpoint - '0');
2911 waddch(window, value);
2916 waddch(window, *fpoint++);
2920 #endif /* __STDC__ */
2924 iout(window, value) /* output characters */
2930 if ((i = value / 10) != 0)
2932 waddch(window, ((value % 10) + '0'));
2936 Comp_line(line1, line2) /* compare lines */
2937 struct _line *line1;
2938 struct _line *line2;
2945 if (line1->last_char != line2->last_char)
2950 att1 = line1->attributes;
2951 att2 = line2->attributes;
2953 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2956 if ((count1 == 1) && (c1[i] == (char) NULL) && (c2[i] == (char) NULL))
2957 count1 = 0; /* both lines blank */
2958 else if ((c1[i] == (char) NULL) && (c2[i] == (char) NULL))
2959 count1 = -1; /* equal */
2961 count1 = 1; /* lines unequal */
2966 Insert_line(row, end_row, window) /* insert line into screen */
2975 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2976 tmp = tmp->next_screen;
2977 if ((end_row + window->SR) == 0)
2978 curscr->first_line = curscr->first_line->next_screen;
2981 | find bottom line to delete
2983 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2984 tmp = tmp->next_screen;
2985 if (tmp->prev_screen != NULL)
2986 tmp->prev_screen->next_screen = tmp->next_screen;
2987 if (tmp->next_screen != NULL)
2988 tmp->next_screen->prev_screen = tmp->prev_screen;
2991 | clear deleted line
2993 clear_line(tmp, 0, window->Num_cols);
2995 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2996 tmp = tmp->next_screen;
2998 for (i = 0, tmp = top_of_win; i < row; i++)
2999 tmp = tmp->next_screen;
3000 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
3001 tmp->prev_screen->next_screen = tmp1;
3002 tmp1->prev_screen = tmp->prev_screen;
3003 tmp->prev_screen = tmp1;
3004 tmp1->next_screen = tmp;
3005 if ((row + window->SR) == 0)
3006 curscr->first_line = tmp1;
3007 if (tmp1->next_screen != NULL)
3008 tmp1 = tmp1->next_screen;
3010 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3012 Position(window, (window->SR + end_row), 0);
3013 String_Out(String_table[dl__], NULL, 0);
3015 Position(window, (window->SR + row), 0);
3016 if (String_table[al__] != NULL)
3017 String_Out(String_table[al__], NULL, 0);
3019 String_Out(String_table[sr__], NULL, 0);
3021 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3022 top_of_win = top_of_win->next_screen;
3028 Delete_line(row, end_row, window) /* delete a line on screen */
3039 tmp = curscr->first_line;
3040 while (i < window->SR)
3043 tmp = tmp->next_screen;
3046 | find line to delete
3049 if ((row + window->SR) == 0)
3050 curscr->first_line = top_of_win->next_screen;
3051 for (i = 0, tmp = top_of_win; i < row; i++)
3052 tmp = tmp->next_screen;
3053 if (tmp->prev_screen != NULL)
3054 tmp->prev_screen->next_screen = tmp->next_screen;
3055 if (tmp->next_screen != NULL)
3056 tmp->next_screen->prev_screen = tmp->prev_screen;
3057 tmp2 = tmp->next_screen;
3060 | clear deleted line
3062 clear_line(tmp1, 0, window->Num_cols);
3065 | find location to insert deleted line
3067 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3068 tmp = tmp->next_screen;
3070 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3071 tmp = tmp->next_screen;
3072 tmp1->next_screen = tmp;
3073 tmp1->prev_screen = tmp->prev_screen;
3074 if (tmp1->prev_screen != NULL)
3075 tmp1->prev_screen->next_screen = tmp1;
3076 tmp->prev_screen = tmp1;
3078 Position(window, (window->SR + row), 0);
3079 String_Out(String_table[dl__], NULL, 0);
3080 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3082 Position(window, (window->SR + end_row), 0);
3083 String_Out(String_table[al__], NULL, 0);
3085 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3087 Position(window, (window->SR + end_row), 0);
3091 if (row == (window->Num_lines-1))
3093 if ((row + window->SR) == 0)
3094 curscr->first_line = top_of_win = tmp2;
3099 CLEAR_TO_EOL(window, row, column)
3106 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3107 tmp1 = tmp1->next_screen;
3108 for (x = column; x<window->Num_cols; x++)
3111 tmp1->attributes[x] = (char) NULL;
3113 tmp1->row[column] = (char) NULL;
3114 tmp1->last_char = column;
3120 Position(window, row, column);
3123 if (String_table[ce__] != NULL)
3124 String_Out(String_table[ce__], NULL, 0);
3127 for (x = column; x < window->Num_cols; x++)
3135 check_delete(window, line, offset, pointer_new, pointer_old)
3138 struct _line *pointer_new, *pointer_old;
3150 new_lin = pointer_new->row;
3151 new_att = pointer_new->attributes;
3152 old_lin = pointer_old->row;
3153 old_att = pointer_old->attributes;
3154 end_old = end_new = offset;
3155 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))
3157 if (old_lin[end_old] != (char) NULL)
3160 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))
3162 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3164 if (new_lin[end_new+k] == (char) NULL)
3166 Position(window, line, (end_new+k));
3167 CLEAR_TO_EOL(window, line, (end_new+k));
3169 Position(window, line, offset);
3170 for (k = offset; k < end_old; k++)
3171 Char_del(old_lin, old_att, offset, window->Num_cols);
3172 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3174 pointer_old->last_char = offset;
3182 | Check if characters were inserted in the middle of a line, and if
3187 check_insert(window, line, offset, pointer_new, pointer_old)
3190 struct _line *pointer_new, *pointer_old;
3193 int end_old, end_new;
3204 new_lin = pointer_new->row;
3205 new_att = pointer_new->attributes;
3206 old_lin = pointer_old->row;
3207 old_att = pointer_old->attributes;
3208 end_old = end_new = offset;
3209 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))
3211 if (new_lin[end_new] != (char) NULL)
3214 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))
3217 | check for commonality between rest of lines (are the old
3218 | and new lines the same, except for a chunk in the middle?)
3219 | if the rest of the lines are common, do not insert text
3222 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]))
3224 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3226 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3228 Position(window, line, offset);
3230 if (String_table[ic__] == NULL)
3232 String_Out(String_table[im__], NULL, 0);
3235 for (k = offset; k < end_new; k++)
3238 String_Out(String_table[ic__], NULL, 0);
3239 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3242 String_Out(String_table[ei__], NULL, 0);
3243 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3245 pointer_old->last_char = offset;
3258 int begin_old, begin_new;
3259 int end_old, end_new;
3261 int from_top, tmp_ft, offset;
3275 struct _line *old1, *new1;
3284 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3286 window = virtual_scr;
3288 if ((nc_attributes & A_NC_BIG5) != 0)
3293 if (String_table[cl__])
3294 String_Out(String_table[cl__], NULL, 0);
3298 while (from_top < LINES)
3300 Position(curscr, from_top, 0);
3301 if (String_table[ce__] != NULL)
3302 String_Out(String_table[ce__], NULL, 0);
3305 for (j = 0; j < window->Num_cols; j++)
3311 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3313 Position(curscr, from_top, 0);
3314 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3316 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3321 Position(curscr, from_top, j);
3325 Repaint_screen = FALSE;
3330 top_of_win = curscr->first_line;
3332 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3333 from_top < window->Num_lines; from_top++)
3335 virtual_lines[from_top] = TRUE;
3336 if ((similar = Comp_line(curr, virt)) > 0)
3338 virtual_lines[from_top] = FALSE;
3341 curr = curr->next_screen;
3342 virt = virt->next_screen;
3346 virt = window->first_line;
3350 | if the window has lines that are different, check for scrolling
3356 for (first_same = window->Num_lines;
3357 (first_same > from_top) && (virtual_lines[first_same - 1]);
3361 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3364 while ((from_top < first_same) && nc_scrolling_ability)
3365 /* check entire lines for diffs */
3368 if (from_top >= last_same)
3370 for (last_same = from_top;
3371 (last_same < window->Num_lines) &&
3372 (virtual_lines[last_same] == FALSE);
3376 if (!virtual_lines[from_top])
3380 | check for lines deleted (scroll up)
3382 for (tmp_ft = from_top+1, old = curr->next_screen;
3383 ((window->scroll_up) && (diff) &&
3384 (tmp_ft < last_same) &&
3385 (!virtual_lines[tmp_ft]));
3388 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3391 | Find the bottom of the
3392 | area that should be
3395 for (bottom = tmp_ft, old1 = old,
3396 new1 = virt, count1 = 0;
3397 (bottom < window->Num_lines) &&
3398 (Comp_line(old1, new1) <= 0);
3399 bottom++, old1 = old1->next_screen,
3400 new1 = new1->next_screen,
3405 if (String_table[cs__]) /* scrolling region */
3408 list[0] = min((bottom - 1), (window->Num_lines - 1));
3409 String_Out(String_table[cs__], list, 2);
3410 Curr_y = Curr_x = -1;
3413 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3415 old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
3419 if (String_table[cs__]) /* scrolling region */
3422 list[0] = LINES - 1;
3423 String_Out(String_table[cs__], list, 2);
3424 Curr_y = Curr_x = -1;
3427 top_of_win = curscr->first_line;
3429 for (offset = 0; offset < from_top; offset++)
3430 curr = curr->next_screen;
3431 for (offset = from_top, old=curr, new=virt;
3432 offset < window->Num_lines;
3433 old=old->next_screen, new=new->next_screen,
3436 similar = Comp_line(old, new);
3437 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3442 old = old->next_screen;
3445 | check for lines inserted (scroll down)
3447 for (tmp_ft = from_top-1, old = curr->prev_screen;
3448 ((window->scroll_down) && (tmp_ft >= 0) &&
3450 (!virtual_lines[tmp_ft]));
3453 if (Comp_line(old, virt) == -1)
3456 | Find the bottom of the
3457 | area that should be
3460 for (bottom = from_top, old1 = old,
3461 new1 = virt, count1 = 0;
3462 (bottom < window->Num_lines) &&
3463 (Comp_line(old1, new1) <= 0);
3464 bottom++, old1 = old1->next_screen,
3465 new1 = new1->next_screen,
3470 if (String_table[cs__]) /* scrolling region */
3473 list[0] = min((bottom - 1), (window->Num_lines - 1));
3474 String_Out(String_table[cs__], list, 2);
3475 Curr_y = Curr_x = -1;
3478 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3480 old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
3484 if (String_table[cs__]) /* scrolling region */
3487 list[0] = LINES - 1;
3488 String_Out(String_table[cs__], list, 2);
3489 Curr_y = Curr_x = -1;
3492 top_of_win = curscr->first_line;
3494 for (offset = 0; offset < from_top; offset++)
3495 curr = curr->next_screen;
3496 for (offset = from_top, old=curr, new=virt;
3497 offset < window->Num_lines;
3498 old=old->next_screen, new=new->next_screen,
3501 similar = Comp_line(old, new);
3502 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3507 old = old->prev_screen;
3511 curr = curr->next_screen;
3512 virt = virt->next_screen;
3518 | Scrolling done, now need to insert, delete, or modify text
3522 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3523 curr = curr->next_screen;
3525 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)
3529 | If either 'insert mode' or 'insert char' are
3530 | available, enter the following 'if' statement,
3531 | else, need to simply rewrite the contents of the line
3532 | at the point where the contents of the line change.
3535 if (((String_table[ic__]) || (String_table[im__])) &&
3536 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3541 vrt_lin = virt->row;
3542 vrt_att = virt->attributes;
3543 cur_lin = curr->row;
3544 cur_att = curr->attributes;
3545 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3547 if ((STAND) && (Booleans[xs__]))
3549 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3551 if ((STAND) && (!vrt_att[j]))
3554 Position(window, from_top, j);
3561 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3564 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3566 Position(window, from_top, j);
3567 /* CLEAR_TO_EOL(window, from_top, j);*/
3571 if (vrt_lin[j] != (char) NULL)
3577 if ((first_time) && (virt->changed))
3579 if (curr->last_char <= virt->last_char)
3580 changed = check_insert(window, from_top, j, virt, curr);
3582 changed = check_delete(window, from_top, j, virt, curr);
3584 virt->changed = FALSE;
3586 changed = check_insert(window, from_top, j, virt, curr);
3587 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3589 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3593 Position(window, from_top, j);
3594 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3597 if ((vrt_lin[j] != (char) NULL))
3600 if ((STAND) && (!vrt_att[j]))
3603 Position(window, from_top, j);
3607 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3609 Position(window, from_top, j);
3610 CLEAR_TO_EOL(window, from_top, j);
3613 else /*if ((similar != -1) && (similar != 0))*/
3617 att1 = curr->attributes;
3619 att2 = virt->attributes;
3620 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3622 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3626 | if previous character is an eight bit
3627 | char, start redraw from that character
3630 if ((NC_chinese) && (highbitset(c1[j - 1])))
3634 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3636 Position(window, from_top, begin_old);
3637 CLEAR_TO_EOL(window, from_top, j);
3638 Position(window, from_top, begin_old);
3639 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3640 Char_out(c2[j], att2[j], c1, att1, j);
3643 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3645 Position(window, from_top, j);
3646 CLEAR_TO_EOL(window, from_top, j);
3652 Position(window, from_top, j);
3655 virt->number = from_top;
3657 Position(window, window->LY, window->LX);
3661 Position(window, row, col) /* position the cursor for output on the screen */
3672 pos_row = row + window->SR;
3673 pos_column = col + window->SC;
3674 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3676 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3679 list[place++] = pos_column;
3680 list[place++] = pos_row;
3681 String_Out(String_table[cm__], list, place);
3682 if ((STAND) && (!Booleans[ms__]))
3685 Curr_x = pos_column;
3691 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3699 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3701 line[one] = line[two];
3702 attrib[one] = attrib[two];
3704 String_Out(String_table[dc__], NULL, 0);
3708 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3719 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3721 for (two = one + 1; (two > offset); one--, two--)
3723 line[two] = line[one];
3724 attrib[two] = attrib[one];
3726 line[offset] = newc;
3727 attrib[offset] = newatt;
3728 Char_out(newc, newatt, line, attrib, offset);
3734 if (String_table[sa__])
3736 attributes_set[0] = 1;
3737 String_Out(String_table[sa__], attributes_set, 1);
3739 else if (String_table[so__])
3740 String_Out(String_table[so__], NULL, 0);
3746 if (String_table[me__])
3747 String_Out(String_table[me__], NULL, 0);
3748 else if (String_table[sa__])
3750 attributes_set[0] = 0;
3751 String_Out(String_table[sa__], attributes_set, 1);
3753 else if (String_table[se__])
3754 String_Out(String_table[se__], NULL, 0);
3758 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3767 if ((newatt) && (!STAND))
3772 else if ((STAND) && (!newatt))
3778 if ((newatt) && (STAND) && (Booleans[xs__]))
3783 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3786 line[offset] = newc;
3787 attrib[offset] = newatt;
3794 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3795 | hacks that notify new_curse to handle characters that have the high
3796 | bit set as the first of two bytes of a multi-byte string.
3804 nc_attributes |= flag;
3808 nc_clearattrib(flag)
3811 nc_attributes &= ~flag;