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.49 1998/12/21 02:25:59 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 #include <sys/cdefs.h>
48 __FBSDID("$FreeBSD$");
50 #include "new_curse.h"
61 #include <sys/types.h>
65 #include <sys/select.h> /* on AIX */
68 #endif /* BSD_SELECT */
81 #include <sys/ioctl.h>
86 static WINDOW *virtual_scr;
88 WINDOW *last_window_refreshed;
94 #define min(a, b) (a < b ? a : b)
95 #define highbitset(a) ((a) & 0x80)
98 #define String_Out(table, stack, place) Info_Out(table, stack, place)
100 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
103 #define bw__ 0 /* booleans */
106 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
109 #define gn__ 6 /* generic type terminal */
110 #define hc__ 7 /* hardcopy terminal */
116 #define mi__ 13 /* safe to move during insert mode */
117 #define ms__ 14 /* safe to move during standout mode */
121 #define hz__ 18 /* hazeltine glitch */
130 #define co__ 0 /* number of columns */ /* numbers */
131 #define it__ 1 /* spaces per tab */
132 #define li__ 2 /* number of lines */
134 #define sg__ 4 /* magic cookie glitch */
148 #define bt__ 0 /* back tab */ /* strings */
149 #define bl__ 1 /* bell */
150 #define cr__ 2 /* carriage return */
151 #define cs__ 3 /* change scroll region */
152 #define ct__ 4 /* clear all tab stops */
153 #define cl__ 5 /* clear screen and home cursor */
154 #define ce__ 6 /* clear to end of line */
155 #define cd__ 7 /* clear to end of display */
156 #define ch__ 8 /* set cursor column */
157 #define CC__ 9 /* term, settable cmd char in */
158 #define cm__ 10 /* screen rel cursor motion, row, column */
159 #define do__ 11 /* down one line */
160 #define ho__ 12 /* home cursor */
161 #define vi__ 13 /* make cursor invisible */
162 #define le__ 14 /* move cursor left one space */
163 #define CM__ 15 /* memory rel cursor addressing */
164 #define ve__ 16 /* make cursor appear normal */
165 #define nd__ 17 /* non-destructive space (cursor right) */
166 #define ll__ 18 /* last line, first col */
167 #define up__ 19 /* cursor up */
169 #define dc__ 21 /* delete character */
170 #define dl__ 22 /* delete line */
175 #define md__ 27 /* turn on bold */
177 #define dm__ 29 /* turn on delete mode */
178 #define mh__ 30 /* half bright mode */
179 #define im__ 31 /* insert mode */
183 #define so__ 35 /* enter standout mode */
190 #define ei__ 42 /* exit insert mode */
191 #define se__ 43 /* exit standout mode */
203 #define kb__ 55 /* backspace key */
235 #define ku__ 87 /* key up */
279 #define sa__ 131 /* sgr */
425 char *Boolean_names[] = {
426 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
427 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
430 char *Number_names[] = {
431 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
434 char *String_names[] = {
435 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
436 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
437 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
438 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
439 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
440 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
441 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
442 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
443 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
444 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
445 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
446 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
447 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
448 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
449 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
450 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
451 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
452 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
453 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
454 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
455 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
456 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
457 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
458 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
459 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
463 char *new_curse = "October 1987";
465 char in_buff[100]; /* buffer for ungetch */
466 int bufp; /* next free position in in_buff */
468 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
470 int Data_Line_len = 0;
471 int Max_Key_len; /* max length of a sequence sent by a key */
472 char *Data_Line = NULL;
473 char *TERM_PATH = NULL;
474 char *TERM_data_ptr = NULL;
475 char *Term_File_name = NULL; /* name of file containing terminal description */
476 FILE *TFP; /* file pointer to file with terminal des. */
477 int Fildes; /* file descriptor for terminfo file */
478 int STAND = FALSE; /* is standout mode activated? */
479 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
480 int Time_Out; /* set when time elapsed while trying to read function key */
481 int Curr_x; /* current x position on screen */
482 int Curr_y; /* current y position on the screen */
485 int Move_It; /* flag to move cursor if magic cookie glitch */
486 int initialized = FALSE; /* tells whether new_curse is initialized */
488 float chars_per_millisecond;
489 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
490 int Intr; /* storeage for interrupt character */
491 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
492 int Noblock; /* for BSD systems */
493 int Num_bits; /* number of bits per character */
494 int Flip_Bytes; /* some systems have byte order reversed */
495 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
502 int length; /* length of string sent by key */
503 char *string; /* string sent by key */
504 int value; /* CURSES value of key (9-bit) */
508 struct KEYS *element;
509 struct KEY_STACK *next;
512 struct KEY_STACK *KEY_TOS = NULL;
513 struct KEY_STACK *KEY_POINT;
517 | Not all systems have good terminal information, so we will define
518 | keyboard information here for the most widely used terminal type,
523 struct KEYS vt100[] =
525 { 3, "\033[A", 0403 }, /* key up */
526 { 3, "\033[C", 0405 }, /* key right */
527 { 3, "\033[D", 0404 }, /* key left */
529 { 4, "\033[6~", 0522 }, /* key next page */
530 { 4, "\033[5~", 0523 }, /* key prev page */
531 { 3, "\033[[", 0550 }, /* key end */
532 { 3, "\033[@", 0406 }, /* key home */
533 { 4, "\033[2~", 0513 }, /* key insert char */
535 { 3, "\033[y", 0410 }, /* key F0 */
536 { 3, "\033[P", 0411 }, /* key F1 */
537 { 3, "\033[Q", 0412 }, /* key F2 */
538 { 3, "\033[R", 0413 }, /* key F3 */
539 { 3, "\033[S", 0414 }, /* key F4 */
540 { 3, "\033[t", 0415 }, /* key F5 */
541 { 3, "\033[u", 0416 }, /* key F6 */
542 { 3, "\033[v", 0417 }, /* key F7 */
543 { 3, "\033[l", 0420 }, /* key F8 */
544 { 3, "\033[w", 0421 }, /* key F9 */
545 { 3, "\033[x", 0422 }, /* key F10 */
547 { 5, "\033[10~", 0410 }, /* key F0 */
548 { 5, "\033[11~", 0411 }, /* key F1 */
549 { 5, "\033[12~", 0412 }, /* key F2 */
550 { 5, "\033[13~", 0413 }, /* key F3 */
551 { 5, "\033[14~", 0414 }, /* key F4 */
552 { 5, "\033[15~", 0415 }, /* key F5 */
553 { 5, "\033[17~", 0416 }, /* key F6 */
554 { 5, "\033[18~", 0417 }, /* key F7 */
555 { 5, "\033[19~", 0420 }, /* key F8 */
556 { 5, "\033[20~", 0421 }, /* key F9 */
557 { 5, "\033[21~", 0422 }, /* key F10 */
558 { 5, "\033[23~", 0423 }, /* key F11 */
559 { 5, "\033[24~", 0424 }, /* key F12 */
560 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
561 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
562 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
563 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
564 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
567 | The following are the same keys as above, but with
568 | a different character following the escape char.
571 { 3, "\033OA", 0403 }, /* key up */
572 { 3, "\033OC", 0405 }, /* key right */
573 { 3, "\033OD", 0404 }, /* key left */
574 { 3, "\033OB", 0402 }, /* key down */
575 { 4, "\033O6~", 0522 }, /* key next page */
576 { 4, "\033O5~", 0523 }, /* key prev page */
577 { 3, "\033O[", 0550 }, /* key end */
578 { 3, "\033O@", 0406 }, /* key home */
579 { 4, "\033O2~", 0513 }, /* key insert char */
581 { 3, "\033Oy", 0410 }, /* key F0 */
582 { 3, "\033OP", 0411 }, /* key F1 */
583 { 3, "\033OQ", 0412 }, /* key F2 */
584 { 3, "\033OR", 0413 }, /* key F3 */
585 { 3, "\033OS", 0414 }, /* key F4 */
586 { 3, "\033Ot", 0415 }, /* key F5 */
587 { 3, "\033Ou", 0416 }, /* key F6 */
588 { 3, "\033Ov", 0417 }, /* key F7 */
589 { 3, "\033Ol", 0420 }, /* key F8 */
590 { 3, "\033Ow", 0421 }, /* key F9 */
591 { 3, "\033Ox", 0422 }, /* key F10 */
593 { 5, "\033O10~", 0410 }, /* key F0 */
594 { 5, "\033O11~", 0411 }, /* key F1 */
595 { 5, "\033O12~", 0412 }, /* key F2 */
596 { 5, "\033O13~", 0413 }, /* key F3 */
597 { 5, "\033O14~", 0414 }, /* key F4 */
598 { 5, "\033O15~", 0415 }, /* key F5 */
599 { 5, "\033O17~", 0416 }, /* key F6 */
600 { 5, "\033O18~", 0417 }, /* key F7 */
601 { 5, "\033O19~", 0420 }, /* key F8 */
602 { 5, "\033O20~", 0421 }, /* key F9 */
603 { 5, "\033O21~", 0422 }, /* key F10 */
604 { 5, "\033O23~", 0423 }, /* key F11 */
605 { 5, "\033O24~", 0424 }, /* key F12 */
606 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
607 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
608 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
609 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
610 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
612 { 0, "", 0 } /* end */
617 struct Parameters *next;
621 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
622 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
623 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
624 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
625 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
626 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
627 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
628 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
629 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
630 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
631 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
632 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
633 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
636 int attributes_set[9];
638 static int nc_attributes = 0; /* global attributes for new_curse to observe */
641 struct termio Terminal;
642 struct termio Saved_tty;
644 struct sgttyb Terminal;
645 struct sgttyb Saved_tty;
652 char *String_table[1024];
656 static char nc_scrolling_ability = FALSE;
661 void CAP_PARSE(void);
662 void Find_term(void);
670 | Copy the contents of one window to another.
674 copy_window(origin, destination)
675 WINDOW *origin, *destination;
678 struct _line *orig, *dest;
680 orig = origin->first_line;
681 dest = destination->first_line;
684 row < (min(origin->Num_lines, destination->Num_lines));
688 column < (min(origin->Num_cols, destination->Num_cols));
691 dest->row[column] = orig->row[column];
692 dest->attributes[column] = orig->attributes[column];
694 dest->changed = orig->changed;
695 dest->scroll = orig->scroll;
696 dest->last_char = min(orig->last_char, destination->Num_cols);
697 orig = orig->next_screen;
698 dest = dest->next_screen;
700 destination->LX = min((destination->Num_cols - 1), origin->LX);
701 destination->LY = min((destination->Num_lines - 1), origin->LY);
702 destination->Attrib = origin->Attrib;
703 destination->scroll_up = origin->scroll_up;
704 destination->scroll_down = origin->scroll_down;
705 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
716 signal(SIGWINCH, reinitscr);
718 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
720 if (ws.ws_row == LINES && ws.ws_col == COLS)
727 #endif /* TIOCGWINSZ */
728 local_virt = newwin(LINES, COLS, 0, 0);
729 local_std = newwin(LINES, COLS, 0, 0);
730 local_cur = newwin(LINES, COLS, 0, 0);
731 copy_window(virtual_scr, local_virt);
732 copy_window(stdscr, local_std);
733 copy_window(curscr, local_cur);
737 virtual_scr = local_virt;
741 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
742 interrupt_flag = TRUE;
744 #endif /* SIGWINCH */
747 initscr() /* initialize terminal for operations */
751 char *columns_string;
757 printf("starting initscr \n");fflush(stdout);
763 #endif /* BSD_SELECT */
771 value = ioctl(0, TCGETA, &Terminal);
772 if (Terminal.c_cflag & PARENB)
774 if (Terminal.c_cflag & PARENB)
779 if ((Terminal.c_cflag & CS8) == CS8)
783 else if ((Terminal.c_cflag & CS7) == CS7)
785 else if ((Terminal.c_cflag & CS6) == CS6)
789 value = Terminal.c_cflag & 037;
791 case 01: speed = 50.0;
793 case 02: speed = 75.0;
795 case 03: speed = 110.0;
797 case 04: speed = 134.5;
799 case 05: speed = 150.0;
801 case 06: speed = 200.0;
803 case 07: speed = 300.0;
805 case 010: speed = 600.0;
807 case 011: speed = 900.0;
809 case 012: speed = 1200.0;
811 case 013: speed = 1800.0;
813 case 014: speed = 2400.0;
815 case 015: speed = 3600.0;
817 case 016: speed = 4800.0;
819 case 017: speed = 7200.0;
821 case 020: speed = 9600.0;
823 case 021: speed = 19200.0;
825 case 022: speed = 38400.0;
827 default: speed = 0.0;
830 value = ioctl(0, TIOCGETP, &Terminal);
831 if (Terminal.sg_flags & EVENP)
833 else if (Terminal.sg_flags & ODDP)
835 value = Terminal.sg_ospeed;
837 case 01: speed = 50.0;
839 case 02: speed = 75.0;
841 case 03: speed = 110.0;
843 case 04: speed = 134.5;
845 case 05: speed = 150.0;
847 case 06: speed = 200.0;
849 case 07: speed = 300.0;
851 case 010: speed = 600.0;
853 case 011: speed = 1200.0;
855 case 012: speed = 1800.0;
857 case 013: speed = 2400.0;
859 case 014: speed = 4800.0;
861 case 015: speed = 9600.0;
863 default: speed = 0.0;
866 chars_per_millisecond = (0.001 * speed) / 8.0;
867 TERMINAL_TYPE = getenv("TERM");
868 if (TERMINAL_TYPE == NULL)
870 printf("unknown terminal type\n");
875 TERM_PATH = getenv("TERMINFO");
876 if (TERM_PATH != NULL)
878 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
879 Term_File_name = malloc(Data_Line_len);
880 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
881 Fildes = open(Term_File_name, O_RDONLY);
885 TERM_PATH = "/usr/lib/terminfo";
886 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
887 Term_File_name = malloc(Data_Line_len);
888 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
889 Fildes = open(Term_File_name, O_RDONLY);
893 TERM_PATH = "/usr/share/lib/terminfo";
894 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
895 Term_File_name = malloc(Data_Line_len);
896 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
897 Fildes = open(Term_File_name, O_RDONLY);
901 TERM_PATH = "/usr/share/terminfo";
902 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
903 Term_File_name = malloc(Data_Line_len);
904 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
905 Fildes = open(Term_File_name, O_RDONLY);
909 free(Term_File_name);
910 Term_File_name = NULL;
913 TERM_INFO = INFO_PARSE();
916 | termcap information can be in the TERMCAP env variable, if so
917 | use that, otherwise check the /etc/termcap file
919 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
921 if (*Term_File_name != '/')
922 Term_File_name = "/etc/termcap";
926 Term_File_name = "/etc/termcap";
928 if ((TFP = fopen(Term_File_name, "r")) == NULL)
930 printf("unable to open /etc/termcap file \n");
933 for (value = 0; value < 1024; value++)
934 String_table[value] = NULL;
935 for (value = 0; value < 128; value++)
937 for (value = 0; value < 128; value++)
939 Data_Line = malloc(512);
940 if (pointer && *pointer != '/')
942 TERM_data_ptr = pointer;
951 if (String_table[pc__] == NULL)
952 String_table[pc__] = "\0";
953 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
955 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
960 LINES = Numbers[li__];
961 COLS = Numbers[co__];
962 if ((lines_string = getenv("LINES")) != NULL)
964 value = atoi(lines_string);
968 if ((columns_string = getenv("COLUMNS")) != NULL)
970 value = atoi(columns_string);
976 | get the window size
978 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
986 virtual_scr = newwin(LINES, COLS, 0, 0);
987 stdscr = newwin(LINES, COLS, 0, 0);
988 curscr = newwin(LINES, COLS, 0, 0);
991 Repaint_screen = TRUE;
993 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
997 | reset size of windows and LINES and COLS if term window
1000 signal(SIGWINCH, reinitscr);
1001 #endif /* SIGWINCH */
1004 | check if scrolling is available
1007 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1008 (String_table[dl__])) || ((String_table[cs__])
1009 && (String_table[sr__]));
1015 Get_int() /* get a two-byte integer from the terminfo file */
1021 Low_byte = *((unsigned char *) TERM_data_ptr++);
1022 High_byte = *((unsigned char *) TERM_data_ptr++);
1026 Low_byte = High_byte;
1029 if ((High_byte == 255) && (Low_byte == 255))
1032 return(Low_byte + (High_byte * 256));
1036 INFO_PARSE() /* parse off the data in the terminfo data file */
1039 int magic_number = 0;
1044 int Num_strings = 0;
1045 int string_table_len = 0;
1048 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1049 Data_Line_len = read(Fildes, Data_Line, 10240);
1050 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1055 magic_number = Get_int();
1057 | if magic number not right, reverse byte order and check again
1059 if (magic_number != 282)
1064 magic_number = Get_int();
1065 if (magic_number != 282)
1069 | get the number of each type in the terminfo data file
1071 Num_names = Get_int();
1072 Num_bools = Get_int();
1073 Num_ints = Get_int();
1074 Num_strings = Get_int();
1075 string_table_len = Get_int();
1076 Strings = malloc(string_table_len);
1077 while (Num_names > 0)
1086 Booleans[counter++] = *TERM_data_ptr++;
1088 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1094 Numbers[counter] = Get_int();
1097 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1098 memcpy(Strings, temp_ptr, string_table_len);
1103 if ((offset=Get_int()) != -1)
1105 if (String_table[counter] == NULL)
1106 String_table[counter] = Strings + offset;
1109 String_table[counter] = NULL;
1116 #endif /* ifndef CAP */
1119 AtoI() /* convert ascii text to integers */
1124 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1126 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1133 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1138 struct KEY_STACK *Spoint;
1143 while (key_def <= kf63__)
1145 if (key_def == ke__)
1147 else if (key_def == (K5__ + 1))
1149 else if (key_def == (kcbt__ + 1))
1151 else if (key_def == (kUND__ + 1))
1153 if (String_table[key_def] != NULL)
1155 if (KEY_TOS == NULL)
1156 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1160 while (Spoint->next != NULL)
1161 Spoint = Spoint->next;
1162 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1163 Spoint = Spoint->next;
1165 Spoint->next = NULL;
1166 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1167 Spoint->element->string = String_table[key_def];
1168 Spoint->element->length = strlen(String_table[key_def]);
1169 Spoint->element->value = Key_vals[Counter];
1170 Klen = strlen(Spoint->element->string);
1171 if (Klen > Max_Key_len)
1174 | Some terminal types accept keystrokes of the form
1175 | \E[A and \EOA, substituting '[' for 'O'. Make a
1176 | duplicate of such key strings (since the
1177 | database will only have one version) so new_curse
1178 | can understand both.
1180 if ((Spoint->element->length > 1) &&
1181 ((String_table[key_def][1] == '[') ||
1182 (String_table[key_def][1] == 'O')))
1184 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1185 Spoint = Spoint->next;
1186 Spoint->next = NULL;
1187 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1188 Spoint->element->length = strlen(String_table[key_def]);
1189 Spoint->element->string = malloc(Spoint->element->length + 1);
1190 strcpy(Spoint->element->string, String_table[key_def]);
1191 Spoint->element->value = Key_vals[Counter];
1192 Klen = strlen(Spoint->element->string);
1193 if (Klen > Max_Key_len)
1196 if (String_table[key_def][1] == '[')
1197 Spoint->element->string[1] = 'O';
1199 Spoint->element->string[1] = '[';
1208 | insert information about keys for a vt100 terminal
1216 struct KEY_STACK *Spoint;
1219 while (Spoint->next != NULL)
1220 Spoint = Spoint->next;
1221 for (counter = 0; vt100[counter].length != 0; counter++)
1223 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1224 Spoint = Spoint->next;
1225 Spoint->next = NULL;
1226 Spoint->element = &vt100[counter];
1227 Klen = strlen(Spoint->element->string);
1228 if (Klen > Max_Key_len)
1235 String_Get(param) /* read the string */
1244 while (*TERM_data_ptr != '=')
1246 Temp = ++TERM_data_ptr;
1248 while ((*Temp != ':') && (*Temp != (char)NULL))
1253 if (Counter == 1) /* no data */
1255 String = Temp = malloc(Counter);
1256 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1258 if (*TERM_data_ptr == '\\')
1261 if (*TERM_data_ptr == 'n')
1263 else if (*TERM_data_ptr == 't')
1265 else if (*TERM_data_ptr == 'b')
1267 else if (*TERM_data_ptr == 'r')
1269 else if (*TERM_data_ptr == 'f')
1271 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1272 *Temp = '\033'; /* escape */
1273 else if (*TERM_data_ptr == '\\')
1275 else if (*TERM_data_ptr == '\'')
1277 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1280 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1282 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1283 TERM_data_ptr++; /* ? */
1291 else if (*TERM_data_ptr == '^')
1294 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1295 *Temp = *TERM_data_ptr - '@';
1296 else if (*TERM_data_ptr == '?')
1302 *Temp++ = *TERM_data_ptr++;
1309 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1316 tc_Get_int(param) /* read the integer */
1323 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1331 while (*TERM_data_ptr != ':')
1338 Find_term() /* find terminal description in termcap file */
1343 Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
1344 strcpy(Name, TERMINAL_TYPE);
1345 while (*Ftemp != (char)NULL)
1348 *Ftemp = (char)NULL;
1350 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1351 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1353 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1355 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1357 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1358 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1360 if (*TERM_data_ptr == '|')
1363 *TERM_data_ptr = (char)NULL;
1369 printf("terminal type %s not found\n", TERMINAL_TYPE);
1375 CAP_PARSE() /* parse off the data in the termcap data file */
1382 while (*TERM_data_ptr != (char)NULL)
1384 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1386 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1389 Booleans[offset] = TRUE;
1394 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1396 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1399 Numbers[offset] = tc_Get_int(Numbers[offset]);
1405 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1407 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1410 String_table[offset] = String_Get(String_table[offset]);
1415 if (!strncmp(TERM_data_ptr, "tc=", 3))
1416 tc_ = String_Get(NULL);
1417 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1419 if (*TERM_data_ptr == ':')
1422 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1425 TERMINAL_TYPE = tc_;
1435 #endif /* ifdef CAP */
1438 Screenalloc(columns)
1444 tmp = (struct _line *) malloc(sizeof (struct _line));
1445 tmp->row = malloc(columns + 1);
1446 tmp->attributes = malloc(columns + 1);
1447 tmp->prev_screen = NULL;
1448 tmp->next_screen = NULL;
1449 for (i = 0; i < columns; i++)
1452 tmp->attributes[i] = (char) NULL;
1454 tmp->scroll = tmp->changed = FALSE;
1455 tmp->row[0] = (char) NULL;
1456 tmp->attributes[0] = (char) NULL;
1457 tmp->row[columns] = (char) NULL;
1458 tmp->attributes[columns] = (char) NULL;
1463 WINDOW *newwin(lines, cols, start_l, start_c)
1464 int lines, cols; /* number of lines and columns to be in window */
1465 int start_l, start_c; /* starting line and column to be inwindow */
1468 struct _line *temp_screen;
1471 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1472 Ntemp->SR = start_l;
1473 Ntemp->SC = start_c;
1474 Ntemp->Num_lines = lines;
1475 Ntemp->Num_cols = cols;
1478 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1479 Ntemp->SCROLL_CLEAR = FALSE;
1480 Ntemp->Attrib = FALSE;
1481 Ntemp->first_line = temp_screen = Screenalloc(cols);
1482 Ntemp->first_line->number = 0;
1483 for (i = 1; i < lines; i++)
1485 temp_screen->next_screen = Screenalloc(cols);
1486 temp_screen->next_screen->number = i;
1487 temp_screen->next_screen->prev_screen = temp_screen;
1488 temp_screen = temp_screen->next_screen;
1490 Ntemp->first_line->prev_screen = NULL;
1491 temp_screen->next_screen = NULL;
1497 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1499 int p_list[]; /* stack of values */
1500 int place; /* place keeper of top of stack */
1502 char *Otemp; /* temporary string pointer to parse output */
1512 p1 = p_list[--place];
1513 p2 = p_list[--place];
1517 if ((*Otemp >= '0') && (*Otemp <= '9'))
1519 delay = atoi(Otemp);
1520 while ((*Otemp >= '0') && (*Otemp <= '9'))
1525 while (*Otemp != (char)NULL)
1530 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1534 else if (*Otemp == '2')
1536 else if (*Otemp == '3')
1538 else if (*Otemp == '+')
1544 else if (*Otemp == '.')
1549 else if (*Otemp == '>')
1560 else if (*Otemp == 'r')
1566 else if (*Otemp == 'i')
1571 else if (*Otemp == '%')
1573 else if (*Otemp == 'n')
1578 else if (*Otemp == 'B')
1580 p1 = (16 * (p1/10)) + (p1 % 10);
1581 p2 = (16 * (p2/10)) + (p2 % 10);
1583 else if (*Otemp == 'D')
1585 p1 = (p1 - 2 * (p1 % 16));
1586 p2 = (p2 - 2 * (p2 % 16));
1595 chars = delay * chars_per_millisecond;
1597 if ((chars - delay) > 0.0)
1599 for (; delay > 0; delay--)
1600 putchar(*String_table[pc__]);
1607 char *Otemp; /* temporary string pointer to parse output */
1613 Operation(Temp_Stack, place) /* handle conditional operations */
1622 temp = Temp_Stack[--place];
1625 else if (!strncmp(Otemp, "2d", 2))
1627 temp = Temp_Stack[--place];
1628 printf("%2d", temp);
1632 else if (!strncmp(Otemp, "3d", 2))
1634 temp = Temp_Stack[--place];
1635 printf("%0d", temp);
1639 else if (!strncmp(Otemp, "02d", 3))
1641 temp = Temp_Stack[--place];
1642 printf("%02d", temp);
1647 else if (!strncmp(Otemp, "03d", 3))
1649 temp = Temp_Stack[--place];
1650 printf("%03d", temp);
1655 else if (*Otemp == '+')
1658 temp = Temp_Stack[--place];
1659 temp += Temp_Stack[--place];
1660 Temp_Stack[place++] = temp;
1662 else if (*Otemp == '-')
1665 temp = Temp_Stack[--place];
1666 temp -= Temp_Stack[--place];
1667 Temp_Stack[place++] = temp;
1669 else if (*Otemp == '*')
1672 temp = Temp_Stack[--place];
1673 temp *= Temp_Stack[--place];
1674 Temp_Stack[place++] = temp;
1676 else if (*Otemp == '/')
1679 temp = Temp_Stack[--place];
1680 temp /= Temp_Stack[--place];
1681 Temp_Stack[place++] = temp;
1683 else if (*Otemp == 'm')
1686 temp = Temp_Stack[--place];
1687 temp %= Temp_Stack[--place];
1688 Temp_Stack[place++] = temp;
1690 else if (*Otemp == '&')
1693 temp = Temp_Stack[--place];
1694 temp &= Temp_Stack[--place];
1695 Temp_Stack[place++] = temp;
1697 else if (*Otemp == '|')
1700 temp = Temp_Stack[--place];
1701 temp |= Temp_Stack[--place];
1702 Temp_Stack[place++] = temp;
1704 else if (*Otemp == '^')
1707 temp = Temp_Stack[--place];
1708 temp ^= Temp_Stack[--place];
1709 Temp_Stack[place++] = temp;
1711 else if (*Otemp == '=')
1714 temp = Temp_Stack[--place];
1715 temp = (temp == Temp_Stack[--place]);
1716 Temp_Stack[place++] = temp;
1718 else if (*Otemp == '>')
1721 temp = Temp_Stack[--place];
1722 temp = temp > Temp_Stack[--place];
1723 Temp_Stack[place++] = temp;
1725 else if (*Otemp == '<')
1728 temp = Temp_Stack[--place];
1729 temp = temp < Temp_Stack[--place];
1730 Temp_Stack[place++] = temp;
1732 else if (*Otemp == 'c')
1735 putchar(Temp_Stack[--place]);
1737 else if (*Otemp == 'i')
1743 else if (*Otemp == '%')
1748 else if (*Otemp == '!')
1750 temp = ! Temp_Stack[--place];
1751 Temp_Stack[place++] = temp;
1754 else if (*Otemp == '~')
1756 temp = ~Temp_Stack[--place];
1757 Temp_Stack[place++] = temp;
1760 else if (*Otemp == 'p')
1763 Temp_Stack[place++] = p[*Otemp - '0'];
1766 else if (*Otemp == 'P')
1769 Temp_Stack[place++] = variable[*Otemp - 'a'];
1772 else if (*Otemp == 'g')
1775 variable[*Otemp - 'a'] = Temp_Stack[--place];
1778 else if (*Otemp == '\'')
1781 Temp_Stack[place++] = *Otemp;
1785 else if (*Otemp == '{')
1789 Temp_Stack[place++] = temp;
1790 while (*Otemp != '}')
1798 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1808 int Cond_Stack[128];
1831 for (temp = 1; (place != 0); temp++)
1833 p[temp] = p_list[--place];
1838 while (*Otemp != (char) NULL)
1843 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1853 | find the end of the
1854 | conditional statement
1856 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1862 Cond_place = Operation(Cond_Stack, Cond_place);
1866 | if condition is true
1868 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1878 else /* condition is false */
1881 | find 'else' or end
1884 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1887 | if an 'else' found
1889 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1895 | check for 'then' part
1897 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1902 if (*tchar == (char) NULL)
1909 | if end of if found,
1913 else if (!strncmp(tchar, "%;", 2))
1922 | if end of if found,
1926 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1932 else /* Otemp == NULL */
1946 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1948 if (*Otemp != (char) NULL)
1960 Top_of_stack = Operation(Stack, Top_of_stack);
1963 else if (!strncmp(Otemp, "$<", 2))
1967 delay = atoi(Otemp);
1968 while (*Otemp != '>')
1971 chars = delay * chars_per_millisecond;
1973 if ((chars - delay) > 0.0)
1975 if (String_table[pc__] == NULL)
1978 temp = *String_table[pc__];
1979 for (; delay > 0; delay--)
1993 wmove(window, row, column) /* move cursor to indicated position in window */
1997 if ((row < window->Num_lines) && (column < window->Num_cols))
1999 window->LX = column;
2005 clear_line(line, column, cols)
2012 if (column > line->last_char)
2013 line->row[line->last_char] = ' ';
2014 line->last_char = column;
2015 line->row[column] = (char) NULL;
2016 line->attributes[column] = (char) NULL;
2017 line->changed = TRUE;
2018 for (j = column + 1; j < cols; j++)
2021 line->attributes[j] = (char) NULL;
2026 werase(window) /* clear the specified window */
2032 window->SCROLL_CLEAR = CLEAR;
2033 window->scroll_up = window->scroll_down = 0;
2034 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2035 clear_line(tmp, 0, window->Num_cols);
2039 wclrtoeol(window) /* erase from current cursor position to end of line */
2045 window->SCROLL_CLEAR = CHANGE;
2046 column = window->LX;
2048 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2049 tmp = tmp->next_screen;
2050 clear_line(tmp, column, window->Num_cols);
2054 wrefresh(window) /* flush all previous output */
2057 wnoutrefresh(window);
2062 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2063 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2065 if (temp->number == -1)
2066 fprintf(stderr, "line moved ");
2068 fprintf(stderr, "scroll_x is set: ");
2069 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2071 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2072 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2073 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->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, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2082 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2083 fprintf(stderr, "line=%s|\n", temp->row);
2087 virtual_scr->SCROLL_CLEAR = FALSE;
2088 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2096 struct _line *user_line;
2097 int line_counter = 0;
2099 for (line_counter = 0, user_line = window->first_line;
2100 line_counter < window->Num_lines; line_counter++)
2102 user_line->changed = TRUE;
2104 window->SCROLL_CLEAR = TRUE;
2108 wnoutrefresh(window)
2111 struct _line *user_line;
2112 struct _line *virtual_line;
2113 int line_counter = 0;
2117 if (window->SR >= virtual_scr->Num_lines)
2119 user_line = window->first_line;
2120 virtual_line = virtual_scr->first_line;
2121 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2122 virtual_scr->LX = window->LX + window->SC;
2123 virtual_scr->LY = window->LY + window->SR;
2124 virtual_scr->scroll_up = window->scroll_up;
2125 virtual_scr->scroll_down = window->scroll_down;
2126 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2128 for (line_counter = 0; line_counter < window->SR; line_counter++)
2130 virtual_line = virtual_line->next_screen;
2132 for (line_counter = 0; (line_counter < window->Num_lines)
2133 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2136 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2138 for (user_col = 0, virt_col = window->SC;
2139 (virt_col < virtual_scr->Num_cols)
2140 && (user_col < window->Num_cols);
2141 virt_col++, user_col++)
2143 virtual_line->row[virt_col] = user_line->row[user_col];
2144 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2147 if (virtual_scr->Num_cols != window->Num_cols)
2149 if (virtual_line->last_char < (user_line->last_char + window->SC))
2151 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2152 virtual_line->row[virtual_line->last_char] = ' ';
2153 virtual_line->last_char =
2154 min(virtual_scr->Num_cols,
2155 (user_line->last_char + window->SC));
2157 else if (virtual_line->last_char > (user_line->last_char + window->SC))
2159 virtual_line->row[min(virtual_scr->Num_cols,
2160 (user_line->last_char + window->SC))] = ' ';
2164 virtual_line->last_char = user_line->last_char;
2165 virtual_line->row[virtual_line->last_char] = (char) NULL;
2166 virtual_line->changed = user_line->changed;
2167 virtual_line = virtual_line->next_screen;
2168 user_line = user_line->next_screen;
2170 window->SCROLL_CLEAR = FALSE;
2171 window->scroll_up = window->scroll_down = 0;
2172 last_window_refreshed = window;
2176 flushinp() /* flush input */
2181 ungetch(c) /* push a character back on input */
2185 in_buff[bufp++] = c;
2200 tv.tv_usec = 500000; /* half a second */
2202 Time_Out = FALSE; /* just in case */
2204 ret_val = select(nfds, &fds, 0, 0, &tv);
2207 | if ret_val is less than zero, there was no input
2208 | otherwise, get a character and return it
2217 return(read(STDIN_FILENO, &temp, 1)? temp : -1);
2222 wgetch(window) /* get character from specified window */
2233 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2235 in_value = ((bufp > 0) ? in_buff[--bufp] : read(STDIN_FILENO, &temp, 1)? temp : -1);
2236 #else /* BSD_SELECT */
2238 in_value = ((bufp > 0) ? in_buff[--bufp] :
2239 (read(STDIN_FILENO, &temp, 1)> 0) ? temp : -1);
2244 old_arg = fcntl(0, F_GETFL, 0);
2245 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2247 in_value = ((bufp > 0) ? in_buff[--bufp] : read(STDIN_FILENO, &temp, 1)? temp : -1);
2250 fcntl(0, F_SETFL, old_arg);
2255 #endif /* BSD_SELECT */
2260 if ((Parity) && (Num_bits < 8))
2261 /* strip eighth bit if parity in use */
2264 else if (interrupt_flag)
2266 interrupt_flag = FALSE;
2267 in_value = wgetch(window);
2270 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2271 in_value = Get_key(in_value);
2277 Clear(arg) /* notify that time out has occurred */
2282 fprintf(stderr, "inside Clear()\n");
2286 #endif /* BSD_SELECT */
2289 Get_key(first_char) /* try to decode key sequence */
2290 int first_char; /* first character of sequence */
2298 struct termio Gterminal;
2300 struct sgttyb Gterminal;
2302 struct KEY_STACK *St_point;
2303 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2305 #endif /* BSD_SELECT */
2309 string[Count++] = first_char;
2310 string[Count] = (char) NULL;
2313 signal(SIGALRM, Clear);
2315 #endif /* BSD_SELECT */
2318 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2319 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2320 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2324 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2326 in_char = wgetch(stdscr);
2328 fprintf(stderr, "back in GetKey()\n");
2333 string[Count++] = in_char;
2334 string[Count] = (char) NULL;
2336 while ((St_point != NULL) && (!Found))
2338 if (!strcmp(string, St_point->element->string))
2341 St_point = St_point->next;
2348 #endif /* BSD_SELECT */
2350 /* value = ioctl(0, TCSETA, &Terminal);*/
2352 value = ioctl(0, TIOCSETP, &Terminal);
2353 /* value = fcntl(0, F_SETFL, old_arg);*/
2358 return(St_point->element->value);
2364 if ((string[--Count] != -1) &&
2365 ((unsigned char) (string[Count]) != 255))
2368 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2370 ungetch(string[Count]);
2378 waddch(window, c) /* output the character in the specified window */
2383 int shift; /* number of spaces to shift if a tab */
2384 struct _line *tmpline;
2387 /*printf("starting waddch \n");fflush(stdout);*/
2390 column = window->LX;
2393 shift = (column + 1) % 8;
2401 waddch(window, ' ');
2404 else if ((column < window->Num_cols) && (row < window->Num_lines))
2406 if ((c == '~') && (Booleans[hz__]))
2409 if (( c != '\b') && (c != '\n') && (c != '\r'))
2412 tmpline = window->first_line;
2413 while (row < window->LY)
2416 tmpline = tmpline->next_screen;
2418 tmpline->row[column] = c;
2419 tmpline->attributes[column] = window->Attrib;
2420 tmpline->changed = TRUE;
2421 if (column >= tmpline->last_char)
2423 if (column > tmpline->last_char)
2424 tmpline->row[tmpline->last_char] = ' ';
2425 tmpline->row[column + 1] = (char) NULL;
2426 tmpline->attributes[column + 1] = (char) NULL;
2427 tmpline->last_char = column + 1;
2433 window->LX = window->Num_cols;
2442 if (window->LX >= window->Num_cols)
2446 if (window->LY >= window->Num_lines)
2448 window->LY = window->Num_lines - 1;
2449 /* window->LY = row;
2450 wmove(window, 0, 0);
2452 wmove(window, row, 0);*/
2455 window->SCROLL_CLEAR = CHANGE;
2459 winsertln(window) /* insert a blank line into the specified window */
2466 window->scroll_down += 1;
2467 window->SCROLL_CLEAR = SCROLL;
2468 column = window->LX;
2470 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2471 tmp = tmp->next_screen;
2472 if (tmp->prev_screen != NULL)
2473 tmp->prev_screen->next_screen = NULL;
2475 clear_line(tmp1, 0, window->Num_cols);
2477 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2478 tmp = tmp->next_screen;
2479 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2481 tmp1->next_screen = tmp->next_screen;
2482 tmp->next_screen = tmp1;
2483 tmp->changed = TRUE;
2484 tmp->next_screen->prev_screen = tmp;
2486 else if (window->Num_lines > 1)
2488 if (tmp->prev_screen != NULL)
2489 tmp->prev_screen->next_screen = tmp1;
2490 tmp1->prev_screen = tmp->prev_screen;
2491 tmp->prev_screen = tmp1;
2492 tmp1->next_screen = tmp;
2493 tmp->changed = TRUE;
2496 if (window->LY == 0)
2497 window->first_line = tmp1;
2501 wdeleteln(window) /* delete a line in the specified window */
2506 struct _line *tmpline;
2508 if (window->Num_lines > 1)
2510 window->scroll_up += 1;
2511 window->SCROLL_CLEAR = SCROLL;
2512 column = window->LX;
2514 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2515 tmp = tmp->next_screen;
2516 if (window->LY == 0)
2517 window->first_line = tmp->next_screen;
2518 if (tmp->prev_screen != NULL)
2519 tmp->prev_screen->next_screen = tmp->next_screen;
2520 if (tmp->next_screen != NULL)
2522 tmp->next_screen->changed = TRUE;
2523 tmp->next_screen->scroll = UP;
2524 tmp->next_screen->prev_screen = tmp->prev_screen;
2527 clear_line(tmpline, 0, window->Num_cols);
2528 tmpline->number = -1;
2529 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2530 tmp = tmp->next_screen;
2533 tmp->next_screen = tmpline;
2534 tmp->next_screen->prev_screen = tmp;
2535 tmp->changed = TRUE;
2536 tmp = tmp->next_screen;
2540 tmp->next_screen = NULL;
2544 clear_line(window->first_line, 0, window->Num_cols);
2549 wclrtobot(window) /* delete from current position to end of the window */
2555 window->SCROLL_CLEAR |= CLEAR;
2556 column = window->LX;
2558 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2559 tmp = tmp->next_screen;
2560 clear_line(tmp, column, window->Num_cols);
2561 for (row = (window->LY + 1); row < window->Num_lines; row++)
2563 tmp = tmp->next_screen;
2564 clear_line(tmp, 0, window->Num_cols);
2566 wmove(window, row, column);
2570 wstandout(window) /* begin standout mode in window */
2573 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2574 window->Attrib |= A_STANDOUT;
2578 wstandend(window) /* end standout mode in window */
2581 window->Attrib &= ~A_STANDOUT;
2585 waddstr(window, string) /* write 'string' in window */
2591 for (wstring = string; *wstring != (char) NULL; wstring++)
2592 waddch(window, *wstring);
2596 clearok(window, flag) /* erase screen and redraw at next refresh */
2600 Repaint_screen = TRUE;
2605 echo() /* turn on echoing */
2610 Terminal.c_lflag |= ECHO; /* enable echo */
2611 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2613 Terminal.sg_flags |= ECHO; /* enable echo */
2614 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2619 noecho() /* turn off echoing */
2624 Terminal.c_lflag &= ~ECHO; /* disable echo */
2625 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2627 Terminal.sg_flags &= ~ECHO; /* disable echo */
2628 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2633 raw() /* set to read characters immediately */
2638 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2639 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2640 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2642 Terminal.c_lflag &= ~FLUSHO;
2645 Terminal.c_lflag &= ~PENDIN;
2648 Terminal.c_lflag &= ~IEXTEN;
2650 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2651 Terminal.c_cc[VTIME] = 255; /* timeout value */
2652 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2653 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2655 Terminal.sg_flags |= RAW; /* enable raw mode */
2656 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2661 noraw() /* set to normal character read mode */
2666 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2667 Terminal.c_lflag |= ISIG; /* enable signal checking */
2668 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2669 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2670 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2671 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2673 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2674 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2675 /* old_arg = fcntl(0, F_GETFL, 0);
2676 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2686 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2687 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2697 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2698 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2699 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2719 nodelay(window, flag)
2733 keypad(window, flag)
2738 String_Out(String_table[ks__], NULL, 0);
2740 String_Out(String_table[ke__], NULL, 0);
2744 savetty() /* save current tty stats */
2749 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2751 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2756 resetty() /* restore previous tty stats */
2761 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2763 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2768 endwin() /* end windows */
2770 keypad(stdscr, FALSE);
2771 initialized = FALSE;
2773 delwin(virtual_scr);
2778 /* old_arg = fcntl(0, F_GETFL, 0);
2779 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2785 delwin(window) /* delete the window structure */
2790 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2792 window->first_line = window->first_line->next_screen;
2793 free(window->first_line->prev_screen->row);
2794 free(window->first_line->prev_screen->attributes);
2795 free(window->first_line->prev_screen);
2797 if (window == last_window_refreshed)
2798 last_window_refreshed = 0;
2799 if (window->first_line != NULL)
2801 free(window->first_line->row);
2802 free(window->first_line->attributes);
2803 free(window->first_line);
2809 wprintw(WINDOW *window, const char *format, ...)
2816 va_start(ap, format);
2818 fpoint = (char *) format;
2819 while (*fpoint != (char) NULL)
2826 value = va_arg(ap, int);
2827 iout(window, value);
2829 else if (*fpoint == 'c')
2831 value = va_arg(ap, int);
2832 waddch(window, value);
2834 else if (*fpoint == 's')
2836 wtemp = va_arg(ap, char *);
2837 waddstr(window, wtemp);
2841 else if (*fpoint == '\\')
2845 waddch(window, '\n');
2846 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2849 while ((*fpoint >= '0') && (*fpoint <= '9'))
2851 value = (value * 8) + (*fpoint - '0');
2854 waddch(window, value);
2859 waddch(window, *fpoint++);
2865 iout(window, value) /* output characters */
2871 if ((i = value / 10) != 0)
2873 waddch(window, ((value % 10) + '0'));
2877 Comp_line(line1, line2) /* compare lines */
2878 struct _line *line1;
2879 struct _line *line2;
2888 att1 = line1->attributes;
2889 att2 = line2->attributes;
2890 count2 = strlen(c1) + 1;
2891 count1 = strlen(c2) + 1;
2892 if (count1 > count2)
2898 if (count2 > (count1 + count1))
2901 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2904 if ((count1 == 1) && (count2 == 1))
2905 count1 = 0; /* both lines blank */
2906 else if (count2 == count1)
2907 count1 = -1; /* equal */
2909 count1 = count2 / count1; /* lines unequal */
2914 Insert_line(row, end_row, window) /* insert line into screen */
2923 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2924 tmp = tmp->next_screen;
2925 if ((end_row + window->SR) == 0)
2926 curscr->first_line = curscr->first_line->next_screen;
2929 | find bottom line to delete
2931 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2932 tmp = tmp->next_screen;
2933 if (tmp->prev_screen != NULL)
2934 tmp->prev_screen->next_screen = tmp->next_screen;
2935 if (tmp->next_screen != NULL)
2936 tmp->next_screen->prev_screen = tmp->prev_screen;
2939 | clear deleted line
2941 clear_line(tmp, 0, window->Num_cols);
2943 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2944 tmp = tmp->next_screen;
2946 for (i = 0, tmp = top_of_win; i < row; i++)
2947 tmp = tmp->next_screen;
2948 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
2949 tmp->prev_screen->next_screen = tmp1;
2950 tmp1->prev_screen = tmp->prev_screen;
2951 tmp->prev_screen = tmp1;
2952 tmp1->next_screen = tmp;
2953 if ((row + window->SR) == 0)
2954 curscr->first_line = tmp1;
2955 if (tmp1->next_screen != NULL)
2956 tmp1 = tmp1->next_screen;
2958 if ((!String_table[cs__]) && (end_row < window->Num_lines))
2960 Position(window, (window->SR + end_row), 0);
2961 String_Out(String_table[dl__], NULL, 0);
2963 Position(window, (window->SR + row), 0);
2964 if (String_table[al__] != NULL)
2965 String_Out(String_table[al__], NULL, 0);
2967 String_Out(String_table[sr__], NULL, 0);
2969 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
2970 top_of_win = top_of_win->next_screen;
2976 Delete_line(row, end_row, window) /* delete a line on screen */
2987 tmp = curscr->first_line;
2988 while (i < window->SR)
2991 tmp = tmp->next_screen;
2994 | find line to delete
2997 if ((row + window->SR) == 0)
2998 curscr->first_line = top_of_win->next_screen;
2999 for (i = 0, tmp = top_of_win; i < row; i++)
3000 tmp = tmp->next_screen;
3001 if (tmp->prev_screen != NULL)
3002 tmp->prev_screen->next_screen = tmp->next_screen;
3003 if (tmp->next_screen != NULL)
3004 tmp->next_screen->prev_screen = tmp->prev_screen;
3005 tmp2 = tmp->next_screen;
3008 | clear deleted line
3010 clear_line(tmp1, 0, window->Num_cols);
3013 | find location to insert deleted line
3015 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3016 tmp = tmp->next_screen;
3018 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3019 tmp = tmp->next_screen;
3020 tmp1->next_screen = tmp;
3021 tmp1->prev_screen = tmp->prev_screen;
3022 if (tmp1->prev_screen != NULL)
3023 tmp1->prev_screen->next_screen = tmp1;
3024 tmp->prev_screen = tmp1;
3026 Position(window, (window->SR + row), 0);
3027 String_Out(String_table[dl__], NULL, 0);
3028 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3030 Position(window, (window->SR + end_row), 0);
3031 String_Out(String_table[al__], NULL, 0);
3033 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3035 Position(window, (window->SR + end_row), 0);
3039 if (row == (window->Num_lines-1))
3041 if ((row + window->SR) == 0)
3042 curscr->first_line = top_of_win = tmp2;
3047 CLEAR_TO_EOL(window, row, column)
3054 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3055 tmp1 = tmp1->next_screen;
3056 for (x = column; x<window->Num_cols; x++)
3059 tmp1->attributes[x] = (char) NULL;
3061 tmp1->row[column] = (char) NULL;
3062 tmp1->last_char = column;
3068 Position(window, row, column);
3071 if (String_table[ce__] != NULL)
3072 String_Out(String_table[ce__], NULL, 0);
3075 for (x = column; x < window->Num_cols; x++)
3083 check_delete(window, line, offset, pointer_new, pointer_old)
3086 struct _line *pointer_new, *pointer_old;
3098 new_lin = pointer_new->row;
3099 new_att = pointer_new->attributes;
3100 old_lin = pointer_old->row;
3101 old_att = pointer_old->attributes;
3102 end_old = end_new = offset;
3103 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))
3105 if (old_lin[end_old] != (char) NULL)
3108 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))
3110 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3112 if (new_lin[end_new+k] == (char) NULL)
3114 Position(window, line, (end_new+k));
3115 CLEAR_TO_EOL(window, line, (end_new+k));
3117 Position(window, line, offset);
3118 for (k = offset; k < end_old; k++)
3119 Char_del(old_lin, old_att, offset, window->Num_cols);
3120 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3122 pointer_old->last_char = offset;
3130 | Check if characters were inserted in the middle of a line, and if
3135 check_insert(window, line, offset, pointer_new, pointer_old)
3138 struct _line *pointer_new, *pointer_old;
3141 int end_old, end_new;
3152 new_lin = pointer_new->row;
3153 new_att = pointer_new->attributes;
3154 old_lin = pointer_old->row;
3155 old_att = pointer_old->attributes;
3156 end_old = end_new = offset;
3157 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))
3159 if (new_lin[end_new] != (char) NULL)
3162 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))
3165 | check for commonality between rest of lines (are the old
3166 | and new lines the same, except for a chunk in the middle?)
3167 | if the rest of the lines are common, do not insert text
3170 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]))
3172 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3174 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3176 Position(window, line, offset);
3178 if (String_table[ic__] == NULL)
3180 String_Out(String_table[im__], NULL, 0);
3183 for (k = offset; k < end_new; k++)
3186 String_Out(String_table[ic__], NULL, 0);
3187 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3190 String_Out(String_table[ei__], NULL, 0);
3191 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3193 pointer_old->last_char = offset;
3206 int begin_old, begin_new;
3207 int end_old, end_new;
3209 int from_top, tmp_ft, offset;
3229 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3231 window = virtual_scr;
3233 if ((nc_attributes & A_NC_BIG5) != 0)
3238 if (String_table[cl__])
3239 String_Out(String_table[cl__], NULL, 0);
3243 while (from_top < LINES)
3245 Position(curscr, from_top, 0);
3246 if (String_table[ce__] != NULL)
3247 String_Out(String_table[ce__], NULL, 0);
3250 for (j = 0; j < window->Num_cols; j++)
3256 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3258 Position(curscr, from_top, 0);
3259 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3261 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3266 Position(curscr, from_top, j);
3270 Repaint_screen = FALSE;
3275 top_of_win = curscr->first_line;
3277 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3278 from_top < window->Num_lines; from_top++)
3280 virtual_lines[from_top] = TRUE;
3281 if ((similar = Comp_line(curr, virt)) > 0)
3283 virtual_lines[from_top] = FALSE;
3286 curr = curr->next_screen;
3287 virt = virt->next_screen;
3291 virt = window->first_line;
3295 | if the window has lines that are different, check for scrolling
3301 for (first_same = window->Num_lines;
3302 (first_same > from_top) && (virtual_lines[first_same - 1]);
3305 count1 = first_same - 1;
3307 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3310 while ((from_top < first_same) && nc_scrolling_ability)
3311 /* check entire lines for diffs */
3315 if (from_top >= last_same)
3317 for (last_same = from_top;
3318 (last_same < window->Num_lines) &&
3319 (virtual_lines[last_same] == FALSE);
3323 if (!virtual_lines[from_top])
3327 | check for lines deleted (scroll up)
3329 for (tmp_ft = from_top+1, old = curr->next_screen;
3330 ((window->scroll_up) && (diff) &&
3331 (tmp_ft < last_same) &&
3332 (!virtual_lines[tmp_ft]));
3335 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3337 if (String_table[cs__]) /* scrolling region */
3340 list[0] = min((last_same - 1), (window->Num_lines - 1));
3341 String_Out(String_table[cs__], list, 2);
3342 Curr_y = Curr_x = -1;
3345 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3347 old = Delete_line(from_top, min((last_same - 1), (window->Num_lines - 1)), window);
3351 if (String_table[cs__]) /* scrolling region */
3354 list[0] = LINES - 1;
3355 String_Out(String_table[cs__], list, 2);
3356 Curr_y = Curr_x = -1;
3359 top_of_win = curscr->first_line;
3361 for (offset = 0; offset < from_top; offset++)
3362 curr = curr->next_screen;
3363 for (offset = from_top, old=curr, new=virt;
3364 offset < window->Num_lines;
3365 old=old->next_screen, new=new->next_screen,
3368 similar = Comp_line(old, new);
3369 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3373 old = old->next_screen;
3376 | check for lines inserted (scroll down)
3378 for (tmp_ft = from_top-1, old = curr->prev_screen;
3379 ((window->scroll_down) && (tmp_ft >= 0) &&
3381 (!virtual_lines[tmp_ft]));
3384 if (Comp_line(old, virt) == -1)
3386 if (String_table[cs__]) /* scrolling region */
3389 list[0] = min((last_same - 1), (window->Num_lines - 1));
3390 String_Out(String_table[cs__], list, 2);
3391 Curr_y = Curr_x = -1;
3394 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3396 old = Insert_line(tmp_ft, min((last_same - 1), (window->Num_lines -1)), window);
3400 if (String_table[cs__]) /* scrolling region */
3403 list[0] = LINES - 1;
3404 String_Out(String_table[cs__], list, 2);
3405 Curr_y = Curr_x = -1;
3408 top_of_win = curscr->first_line;
3410 for (offset = 0; offset < from_top; offset++)
3411 curr = curr->next_screen;
3412 for (offset = from_top, old=curr, new=virt;
3413 offset < window->Num_lines;
3414 old=old->next_screen, new=new->next_screen,
3417 similar = Comp_line(old, new);
3418 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3422 old = old->prev_screen;
3426 curr = curr->next_screen;
3427 virt = virt->next_screen;
3433 | Scrolling done, now need to insert, delete, or modify text
3437 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3438 curr = curr->next_screen;
3440 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)
3444 | If either 'insert mode' or 'insert char' are
3445 | available, enter the following 'if' statement,
3446 | else, need to simply rewrite the contents of the line
3447 | at the point where the contents of the line change.
3450 if (((String_table[ic__]) || (String_table[im__])) &&
3451 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3456 vrt_lin = virt->row;
3457 vrt_att = virt->attributes;
3458 cur_lin = curr->row;
3459 cur_att = curr->attributes;
3460 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3462 if ((STAND) && (Booleans[xs__]))
3464 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3466 if ((STAND) && (!vrt_att[j]))
3469 Position(window, from_top, j);
3476 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3479 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3481 Position(window, from_top, j);
3482 /* CLEAR_TO_EOL(window, from_top, j);*/
3486 if (vrt_lin[j] != (char) NULL)
3492 if ((first_time) && (virt->changed))
3494 if (curr->last_char <= virt->last_char)
3495 changed = check_insert(window, from_top, j, virt, curr);
3497 changed = check_delete(window, from_top, j, virt, curr);
3499 virt->changed = FALSE;
3501 changed = check_insert(window, from_top, j, virt, curr);
3502 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3504 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3508 Position(window, from_top, j);
3509 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3512 if ((vrt_lin[j] != (char) NULL))
3515 if ((STAND) && (!vrt_att[j]))
3518 Position(window, from_top, j);
3522 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3524 Position(window, from_top, j);
3525 CLEAR_TO_EOL(window, from_top, j);
3528 else /*if ((similar != -1) && (similar != 0))*/
3532 att1 = curr->attributes;
3534 att2 = virt->attributes;
3535 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3537 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3541 | if previous character is an eight bit
3542 | char, start redraw from that character
3545 if ((NC_chinese) && (highbitset(c1[j - 1])))
3549 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3551 Position(window, from_top, begin_old);
3552 CLEAR_TO_EOL(window, from_top, j);
3553 Position(window, from_top, begin_old);
3554 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3555 Char_out(c2[j], att2[j], c1, att1, j);
3558 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3560 Position(window, from_top, j);
3561 CLEAR_TO_EOL(window, from_top, j);
3567 Position(window, from_top, j);
3570 virt->number = from_top;
3572 Position(window, window->LY, window->LX);
3576 Position(window, row, col) /* position the cursor for output on the screen */
3587 pos_row = row + window->SR;
3588 pos_column = col + window->SC;
3589 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3591 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3594 list[place++] = pos_column;
3595 list[place++] = pos_row;
3596 String_Out(String_table[cm__], list, place);
3597 if ((STAND) && (!Booleans[ms__]))
3600 Curr_x = pos_column;
3606 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3614 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3616 line[one] = line[two];
3617 attrib[one] = attrib[two];
3619 String_Out(String_table[dc__], NULL, 0);
3623 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3634 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3636 for (two = one + 1; (two > offset); one--, two--)
3638 line[two] = line[one];
3639 attrib[two] = attrib[one];
3641 line[offset] = newc;
3642 attrib[offset] = newatt;
3643 Char_out(newc, newatt, line, attrib, offset);
3649 if (String_table[sa__])
3651 attributes_set[0] = 1;
3652 String_Out(String_table[sa__], attributes_set, 1);
3654 else if (String_table[so__])
3655 String_Out(String_table[so__], NULL, 0);
3661 if (String_table[me__])
3662 String_Out(String_table[me__], NULL, 0);
3663 else if (String_table[sa__])
3665 attributes_set[0] = 0;
3666 String_Out(String_table[sa__], attributes_set, 1);
3668 else if (String_table[se__])
3669 String_Out(String_table[se__], NULL, 0);
3673 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3682 if ((newatt) && (!STAND))
3687 else if ((STAND) && (!newatt))
3693 if ((newatt) && (STAND) && (Booleans[xs__]))
3698 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3701 line[offset] = newc;
3702 attrib[offset] = newatt;
3709 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3710 | hacks that notify new_curse to handle characters that have the high
3711 | bit set as the first of two bytes of a multi-byte string.
3719 nc_attributes |= flag;
3723 nc_clearattrib(flag)
3726 nc_attributes &= ~flag;