4 | A subset of curses developed for use with ae.
6 | written by Hugh Mahon
8 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11 | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 | FITNESS FOR A PARTICULAR PURPOSE. Neither
13 | Hewlett-Packard nor Hugh Mahon shall be liable
14 | for errors contained herein, nor for
15 | incidental or consequential damages in
16 | connection with the furnishing, performance or
17 | use of this material. Neither Hewlett-Packard
18 | nor Hugh Mahon assumes any responsibility for
19 | the use or reliability of this software or
20 | documentation. This software and
21 | documentation is totally UNSUPPORTED. There
22 | is no support contract available. Hewlett-
23 | Packard has done NO Quality Assurance on ANY
24 | of the program or documentation. You may find
25 | the quality of the materials inferior to
26 | supported materials.
28 | This software is not a product of Hewlett-Packard, Co., or any
29 | other company. No support is implied or offered with this software.
30 | You've got the source, and you're on your own.
32 | This software may be distributed under the terms of Larry Wall's
33 | Artistic license, a copy of which is included in this distribution.
35 | This notice must be included with this software and any derivatives.
37 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
38 | All are rights reserved.
40 | $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $
44 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
45 "All rights are reserved."};
47 char * new_curse_name= "@(#) new_curse.c $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $";
49 #include "new_curse.h"
60 #include <sys/types.h>
64 #include <sys/select.h> /* on AIX */
67 #endif /* BSD_SELECT */
84 #include <sys/ioctl.h>
89 static WINDOW *virtual_scr;
91 WINDOW *last_window_refreshed;
97 #define min(a, b) (a < b ? a : b)
98 #define highbitset(a) ((a) & 0x80)
101 #define String_Out(table, stack, place) Info_Out(table, stack, place)
103 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
106 #define bw__ 0 /* booleans */
109 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
112 #define gn__ 6 /* generic type terminal */
113 #define hc__ 7 /* hardcopy terminal */
119 #define mi__ 13 /* safe to move during insert mode */
120 #define ms__ 14 /* safe to move during standout mode */
124 #define hz__ 18 /* hazeltine glitch */
133 #define co__ 0 /* number of columns */ /* numbers */
134 #define it__ 1 /* spaces per tab */
135 #define li__ 2 /* number of lines */
137 #define sg__ 4 /* magic cookie glitch */
151 #define bt__ 0 /* back tab */ /* strings */
152 #define bl__ 1 /* bell */
153 #define cr__ 2 /* carriage return */
154 #define cs__ 3 /* change scroll region */
155 #define ct__ 4 /* clear all tab stops */
156 #define cl__ 5 /* clear screen and home cursor */
157 #define ce__ 6 /* clear to end of line */
158 #define cd__ 7 /* clear to end of display */
159 #define ch__ 8 /* set cursor column */
160 #define CC__ 9 /* term, settable cmd char in */
161 #define cm__ 10 /* screen rel cursor motion, row, column */
162 #define do__ 11 /* down one line */
163 #define ho__ 12 /* home cursor */
164 #define vi__ 13 /* make cursor invisible */
165 #define le__ 14 /* move cursor left one space */
166 #define CM__ 15 /* memory rel cursor addressing */
167 #define ve__ 16 /* make cursor appear normal */
168 #define nd__ 17 /* non-destructive space (cursor right) */
169 #define ll__ 18 /* last line, first col */
170 #define up__ 19 /* cursor up */
172 #define dc__ 21 /* delete character */
173 #define dl__ 22 /* delete line */
178 #define md__ 27 /* turn on bold */
180 #define dm__ 29 /* turn on delete mode */
181 #define mh__ 30 /* half bright mode */
182 #define im__ 31 /* insert mode */
186 #define so__ 35 /* enter standout mode */
193 #define ei__ 42 /* exit insert mode */
194 #define se__ 43 /* exit standout mode */
206 #define kb__ 55 /* backspace key */
238 #define ku__ 87 /* key up */
282 #define sa__ 131 /* sgr */
428 char *Boolean_names[] = {
429 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
430 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
433 char *Number_names[] = {
434 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
437 char *String_names[] = {
438 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
439 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
440 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
441 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
442 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
443 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
444 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
445 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
446 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
447 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
448 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
449 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
450 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
451 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
452 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
453 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
454 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
455 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
456 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
457 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
458 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
459 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
460 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
461 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
462 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
466 char *new_curse = "October 1987";
468 char in_buff[100]; /* buffer for ungetch */
469 int bufp; /* next free position in in_buff */
471 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
473 int Data_Line_len = 0;
474 int Max_Key_len; /* max length of a sequence sent by a key */
475 char *Data_Line = NULL;
476 char *TERM_PATH = NULL;
477 char *TERM_data_ptr = NULL;
478 char *Term_File_name = NULL; /* name of file containing terminal description */
479 FILE *TFP; /* file pointer to file with terminal des. */
480 int Fildes; /* file descriptor for terminfo file */
481 int STAND = FALSE; /* is standout mode activated? */
482 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
483 int Time_Out; /* set when time elapsed while trying to read function key */
484 int Curr_x; /* current x position on screen */
485 int Curr_y; /* current y position on the screen */
488 int Move_It; /* flag to move cursor if magic cookie glitch */
489 int initialized = FALSE; /* tells whether new_curse is initialized */
491 float chars_per_millisecond;
492 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
493 int Intr; /* storeage for interrupt character */
494 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
495 int Noblock; /* for BSD systems */
496 int Num_bits; /* number of bits per character */
497 int Flip_Bytes; /* some systems have byte order reversed */
498 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
505 int length; /* length of string sent by key */
506 char *string; /* string sent by key */
507 int value; /* CURSES value of key (9-bit) */
511 struct KEYS *element;
512 struct KEY_STACK *next;
515 struct KEY_STACK *KEY_TOS = NULL;
516 struct KEY_STACK *KEY_POINT;
520 | Not all systems have good terminal information, so we will define
521 | keyboard information here for the most widely used terminal type,
526 struct KEYS vt100[] =
528 { 3, "\033[A", 0403 }, /* key up */
529 { 3, "\033[C", 0405 }, /* key right */
530 { 3, "\033[D", 0404 }, /* key left */
532 { 4, "\033[6~", 0522 }, /* key next page */
533 { 4, "\033[5~", 0523 }, /* key prev page */
534 { 3, "\033[[", 0550 }, /* key end */
535 { 3, "\033[@", 0406 }, /* key home */
536 { 4, "\033[2~", 0513 }, /* key insert char */
538 { 3, "\033[y", 0410 }, /* key F0 */
539 { 3, "\033[P", 0411 }, /* key F1 */
540 { 3, "\033[Q", 0412 }, /* key F2 */
541 { 3, "\033[R", 0413 }, /* key F3 */
542 { 3, "\033[S", 0414 }, /* key F4 */
543 { 3, "\033[t", 0415 }, /* key F5 */
544 { 3, "\033[u", 0416 }, /* key F6 */
545 { 3, "\033[v", 0417 }, /* key F7 */
546 { 3, "\033[l", 0420 }, /* key F8 */
547 { 3, "\033[w", 0421 }, /* key F9 */
548 { 3, "\033[x", 0422 }, /* key F10 */
550 { 5, "\033[10~", 0410 }, /* key F0 */
551 { 5, "\033[11~", 0411 }, /* key F1 */
552 { 5, "\033[12~", 0412 }, /* key F2 */
553 { 5, "\033[13~", 0413 }, /* key F3 */
554 { 5, "\033[14~", 0414 }, /* key F4 */
555 { 5, "\033[15~", 0415 }, /* key F5 */
556 { 5, "\033[17~", 0416 }, /* key F6 */
557 { 5, "\033[18~", 0417 }, /* key F7 */
558 { 5, "\033[19~", 0420 }, /* key F8 */
559 { 5, "\033[20~", 0421 }, /* key F9 */
560 { 5, "\033[21~", 0422 }, /* key F10 */
561 { 5, "\033[23~", 0423 }, /* key F11 */
562 { 5, "\033[24~", 0424 }, /* key F12 */
563 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
564 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
565 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
566 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
567 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
570 | The following are the same keys as above, but with
571 | a different character following the escape char.
574 { 3, "\033OA", 0403 }, /* key up */
575 { 3, "\033OC", 0405 }, /* key right */
576 { 3, "\033OD", 0404 }, /* key left */
577 { 3, "\033OB", 0402 }, /* key down */
578 { 4, "\033O6~", 0522 }, /* key next page */
579 { 4, "\033O5~", 0523 }, /* key prev page */
580 { 3, "\033O[", 0550 }, /* key end */
581 { 3, "\033O@", 0406 }, /* key home */
582 { 4, "\033O2~", 0513 }, /* key insert char */
584 { 3, "\033Oy", 0410 }, /* key F0 */
585 { 3, "\033OP", 0411 }, /* key F1 */
586 { 3, "\033OQ", 0412 }, /* key F2 */
587 { 3, "\033OR", 0413 }, /* key F3 */
588 { 3, "\033OS", 0414 }, /* key F4 */
589 { 3, "\033Ot", 0415 }, /* key F5 */
590 { 3, "\033Ou", 0416 }, /* key F6 */
591 { 3, "\033Ov", 0417 }, /* key F7 */
592 { 3, "\033Ol", 0420 }, /* key F8 */
593 { 3, "\033Ow", 0421 }, /* key F9 */
594 { 3, "\033Ox", 0422 }, /* key F10 */
596 { 5, "\033O10~", 0410 }, /* key F0 */
597 { 5, "\033O11~", 0411 }, /* key F1 */
598 { 5, "\033O12~", 0412 }, /* key F2 */
599 { 5, "\033O13~", 0413 }, /* key F3 */
600 { 5, "\033O14~", 0414 }, /* key F4 */
601 { 5, "\033O15~", 0415 }, /* key F5 */
602 { 5, "\033O17~", 0416 }, /* key F6 */
603 { 5, "\033O18~", 0417 }, /* key F7 */
604 { 5, "\033O19~", 0420 }, /* key F8 */
605 { 5, "\033O20~", 0421 }, /* key F9 */
606 { 5, "\033O21~", 0422 }, /* key F10 */
607 { 5, "\033O23~", 0423 }, /* key F11 */
608 { 5, "\033O24~", 0424 }, /* key F12 */
609 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
610 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
611 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
612 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
613 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
615 { 0, "", 0 } /* end */
620 struct Parameters *next;
624 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
625 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
626 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
627 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
628 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
629 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
630 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
631 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
632 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
633 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
634 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
635 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
636 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
639 int attributes_set[9];
641 static int nc_attributes = 0; /* global attributes for new_curse to observe */
644 struct termio Terminal;
645 struct termio Saved_tty;
647 struct sgttyb Terminal;
648 struct sgttyb Saved_tty;
655 char *String_table[1024];
659 static char nc_scrolling_ability = FALSE;
663 #if __STDC__ || defined(__cplusplus)
667 #endif /* __STDC__ */
669 int tc_Get_int P_((int));
670 void CAP_PARSE P_((void));
671 void Find_term P_((void));
680 extern char *fgets();
681 extern char *malloc();
682 extern char *getenv();
683 FILE *fopen(); /* declaration for open function */
684 #endif /* HAS_STDLIB */
685 #endif /* __STDC__ */
690 | Copy the contents of one window to another.
694 copy_window(WINDOW *origin, WINDOW *destination)
697 struct _line *orig, *dest;
699 orig = origin->first_line;
700 dest = destination->first_line;
703 row < (min(origin->Num_lines, destination->Num_lines));
707 column < (min(origin->Num_cols, destination->Num_cols));
710 dest->row[column] = orig->row[column];
711 dest->attributes[column] = orig->attributes[column];
713 dest->changed = orig->changed;
714 dest->scroll = orig->scroll;
715 dest->last_char = min(orig->last_char, destination->Num_cols);
716 orig = orig->next_screen;
717 dest = dest->next_screen;
719 destination->LX = min((destination->Num_cols - 1), origin->LX);
720 destination->LY = min((destination->Num_lines - 1), origin->LY);
721 destination->Attrib = origin->Attrib;
722 destination->scroll_up = origin->scroll_up;
723 destination->scroll_down = origin->scroll_down;
724 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
734 signal(SIGWINCH, reinitscr);
736 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
738 if (ws.ws_row == LINES && ws.ws_col == COLS)
745 #endif /* TIOCGWINSZ */
746 local_virt = newwin(LINES, COLS, 0, 0);
747 local_std = newwin(LINES, COLS, 0, 0);
748 local_cur = newwin(LINES, COLS, 0, 0);
749 copy_window(virtual_scr, local_virt);
750 copy_window(stdscr, local_std);
751 copy_window(curscr, local_cur);
755 virtual_scr = local_virt;
759 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
760 interrupt_flag = TRUE;
762 #endif /* SIGWINCH */
765 initscr(void) /* initialize terminal for operations */
769 char *columns_string;
775 printf("starting initscr \n");fflush(stdout);
781 #endif /* BSD_SELECT */
789 value = ioctl(0, TCGETA, &Terminal);
790 if (Terminal.c_cflag & PARENB)
792 if (Terminal.c_cflag & PARENB)
797 if ((Terminal.c_cflag & CS8) == CS8)
801 else if ((Terminal.c_cflag & CS7) == CS7)
803 else if ((Terminal.c_cflag & CS6) == CS6)
807 value = Terminal.c_cflag & 037;
809 case 01: speed = 50.0;
811 case 02: speed = 75.0;
813 case 03: speed = 110.0;
815 case 04: speed = 134.5;
817 case 05: speed = 150.0;
819 case 06: speed = 200.0;
821 case 07: speed = 300.0;
823 case 010: speed = 600.0;
825 case 011: speed = 900.0;
827 case 012: speed = 1200.0;
829 case 013: speed = 1800.0;
831 case 014: speed = 2400.0;
833 case 015: speed = 3600.0;
835 case 016: speed = 4800.0;
837 case 017: speed = 7200.0;
839 case 020: speed = 9600.0;
841 case 021: speed = 19200.0;
843 case 022: speed = 38400.0;
845 default: speed = 0.0;
848 value = ioctl(0, TIOCGETP, &Terminal);
849 if (Terminal.sg_flags & EVENP)
851 else if (Terminal.sg_flags & ODDP)
853 value = Terminal.sg_ospeed;
855 case 01: speed = 50.0;
857 case 02: speed = 75.0;
859 case 03: speed = 110.0;
861 case 04: speed = 134.5;
863 case 05: speed = 150.0;
865 case 06: speed = 200.0;
867 case 07: speed = 300.0;
869 case 010: speed = 600.0;
871 case 011: speed = 1200.0;
873 case 012: speed = 1800.0;
875 case 013: speed = 2400.0;
877 case 014: speed = 4800.0;
879 case 015: speed = 9600.0;
881 default: speed = 0.0;
884 chars_per_millisecond = (0.001 * speed) / 8.0;
885 TERMINAL_TYPE = getenv("TERM");
886 if (TERMINAL_TYPE == NULL)
888 printf("unknown terminal type\n");
893 TERM_PATH = getenv("TERMINFO");
894 if (TERM_PATH != NULL)
896 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
897 Term_File_name = malloc(Data_Line_len);
898 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
899 Fildes = open(Term_File_name, O_RDONLY);
903 TERM_PATH = "/usr/lib/terminfo";
904 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
905 Term_File_name = malloc(Data_Line_len);
906 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
907 Fildes = open(Term_File_name, O_RDONLY);
911 TERM_PATH = "/usr/share/lib/terminfo";
912 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
913 Term_File_name = malloc(Data_Line_len);
914 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
915 Fildes = open(Term_File_name, O_RDONLY);
919 TERM_PATH = "/usr/share/terminfo";
920 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
921 Term_File_name = malloc(Data_Line_len);
922 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
923 Fildes = open(Term_File_name, O_RDONLY);
927 free(Term_File_name);
928 Term_File_name = NULL;
931 TERM_INFO = INFO_PARSE();
934 | termcap information can be in the TERMCAP env variable, if so
935 | use that, otherwise check the /etc/termcap file
937 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
939 if (*Term_File_name != '/')
940 Term_File_name = "/etc/termcap";
944 Term_File_name = "/etc/termcap";
946 if ((TFP = fopen(Term_File_name, "r")) == NULL)
948 printf("unable to open /etc/termcap file \n");
951 for (value = 0; value < 1024; value++)
952 String_table[value] = NULL;
953 for (value = 0; value < 128; value++)
955 for (value = 0; value < 128; value++)
957 Data_Line = malloc(512);
958 if (pointer && *pointer != '/')
960 TERM_data_ptr = pointer;
969 if (String_table[pc__] == NULL)
970 String_table[pc__] = "\0";
971 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
973 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
978 LINES = Numbers[li__];
979 COLS = Numbers[co__];
980 if ((lines_string = getenv("LINES")) != NULL)
982 value = atoi(lines_string);
986 if ((columns_string = getenv("COLUMNS")) != NULL)
988 value = atoi(columns_string);
994 | get the window size
996 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1004 virtual_scr = newwin(LINES, COLS, 0, 0);
1005 stdscr = newwin(LINES, COLS, 0, 0);
1006 curscr = newwin(LINES, COLS, 0, 0);
1007 wmove(stdscr, 0, 0);
1009 Repaint_screen = TRUE;
1011 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1015 | reset size of windows and LINES and COLS if term window
1018 signal(SIGWINCH, reinitscr);
1019 #endif /* SIGWINCH */
1022 | check if scrolling is available
1025 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1026 (String_table[dl__])) || ((String_table[cs__])
1027 && (String_table[sr__]));
1033 Get_int(void) /* get a two-byte integer from the terminfo file */
1039 Low_byte = *((unsigned char *) TERM_data_ptr++);
1040 High_byte = *((unsigned char *) TERM_data_ptr++);
1044 Low_byte = High_byte;
1047 if ((High_byte == 255) && (Low_byte == 255))
1050 return(Low_byte + (High_byte * 256));
1054 INFO_PARSE(void) /* parse off the data in the terminfo data file */
1057 int magic_number = 0;
1062 int Num_strings = 0;
1063 int string_table_len = 0;
1066 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1067 Data_Line_len = read(Fildes, Data_Line, 10240);
1068 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1073 magic_number = Get_int();
1075 | if magic number not right, reverse byte order and check again
1077 if (magic_number != 282)
1082 magic_number = Get_int();
1083 if (magic_number != 282)
1087 | get the number of each type in the terminfo data file
1089 Num_names = Get_int();
1090 Num_bools = Get_int();
1091 Num_ints = Get_int();
1092 Num_strings = Get_int();
1093 string_table_len = Get_int();
1094 Strings = malloc(string_table_len);
1095 while (Num_names > 0)
1104 Booleans[counter++] = *TERM_data_ptr++;
1106 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1112 Numbers[counter] = Get_int();
1115 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1116 memcpy(Strings, temp_ptr, string_table_len);
1121 if ((offset=Get_int()) != -1)
1123 if (String_table[counter] == NULL)
1124 String_table[counter] = Strings + offset;
1127 String_table[counter] = NULL;
1134 #endif /* ifndef CAP */
1137 AtoI(void) /* convert ascii text to integers */
1142 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1144 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1151 Key_Get(void) /* create linked list with all key sequences obtained from terminal database */
1156 struct KEY_STACK *Spoint;
1161 while (key_def <= kf63__)
1163 if (key_def == ke__)
1165 else if (key_def == (K5__ + 1))
1167 else if (key_def == (kcbt__ + 1))
1169 else if (key_def == (kUND__ + 1))
1171 if (String_table[key_def] != NULL)
1173 if (KEY_TOS == NULL)
1174 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1178 while (Spoint->next != NULL)
1179 Spoint = Spoint->next;
1180 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1181 Spoint = Spoint->next;
1183 Spoint->next = NULL;
1184 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1185 Spoint->element->string = String_table[key_def];
1186 Spoint->element->length = strlen(String_table[key_def]);
1187 Spoint->element->value = Key_vals[Counter];
1188 Klen = strlen(Spoint->element->string);
1189 if (Klen > Max_Key_len)
1192 | Some terminal types accept keystrokes of the form
1193 | \E[A and \EOA, substituting '[' for 'O'. Make a
1194 | duplicate of such key strings (since the
1195 | database will only have one version) so new_curse
1196 | can understand both.
1198 if ((Spoint->element->length > 1) &&
1199 ((String_table[key_def][1] == '[') ||
1200 (String_table[key_def][1] == 'O')))
1202 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1203 Spoint = Spoint->next;
1204 Spoint->next = NULL;
1205 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1206 Spoint->element->length = strlen(String_table[key_def]);
1207 Spoint->element->string = malloc(Spoint->element->length + 1);
1208 strcpy(Spoint->element->string, String_table[key_def]);
1209 Spoint->element->value = Key_vals[Counter];
1210 Klen = strlen(Spoint->element->string);
1211 if (Klen > Max_Key_len)
1214 if (String_table[key_def][1] == '[')
1215 Spoint->element->string[1] = 'O';
1217 Spoint->element->string[1] = '[';
1226 | insert information about keys for a vt100 terminal
1234 struct KEY_STACK *Spoint;
1237 while (Spoint->next != NULL)
1238 Spoint = Spoint->next;
1239 for (counter = 0; vt100[counter].length != 0; counter++)
1241 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1242 Spoint = Spoint->next;
1243 Spoint->next = NULL;
1244 Spoint->element = &vt100[counter];
1245 Klen = strlen(Spoint->element->string);
1246 if (Klen > Max_Key_len)
1253 String_Get(char *param) /* read the string */
1261 while (*TERM_data_ptr != '=')
1263 Temp = ++TERM_data_ptr;
1265 while ((*Temp != ':') && (*Temp != (char)NULL))
1270 if (Counter == 1) /* no data */
1272 String = Temp = malloc(Counter);
1273 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1275 if (*TERM_data_ptr == '\\')
1278 if (*TERM_data_ptr == 'n')
1280 else if (*TERM_data_ptr == 't')
1282 else if (*TERM_data_ptr == 'b')
1284 else if (*TERM_data_ptr == 'r')
1286 else if (*TERM_data_ptr == 'f')
1288 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1289 *Temp = '\033'; /* escape */
1290 else if (*TERM_data_ptr == '\\')
1292 else if (*TERM_data_ptr == '\'')
1294 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1297 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1299 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1300 TERM_data_ptr++; /* ? */
1308 else if (*TERM_data_ptr == '^')
1311 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1312 *Temp = *TERM_data_ptr - '@';
1313 else if (*TERM_data_ptr == '?')
1319 *Temp++ = *TERM_data_ptr++;
1326 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1333 tc_Get_int(int param) /* read the integer */
1339 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1347 while (*TERM_data_ptr != ':')
1354 Find_term(void) /* find terminal description in termcap file */
1359 Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
1360 strcpy(Name, TERMINAL_TYPE);
1361 while (*Ftemp != (char)NULL)
1364 *Ftemp = (char)NULL;
1366 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1367 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1369 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1371 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1373 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1374 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1376 if (*TERM_data_ptr == '|')
1379 *TERM_data_ptr = (char)NULL;
1385 printf("terminal type %s not found\n", TERMINAL_TYPE);
1391 CAP_PARSE(void) /* parse off the data in the termcap data file */
1398 while (*TERM_data_ptr != (char)NULL)
1400 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1402 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1405 Booleans[offset] = TRUE;
1410 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1412 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1415 Numbers[offset] = tc_Get_int(Numbers[offset]);
1421 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1423 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1426 String_table[offset] = String_Get(String_table[offset]);
1431 if (!strncmp(TERM_data_ptr, "tc=", 3))
1432 tc_ = String_Get(NULL);
1433 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1435 if (*TERM_data_ptr == ':')
1438 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1441 TERMINAL_TYPE = tc_;
1451 #endif /* ifdef CAP */
1454 Screenalloc(int columns)
1459 tmp = (struct _line *) malloc(sizeof (struct _line));
1460 tmp->row = malloc(columns + 1);
1461 tmp->attributes = malloc(columns + 1);
1462 tmp->prev_screen = NULL;
1463 tmp->next_screen = NULL;
1464 for (i = 0; i < columns; i++)
1467 tmp->attributes[i] = (char) NULL;
1469 tmp->scroll = tmp->changed = FALSE;
1470 tmp->row[0] = (char) NULL;
1471 tmp->attributes[0] = (char) NULL;
1472 tmp->row[columns] = (char) NULL;
1473 tmp->attributes[columns] = (char) NULL;
1479 lines, cols: number of lines and columns to be in window
1480 start_l, start_c: starting line and column to be in window
1483 newwin(int lines, int cols, int start_l, int start_c)
1486 struct _line *temp_screen;
1489 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1490 Ntemp->SR = start_l;
1491 Ntemp->SC = start_c;
1492 Ntemp->Num_lines = lines;
1493 Ntemp->Num_cols = cols;
1496 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1497 Ntemp->SCROLL_CLEAR = FALSE;
1498 Ntemp->Attrib = FALSE;
1499 Ntemp->first_line = temp_screen = Screenalloc(cols);
1500 Ntemp->first_line->number = 0;
1501 for (i = 1; i < lines; i++)
1503 temp_screen->next_screen = Screenalloc(cols);
1504 temp_screen->next_screen->number = i;
1505 temp_screen->next_screen->prev_screen = temp_screen;
1506 temp_screen = temp_screen->next_screen;
1508 Ntemp->first_line->prev_screen = NULL;
1509 temp_screen->next_screen = NULL;
1515 p_list: stack of values
1516 place: place keeper of top of stack
1519 Cap_Out(char *string, int *p_list, int place)
1520 /* interpret the output string if necessary */
1522 char *Otemp; /* temporary string pointer to parse output */
1532 p1 = p_list[--place];
1533 p2 = p_list[--place];
1537 if ((*Otemp >= '0') && (*Otemp <= '9'))
1539 delay = atoi(Otemp);
1540 while ((*Otemp >= '0') && (*Otemp <= '9'))
1545 while (*Otemp != (char)NULL)
1550 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1554 else if (*Otemp == '2')
1556 else if (*Otemp == '3')
1558 else if (*Otemp == '+')
1564 else if (*Otemp == '.')
1569 else if (*Otemp == '>')
1580 else if (*Otemp == 'r')
1586 else if (*Otemp == 'i')
1591 else if (*Otemp == '%')
1593 else if (*Otemp == 'n')
1598 else if (*Otemp == 'B')
1600 p1 = (16 * (p1/10)) + (p1 % 10);
1601 p2 = (16 * (p2/10)) + (p2 % 10);
1603 else if (*Otemp == 'D')
1605 p1 = (p1 - 2 * (p1 % 16));
1606 p2 = (p2 - 2 * (p2 % 16));
1615 chars = delay * chars_per_millisecond;
1617 if ((chars - delay) > 0.0)
1619 for (; delay > 0; delay--)
1620 putchar(*String_table[pc__]);
1627 char *Otemp; /* temporary string pointer to parse output */
1633 Operation(int *Temp_Stack, int place) /* handle conditional operations */
1640 temp = Temp_Stack[--place];
1643 else if (!strncmp(Otemp, "2d", 2))
1645 temp = Temp_Stack[--place];
1646 printf("%2d", temp);
1650 else if (!strncmp(Otemp, "3d", 2))
1652 temp = Temp_Stack[--place];
1653 printf("%0d", temp);
1657 else if (!strncmp(Otemp, "02d", 3))
1659 temp = Temp_Stack[--place];
1660 printf("%02d", temp);
1665 else if (!strncmp(Otemp, "03d", 3))
1667 temp = Temp_Stack[--place];
1668 printf("%03d", temp);
1673 else if (*Otemp == '+')
1676 temp = Temp_Stack[--place];
1677 temp += Temp_Stack[--place];
1678 Temp_Stack[place++] = temp;
1680 else if (*Otemp == '-')
1683 temp = Temp_Stack[--place];
1684 temp -= Temp_Stack[--place];
1685 Temp_Stack[place++] = 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 == 'm')
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 == '|')
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 == Temp_Stack[--place]);
1734 Temp_Stack[place++] = temp;
1736 else if (*Otemp == '>')
1739 temp = Temp_Stack[--place];
1740 temp = 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 == 'c')
1753 putchar(Temp_Stack[--place]);
1755 else if (*Otemp == 'i')
1761 else if (*Otemp == '%')
1766 else if (*Otemp == '!')
1768 temp = ! Temp_Stack[--place];
1769 Temp_Stack[place++] = temp;
1772 else if (*Otemp == '~')
1774 temp = ~Temp_Stack[--place];
1775 Temp_Stack[place++] = temp;
1778 else if (*Otemp == 'p')
1781 Temp_Stack[place++] = p[*Otemp - '0'];
1784 else if (*Otemp == 'P')
1787 Temp_Stack[place++] = variable[*Otemp - 'a'];
1790 else if (*Otemp == 'g')
1793 variable[*Otemp - 'a'] = Temp_Stack[--place];
1796 else if (*Otemp == '\'')
1799 Temp_Stack[place++] = *Otemp;
1803 else if (*Otemp == '{')
1807 Temp_Stack[place++] = temp;
1808 while (*Otemp != '}')
1816 Info_Out(char *string, int *p_list, int place)
1817 /* interpret the output string if necessary */
1824 int Cond_Stack[128];
1847 for (temp = 1; (place != 0); temp++)
1849 p[temp] = p_list[--place];
1854 while (*Otemp != (char) NULL)
1859 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1869 | find the end of the
1870 | conditional statement
1872 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1878 Cond_place = Operation(Cond_Stack, Cond_place);
1882 | if condition is true
1884 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1894 else /* condition is false */
1897 | find 'else' or end
1900 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1903 | if an 'else' found
1905 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1911 | check for 'then' part
1913 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1918 if (*tchar == (char) NULL)
1925 | if end of if found,
1929 else if (!strncmp(tchar, "%;", 2))
1938 | if end of if found,
1942 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1948 else /* Otemp == NULL */
1962 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1964 if (*Otemp != (char) NULL)
1976 Top_of_stack = Operation(Stack, Top_of_stack);
1979 else if (!strncmp(Otemp, "$<", 2))
1983 delay = atoi(Otemp);
1984 while (*Otemp != '>')
1987 chars = delay * chars_per_millisecond;
1989 if ((chars - delay) > 0.0)
1991 if (String_table[pc__] == NULL)
1994 temp = *String_table[pc__];
1995 for (; delay > 0; delay--)
2009 wmove(WINDOW *window, int row, int column)
2010 /* move cursor to indicated position in window */
2012 if ((row < window->Num_lines) && (column < window->Num_cols))
2014 window->LX = column;
2020 clear_line(struct _line *line, int column, int cols)
2024 if (column > line->last_char)
2025 line->row[line->last_char] = ' ';
2026 line->last_char = column;
2027 line->row[column] = (char) NULL;
2028 line->attributes[column] = (char) NULL;
2029 line->changed = TRUE;
2030 for (j = column + 1; j < cols; j++)
2033 line->attributes[j] = (char) NULL;
2038 werase(WINDOW *window) /* clear the specified window */
2043 window->SCROLL_CLEAR = CLEAR;
2044 window->scroll_up = window->scroll_down = 0;
2045 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2046 clear_line(tmp, 0, window->Num_cols);
2050 wclrtoeol(WINDOW *window)
2051 /* erase from current cursor position to end of line */
2056 window->SCROLL_CLEAR = CHANGE;
2057 column = window->LX;
2059 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2060 tmp = tmp->next_screen;
2061 clear_line(tmp, column, window->Num_cols);
2065 wrefresh(WINDOW *window) /* flush all previous output */
2067 wnoutrefresh(window);
2072 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2073 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2075 if (temp->number == -1)
2076 fprintf(stderr, "line moved ");
2078 fprintf(stderr, "scroll_x is set: ");
2079 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2081 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2082 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2083 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2085 if (temp->number == -1)
2086 fprintf(stderr, "line moved ");
2088 fprintf(stderr, "scroll_x is set: ");
2089 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2091 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2092 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2093 fprintf(stderr, "line=%s|\n", temp->row);
2097 virtual_scr->SCROLL_CLEAR = FALSE;
2098 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2103 touchwin(WINDOW *window)
2105 struct _line *user_line;
2106 int line_counter = 0;
2108 for (line_counter = 0, user_line = window->first_line;
2109 line_counter < window->Num_lines; line_counter++)
2111 user_line->changed = TRUE;
2113 window->SCROLL_CLEAR = TRUE;
2117 wnoutrefresh(WINDOW *window)
2119 struct _line *user_line;
2120 struct _line *virtual_line;
2121 int line_counter = 0;
2125 if (window->SR >= virtual_scr->Num_lines)
2127 user_line = window->first_line;
2128 virtual_line = virtual_scr->first_line;
2129 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2130 virtual_scr->LX = window->LX + window->SC;
2131 virtual_scr->LY = window->LY + window->SR;
2132 virtual_scr->scroll_up = window->scroll_up;
2133 virtual_scr->scroll_down = window->scroll_down;
2134 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2136 for (line_counter = 0; line_counter < window->SR; line_counter++)
2138 virtual_line = virtual_line->next_screen;
2140 for (line_counter = 0; (line_counter < window->Num_lines)
2141 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2144 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2146 for (user_col = 0, virt_col = window->SC;
2147 (virt_col < virtual_scr->Num_cols)
2148 && (user_col < window->Num_cols);
2149 virt_col++, user_col++)
2151 virtual_line->row[virt_col] = user_line->row[user_col];
2152 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2155 if (virtual_scr->Num_cols != window->Num_cols)
2157 if (virtual_line->last_char < (user_line->last_char + window->SC))
2159 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2160 virtual_line->row[virtual_line->last_char] = ' ';
2161 virtual_line->last_char =
2162 min(virtual_scr->Num_cols,
2163 (user_line->last_char + window->SC));
2165 else if (virtual_line->last_char > (user_line->last_char + window->SC))
2167 virtual_line->row[min(virtual_scr->Num_cols,
2168 (user_line->last_char + window->SC))] = ' ';
2172 virtual_line->last_char = user_line->last_char;
2173 virtual_line->row[virtual_line->last_char] = (char) NULL;
2174 virtual_line->changed = user_line->changed;
2175 virtual_line = virtual_line->next_screen;
2176 user_line = user_line->next_screen;
2178 window->SCROLL_CLEAR = FALSE;
2179 window->scroll_up = window->scroll_down = 0;
2180 last_window_refreshed = window;
2184 flushinp(void) /* flush input */
2189 ungetch(int c) /* push a character back on input */
2192 in_buff[bufp++] = c;
2207 tv.tv_usec = 500000; /* half a second */
2209 Time_Out = FALSE; /* just in case */
2211 ret_val = select(nfds, &fds, 0, 0, &tv);
2214 | if ret_val is less than zero, there was no input
2215 | otherwise, get a character and return it
2224 return(read(0, &temp, 1)? temp : -1);
2229 wgetch(WINDOW *window) /* get character from specified window */
2239 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2241 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2242 #else /* BSD_SELECT */
2244 in_value = ((bufp > 0) ? in_buff[--bufp] :
2245 (read(0, &temp, 1)> 0) ? temp : -1);
2250 old_arg = fcntl(0, F_GETFL, 0);
2251 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2253 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2256 fcntl(0, F_SETFL, old_arg);
2261 #endif /* BSD_SELECT */
2266 if ((Parity) && (Num_bits < 8))
2267 /* strip eighth bit if parity in use */
2270 else if (interrupt_flag)
2272 interrupt_flag = FALSE;
2273 in_value = wgetch(window);
2276 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2277 in_value = Get_key(in_value);
2283 Clear(int arg) /* notify that time out has occurred */
2287 fprintf(stderr, "inside Clear()\n");
2291 #endif /* BSD_SELECT */
2293 /* first_char: first character of sequence */
2295 Get_key(int first_char) /* try to decode key sequence */
2303 struct termio Gterminal;
2305 struct sgttyb Gterminal;
2307 struct KEY_STACK *St_point;
2308 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2310 #endif /* BSD_SELECT */
2314 string[Count++] = first_char;
2315 string[Count] = (char) NULL;
2318 signal(SIGALRM, Clear);
2320 #endif /* BSD_SELECT */
2323 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2324 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2325 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2329 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2331 in_char = wgetch(stdscr);
2333 fprintf(stderr, "back in GetKey()\n");
2338 string[Count++] = in_char;
2339 string[Count] = (char) NULL;
2341 while ((St_point != NULL) && (!Found))
2343 if (!strcmp(string, St_point->element->string))
2346 St_point = St_point->next;
2353 #endif /* BSD_SELECT */
2355 /* value = ioctl(0, TCSETA, &Terminal);*/
2357 value = ioctl(0, TIOCSETP, &Terminal);
2358 /* value = fcntl(0, F_SETFL, old_arg);*/
2363 return(St_point->element->value);
2369 if ((string[--Count] != -1) &&
2370 ((unsigned char) (string[Count]) != 255))
2373 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2375 ungetch(string[Count]);
2383 waddch(WINDOW *window, int c) /* output the character in the specified window */
2386 int shift; /* number of spaces to shift if a tab */
2387 struct _line *tmpline;
2390 /*printf("starting waddch \n");fflush(stdout);*/
2393 column = window->LX;
2396 shift = (column + 1) % 8;
2404 waddch(window, ' ');
2407 else if ((column < window->Num_cols) && (row < window->Num_lines))
2409 if ((c == '~') && (Booleans[hz__]))
2412 if (( c != '\b') && (c != '\n') && (c != '\r'))
2415 tmpline = window->first_line;
2416 while (row < window->LY)
2419 tmpline = tmpline->next_screen;
2421 tmpline->row[column] = c;
2422 tmpline->attributes[column] = window->Attrib;
2423 tmpline->changed = TRUE;
2424 if (column >= tmpline->last_char)
2426 if (column > tmpline->last_char)
2427 tmpline->row[tmpline->last_char] = ' ';
2428 tmpline->row[column + 1] = (char) NULL;
2429 tmpline->attributes[column + 1] = (char) NULL;
2430 tmpline->last_char = column + 1;
2436 window->LX = window->Num_cols;
2445 if (window->LX >= window->Num_cols)
2449 if (window->LY >= window->Num_lines)
2451 window->LY = window->Num_lines - 1;
2452 /* window->LY = row;
2453 wmove(window, 0, 0);
2455 wmove(window, row, 0);*/
2458 window->SCROLL_CLEAR = CHANGE;
2462 winsertln(WINDOW *window) /* insert a blank line into the specified window */
2468 window->scroll_down += 1;
2469 window->SCROLL_CLEAR = SCROLL;
2470 column = window->LX;
2472 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2473 tmp = tmp->next_screen;
2474 if (tmp->prev_screen != NULL)
2475 tmp->prev_screen->next_screen = NULL;
2477 clear_line(tmp1, 0, window->Num_cols);
2479 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2480 tmp = tmp->next_screen;
2481 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2483 tmp1->next_screen = tmp->next_screen;
2484 tmp->next_screen = tmp1;
2485 tmp->changed = TRUE;
2486 tmp->next_screen->prev_screen = tmp;
2488 else if (window->Num_lines > 1)
2490 if (tmp->prev_screen != NULL)
2491 tmp->prev_screen->next_screen = tmp1;
2492 tmp1->prev_screen = tmp->prev_screen;
2493 tmp->prev_screen = tmp1;
2494 tmp1->next_screen = tmp;
2495 tmp->changed = TRUE;
2498 if (window->LY == 0)
2499 window->first_line = tmp1;
2503 wdeleteln(WINDOW *window) /* delete a line in the specified window */
2507 struct _line *tmpline;
2509 if (window->Num_lines > 1)
2511 window->scroll_up += 1;
2512 window->SCROLL_CLEAR = SCROLL;
2513 column = window->LX;
2515 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2516 tmp = tmp->next_screen;
2517 if (window->LY == 0)
2518 window->first_line = tmp->next_screen;
2519 if (tmp->prev_screen != NULL)
2520 tmp->prev_screen->next_screen = tmp->next_screen;
2521 if (tmp->next_screen != NULL)
2523 tmp->next_screen->changed = TRUE;
2524 tmp->next_screen->scroll = UP;
2525 tmp->next_screen->prev_screen = tmp->prev_screen;
2528 clear_line(tmpline, 0, window->Num_cols);
2529 tmpline->number = -1;
2530 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2531 tmp = tmp->next_screen;
2534 tmp->next_screen = tmpline;
2535 tmp->next_screen->prev_screen = tmp;
2536 tmp->changed = TRUE;
2537 tmp = tmp->next_screen;
2541 tmp->next_screen = NULL;
2545 clear_line(window->first_line, 0, window->Num_cols);
2550 wclrtobot(WINDOW *window)
2551 /* delete from current position to end of the window */
2556 window->SCROLL_CLEAR |= CLEAR;
2557 column = window->LX;
2559 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2560 tmp = tmp->next_screen;
2561 clear_line(tmp, column, window->Num_cols);
2562 for (row = (window->LY + 1); row < window->Num_lines; row++)
2564 tmp = tmp->next_screen;
2565 clear_line(tmp, 0, window->Num_cols);
2567 wmove(window, row, column);
2571 wstandout(WINDOW *window) /* begin standout mode in window */
2573 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2574 window->Attrib |= A_STANDOUT;
2578 wstandend(WINDOW *window) /* end standout mode in window */
2580 window->Attrib &= ~A_STANDOUT;
2584 waddstr(WINDOW *window, char *string) /* write 'string' in window */
2588 for (wstring = string; *wstring != (char) NULL; wstring++)
2589 waddch(window, *wstring);
2593 clearok(WINDOW *window, int flag) /* erase screen and redraw at next refresh */
2595 Repaint_screen = TRUE;
2600 echo(void) /* turn on echoing */
2605 Terminal.c_lflag |= ECHO; /* enable echo */
2606 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2608 Terminal.sg_flags |= ECHO; /* enable echo */
2609 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2614 noecho(void) /* turn off echoing */
2619 Terminal.c_lflag &= ~ECHO; /* disable echo */
2620 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2622 Terminal.sg_flags &= ~ECHO; /* disable echo */
2623 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2628 raw(void) /* set to read characters immediately */
2633 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2634 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2635 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2637 Terminal.c_lflag &= ~FLUSHO;
2640 Terminal.c_lflag &= ~PENDIN;
2643 Terminal.c_lflag &= ~IEXTEN;
2645 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2646 Terminal.c_cc[VTIME] = 255; /* timeout value */
2647 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2648 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2650 Terminal.sg_flags |= RAW; /* enable raw mode */
2651 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2656 noraw(void) /* set to normal character read mode */
2661 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2662 Terminal.c_lflag |= ISIG; /* enable signal checking */
2663 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2664 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2665 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2666 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2668 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2669 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2670 /* old_arg = fcntl(0, F_GETFL, 0);
2671 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2681 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2682 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2692 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2693 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2694 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2714 nodelay(WINDOW *window, int flag)
2719 idlok(WINDOW *window, int flag)
2724 keypad(WINDOW *window, int flag)
2727 String_Out(String_table[ks__], NULL, 0);
2729 String_Out(String_table[ke__], NULL, 0);
2733 savetty(void) /* save current tty stats */
2738 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2740 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2745 resetty(void) /* restore previous tty stats */
2750 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2752 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2757 endwin(void) /* end windows */
2759 keypad(stdscr, FALSE);
2760 initialized = FALSE;
2762 delwin(virtual_scr);
2767 /* old_arg = fcntl(0, F_GETFL, 0);
2768 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2774 delwin(WINDOW *window) /* delete the window structure */
2778 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2780 window->first_line = window->first_line->next_screen;
2781 free(window->first_line->prev_screen->row);
2782 free(window->first_line->prev_screen->attributes);
2783 free(window->first_line->prev_screen);
2785 if (window == last_window_refreshed)
2786 last_window_refreshed = NULL;
2787 if (window->first_line != NULL)
2789 free(window->first_line->row);
2790 free(window->first_line->attributes);
2791 free(window->first_line);
2797 wprintw(WINDOW *window, const char *format, ...)
2804 va_start(ap, format);
2806 fpoint = (char *) format;
2807 while (*fpoint != (char) NULL)
2814 value = va_arg(ap, int);
2815 iout(window, value);
2817 else if (*fpoint == 'c')
2819 value = va_arg(ap, int);
2820 waddch(window, value);
2822 else if (*fpoint == 's')
2824 wtemp = va_arg(ap, char *);
2825 waddstr(window, wtemp);
2829 else if (*fpoint == '\\')
2833 waddch(window, '\n');
2834 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2837 while ((*fpoint >= '0') && (*fpoint <= '9'))
2839 value = (value * 8) + (*fpoint - '0');
2842 waddch(window, value);
2847 waddch(window, *fpoint++);
2853 iout(WINDOW *window, int value) /* output characters */
2857 if ((i = value / 10) != 0)
2859 waddch(window, ((value % 10) + '0'));
2863 Comp_line(struct _line *line1, struct _line *line2) /* compare lines */
2872 att1 = line1->attributes;
2873 att2 = line2->attributes;
2874 count2 = strlen(c1) + 1;
2875 count1 = strlen(c2) + 1;
2876 if (count1 > count2)
2882 if (count2 > (count1 + count1))
2885 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2888 if ((count1 == 1) && (count2 == 1))
2889 count1 = 0; /* both lines blank */
2890 else if (count2 == count1)
2891 count1 = -1; /* equal */
2893 count1 = count2 / count1; /* lines unequal */
2898 Insert_line(int row, int end_row, WINDOW *window) /* insert line into screen */
2904 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2905 tmp = tmp->next_screen;
2906 if ((end_row + window->SR) == 0)
2907 curscr->first_line = curscr->first_line->next_screen;
2910 | find bottom line to delete
2912 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2913 tmp = tmp->next_screen;
2914 if (tmp->prev_screen != NULL)
2915 tmp->prev_screen->next_screen = tmp->next_screen;
2916 if (tmp->next_screen != NULL)
2917 tmp->next_screen->prev_screen = tmp->prev_screen;
2920 | clear deleted line
2922 clear_line(tmp, 0, window->Num_cols);
2924 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2925 tmp = tmp->next_screen;
2927 for (i = 0, tmp = top_of_win; i < row; i++)
2928 tmp = tmp->next_screen;
2929 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
2930 tmp->prev_screen->next_screen = tmp1;
2931 tmp1->prev_screen = tmp->prev_screen;
2932 tmp->prev_screen = tmp1;
2933 tmp1->next_screen = tmp;
2934 if ((row + window->SR) == 0)
2935 curscr->first_line = tmp1;
2936 if (tmp1->next_screen != NULL)
2937 tmp1 = tmp1->next_screen;
2939 if ((!String_table[cs__]) && (end_row < window->Num_lines))
2941 Position(window, (window->SR + end_row), 0);
2942 String_Out(String_table[dl__], NULL, 0);
2944 Position(window, (window->SR + row), 0);
2945 if (String_table[al__] != NULL)
2946 String_Out(String_table[al__], NULL, 0);
2948 String_Out(String_table[sr__], NULL, 0);
2950 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
2951 top_of_win = top_of_win->next_screen;
2957 Delete_line(int row, int end_row, struct _line *window)
2958 /* delete a line on screen */
2966 tmp = curscr->first_line;
2967 while (i < window->SR)
2970 tmp = tmp->next_screen;
2973 | find line to delete
2976 if ((row + window->SR) == 0)
2977 curscr->first_line = top_of_win->next_screen;
2978 for (i = 0, tmp = top_of_win; i < row; i++)
2979 tmp = tmp->next_screen;
2980 if (tmp->prev_screen != NULL)
2981 tmp->prev_screen->next_screen = tmp->next_screen;
2982 if (tmp->next_screen != NULL)
2983 tmp->next_screen->prev_screen = tmp->prev_screen;
2984 tmp2 = tmp->next_screen;
2987 | clear deleted line
2989 clear_line(tmp1, 0, window->Num_cols);
2992 | find location to insert deleted line
2994 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2995 tmp = tmp->next_screen;
2997 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
2998 tmp = tmp->next_screen;
2999 tmp1->next_screen = tmp;
3000 tmp1->prev_screen = tmp->prev_screen;
3001 if (tmp1->prev_screen != NULL)
3002 tmp1->prev_screen->next_screen = tmp1;
3003 tmp->prev_screen = tmp1;
3005 Position(window, (window->SR + row), 0);
3006 String_Out(String_table[dl__], NULL, 0);
3007 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3009 Position(window, (window->SR + end_row), 0);
3010 String_Out(String_table[al__], NULL, 0);
3012 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3014 Position(window, (window->SR + end_row), 0);
3018 if (row == (window->Num_lines-1))
3020 if ((row + window->SR) == 0)
3021 curscr->first_line = top_of_win = tmp2;
3026 CLEAR_TO_EOL(WINDOW *window, int row, int column)
3031 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3032 tmp1 = tmp1->next_screen;
3033 for (x = column; x<window->Num_cols; x++)
3036 tmp1->attributes[x] = (char) NULL;
3038 tmp1->row[column] = (char) NULL;
3039 tmp1->last_char = column;
3045 Position(window, row, column);
3048 if (String_table[ce__] != NULL)
3049 String_Out(String_table[ce__], NULL, 0);
3052 for (x = column; x < window->Num_cols; x++)
3060 check_delete(WINDOW *window, int line, int offset, struct _line *pointer_new,
3061 struct _line *pointer_old)
3073 new_lin = pointer_new->row;
3074 new_att = pointer_new->attributes;
3075 old_lin = pointer_old->row;
3076 old_att = pointer_old->attributes;
3077 end_old = end_new = offset;
3078 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))
3080 if (old_lin[end_old] != (char) NULL)
3083 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))
3085 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3087 if (new_lin[end_new+k] == (char) NULL)
3089 Position(window, line, (end_new+k));
3090 CLEAR_TO_EOL(window, line, (end_new+k));
3092 Position(window, line, offset);
3093 for (k = offset; k < end_old; k++)
3094 Char_del(old_lin, old_att, offset, window->Num_cols);
3095 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3097 pointer_old->last_char = offset;
3105 | Check if characters were inserted in the middle of a line, and if
3110 check_insert(WINDOW *window, int line, int offset, struct _line *pointer_new,
3111 struct _line *pointer_old)
3114 int end_old, end_new;
3125 new_lin = pointer_new->row;
3126 new_att = pointer_new->attributes;
3127 old_lin = pointer_old->row;
3128 old_att = pointer_old->attributes;
3129 end_old = end_new = offset;
3130 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))
3132 if (new_lin[end_new] != (char) NULL)
3135 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))
3138 | check for commonality between rest of lines (are the old
3139 | and new lines the same, except for a chunk in the middle?)
3140 | if the rest of the lines are common, do not insert text
3143 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]))
3145 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3147 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3149 Position(window, line, offset);
3151 if (String_table[ic__] == NULL)
3153 String_Out(String_table[im__], NULL, 0);
3156 for (k = offset; k < end_new; k++)
3159 String_Out(String_table[ic__], NULL, 0);
3160 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3163 String_Out(String_table[ei__], NULL, 0);
3164 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3166 pointer_old->last_char = offset;
3179 int begin_old, begin_new;
3180 int end_old, end_new;
3182 int from_top, tmp_ft, offset;
3202 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3204 window = virtual_scr;
3206 if ((nc_attributes & A_NC_BIG5) != 0)
3211 if (String_table[cl__])
3212 String_Out(String_table[cl__], NULL, 0);
3216 while (from_top < LINES)
3218 Position(curscr, from_top, 0);
3219 if (String_table[ce__] != NULL)
3220 String_Out(String_table[ce__], NULL, 0);
3223 for (j = 0; j < window->Num_cols; j++)
3229 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3231 Position(curscr, from_top, 0);
3232 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3234 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3239 Position(curscr, from_top, j);
3243 Repaint_screen = FALSE;
3248 top_of_win = curscr->first_line;
3250 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3251 from_top < window->Num_lines; from_top++)
3253 virtual_lines[from_top] = TRUE;
3254 if ((similar = Comp_line(curr, virt)) > 0)
3256 virtual_lines[from_top] = FALSE;
3259 curr = curr->next_screen;
3260 virt = virt->next_screen;
3264 virt = window->first_line;
3268 | if the window has lines that are different, check for scrolling
3274 for (first_same = window->Num_lines;
3275 (first_same > from_top) && (virtual_lines[first_same - 1]);
3278 count1 = first_same - 1;
3280 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3283 while ((from_top < first_same) && nc_scrolling_ability)
3284 /* check entire lines for diffs */
3288 if (from_top >= last_same)
3290 for (last_same = from_top;
3291 (last_same < window->Num_lines) &&
3292 (virtual_lines[last_same] == FALSE);
3296 if (!virtual_lines[from_top])
3300 | check for lines deleted (scroll up)
3302 for (tmp_ft = from_top+1, old = curr->next_screen;
3303 ((window->scroll_up) && (diff) &&
3304 (tmp_ft < last_same) &&
3305 (!virtual_lines[tmp_ft]));
3308 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3310 if (String_table[cs__]) /* scrolling region */
3313 list[0] = min((last_same - 1), (window->Num_lines - 1));
3314 String_Out(String_table[cs__], list, 2);
3315 Curr_y = Curr_x = -1;
3318 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3320 old = Delete_line(from_top, min((last_same - 1), (window->Num_lines - 1)), window);
3324 if (String_table[cs__]) /* scrolling region */
3327 list[0] = LINES - 1;
3328 String_Out(String_table[cs__], list, 2);
3329 Curr_y = Curr_x = -1;
3332 top_of_win = curscr->first_line;
3334 for (offset = 0; offset < from_top; offset++)
3335 curr = curr->next_screen;
3336 for (offset = from_top, old=curr, new=virt;
3337 offset < window->Num_lines;
3338 old=old->next_screen, new=new->next_screen,
3341 similar = Comp_line(old, new);
3342 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3346 old = old->next_screen;
3349 | check for lines inserted (scroll down)
3351 for (tmp_ft = from_top-1, old = curr->prev_screen;
3352 ((window->scroll_down) && (tmp_ft >= 0) &&
3354 (!virtual_lines[tmp_ft]));
3357 if (Comp_line(old, virt) == -1)
3359 if (String_table[cs__]) /* scrolling region */
3362 list[0] = min((last_same - 1), (window->Num_lines - 1));
3363 String_Out(String_table[cs__], list, 2);
3364 Curr_y = Curr_x = -1;
3367 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3369 old = Insert_line(tmp_ft, min((last_same - 1), (window->Num_lines -1)), window);
3373 if (String_table[cs__]) /* scrolling region */
3376 list[0] = LINES - 1;
3377 String_Out(String_table[cs__], list, 2);
3378 Curr_y = Curr_x = -1;
3381 top_of_win = curscr->first_line;
3383 for (offset = 0; offset < from_top; offset++)
3384 curr = curr->next_screen;
3385 for (offset = from_top, old=curr, new=virt;
3386 offset < window->Num_lines;
3387 old=old->next_screen, new=new->next_screen,
3390 similar = Comp_line(old, new);
3391 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3395 old = old->prev_screen;
3399 curr = curr->next_screen;
3400 virt = virt->next_screen;
3406 | Scrolling done, now need to insert, delete, or modify text
3410 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3411 curr = curr->next_screen;
3413 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)
3417 | If either 'insert mode' or 'insert char' are
3418 | available, enter the following 'if' statement,
3419 | else, need to simply rewrite the contents of the line
3420 | at the point where the contents of the line change.
3423 if (((String_table[ic__]) || (String_table[im__])) &&
3424 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3429 vrt_lin = virt->row;
3430 vrt_att = virt->attributes;
3431 cur_lin = curr->row;
3432 cur_att = curr->attributes;
3433 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3435 if ((STAND) && (Booleans[xs__]))
3437 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3439 if ((STAND) && (!vrt_att[j]))
3442 Position(window, from_top, j);
3449 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3452 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3454 Position(window, from_top, j);
3455 /* CLEAR_TO_EOL(window, from_top, j);*/
3459 if (vrt_lin[j] != (char) NULL)
3465 if ((first_time) && (virt->changed))
3467 if (curr->last_char <= virt->last_char)
3468 changed = check_insert(window, from_top, j, virt, curr);
3470 changed = check_delete(window, from_top, j, virt, curr);
3472 virt->changed = FALSE;
3474 changed = check_insert(window, from_top, j, virt, curr);
3475 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3477 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3481 Position(window, from_top, j);
3482 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3485 if ((vrt_lin[j] != (char) NULL))
3488 if ((STAND) && (!vrt_att[j]))
3491 Position(window, from_top, j);
3495 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3497 Position(window, from_top, j);
3498 CLEAR_TO_EOL(window, from_top, j);
3501 else /*if ((similar != -1) && (similar != 0))*/
3505 att1 = curr->attributes;
3507 att2 = virt->attributes;
3508 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3510 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3514 | if previous character is an eight bit
3515 | char, start redraw from that character
3518 if ((NC_chinese) && (highbitset(c1[j - 1])))
3522 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3524 Position(window, from_top, begin_old);
3525 CLEAR_TO_EOL(window, from_top, j);
3526 Position(window, from_top, begin_old);
3527 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3528 Char_out(c2[j], att2[j], c1, att1, j);
3531 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3533 Position(window, from_top, j);
3534 CLEAR_TO_EOL(window, from_top, j);
3540 Position(window, from_top, j);
3543 virt->number = from_top;
3545 Position(window, window->LY, window->LX);
3549 Position(WINDOW *window, int row, int col)
3550 /* position the cursor for output on the screen */
3558 pos_row = row + window->SR;
3559 pos_column = col + window->SC;
3560 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3562 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3565 list[place++] = pos_column;
3566 list[place++] = pos_row;
3567 String_Out(String_table[cm__], list, place);
3568 if ((STAND) && (!Booleans[ms__]))
3571 Curr_x = pos_column;
3577 Char_del(char *line, char *attrib, int offset, int maxlen)
3578 /* delete chars from line */
3582 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3584 line[one] = line[two];
3585 attrib[one] = attrib[two];
3587 String_Out(String_table[dc__], NULL, 0);
3591 Char_ins(char *line, char *attrib, char newc, char newatt, int offset,
3592 int maxlen) /* insert chars in line */
3597 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3599 for (two = one + 1; (two > offset); one--, two--)
3601 line[two] = line[one];
3602 attrib[two] = attrib[one];
3604 line[offset] = newc;
3605 attrib[offset] = newatt;
3606 Char_out(newc, newatt, line, attrib, offset);
3612 if (String_table[sa__])
3614 attributes_set[0] = 1;
3615 String_Out(String_table[sa__], attributes_set, 1);
3617 else if (String_table[so__])
3618 String_Out(String_table[so__], NULL, 0);
3624 if (String_table[me__])
3625 String_Out(String_table[me__], NULL, 0);
3626 else if (String_table[sa__])
3628 attributes_set[0] = 0;
3629 String_Out(String_table[sa__], attributes_set, 1);
3631 else if (String_table[se__])
3632 String_Out(String_table[se__], NULL, 0);
3636 Char_out(char newc, char newatt, char *line, char *attrib, int offset)
3637 /* output character with proper attribute */
3641 if ((newatt) && (!STAND))
3646 else if ((STAND) && (!newatt))
3652 if ((newatt) && (STAND) && (Booleans[xs__]))
3657 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3660 line[offset] = newc;
3661 attrib[offset] = newatt;
3668 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3669 | hacks that notify new_curse to handle characters that have the high
3670 | bit set as the first of two bytes of a multi-byte string.
3675 nc_setattrib(int flag)
3677 nc_attributes |= flag;
3681 nc_clearattrib(int flag)
3683 nc_attributes &= ~flag;