4 | A subset of curses developed for use with ae.
6 | written by Hugh Mahon
8 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon
11 | Redistribution and use in source and binary forms, with or without
12 | modification, are permitted provided that the following conditions
15 | * Redistributions of source code must retain the above copyright
16 | notice, this list of conditions and the following disclaimer.
17 | * Redistributions in binary form must reproduce the above
18 | copyright notice, this list of conditions and the following
19 | disclaimer in the documentation and/or other materials provided
20 | with the distribution.
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 | POSSIBILITY OF SUCH DAMAGE.
36 | All are rights reserved.
38 | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh Exp $
42 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon",
43 "All rights are reserved."};
45 char * new_curse_name= "@(#) new_curse.c $Revision: 1.54 $";
47 #include "new_curse.h"
58 #include <sys/types.h>
62 #include <sys/select.h> /* on AIX */
65 #endif /* BSD_SELECT */
82 #include <sys/ioctl.h>
87 static WINDOW *virtual_scr;
89 WINDOW *last_window_refreshed;
95 #define min(a, b) (a < b ? a : b)
96 #define highbitset(a) ((a) & 0x80)
99 #define String_Out(table, stack, place) Info_Out(table, stack, place)
101 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
104 #define bw__ 0 /* booleans */
107 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
110 #define gn__ 6 /* generic type terminal */
111 #define hc__ 7 /* hardcopy terminal */
117 #define mi__ 13 /* safe to move during insert mode */
118 #define ms__ 14 /* safe to move during standout mode */
122 #define hz__ 18 /* hazeltine glitch */
131 #define co__ 0 /* number of columns */ /* numbers */
132 #define it__ 1 /* spaces per tab */
133 #define li__ 2 /* number of lines */
135 #define sg__ 4 /* magic cookie glitch */
149 #define bt__ 0 /* back tab */ /* strings */
150 #define bl__ 1 /* bell */
151 #define cr__ 2 /* carriage return */
152 #define cs__ 3 /* change scroll region */
153 #define ct__ 4 /* clear all tab stops */
154 #define cl__ 5 /* clear screen and home cursor */
155 #define ce__ 6 /* clear to end of line */
156 #define cd__ 7 /* clear to end of display */
157 #define ch__ 8 /* set cursor column */
158 #define CC__ 9 /* term, settable cmd char in */
159 #define cm__ 10 /* screen rel cursor motion, row, column */
160 #define do__ 11 /* down one line */
161 #define ho__ 12 /* home cursor */
162 #define vi__ 13 /* make cursor invisible */
163 #define le__ 14 /* move cursor left one space */
164 #define CM__ 15 /* memory rel cursor addressing */
165 #define ve__ 16 /* make cursor appear normal */
166 #define nd__ 17 /* non-destructive space (cursor right) */
167 #define ll__ 18 /* last line, first col */
168 #define up__ 19 /* cursor up */
170 #define dc__ 21 /* delete character */
171 #define dl__ 22 /* delete line */
176 #define md__ 27 /* turn on bold */
178 #define dm__ 29 /* turn on delete mode */
179 #define mh__ 30 /* half bright mode */
180 #define im__ 31 /* insert mode */
184 #define so__ 35 /* enter standout mode */
191 #define ei__ 42 /* exit insert mode */
192 #define se__ 43 /* exit standout mode */
204 #define kb__ 55 /* backspace key */
236 #define ku__ 87 /* key up */
280 #define sa__ 131 /* sgr */
426 char *Boolean_names[] = {
427 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
428 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
431 char *Number_names[] = {
432 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
435 char *String_names[] = {
436 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
437 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
438 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
439 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
440 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
441 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
442 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
443 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
444 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
445 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
446 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
447 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
448 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
449 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
450 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
451 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
452 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
453 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
454 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
455 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
456 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
457 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
458 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
459 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
460 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
464 char *new_curse = "October 1987";
466 char in_buff[100]; /* buffer for ungetch */
467 int bufp; /* next free position in in_buff */
469 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
471 int Data_Line_len = 0;
472 int Max_Key_len; /* max length of a sequence sent by a key */
473 char *Data_Line = NULL;
474 char *TERM_PATH = NULL;
475 char *TERM_data_ptr = NULL;
476 char *Term_File_name = NULL; /* name of file containing terminal description */
477 FILE *TFP; /* file pointer to file with terminal des. */
478 int Fildes; /* file descriptor for terminfo file */
479 int STAND = FALSE; /* is standout mode activated? */
480 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
481 int Time_Out; /* set when time elapsed while trying to read function key */
482 int Curr_x; /* current x position on screen */
483 int Curr_y; /* current y position on the screen */
486 int Move_It; /* flag to move cursor if magic cookie glitch */
487 int initialized = FALSE; /* tells whether new_curse is initialized */
489 float chars_per_millisecond;
490 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
491 int Intr; /* storeage for interrupt character */
492 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
493 int Noblock; /* for BSD systems */
494 int Num_bits; /* number of bits per character */
495 int Flip_Bytes; /* some systems have byte order reversed */
496 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
502 #if !defined(TERMCAP)
503 #define TERMCAP "/etc/termcap"
507 int length; /* length of string sent by key */
508 char *string; /* string sent by key */
509 int value; /* CURSES value of key (9-bit) */
513 struct KEYS *element;
514 struct KEY_STACK *next;
517 struct KEY_STACK *KEY_TOS = NULL;
518 struct KEY_STACK *KEY_POINT;
522 | Not all systems have good terminal information, so we will define
523 | keyboard information here for the most widely used terminal type,
528 struct KEYS vt100[] =
530 { 3, "\033[A", 0403 }, /* key up */
531 { 3, "\033[C", 0405 }, /* key right */
532 { 3, "\033[D", 0404 }, /* key left */
534 { 4, "\033[6~", 0522 }, /* key next page */
535 { 4, "\033[5~", 0523 }, /* key prev page */
536 { 3, "\033[[", 0550 }, /* key end */
537 { 3, "\033[@", 0406 }, /* key home */
538 { 4, "\033[2~", 0513 }, /* key insert char */
540 { 3, "\033[y", 0410 }, /* key F0 */
541 { 3, "\033[P", 0411 }, /* key F1 */
542 { 3, "\033[Q", 0412 }, /* key F2 */
543 { 3, "\033[R", 0413 }, /* key F3 */
544 { 3, "\033[S", 0414 }, /* key F4 */
545 { 3, "\033[t", 0415 }, /* key F5 */
546 { 3, "\033[u", 0416 }, /* key F6 */
547 { 3, "\033[v", 0417 }, /* key F7 */
548 { 3, "\033[l", 0420 }, /* key F8 */
549 { 3, "\033[w", 0421 }, /* key F9 */
550 { 3, "\033[x", 0422 }, /* key F10 */
552 { 5, "\033[10~", 0410 }, /* key F0 */
553 { 5, "\033[11~", 0411 }, /* key F1 */
554 { 5, "\033[12~", 0412 }, /* key F2 */
555 { 5, "\033[13~", 0413 }, /* key F3 */
556 { 5, "\033[14~", 0414 }, /* key F4 */
557 { 5, "\033[15~", 0415 }, /* key F5 */
558 { 5, "\033[17~", 0416 }, /* key F6 */
559 { 5, "\033[18~", 0417 }, /* key F7 */
560 { 5, "\033[19~", 0420 }, /* key F8 */
561 { 5, "\033[20~", 0421 }, /* key F9 */
562 { 5, "\033[21~", 0422 }, /* key F10 */
563 { 5, "\033[23~", 0423 }, /* key F11 */
564 { 5, "\033[24~", 0424 }, /* key F12 */
565 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
566 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
567 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
568 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
569 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
572 | The following are the same keys as above, but with
573 | a different character following the escape char.
576 { 3, "\033OA", 0403 }, /* key up */
577 { 3, "\033OC", 0405 }, /* key right */
578 { 3, "\033OD", 0404 }, /* key left */
579 { 3, "\033OB", 0402 }, /* key down */
580 { 4, "\033O6~", 0522 }, /* key next page */
581 { 4, "\033O5~", 0523 }, /* key prev page */
582 { 3, "\033O[", 0550 }, /* key end */
583 { 3, "\033O@", 0406 }, /* key home */
584 { 4, "\033O2~", 0513 }, /* key insert char */
586 { 3, "\033Oy", 0410 }, /* key F0 */
587 { 3, "\033OP", 0411 }, /* key F1 */
588 { 3, "\033OQ", 0412 }, /* key F2 */
589 { 3, "\033OR", 0413 }, /* key F3 */
590 { 3, "\033OS", 0414 }, /* key F4 */
591 { 3, "\033Ot", 0415 }, /* key F5 */
592 { 3, "\033Ou", 0416 }, /* key F6 */
593 { 3, "\033Ov", 0417 }, /* key F7 */
594 { 3, "\033Ol", 0420 }, /* key F8 */
595 { 3, "\033Ow", 0421 }, /* key F9 */
596 { 3, "\033Ox", 0422 }, /* key F10 */
598 { 5, "\033O10~", 0410 }, /* key F0 */
599 { 5, "\033O11~", 0411 }, /* key F1 */
600 { 5, "\033O12~", 0412 }, /* key F2 */
601 { 5, "\033O13~", 0413 }, /* key F3 */
602 { 5, "\033O14~", 0414 }, /* key F4 */
603 { 5, "\033O15~", 0415 }, /* key F5 */
604 { 5, "\033O17~", 0416 }, /* key F6 */
605 { 5, "\033O18~", 0417 }, /* key F7 */
606 { 5, "\033O19~", 0420 }, /* key F8 */
607 { 5, "\033O20~", 0421 }, /* key F9 */
608 { 5, "\033O21~", 0422 }, /* key F10 */
609 { 5, "\033O23~", 0423 }, /* key F11 */
610 { 5, "\033O24~", 0424 }, /* key F12 */
611 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
612 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
613 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
614 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
615 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
617 { 0, "", 0 } /* end */
622 struct Parameters *next;
626 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
627 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
628 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
629 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
630 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
631 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
632 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
633 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
634 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
635 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
636 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
637 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
638 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
641 int attributes_set[9];
643 static int nc_attributes = 0; /* global attributes for new_curse to observe */
646 struct termio Terminal;
647 struct termio Saved_tty;
649 struct sgttyb Terminal;
650 struct sgttyb Saved_tty;
657 char *String_table[1024];
661 static char nc_scrolling_ability = FALSE;
663 char *terminfo_path[] = {
665 "/usr/share/lib/terminfo",
666 "/usr/share/terminfo",
672 #if defined(__STDC__) || defined(__cplusplus)
676 #endif /* __STDC__ */
678 int tc_Get_int P_((int));
679 void CAP_PARSE P_((void));
680 void Find_term P_((void));
689 extern char *fgets();
690 extern char *malloc();
691 extern char *getenv();
692 FILE *fopen(); /* declaration for open function */
693 #endif /* HAS_STDLIB */
694 #endif /* __STDC__ */
699 | Copy the contents of one window to another.
703 copy_window(origin, destination)
704 WINDOW *origin, *destination;
707 struct _line *orig, *dest;
709 orig = origin->first_line;
710 dest = destination->first_line;
713 row < (min(origin->Num_lines, destination->Num_lines));
717 column < (min(origin->Num_cols, destination->Num_cols));
720 dest->row[column] = orig->row[column];
721 dest->attributes[column] = orig->attributes[column];
723 dest->changed = orig->changed;
724 dest->scroll = orig->scroll;
725 dest->last_char = min(orig->last_char, destination->Num_cols);
726 orig = orig->next_screen;
727 dest = dest->next_screen;
729 destination->LX = min((destination->Num_cols - 1), origin->LX);
730 destination->LY = min((destination->Num_lines - 1), origin->LY);
731 destination->Attrib = origin->Attrib;
732 destination->scroll_up = origin->scroll_up;
733 destination->scroll_down = origin->scroll_down;
734 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
745 signal(SIGWINCH, reinitscr);
747 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
749 if (ws.ws_row == LINES && ws.ws_col == COLS)
756 #endif /* TIOCGWINSZ */
757 local_virt = newwin(LINES, COLS, 0, 0);
758 local_std = newwin(LINES, COLS, 0, 0);
759 local_cur = newwin(LINES, COLS, 0, 0);
760 copy_window(virtual_scr, local_virt);
761 copy_window(stdscr, local_std);
762 copy_window(curscr, local_cur);
766 virtual_scr = local_virt;
770 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
771 interrupt_flag = TRUE;
773 #endif /* SIGWINCH */
776 initscr() /* initialize terminal for operations */
781 char *columns_string;
787 printf("starting initscr \n");fflush(stdout);
793 #endif /* BSD_SELECT */
801 value = ioctl(0, TCGETA, &Terminal);
802 if (Terminal.c_cflag & PARENB)
804 if (Terminal.c_cflag & PARENB)
809 if ((Terminal.c_cflag & CS8) == CS8)
813 else if ((Terminal.c_cflag & CS7) == CS7)
815 else if ((Terminal.c_cflag & CS6) == CS6)
819 value = Terminal.c_cflag & 037;
821 case 01: speed = 50.0;
823 case 02: speed = 75.0;
825 case 03: speed = 110.0;
827 case 04: speed = 134.5;
829 case 05: speed = 150.0;
831 case 06: speed = 200.0;
833 case 07: speed = 300.0;
835 case 010: speed = 600.0;
837 case 011: speed = 900.0;
839 case 012: speed = 1200.0;
841 case 013: speed = 1800.0;
843 case 014: speed = 2400.0;
845 case 015: speed = 3600.0;
847 case 016: speed = 4800.0;
849 case 017: speed = 7200.0;
851 case 020: speed = 9600.0;
853 case 021: speed = 19200.0;
855 case 022: speed = 38400.0;
857 default: speed = 0.0;
860 value = ioctl(0, TIOCGETP, &Terminal);
861 if (Terminal.sg_flags & EVENP)
863 else if (Terminal.sg_flags & ODDP)
865 value = Terminal.sg_ospeed;
867 case 01: speed = 50.0;
869 case 02: speed = 75.0;
871 case 03: speed = 110.0;
873 case 04: speed = 134.5;
875 case 05: speed = 150.0;
877 case 06: speed = 200.0;
879 case 07: speed = 300.0;
881 case 010: speed = 600.0;
883 case 011: speed = 1200.0;
885 case 012: speed = 1800.0;
887 case 013: speed = 2400.0;
889 case 014: speed = 4800.0;
891 case 015: speed = 9600.0;
893 default: speed = 0.0;
896 chars_per_millisecond = (0.001 * speed) / 8.0;
897 TERMINAL_TYPE = getenv("TERM");
898 if (TERMINAL_TYPE == NULL)
900 printf("unknown terminal type\n");
905 TERM_PATH = getenv("TERMINFO");
906 if (TERM_PATH != NULL)
908 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
909 Term_File_name = malloc(Data_Line_len);
910 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
911 Fildes = open(Term_File_name, O_RDONLY);
914 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
915 Fildes = open(Term_File_name, O_RDONLY);
919 while ((Fildes == -1) && (terminfo_path[counter] != NULL))
921 TERM_PATH = terminfo_path[counter];
922 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
923 Term_File_name = malloc(Data_Line_len);
924 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
925 Fildes = open(Term_File_name, O_RDONLY);
928 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
929 Fildes = open(Term_File_name, O_RDONLY);
935 free(Term_File_name);
936 Term_File_name = NULL;
939 TERM_INFO = INFO_PARSE();
942 | termcap information can be in the TERMCAP env variable, if so
943 | use that, otherwise check the /etc/termcap file
945 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
947 if (*Term_File_name != '/')
948 Term_File_name = TERMCAP;
952 Term_File_name = TERMCAP;
954 if ((TFP = fopen(Term_File_name, "r")) == NULL)
956 printf("unable to open %s file \n", TERMCAP);
959 for (value = 0; value < 1024; value++)
960 String_table[value] = NULL;
961 for (value = 0; value < 128; value++)
963 for (value = 0; value < 128; value++)
965 Data_Line = malloc(512);
966 if (pointer && *pointer != '/')
968 TERM_data_ptr = pointer;
977 if (String_table[pc__] == NULL)
978 String_table[pc__] = "\0";
979 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
981 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
986 LINES = Numbers[li__];
987 COLS = Numbers[co__];
988 if ((lines_string = getenv("LINES")) != NULL)
990 value = atoi(lines_string);
994 if ((columns_string = getenv("COLUMNS")) != NULL)
996 value = atoi(columns_string);
1002 | get the window size
1004 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1012 virtual_scr = newwin(LINES, COLS, 0, 0);
1013 stdscr = newwin(LINES, COLS, 0, 0);
1014 curscr = newwin(LINES, COLS, 0, 0);
1015 wmove(stdscr, 0, 0);
1017 Repaint_screen = TRUE;
1019 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1023 | reset size of windows and LINES and COLS if term window
1026 signal(SIGWINCH, reinitscr);
1027 #endif /* SIGWINCH */
1030 | check if scrolling is available
1033 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1034 (String_table[dl__])) || ((String_table[cs__])
1035 && (String_table[sr__]));
1041 Get_int() /* get a two-byte integer from the terminfo file */
1047 Low_byte = *((unsigned char *) TERM_data_ptr++);
1048 High_byte = *((unsigned char *) TERM_data_ptr++);
1052 Low_byte = High_byte;
1055 if ((High_byte == 255) && (Low_byte == 255))
1058 return(Low_byte + (High_byte * 256));
1062 INFO_PARSE() /* parse off the data in the terminfo data file */
1065 int magic_number = 0;
1070 int Num_strings = 0;
1071 int string_table_len = 0;
1074 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1075 Data_Line_len = read(Fildes, Data_Line, 10240);
1076 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1081 magic_number = Get_int();
1083 | if magic number not right, reverse byte order and check again
1085 if (magic_number != 282)
1090 magic_number = Get_int();
1091 if (magic_number != 282)
1095 | get the number of each type in the terminfo data file
1097 Num_names = Get_int();
1098 Num_bools = Get_int();
1099 Num_ints = Get_int();
1100 Num_strings = Get_int();
1101 string_table_len = Get_int();
1102 Strings = malloc(string_table_len);
1103 while (Num_names > 0)
1112 Booleans[counter++] = *TERM_data_ptr++;
1114 if ((unsigned long)TERM_data_ptr & 1) /* force alignment */
1120 Numbers[counter] = Get_int();
1123 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1124 memcpy(Strings, temp_ptr, string_table_len);
1129 if ((offset=Get_int()) != -1)
1131 if (String_table[counter] == NULL)
1132 String_table[counter] = Strings + offset;
1135 String_table[counter] = NULL;
1142 #endif /* ifndef CAP */
1145 AtoI() /* convert ascii text to integers */
1150 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1152 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1159 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1164 struct KEY_STACK *Spoint;
1169 while (key_def <= kf63__)
1171 if (key_def == ke__)
1173 else if (key_def == (K5__ + 1))
1175 else if (key_def == (kcbt__ + 1))
1177 else if (key_def == (kUND__ + 1))
1179 if (String_table[key_def] != NULL)
1181 if (KEY_TOS == NULL)
1182 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1186 while (Spoint->next != NULL)
1187 Spoint = Spoint->next;
1188 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1189 Spoint = Spoint->next;
1191 Spoint->next = NULL;
1192 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1193 Spoint->element->string = String_table[key_def];
1194 Spoint->element->length = strlen(String_table[key_def]);
1195 Spoint->element->value = Key_vals[Counter];
1196 Klen = strlen(Spoint->element->string);
1197 if (Klen > Max_Key_len)
1200 | Some terminal types accept keystrokes of the form
1201 | \E[A and \EOA, substituting '[' for 'O'. Make a
1202 | duplicate of such key strings (since the
1203 | database will only have one version) so new_curse
1204 | can understand both.
1206 if ((Spoint->element->length > 1) &&
1207 ((String_table[key_def][1] == '[') ||
1208 (String_table[key_def][1] == 'O')))
1210 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1211 Spoint = Spoint->next;
1212 Spoint->next = NULL;
1213 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1214 Spoint->element->length = strlen(String_table[key_def]);
1215 Spoint->element->string = malloc(Spoint->element->length + 1);
1216 strcpy(Spoint->element->string, String_table[key_def]);
1217 Spoint->element->value = Key_vals[Counter];
1218 Klen = strlen(Spoint->element->string);
1219 if (Klen > Max_Key_len)
1222 if (String_table[key_def][1] == '[')
1223 Spoint->element->string[1] = 'O';
1225 Spoint->element->string[1] = '[';
1234 | insert information about keys for a vt100 terminal
1242 struct KEY_STACK *Spoint;
1245 while (Spoint->next != NULL)
1246 Spoint = Spoint->next;
1247 for (counter = 0; vt100[counter].length != 0; counter++)
1249 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1250 Spoint = Spoint->next;
1251 Spoint->next = NULL;
1252 Spoint->element = &vt100[counter];
1253 Klen = strlen(Spoint->element->string);
1254 if (Klen > Max_Key_len)
1261 String_Get(param) /* read the string */
1270 while (*TERM_data_ptr != '=')
1272 Temp = ++TERM_data_ptr;
1274 while ((*Temp != ':') && (*Temp != (char)NULL))
1279 if (Counter == 1) /* no data */
1281 String = Temp = malloc(Counter);
1282 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1284 if (*TERM_data_ptr == '\\')
1287 if (*TERM_data_ptr == 'n')
1289 else if (*TERM_data_ptr == 't')
1291 else if (*TERM_data_ptr == 'b')
1293 else if (*TERM_data_ptr == 'r')
1295 else if (*TERM_data_ptr == 'f')
1297 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1298 *Temp = '\033'; /* escape */
1299 else if (*TERM_data_ptr == '\\')
1301 else if (*TERM_data_ptr == '\'')
1303 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1306 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1308 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1309 TERM_data_ptr++; /* ? */
1317 else if (*TERM_data_ptr == '^')
1320 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1321 *Temp = *TERM_data_ptr - '@';
1322 else if (*TERM_data_ptr == '?')
1328 *Temp++ = *TERM_data_ptr++;
1335 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1342 tc_Get_int(param) /* read the integer */
1349 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1357 while (*TERM_data_ptr != ':')
1364 Find_term() /* find terminal description in termcap file */
1369 Ftemp = Name = malloc(strlen(TERMINAL_TYPE) + 2);
1370 strcpy(Name, TERMINAL_TYPE);
1371 while (*Ftemp != (char)NULL)
1374 *Ftemp = (char)NULL;
1376 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1377 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1379 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1381 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1383 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1384 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1386 if (*TERM_data_ptr == '|')
1389 *TERM_data_ptr = (char)NULL;
1395 printf("terminal type %s not found\n", TERMINAL_TYPE);
1401 CAP_PARSE() /* parse off the data in the termcap data file */
1408 while (*TERM_data_ptr != (char)NULL)
1410 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1412 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1415 Booleans[offset] = TRUE;
1420 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1422 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1425 Numbers[offset] = tc_Get_int(Numbers[offset]);
1431 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1433 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1436 String_table[offset] = String_Get(String_table[offset]);
1441 if (!strncmp(TERM_data_ptr, "tc=", 3))
1442 tc_ = String_Get(NULL);
1443 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1445 if (*TERM_data_ptr == ':')
1448 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1451 TERMINAL_TYPE = tc_;
1460 #endif /* ifdef CAP */
1463 Screenalloc(columns)
1469 tmp = (struct _line *) malloc(sizeof (struct _line));
1470 tmp->row = malloc(columns + 1);
1471 tmp->attributes = malloc(columns + 1);
1472 tmp->prev_screen = NULL;
1473 tmp->next_screen = NULL;
1474 for (i = 0; i < columns; i++)
1477 tmp->attributes[i] = '\0';
1479 tmp->scroll = tmp->changed = FALSE;
1481 tmp->attributes[0] = '\0';
1482 tmp->row[columns] = '\0';
1483 tmp->attributes[columns] = '\0';
1488 WINDOW *newwin(lines, cols, start_l, start_c)
1489 int lines, cols; /* number of lines and columns to be in window */
1490 int start_l, start_c; /* starting line and column to be inwindow */
1493 struct _line *temp_screen;
1496 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1497 Ntemp->SR = start_l;
1498 Ntemp->SC = start_c;
1499 Ntemp->Num_lines = lines;
1500 Ntemp->Num_cols = cols;
1503 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1504 Ntemp->SCROLL_CLEAR = FALSE;
1505 Ntemp->Attrib = FALSE;
1506 Ntemp->first_line = temp_screen = Screenalloc(cols);
1507 Ntemp->first_line->number = 0;
1508 Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
1510 Ntemp->line_array[0] = Ntemp->first_line;
1512 for (i = 1; i < lines; i++)
1514 temp_screen->next_screen = Screenalloc(cols);
1515 temp_screen->next_screen->number = i;
1516 temp_screen->next_screen->prev_screen = temp_screen;
1517 temp_screen = temp_screen->next_screen;
1518 Ntemp->line_array[i] = temp_screen;
1520 Ntemp->first_line->prev_screen = NULL;
1521 temp_screen->next_screen = NULL;
1527 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1529 int p_list[]; /* stack of values */
1530 int place; /* place keeper of top of stack */
1532 char *Otemp; /* temporary string pointer to parse output */
1542 p1 = p_list[--place];
1543 p2 = p_list[--place];
1547 if ((*Otemp >= '0') && (*Otemp <= '9'))
1549 delay = atoi(Otemp);
1550 while ((*Otemp >= '0') && (*Otemp <= '9'))
1555 while (*Otemp != (char)NULL)
1560 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1564 else if (*Otemp == '2')
1566 else if (*Otemp == '3')
1568 else if (*Otemp == '+')
1574 else if (*Otemp == '.')
1579 else if (*Otemp == '>')
1590 else if (*Otemp == 'r')
1596 else if (*Otemp == 'i')
1601 else if (*Otemp == '%')
1603 else if (*Otemp == 'n')
1608 else if (*Otemp == 'B')
1610 p1 = (16 * (p1/10)) + (p1 % 10);
1611 p2 = (16 * (p2/10)) + (p2 % 10);
1613 else if (*Otemp == 'D')
1615 p1 = (p1 - 2 * (p1 % 16));
1616 p2 = (p2 - 2 * (p2 % 16));
1625 chars = delay * chars_per_millisecond;
1627 if ((chars - delay) > 0.0)
1629 for (; delay > 0; delay--)
1630 putchar(*String_table[pc__]);
1637 char *Otemp; /* temporary string pointer to parse output */
1643 Operation(Temp_Stack, place) /* handle conditional operations */
1652 temp = Temp_Stack[--place];
1655 else if (!strncmp(Otemp, "2d", 2))
1657 temp = Temp_Stack[--place];
1658 printf("%2d", temp);
1662 else if (!strncmp(Otemp, "3d", 2))
1664 temp = Temp_Stack[--place];
1665 printf("%0d", temp);
1669 else if (!strncmp(Otemp, "02d", 3))
1671 temp = Temp_Stack[--place];
1672 printf("%02d", temp);
1677 else if (!strncmp(Otemp, "03d", 3))
1679 temp = Temp_Stack[--place];
1680 printf("%03d", temp);
1685 else if (*Otemp == '+')
1688 temp = Temp_Stack[--place];
1689 temp += Temp_Stack[--place];
1690 Temp_Stack[place++] = temp;
1692 else if (*Otemp == '-')
1695 temp = Temp_Stack[--place];
1696 temp -= Temp_Stack[--place];
1697 Temp_Stack[place++] = temp;
1699 else if (*Otemp == '*')
1702 temp = Temp_Stack[--place];
1703 temp *= Temp_Stack[--place];
1704 Temp_Stack[place++] = temp;
1706 else if (*Otemp == '/')
1709 temp = Temp_Stack[--place];
1710 temp /= Temp_Stack[--place];
1711 Temp_Stack[place++] = temp;
1713 else if (*Otemp == 'm')
1716 temp = Temp_Stack[--place];
1717 temp %= Temp_Stack[--place];
1718 Temp_Stack[place++] = temp;
1720 else if (*Otemp == '&')
1723 temp = Temp_Stack[--place];
1724 temp &= Temp_Stack[--place];
1725 Temp_Stack[place++] = temp;
1727 else if (*Otemp == '|')
1730 temp = Temp_Stack[--place];
1731 temp |= Temp_Stack[--place];
1732 Temp_Stack[place++] = temp;
1734 else if (*Otemp == '^')
1737 temp = Temp_Stack[--place];
1738 temp ^= Temp_Stack[--place];
1739 Temp_Stack[place++] = temp;
1741 else if (*Otemp == '=')
1744 temp = Temp_Stack[--place];
1745 temp = (temp == Temp_Stack[--place]);
1746 Temp_Stack[place++] = temp;
1748 else if (*Otemp == '>')
1751 temp = Temp_Stack[--place];
1752 temp = temp > Temp_Stack[--place];
1753 Temp_Stack[place++] = temp;
1755 else if (*Otemp == '<')
1758 temp = Temp_Stack[--place];
1759 temp = temp < Temp_Stack[--place];
1760 Temp_Stack[place++] = temp;
1762 else if (*Otemp == 'c')
1765 putchar(Temp_Stack[--place]);
1767 else if (*Otemp == 'i')
1773 else if (*Otemp == '%')
1778 else if (*Otemp == '!')
1780 temp = ! Temp_Stack[--place];
1781 Temp_Stack[place++] = temp;
1784 else if (*Otemp == '~')
1786 temp = ~Temp_Stack[--place];
1787 Temp_Stack[place++] = temp;
1790 else if (*Otemp == 'p')
1793 Temp_Stack[place++] = p[*Otemp - '0'];
1796 else if (*Otemp == 'P')
1799 Temp_Stack[place++] = variable[*Otemp - 'a'];
1802 else if (*Otemp == 'g')
1805 variable[*Otemp - 'a'] = Temp_Stack[--place];
1808 else if (*Otemp == '\'')
1811 Temp_Stack[place++] = *Otemp;
1815 else if (*Otemp == '{')
1819 Temp_Stack[place++] = temp;
1820 while (*Otemp != '}')
1828 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1838 int Cond_Stack[128];
1861 for (temp = 1; (place != 0); temp++)
1863 p[temp] = p_list[--place];
1868 while (*Otemp != '\0')
1873 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1883 | find the end of the
1884 | conditional statement
1886 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != '\0'))
1892 Cond_place = Operation(Cond_Stack, Cond_place);
1896 | if condition is true
1898 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1908 else /* condition is false */
1911 | find 'else' or end
1914 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != '\0'))
1917 | if an 'else' found
1919 if ((*Otemp != '\0') && (!strncmp(Otemp, "%e", 2)))
1925 | check for 'then' part
1927 while ((*tchar != '\0') && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1939 | if end of if found,
1943 else if (!strncmp(tchar, "%;", 2))
1952 | if end of if found,
1956 else if ((*Otemp != '\0') && (!strncmp(Otemp, "%;", 2)))
1962 else /* Otemp == NULL */
1976 while ((*Otemp != '\0') && (strncmp(Otemp, "%;", 2)))
1990 Top_of_stack = Operation(Stack, Top_of_stack);
1993 else if (!strncmp(Otemp, "$<", 2))
1997 delay = atoi(Otemp);
1998 while (*Otemp != '>')
2001 chars = delay * chars_per_millisecond;
2003 if ((chars - delay) > 0.0)
2005 if (String_table[pc__] == NULL)
2008 temp = *String_table[pc__];
2009 for (; delay > 0; delay--)
2023 wmove(window, row, column) /* move cursor to indicated position in window */
2027 if ((row < window->Num_lines) && (column < window->Num_cols))
2029 window->LX = column;
2035 clear_line(line, column, cols)
2042 if (column > line->last_char)
2044 for (j = line->last_char; j < column; j++)
2047 line->attributes[j] = '\0';
2050 line->last_char = column;
2051 line->row[column] = '\0';
2052 line->attributes[column] = '\0';
2053 line->changed = TRUE;
2057 werase(window) /* clear the specified window */
2063 window->SCROLL_CLEAR = CLEAR;
2064 window->scroll_up = window->scroll_down = 0;
2065 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2066 clear_line(tmp, 0, window->Num_cols);
2070 wclrtoeol(window) /* erase from current cursor position to end of line */
2076 window->SCROLL_CLEAR = CHANGE;
2077 column = window->LX;
2079 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2080 tmp = tmp->next_screen;
2081 clear_line(tmp, column, window->Num_cols);
2085 wrefresh(window) /* flush all previous output */
2088 wnoutrefresh(window);
2093 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2094 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2096 if (temp->number == -1)
2097 fprintf(stderr, "line moved ");
2099 fprintf(stderr, "scroll_x is set: ");
2100 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2102 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2103 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2104 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2106 if (temp->number == -1)
2107 fprintf(stderr, "line moved ");
2109 fprintf(stderr, "scroll_x is set: ");
2110 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2112 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2113 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2114 fprintf(stderr, "line=%s|\n", temp->row);
2118 virtual_scr->SCROLL_CLEAR = FALSE;
2119 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2127 struct _line *user_line;
2128 int line_counter = 0;
2130 for (line_counter = 0, user_line = window->first_line;
2131 line_counter < window->Num_lines; line_counter++)
2133 user_line->changed = TRUE;
2135 window->SCROLL_CLEAR = TRUE;
2139 wnoutrefresh(window)
2142 struct _line *user_line;
2143 struct _line *virtual_line;
2144 int line_counter = 0;
2148 if (window->SR >= virtual_scr->Num_lines)
2150 user_line = window->first_line;
2151 virtual_line = virtual_scr->first_line;
2152 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2153 virtual_scr->LX = window->LX + window->SC;
2154 virtual_scr->LY = window->LY + window->SR;
2155 virtual_scr->scroll_up = window->scroll_up;
2156 virtual_scr->scroll_down = window->scroll_down;
2157 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2159 for (line_counter = 0; line_counter < window->SR; line_counter++)
2161 virtual_line = virtual_line->next_screen;
2163 for (line_counter = 0; (line_counter < window->Num_lines)
2164 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2167 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2169 for (user_col = 0, virt_col = window->SC;
2170 (virt_col < virtual_scr->Num_cols)
2171 && (user_col < user_line->last_char);
2172 virt_col++, user_col++)
2174 virtual_line->row[virt_col] = user_line->row[user_col];
2175 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2177 for (user_col = user_line->last_char,
2178 virt_col = window->SC + user_line->last_char;
2179 (virt_col < virtual_scr->Num_cols)
2180 && (user_col < window->Num_cols);
2181 virt_col++, user_col++)
2183 virtual_line->row[virt_col] = ' ';
2184 virtual_line->attributes[virt_col] = '\0';
2187 if (virtual_scr->Num_cols != window->Num_cols)
2189 if (virtual_line->last_char < (user_line->last_char + window->SC))
2191 if (virtual_line->row[virtual_line->last_char] == '\0')
2192 virtual_line->row[virtual_line->last_char] = ' ';
2193 virtual_line->last_char =
2194 min(virtual_scr->Num_cols,
2195 (user_line->last_char + window->SC));
2199 virtual_line->last_char = user_line->last_char;
2200 virtual_line->row[virtual_line->last_char] = '\0';
2201 virtual_line->changed = user_line->changed;
2202 virtual_line = virtual_line->next_screen;
2203 user_line = user_line->next_screen;
2205 window->SCROLL_CLEAR = FALSE;
2206 window->scroll_up = window->scroll_down = 0;
2207 last_window_refreshed = window;
2211 flushinp() /* flush input */
2216 ungetch(c) /* push a character back on input */
2220 in_buff[bufp++] = c;
2235 tv.tv_usec = 500000; /* half a second */
2237 Time_Out = FALSE; /* just in case */
2239 ret_val = select(nfds, &fds, 0, 0, &tv);
2242 | if ret_val is less than zero, there was no input
2243 | otherwise, get a character and return it
2252 return(read(0, &temp, 1)? temp : -1);
2257 wgetch(window) /* get character from specified window */
2268 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2270 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2271 #else /* BSD_SELECT */
2273 in_value = ((bufp > 0) ? in_buff[--bufp] :
2274 (read(0, &temp, 1)> 0) ? temp : -1);
2279 old_arg = fcntl(0, F_GETFL, 0);
2280 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2282 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2285 fcntl(0, F_SETFL, old_arg);
2290 #endif /* BSD_SELECT */
2295 if ((Parity) && (Num_bits < 8))
2296 /* strip eighth bit if parity in use */
2299 else if (interrupt_flag)
2301 interrupt_flag = FALSE;
2302 in_value = wgetch(window);
2305 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2306 in_value = Get_key(in_value);
2312 Clear(arg) /* notify that time out has occurred */
2317 fprintf(stderr, "inside Clear()\n");
2321 #endif /* BSD_SELECT */
2324 Get_key(first_char) /* try to decode key sequence */
2325 int first_char; /* first character of sequence */
2333 struct termio Gterminal;
2335 struct sgttyb Gterminal;
2337 struct KEY_STACK *St_point;
2338 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2340 #endif /* BSD_SELECT */
2344 string[Count++] = first_char;
2345 string[Count] = '\0';
2348 signal(SIGALRM, Clear);
2350 #endif /* BSD_SELECT */
2353 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2354 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2355 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2359 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2361 in_char = wgetch(stdscr);
2363 fprintf(stderr, "back in GetKey()\n");
2368 string[Count++] = in_char;
2369 string[Count] = '\0';
2371 while ((St_point != NULL) && (!Found))
2373 if (!strcmp(string, St_point->element->string))
2376 St_point = St_point->next;
2383 #endif /* BSD_SELECT */
2385 /* value = ioctl(0, TCSETA, &Terminal);*/
2387 value = ioctl(0, TIOCSETP, &Terminal);
2388 /* value = fcntl(0, F_SETFL, old_arg);*/
2393 return(St_point->element->value);
2399 if ((string[--Count] != -1) &&
2400 ((unsigned char) (string[Count]) != 255))
2403 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2405 ungetch(string[Count]);
2413 waddch(window, c) /* output the character in the specified window */
2418 int shift; /* number of spaces to shift if a tab */
2419 struct _line *tmpline;
2422 /*printf("starting waddch \n");fflush(stdout);*/
2424 column = window->LX;
2427 shift = (column + 1) % 8;
2435 waddch(window, ' ');
2438 else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
2440 if ((c == '~') && (Booleans[hz__]))
2443 if (( c != '\b') && (c != '\n') && (c != '\r'))
2445 tmpline = window->line_array[window->LY];
2446 tmpline->row[column] = c;
2447 tmpline->attributes[column] = window->Attrib;
2448 tmpline->changed = TRUE;
2449 if (column >= tmpline->last_char)
2451 if (column > tmpline->last_char)
2452 for (j = tmpline->last_char; j < column; j++)
2454 tmpline->row[j] = ' ';
2455 tmpline->attributes[j] = '\0';
2457 tmpline->row[column + 1] = '\0';
2458 tmpline->attributes[column + 1] = '\0';
2459 tmpline->last_char = column + 1;
2465 window->LX = window->Num_cols;
2474 if (window->LX >= window->Num_cols)
2478 if (window->LY >= window->Num_lines)
2480 window->LY = window->Num_lines - 1;
2481 /* window->LY = row;
2482 wmove(window, 0, 0);
2484 wmove(window, row, 0);*/
2487 window->SCROLL_CLEAR = CHANGE;
2491 winsertln(window) /* insert a blank line into the specified window */
2498 window->scroll_down += 1;
2499 window->SCROLL_CLEAR = SCROLL;
2500 column = window->LX;
2502 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2503 tmp = tmp->next_screen;
2504 if (tmp->prev_screen != NULL)
2505 tmp->prev_screen->next_screen = NULL;
2507 clear_line(tmp1, 0, window->Num_cols);
2509 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2510 tmp = tmp->next_screen;
2511 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2513 tmp1->next_screen = tmp->next_screen;
2514 tmp->next_screen = tmp1;
2515 tmp->changed = TRUE;
2516 tmp->next_screen->prev_screen = tmp;
2518 else if (window->Num_lines > 1)
2520 if (tmp->prev_screen != NULL)
2521 tmp->prev_screen->next_screen = tmp1;
2522 tmp1->prev_screen = tmp->prev_screen;
2523 tmp->prev_screen = tmp1;
2524 tmp1->next_screen = tmp;
2525 tmp->changed = TRUE;
2528 if (window->LY == 0)
2529 window->first_line = tmp1;
2531 for (row = 0, tmp1 = window->first_line;
2532 row < window->Num_lines; row++)
2534 window->line_array[row] = tmp1;
2535 tmp1 = tmp1->next_screen;
2540 wdeleteln(window) /* delete a line in the specified window */
2545 struct _line *tmpline;
2547 if (window->Num_lines > 1)
2549 window->scroll_up += 1;
2550 window->SCROLL_CLEAR = SCROLL;
2551 column = window->LX;
2553 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2554 tmp = tmp->next_screen;
2555 if (window->LY == 0)
2556 window->first_line = tmp->next_screen;
2557 if (tmp->prev_screen != NULL)
2558 tmp->prev_screen->next_screen = tmp->next_screen;
2559 if (tmp->next_screen != NULL)
2561 tmp->next_screen->changed = TRUE;
2562 tmp->next_screen->scroll = UP;
2563 tmp->next_screen->prev_screen = tmp->prev_screen;
2566 clear_line(tmpline, 0, window->Num_cols);
2567 tmpline->number = -1;
2568 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2569 tmp = tmp->next_screen;
2572 tmp->next_screen = tmpline;
2573 tmp->next_screen->prev_screen = tmp;
2574 tmp->changed = TRUE;
2575 tmp = tmp->next_screen;
2579 tmp->next_screen = NULL;
2581 for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
2583 window->line_array[row] = tmp;
2584 tmp = tmp->next_screen;
2589 clear_line(window->first_line, 0, window->Num_cols);
2594 wclrtobot(window) /* delete from current position to end of the window */
2600 window->SCROLL_CLEAR |= CLEAR;
2601 column = window->LX;
2603 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2604 tmp = tmp->next_screen;
2605 clear_line(tmp, column, window->Num_cols);
2606 for (row = (window->LY + 1); row < window->Num_lines; row++)
2608 tmp = tmp->next_screen;
2609 clear_line(tmp, 0, window->Num_cols);
2611 wmove(window, row, column);
2615 wstandout(window) /* begin standout mode in window */
2618 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2619 window->Attrib |= A_STANDOUT;
2623 wstandend(window) /* end standout mode in window */
2626 window->Attrib &= ~A_STANDOUT;
2630 waddstr(window, string) /* write 'string' in window */
2636 for (wstring = string; *wstring != '\0'; wstring++)
2637 waddch(window, *wstring);
2641 clearok(window, flag) /* erase screen and redraw at next refresh */
2645 Repaint_screen = TRUE;
2650 echo() /* turn on echoing */
2655 Terminal.c_lflag |= ECHO; /* enable echo */
2656 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2658 Terminal.sg_flags |= ECHO; /* enable echo */
2659 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2664 noecho() /* turn off echoing */
2669 Terminal.c_lflag &= ~ECHO; /* disable echo */
2670 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2672 Terminal.sg_flags &= ~ECHO; /* disable echo */
2673 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2678 raw() /* set to read characters immediately */
2683 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2684 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2685 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2687 Terminal.c_lflag &= ~FLUSHO;
2690 Terminal.c_lflag &= ~PENDIN;
2693 Terminal.c_lflag &= ~IEXTEN;
2695 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2696 Terminal.c_cc[VTIME] = 0; /* timeout value */
2697 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2698 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2700 Terminal.sg_flags |= RAW; /* enable raw mode */
2701 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2706 noraw() /* set to normal character read mode */
2711 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2712 Terminal.c_lflag |= ISIG; /* enable signal checking */
2713 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2714 Terminal.c_cc[VEOL] = '\0'; /* EOL = 0 */
2715 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2716 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2718 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2719 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2720 /* old_arg = fcntl(0, F_GETFL, 0);
2721 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2731 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2732 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2742 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2743 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2744 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2764 nodelay(window, flag)
2778 keypad(window, flag)
2783 String_Out(String_table[ks__], NULL, 0);
2785 String_Out(String_table[ke__], NULL, 0);
2789 savetty() /* save current tty stats */
2794 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2796 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2801 resetty() /* restore previous tty stats */
2806 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2808 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2813 endwin() /* end windows */
2815 keypad(stdscr, FALSE);
2816 initialized = FALSE;
2818 delwin(virtual_scr);
2823 /* old_arg = fcntl(0, F_GETFL, 0);
2824 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2830 delwin(window) /* delete the window structure */
2835 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2837 window->first_line = window->first_line->next_screen;
2838 free(window->first_line->prev_screen->row);
2839 free(window->first_line->prev_screen->attributes);
2840 free(window->first_line->prev_screen);
2842 if (window == last_window_refreshed)
2843 last_window_refreshed = 0;
2844 if (window->first_line != NULL)
2846 free(window->first_line->row);
2847 free(window->first_line->attributes);
2848 free(window->first_line);
2857 #else /* __STDC__ */
2859 wprintw(WINDOW *window, const char *format, ...)
2860 #endif /* __STDC__ */
2875 window = va_arg(ap, WINDOW *);
2876 format = va_arg(ap, char *);
2877 #else /* __STDC__ */
2878 va_start(ap, format);
2879 #endif /* __STDC__ */
2881 fpoint = (char *) format;
2882 while (*fpoint != '\0')
2889 value = va_arg(ap, int);
2890 iout(window, value);
2892 else if (*fpoint == 'c')
2894 value = va_arg(ap, int);
2895 waddch(window, value);
2897 else if (*fpoint == 's')
2899 wtemp = va_arg(ap, char *);
2900 waddstr(window, wtemp);
2904 else if (*fpoint == '\\')
2908 waddch(window, '\n');
2909 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2912 while ((*fpoint >= '0') && (*fpoint <= '9'))
2914 value = (value * 8) + (*fpoint - '0');
2917 waddch(window, value);
2922 waddch(window, *fpoint++);
2926 #endif /* __STDC__ */
2930 iout(window, value) /* output characters */
2936 if ((i = value / 10) != 0)
2938 waddch(window, ((value % 10) + '0'));
2942 Comp_line(line1, line2) /* compare lines */
2943 struct _line *line1;
2944 struct _line *line2;
2951 if (line1->last_char != line2->last_char)
2956 att1 = line1->attributes;
2957 att2 = line2->attributes;
2959 while ((c1[i] != '\0') && (c2[i] != '\0') && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2962 if ((count1 == 1) && (c1[i] == '\0') && (c2[i] == '\0'))
2963 count1 = 0; /* both lines blank */
2964 else if ((c1[i] == '\0') && (c2[i] == '\0'))
2965 count1 = -1; /* equal */
2967 count1 = 1; /* lines unequal */
2972 Insert_line(row, end_row, window) /* insert line into screen */
2981 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2982 tmp = tmp->next_screen;
2983 if ((end_row + window->SR) == 0)
2984 curscr->first_line = curscr->first_line->next_screen;
2987 | find bottom line to delete
2989 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2990 tmp = tmp->next_screen;
2991 if (tmp->prev_screen != NULL)
2992 tmp->prev_screen->next_screen = tmp->next_screen;
2993 if (tmp->next_screen != NULL)
2994 tmp->next_screen->prev_screen = tmp->prev_screen;
2997 | clear deleted line
2999 clear_line(tmp, 0, window->Num_cols);
3001 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3002 tmp = tmp->next_screen;
3004 for (i = 0, tmp = top_of_win; i < row; i++)
3005 tmp = tmp->next_screen;
3006 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
3007 tmp->prev_screen->next_screen = tmp1;
3008 tmp1->prev_screen = tmp->prev_screen;
3009 tmp->prev_screen = tmp1;
3010 tmp1->next_screen = tmp;
3011 if ((row + window->SR) == 0)
3012 curscr->first_line = tmp1;
3013 if (tmp1->next_screen != NULL)
3014 tmp1 = tmp1->next_screen;
3016 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3018 Position(window, (window->SR + end_row), 0);
3019 String_Out(String_table[dl__], NULL, 0);
3021 Position(window, (window->SR + row), 0);
3022 if (String_table[al__] != NULL)
3023 String_Out(String_table[al__], NULL, 0);
3025 String_Out(String_table[sr__], NULL, 0);
3027 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3028 top_of_win = top_of_win->next_screen;
3034 Delete_line(row, end_row, window) /* delete a line on screen */
3045 tmp = curscr->first_line;
3046 while (i < window->SR)
3049 tmp = tmp->next_screen;
3052 | find line to delete
3055 if ((row + window->SR) == 0)
3056 curscr->first_line = top_of_win->next_screen;
3057 for (i = 0, tmp = top_of_win; i < row; i++)
3058 tmp = tmp->next_screen;
3059 if (tmp->prev_screen != NULL)
3060 tmp->prev_screen->next_screen = tmp->next_screen;
3061 if (tmp->next_screen != NULL)
3062 tmp->next_screen->prev_screen = tmp->prev_screen;
3063 tmp2 = tmp->next_screen;
3066 | clear deleted line
3068 clear_line(tmp1, 0, window->Num_cols);
3071 | find location to insert deleted line
3073 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3074 tmp = tmp->next_screen;
3076 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3077 tmp = tmp->next_screen;
3078 tmp1->next_screen = tmp;
3079 tmp1->prev_screen = tmp->prev_screen;
3080 if (tmp1->prev_screen != NULL)
3081 tmp1->prev_screen->next_screen = tmp1;
3082 tmp->prev_screen = tmp1;
3084 Position(window, (window->SR + row), 0);
3085 String_Out(String_table[dl__], NULL, 0);
3086 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3088 Position(window, (window->SR + end_row), 0);
3089 String_Out(String_table[al__], NULL, 0);
3091 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3093 Position(window, (window->SR + end_row), 0);
3097 if (row == (window->Num_lines-1))
3099 if ((row + window->SR) == 0)
3100 curscr->first_line = top_of_win = tmp2;
3105 CLEAR_TO_EOL(window, row, column)
3112 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3113 tmp1 = tmp1->next_screen;
3114 for (x = column; x<window->Num_cols; x++)
3117 tmp1->attributes[x] = '\0';
3119 tmp1->row[column] = '\0';
3120 tmp1->last_char = column;
3126 Position(window, row, column);
3129 if (String_table[ce__] != NULL)
3130 String_Out(String_table[ce__], NULL, 0);
3133 for (x = column; x < window->Num_cols; x++)
3141 check_delete(window, line, offset, pointer_new, pointer_old)
3144 struct _line *pointer_new, *pointer_old;
3156 new_lin = pointer_new->row;
3157 new_att = pointer_new->attributes;
3158 old_lin = pointer_old->row;
3159 old_att = pointer_old->attributes;
3160 end_old = end_new = offset;
3161 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != '\0') && (new_lin[end_old] != '\0'))
3163 if (old_lin[end_old] != '\0')
3166 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] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10))
3168 if ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0)))
3170 if (new_lin[end_new+k] == '\0')
3172 Position(window, line, (end_new+k));
3173 CLEAR_TO_EOL(window, line, (end_new+k));
3175 Position(window, line, offset);
3176 for (k = offset; k < end_old; k++)
3177 Char_del(old_lin, old_att, offset, window->Num_cols);
3178 while ((old_lin[offset] != '\0') && (offset < COLS))
3180 pointer_old->last_char = offset;
3188 | Check if characters were inserted in the middle of a line, and if
3193 check_insert(window, line, offset, pointer_new, pointer_old)
3196 struct _line *pointer_new, *pointer_old;
3199 int end_old, end_new;
3210 new_lin = pointer_new->row;
3211 new_att = pointer_new->attributes;
3212 old_lin = pointer_old->row;
3213 old_att = pointer_old->attributes;
3214 end_old = end_new = offset;
3215 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != '\0') && (old_lin[end_new] != '\0'))
3217 if (new_lin[end_new] != '\0')
3220 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] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10))
3223 | check for commonality between rest of lines (are the old
3224 | and new lines the same, except for a chunk in the middle?)
3225 | if the rest of the lines are common, do not insert text
3228 while ((old_lin[old_off] != '\0') && (new_lin[old_off] != '\0') && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3230 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3232 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0))))
3234 Position(window, line, offset);
3236 if (String_table[ic__] == NULL)
3238 String_Out(String_table[im__], NULL, 0);
3241 for (k = offset; k < end_new; k++)
3244 String_Out(String_table[ic__], NULL, 0);
3245 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3248 String_Out(String_table[ei__], NULL, 0);
3249 while ((old_lin[offset] != '\0') && (offset < COLS))
3251 pointer_old->last_char = offset;
3264 int begin_old, begin_new;
3265 int end_old, end_new;
3267 int from_top, tmp_ft, offset;
3281 struct _line *old1, *new1;
3290 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3292 window = virtual_scr;
3294 if ((nc_attributes & A_NC_BIG5) != 0)
3299 if (String_table[cl__])
3300 String_Out(String_table[cl__], NULL, 0);
3304 while (from_top < LINES)
3306 Position(curscr, from_top, 0);
3307 if (String_table[ce__] != NULL)
3308 String_Out(String_table[ce__], NULL, 0);
3311 for (j = 0; j < window->Num_cols; j++)
3317 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3319 Position(curscr, from_top, 0);
3320 for (j = 0; (curr->row[j] != '\0') && (j < curscr->Num_cols); j++)
3322 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3327 Position(curscr, from_top, j);
3331 Repaint_screen = FALSE;
3336 top_of_win = curscr->first_line;
3338 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3339 from_top < window->Num_lines; from_top++)
3341 virtual_lines[from_top] = TRUE;
3342 if ((similar = Comp_line(curr, virt)) > 0)
3344 virtual_lines[from_top] = FALSE;
3347 curr = curr->next_screen;
3348 virt = virt->next_screen;
3352 virt = window->first_line;
3356 | if the window has lines that are different, check for scrolling
3362 for (first_same = window->Num_lines;
3363 (first_same > from_top) && (virtual_lines[first_same - 1]);
3367 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3370 while ((from_top < first_same) && nc_scrolling_ability)
3371 /* check entire lines for diffs */
3374 if (from_top >= last_same)
3376 for (last_same = from_top;
3377 (last_same < window->Num_lines) &&
3378 (virtual_lines[last_same] == FALSE);
3382 if (!virtual_lines[from_top])
3386 | check for lines deleted (scroll up)
3388 for (tmp_ft = from_top+1, old = curr->next_screen;
3389 ((window->scroll_up) && (diff) &&
3390 (tmp_ft < last_same) &&
3391 (!virtual_lines[tmp_ft]));
3394 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3397 | Find the bottom of the
3398 | area that should be
3401 for (bottom = tmp_ft, old1 = old,
3402 new1 = virt, count1 = 0;
3403 (bottom < window->Num_lines) &&
3404 (Comp_line(old1, new1) <= 0);
3405 bottom++, old1 = old1->next_screen,
3406 new1 = new1->next_screen,
3411 if (String_table[cs__]) /* scrolling region */
3414 list[0] = min((bottom - 1), (window->Num_lines - 1));
3415 String_Out(String_table[cs__], list, 2);
3416 Curr_y = Curr_x = -1;
3419 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3421 old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
3425 if (String_table[cs__]) /* scrolling region */
3428 list[0] = LINES - 1;
3429 String_Out(String_table[cs__], list, 2);
3430 Curr_y = Curr_x = -1;
3433 top_of_win = curscr->first_line;
3435 for (offset = 0; offset < from_top; offset++)
3436 curr = curr->next_screen;
3437 for (offset = from_top, old=curr, new=virt;
3438 offset < window->Num_lines;
3439 old=old->next_screen, new=new->next_screen,
3442 similar = Comp_line(old, new);
3443 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3448 old = old->next_screen;
3451 | check for lines inserted (scroll down)
3453 for (tmp_ft = from_top-1, old = curr->prev_screen;
3454 ((window->scroll_down) && (tmp_ft >= 0) &&
3456 (!virtual_lines[tmp_ft]));
3459 if (Comp_line(old, virt) == -1)
3462 | Find the bottom of the
3463 | area that should be
3466 for (bottom = from_top, old1 = old,
3467 new1 = virt, count1 = 0;
3468 (bottom < window->Num_lines) &&
3469 (Comp_line(old1, new1) <= 0);
3470 bottom++, old1 = old1->next_screen,
3471 new1 = new1->next_screen,
3476 if (String_table[cs__]) /* scrolling region */
3479 list[0] = min((bottom - 1), (window->Num_lines - 1));
3480 String_Out(String_table[cs__], list, 2);
3481 Curr_y = Curr_x = -1;
3484 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3486 old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
3490 if (String_table[cs__]) /* scrolling region */
3493 list[0] = LINES - 1;
3494 String_Out(String_table[cs__], list, 2);
3495 Curr_y = Curr_x = -1;
3498 top_of_win = curscr->first_line;
3500 for (offset = 0; offset < from_top; offset++)
3501 curr = curr->next_screen;
3502 for (offset = from_top, old=curr, new=virt;
3503 offset < window->Num_lines;
3504 old=old->next_screen, new=new->next_screen,
3507 similar = Comp_line(old, new);
3508 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3513 old = old->prev_screen;
3517 curr = curr->next_screen;
3518 virt = virt->next_screen;
3524 | Scrolling done, now need to insert, delete, or modify text
3528 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3529 curr = curr->next_screen;
3531 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)
3535 | If either 'insert mode' or 'insert char' are
3536 | available, enter the following 'if' statement,
3537 | else, need to simply rewrite the contents of the line
3538 | at the point where the contents of the line change.
3541 if (((String_table[ic__]) || (String_table[im__])) &&
3542 (String_table[dc__]) && (curr->row[0] != '\0') &&
3547 vrt_lin = virt->row;
3548 vrt_att = virt->attributes;
3549 cur_lin = curr->row;
3550 cur_att = curr->attributes;
3551 while ((vrt_lin[j] != '\0') && (j < window->Num_cols))
3553 if ((STAND) && (Booleans[xs__]))
3555 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0') && (vrt_att[j]))
3557 if ((STAND) && (!vrt_att[j]))
3560 Position(window, from_top, j);
3567 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0'))
3570 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3572 Position(window, from_top, j);
3573 /* CLEAR_TO_EOL(window, from_top, j);*/
3577 if (vrt_lin[j] != '\0')
3583 if ((first_time) && (virt->changed))
3585 if (curr->last_char <= virt->last_char)
3586 changed = check_insert(window, from_top, j, virt, curr);
3588 changed = check_delete(window, from_top, j, virt, curr);
3590 virt->changed = FALSE;
3592 changed = check_insert(window, from_top, j, virt, curr);
3593 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3595 if ((vrt_lin[j] == ' ') && (cur_lin[j] == '\0') && (vrt_att[j] == cur_att[j]))
3599 Position(window, from_top, j);
3600 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3603 if ((vrt_lin[j] != '\0'))
3606 if ((STAND) && (!vrt_att[j]))
3609 Position(window, from_top, j);
3613 if ((vrt_lin[j] == '\0') && (cur_lin[j] != '\0'))
3615 Position(window, from_top, j);
3616 CLEAR_TO_EOL(window, from_top, j);
3619 else /*if ((similar != -1) && (similar != 0))*/
3623 att1 = curr->attributes;
3625 att2 = virt->attributes;
3626 while ((j < window->Num_cols) && (c2[j] != '\0'))
3628 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != '\0'))
3632 | if previous character is an eight bit
3633 | char, start redraw from that character
3636 if ((NC_chinese) && (highbitset(c1[j - 1])))
3640 if ((j < window->Num_cols) && (c2[j] != '\0'))
3642 Position(window, from_top, begin_old);
3643 CLEAR_TO_EOL(window, from_top, j);
3644 Position(window, from_top, begin_old);
3645 for (j = begin_old; (c2[j] != '\0') && (j < window->Num_cols); j++)
3646 Char_out(c2[j], att2[j], c1, att1, j);
3649 if ((c2[j] == '\0') && (c1[j] != '\0'))
3651 Position(window, from_top, j);
3652 CLEAR_TO_EOL(window, from_top, j);
3658 Position(window, from_top, j);
3661 virt->number = from_top;
3663 Position(window, window->LY, window->LX);
3667 Position(window, row, col) /* position the cursor for output on the screen */
3678 pos_row = row + window->SR;
3679 pos_column = col + window->SC;
3680 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3682 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3685 list[place++] = pos_column;
3686 list[place++] = pos_row;
3687 String_Out(String_table[cm__], list, place);
3688 if ((STAND) && (!Booleans[ms__]))
3691 Curr_x = pos_column;
3697 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3705 for (one = offset, two = offset+1; (line[one] != '\0') && (one < maxlen); one++, two++)
3707 line[one] = line[two];
3708 attrib[one] = attrib[two];
3710 String_Out(String_table[dc__], NULL, 0);
3714 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3725 while ((line[one] != '\0') && (one < (maxlen - 2)))
3727 for (two = one + 1; (two > offset); one--, two--)
3729 line[two] = line[one];
3730 attrib[two] = attrib[one];
3732 line[offset] = newc;
3733 attrib[offset] = newatt;
3734 Char_out(newc, newatt, line, attrib, offset);
3740 if (String_table[sa__])
3742 attributes_set[0] = 1;
3743 String_Out(String_table[sa__], attributes_set, 1);
3745 else if (String_table[so__])
3746 String_Out(String_table[so__], NULL, 0);
3752 if (String_table[me__])
3753 String_Out(String_table[me__], NULL, 0);
3754 else if (String_table[sa__])
3756 attributes_set[0] = 0;
3757 String_Out(String_table[sa__], attributes_set, 1);
3759 else if (String_table[se__])
3760 String_Out(String_table[se__], NULL, 0);
3764 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3773 if ((newatt) && (!STAND))
3778 else if ((STAND) && (!newatt))
3784 if ((newatt) && (STAND) && (Booleans[xs__]))
3789 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3792 line[offset] = newc;
3793 attrib[offset] = newatt;
3800 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3801 | hacks that notify new_curse to handle characters that have the high
3802 | bit set as the first of two bytes of a multi-byte string.
3810 nc_attributes |= flag;
3814 nc_clearattrib(flag)
3817 nc_attributes &= ~flag;