4 | A subset of curses developed for use with ae.
6 | written by Hugh Mahon
8 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11 | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 | FITNESS FOR A PARTICULAR PURPOSE. Neither
13 | Hewlett-Packard nor Hugh Mahon shall be liable
14 | for errors contained herein, nor for
15 | incidental or consequential damages in
16 | connection with the furnishing, performance or
17 | use of this material. Neither Hewlett-Packard
18 | nor Hugh Mahon assumes any responsibility for
19 | the use or reliability of this software or
20 | documentation. This software and
21 | documentation is totally UNSUPPORTED. There
22 | is no support contract available. Hewlett-
23 | Packard has done NO Quality Assurance on ANY
24 | of the program or documentation. You may find
25 | the quality of the materials inferior to
26 | supported materials.
28 | This software is not a product of Hewlett-Packard, Co., or any
29 | other company. No support is implied or offered with this software.
30 | You've got the source, and you're on your own.
32 | This software may be distributed under the terms of Larry Wall's
33 | Artistic license, a copy of which is included in this distribution.
35 | This notice must be included with this software and any derivatives.
37 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
38 | All are rights reserved.
40 | $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $
41 | $DragonFly: src/usr.bin/ee/new_curse.c,v 1.4 2005/10/30 23:00:57 swildner Exp $
45 char *copyright_message
[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
46 "All rights are reserved."};
48 char * new_curse_name
= "@(#) new_curse.c $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $";
50 #include "new_curse.h"
61 #include <sys/types.h>
65 #include <sys/select.h> /* on AIX */
68 #endif /* BSD_SELECT */
85 #include <sys/ioctl.h>
90 static WINDOW
*virtual_scr
;
92 WINDOW
*last_window_refreshed
;
98 #define min(a, b) (a < b ? a : b)
99 #define highbitset(a) ((a) & 0x80)
102 #define String_Out(table, stack, place) Info_Out(table, stack, place)
104 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
107 #define bw__ 0 /* booleans */
110 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
113 #define gn__ 6 /* generic type terminal */
114 #define hc__ 7 /* hardcopy terminal */
120 #define mi__ 13 /* safe to move during insert mode */
121 #define ms__ 14 /* safe to move during standout mode */
125 #define hz__ 18 /* hazeltine glitch */
134 #define co__ 0 /* number of columns */ /* numbers */
135 #define it__ 1 /* spaces per tab */
136 #define li__ 2 /* number of lines */
138 #define sg__ 4 /* magic cookie glitch */
152 #define bt__ 0 /* back tab */ /* strings */
153 #define bl__ 1 /* bell */
154 #define cr__ 2 /* carriage return */
155 #define cs__ 3 /* change scroll region */
156 #define ct__ 4 /* clear all tab stops */
157 #define cl__ 5 /* clear screen and home cursor */
158 #define ce__ 6 /* clear to end of line */
159 #define cd__ 7 /* clear to end of display */
160 #define ch__ 8 /* set cursor column */
161 #define CC__ 9 /* term, settable cmd char in */
162 #define cm__ 10 /* screen rel cursor motion, row, column */
163 #define do__ 11 /* down one line */
164 #define ho__ 12 /* home cursor */
165 #define vi__ 13 /* make cursor invisible */
166 #define le__ 14 /* move cursor left one space */
167 #define CM__ 15 /* memory rel cursor addressing */
168 #define ve__ 16 /* make cursor appear normal */
169 #define nd__ 17 /* non-destructive space (cursor right) */
170 #define ll__ 18 /* last line, first col */
171 #define up__ 19 /* cursor up */
173 #define dc__ 21 /* delete character */
174 #define dl__ 22 /* delete line */
179 #define md__ 27 /* turn on bold */
181 #define dm__ 29 /* turn on delete mode */
182 #define mh__ 30 /* half bright mode */
183 #define im__ 31 /* insert mode */
187 #define so__ 35 /* enter standout mode */
194 #define ei__ 42 /* exit insert mode */
195 #define se__ 43 /* exit standout mode */
207 #define kb__ 55 /* backspace key */
239 #define ku__ 87 /* key up */
283 #define sa__ 131 /* sgr */
429 char *Boolean_names
[] = {
430 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
431 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
434 char *Number_names
[] = {
435 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
438 char *String_names
[] = {
439 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
440 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
441 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
442 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
443 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
444 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
445 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
446 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
447 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
448 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
449 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
450 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
451 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
452 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
453 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
454 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
455 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
456 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
457 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
458 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
459 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
460 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
461 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
462 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
463 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
467 char *new_curse
= "October 1987";
469 char in_buff
[100]; /* buffer for ungetch */
470 int bufp
; /* next free position in in_buff */
472 char *TERMINAL_TYPE
= NULL
; /* terminal type to be gotten from environment */
474 int Data_Line_len
= 0;
475 int Max_Key_len
; /* max length of a sequence sent by a key */
476 char *Data_Line
= NULL
;
477 char *TERM_PATH
= NULL
;
478 char *TERM_data_ptr
= NULL
;
479 char *Term_File_name
= NULL
; /* name of file containing terminal description */
480 FILE *TFP
; /* file pointer to file with terminal des. */
481 int Fildes
; /* file descriptor for terminfo file */
482 int STAND
= FALSE
; /* is standout mode activated? */
483 int TERM_INFO
= FALSE
; /* is terminfo being used (TRUE), or termcap (FALSE) */
484 int Time_Out
; /* set when time elapsed while trying to read function key */
485 int Curr_x
; /* current x position on screen */
486 int Curr_y
; /* current y position on the screen */
489 int Move_It
; /* flag to move cursor if magic cookie glitch */
490 int initialized
= FALSE
; /* tells whether new_curse is initialized */
492 float chars_per_millisecond
;
493 int Repaint_screen
; /* if an operation to change screen impossible, repaint screen */
494 int Intr
; /* storeage for interrupt character */
495 int Parity
; /* 0 = no parity, 1 = odd parity, 2 = even parity */
496 int Noblock
; /* for BSD systems */
497 int Num_bits
; /* number of bits per character */
498 int Flip_Bytes
; /* some systems have byte order reversed */
499 int interrupt_flag
= FALSE
; /* set true if SIGWINCH received */
506 int length
; /* length of string sent by key */
507 char *string
; /* string sent by key */
508 int value
; /* CURSES value of key (9-bit) */
512 struct KEYS
*element
;
513 struct KEY_STACK
*next
;
516 struct KEY_STACK
*KEY_TOS
= NULL
;
517 struct KEY_STACK
*KEY_POINT
;
521 | Not all systems have good terminal information, so we will define
522 | keyboard information here for the most widely used terminal type,
527 struct KEYS vt100
[] =
529 { 3, "\033[A", 0403 }, /* key up */
530 { 3, "\033[C", 0405 }, /* key right */
531 { 3, "\033[D", 0404 }, /* key left */
533 { 4, "\033[6~", 0522 }, /* key next page */
534 { 4, "\033[5~", 0523 }, /* key prev page */
535 { 3, "\033[[", 0550 }, /* key end */
536 { 3, "\033[@", 0406 }, /* key home */
537 { 4, "\033[2~", 0513 }, /* key insert char */
539 { 3, "\033[y", 0410 }, /* key F0 */
540 { 3, "\033[P", 0411 }, /* key F1 */
541 { 3, "\033[Q", 0412 }, /* key F2 */
542 { 3, "\033[R", 0413 }, /* key F3 */
543 { 3, "\033[S", 0414 }, /* key F4 */
544 { 3, "\033[t", 0415 }, /* key F5 */
545 { 3, "\033[u", 0416 }, /* key F6 */
546 { 3, "\033[v", 0417 }, /* key F7 */
547 { 3, "\033[l", 0420 }, /* key F8 */
548 { 3, "\033[w", 0421 }, /* key F9 */
549 { 3, "\033[x", 0422 }, /* key F10 */
551 { 5, "\033[10~", 0410 }, /* key F0 */
552 { 5, "\033[11~", 0411 }, /* key F1 */
553 { 5, "\033[12~", 0412 }, /* key F2 */
554 { 5, "\033[13~", 0413 }, /* key F3 */
555 { 5, "\033[14~", 0414 }, /* key F4 */
556 { 5, "\033[15~", 0415 }, /* key F5 */
557 { 5, "\033[17~", 0416 }, /* key F6 */
558 { 5, "\033[18~", 0417 }, /* key F7 */
559 { 5, "\033[19~", 0420 }, /* key F8 */
560 { 5, "\033[20~", 0421 }, /* key F9 */
561 { 5, "\033[21~", 0422 }, /* key F10 */
562 { 5, "\033[23~", 0423 }, /* key F11 */
563 { 5, "\033[24~", 0424 }, /* key F12 */
564 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
565 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
566 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
567 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
568 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
571 | The following are the same keys as above, but with
572 | a different character following the escape char.
575 { 3, "\033OA", 0403 }, /* key up */
576 { 3, "\033OC", 0405 }, /* key right */
577 { 3, "\033OD", 0404 }, /* key left */
578 { 3, "\033OB", 0402 }, /* key down */
579 { 4, "\033O6~", 0522 }, /* key next page */
580 { 4, "\033O5~", 0523 }, /* key prev page */
581 { 3, "\033O[", 0550 }, /* key end */
582 { 3, "\033O@", 0406 }, /* key home */
583 { 4, "\033O2~", 0513 }, /* key insert char */
585 { 3, "\033Oy", 0410 }, /* key F0 */
586 { 3, "\033OP", 0411 }, /* key F1 */
587 { 3, "\033OQ", 0412 }, /* key F2 */
588 { 3, "\033OR", 0413 }, /* key F3 */
589 { 3, "\033OS", 0414 }, /* key F4 */
590 { 3, "\033Ot", 0415 }, /* key F5 */
591 { 3, "\033Ou", 0416 }, /* key F6 */
592 { 3, "\033Ov", 0417 }, /* key F7 */
593 { 3, "\033Ol", 0420 }, /* key F8 */
594 { 3, "\033Ow", 0421 }, /* key F9 */
595 { 3, "\033Ox", 0422 }, /* key F10 */
597 { 5, "\033O10~", 0410 }, /* key F0 */
598 { 5, "\033O11~", 0411 }, /* key F1 */
599 { 5, "\033O12~", 0412 }, /* key F2 */
600 { 5, "\033O13~", 0413 }, /* key F3 */
601 { 5, "\033O14~", 0414 }, /* key F4 */
602 { 5, "\033O15~", 0415 }, /* key F5 */
603 { 5, "\033O17~", 0416 }, /* key F6 */
604 { 5, "\033O18~", 0417 }, /* key F7 */
605 { 5, "\033O19~", 0420 }, /* key F8 */
606 { 5, "\033O20~", 0421 }, /* key F9 */
607 { 5, "\033O21~", 0422 }, /* key F10 */
608 { 5, "\033O23~", 0423 }, /* key F11 */
609 { 5, "\033O24~", 0424 }, /* key F12 */
610 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
611 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
612 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
613 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
614 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
616 { 0, "", 0 } /* end */
621 struct Parameters
*next
;
625 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
626 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
627 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
628 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
629 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
630 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
631 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
632 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
633 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
634 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
635 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
636 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
637 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
640 int attributes_set
[9];
642 static int nc_attributes
= 0; /* global attributes for new_curse to observe */
645 struct termio Terminal
;
646 struct termio Saved_tty
;
648 struct sgttyb Terminal
;
649 struct sgttyb Saved_tty
;
656 char *String_table
[1024];
660 static char nc_scrolling_ability
= FALSE
;
664 #if __STDC__ || defined(__cplusplus)
668 #endif /* __STDC__ */
670 int tc_Get_int
P_((int));
671 void CAP_PARSE
P_((void));
672 void Find_term
P_((void));
681 extern char *fgets();
682 extern char *malloc();
683 extern char *getenv();
684 FILE *fopen(); /* declaration for open function */
685 #endif /* HAS_STDLIB */
686 #endif /* __STDC__ */
691 | Copy the contents of one window to another.
695 copy_window(WINDOW
*origin
, WINDOW
*destination
)
698 struct _line
*orig
, *dest
;
700 orig
= origin
->first_line
;
701 dest
= destination
->first_line
;
704 row
< (min(origin
->Num_lines
, destination
->Num_lines
));
708 column
< (min(origin
->Num_cols
, destination
->Num_cols
));
711 dest
->row
[column
] = orig
->row
[column
];
712 dest
->attributes
[column
] = orig
->attributes
[column
];
714 dest
->changed
= orig
->changed
;
715 dest
->scroll
= orig
->scroll
;
716 dest
->last_char
= min(orig
->last_char
, destination
->Num_cols
);
717 orig
= orig
->next_screen
;
718 dest
= dest
->next_screen
;
720 destination
->LX
= min((destination
->Num_cols
- 1), origin
->LX
);
721 destination
->LY
= min((destination
->Num_lines
- 1), origin
->LY
);
722 destination
->Attrib
= origin
->Attrib
;
723 destination
->scroll_up
= origin
->scroll_up
;
724 destination
->scroll_down
= origin
->scroll_down
;
725 destination
->SCROLL_CLEAR
= origin
->SCROLL_CLEAR
;
735 signal(SIGWINCH
, reinitscr
);
737 if (ioctl(0, TIOCGWINSZ
, &ws
) >= 0)
739 if (ws
.ws_row
== LINES
&& ws
.ws_col
== COLS
)
746 #endif /* TIOCGWINSZ */
747 local_virt
= newwin(LINES
, COLS
, 0, 0);
748 local_std
= newwin(LINES
, COLS
, 0, 0);
749 local_cur
= newwin(LINES
, COLS
, 0, 0);
750 copy_window(virtual_scr
, local_virt
);
751 copy_window(stdscr
, local_std
);
752 copy_window(curscr
, local_cur
);
756 virtual_scr
= local_virt
;
760 virtual_lines
= (int *) malloc(LINES
* (sizeof(int)));
761 interrupt_flag
= TRUE
;
763 #endif /* SIGWINCH */
766 initscr(void) /* initialize terminal for operations */
770 char *columns_string
;
776 printf("starting initscr \n");fflush(stdout
);
782 #endif /* BSD_SELECT */
790 value
= ioctl(0, TCGETA
, &Terminal
);
791 if (Terminal
.c_cflag
& PARENB
)
793 if (Terminal
.c_cflag
& PARENB
)
798 if ((Terminal
.c_cflag
& CS8
) == CS8
)
802 else if ((Terminal
.c_cflag
& CS7
) == CS7
)
804 else if ((Terminal
.c_cflag
& CS6
) == CS6
)
808 value
= Terminal
.c_cflag
& 037;
810 case 01: speed
= 50.0;
812 case 02: speed
= 75.0;
814 case 03: speed
= 110.0;
816 case 04: speed
= 134.5;
818 case 05: speed
= 150.0;
820 case 06: speed
= 200.0;
822 case 07: speed
= 300.0;
824 case 010: speed
= 600.0;
826 case 011: speed
= 900.0;
828 case 012: speed
= 1200.0;
830 case 013: speed
= 1800.0;
832 case 014: speed
= 2400.0;
834 case 015: speed
= 3600.0;
836 case 016: speed
= 4800.0;
838 case 017: speed
= 7200.0;
840 case 020: speed
= 9600.0;
842 case 021: speed
= 19200.0;
844 case 022: speed
= 38400.0;
846 default: speed
= 0.0;
849 value
= ioctl(0, TIOCGETP
, &Terminal
);
850 if (Terminal
.sg_flags
& EVENP
)
852 else if (Terminal
.sg_flags
& ODDP
)
854 value
= Terminal
.sg_ospeed
;
856 case 01: speed
= 50.0;
858 case 02: speed
= 75.0;
860 case 03: speed
= 110.0;
862 case 04: speed
= 134.5;
864 case 05: speed
= 150.0;
866 case 06: speed
= 200.0;
868 case 07: speed
= 300.0;
870 case 010: speed
= 600.0;
872 case 011: speed
= 1200.0;
874 case 012: speed
= 1800.0;
876 case 013: speed
= 2400.0;
878 case 014: speed
= 4800.0;
880 case 015: speed
= 9600.0;
882 default: speed
= 0.0;
885 chars_per_millisecond
= (0.001 * speed
) / 8.0;
886 TERMINAL_TYPE
= getenv("TERM");
887 if (TERMINAL_TYPE
== NULL
)
889 printf("unknown terminal type\n");
894 TERM_PATH
= getenv("TERMINFO");
895 if (TERM_PATH
!= NULL
)
897 Data_Line_len
= 23 + strlen(TERM_PATH
) + strlen(TERMINAL_TYPE
);
898 Term_File_name
= malloc(Data_Line_len
);
899 sprintf(Term_File_name
, "%s/%c/%s", TERM_PATH
, *TERMINAL_TYPE
, TERMINAL_TYPE
);
900 Fildes
= open(Term_File_name
, O_RDONLY
);
904 TERM_PATH
= "/usr/lib/terminfo";
905 Data_Line_len
= 23 + strlen(TERM_PATH
) + strlen(TERMINAL_TYPE
);
906 Term_File_name
= malloc(Data_Line_len
);
907 sprintf(Term_File_name
, "%s/%c/%s", TERM_PATH
, *TERMINAL_TYPE
, TERMINAL_TYPE
);
908 Fildes
= open(Term_File_name
, O_RDONLY
);
912 TERM_PATH
= "/usr/share/lib/terminfo";
913 Data_Line_len
= 23 + strlen(TERM_PATH
) + strlen(TERMINAL_TYPE
);
914 Term_File_name
= malloc(Data_Line_len
);
915 sprintf(Term_File_name
, "%s/%c/%s", TERM_PATH
, *TERMINAL_TYPE
, TERMINAL_TYPE
);
916 Fildes
= open(Term_File_name
, O_RDONLY
);
920 TERM_PATH
= "/usr/share/terminfo";
921 Data_Line_len
= 23 + strlen(TERM_PATH
) + strlen(TERMINAL_TYPE
);
922 Term_File_name
= malloc(Data_Line_len
);
923 sprintf(Term_File_name
, "%s/%c/%s", TERM_PATH
, *TERMINAL_TYPE
, TERMINAL_TYPE
);
924 Fildes
= open(Term_File_name
, O_RDONLY
);
928 free(Term_File_name
);
929 Term_File_name
= NULL
;
932 TERM_INFO
= INFO_PARSE();
935 | termcap information can be in the TERMCAP env variable, if so
936 | use that, otherwise check the /etc/termcap file
938 if ((pointer
= Term_File_name
= getenv("TERMCAP")) != NULL
)
940 if (*Term_File_name
!= '/')
941 Term_File_name
= "/etc/termcap";
945 Term_File_name
= "/etc/termcap";
947 if ((TFP
= fopen(Term_File_name
, "r")) == NULL
)
949 printf("unable to open /etc/termcap file \n");
952 for (value
= 0; value
< 1024; value
++)
953 String_table
[value
] = NULL
;
954 for (value
= 0; value
< 128; value
++)
956 for (value
= 0; value
< 128; value
++)
958 Data_Line
= malloc(512);
959 if (pointer
&& *pointer
!= '/')
961 TERM_data_ptr
= pointer
;
970 if (String_table
[pc__
] == NULL
)
971 String_table
[pc__
] = "\0";
972 if ((String_table
[cm__
] == NULL
) || (Booleans
[hc__
]))
974 fprintf(stderr
, "sorry, unable to use this terminal type for screen editing\n");
979 LINES
= Numbers
[li__
];
980 COLS
= Numbers
[co__
];
981 if ((lines_string
= getenv("LINES")) != NULL
)
983 value
= atoi(lines_string
);
987 if ((columns_string
= getenv("COLUMNS")) != NULL
)
989 value
= atoi(columns_string
);
995 | get the window size
997 if (ioctl(0, TIOCGWINSZ
, &ws
) >= 0)
1005 virtual_scr
= newwin(LINES
, COLS
, 0, 0);
1006 stdscr
= newwin(LINES
, COLS
, 0, 0);
1007 curscr
= newwin(LINES
, COLS
, 0, 0);
1008 wmove(stdscr
, 0, 0);
1010 Repaint_screen
= TRUE
;
1012 virtual_lines
= (int *) malloc(LINES
* (sizeof(int)));
1016 | reset size of windows and LINES and COLS if term window
1019 signal(SIGWINCH
, reinitscr
);
1020 #endif /* SIGWINCH */
1023 | check if scrolling is available
1026 nc_scrolling_ability
= ((String_table
[al__
] != NULL
) &&
1027 (String_table
[dl__
])) || ((String_table
[cs__
])
1028 && (String_table
[sr__
]));
1034 Get_int(void) /* get a two-byte integer from the terminfo file */
1040 Low_byte
= *((unsigned char *) TERM_data_ptr
++);
1041 High_byte
= *((unsigned char *) TERM_data_ptr
++);
1045 Low_byte
= High_byte
;
1048 if ((High_byte
== 255) && (Low_byte
== 255))
1051 return(Low_byte
+ (High_byte
* 256));
1055 INFO_PARSE(void) /* parse off the data in the terminfo data file */
1058 int magic_number
= 0;
1063 int Num_strings
= 0;
1064 int string_table_len
= 0;
1067 TERM_data_ptr
= Data_Line
= malloc((10240 * (sizeof(char))));
1068 Data_Line_len
= read(Fildes
, Data_Line
, 10240);
1069 if ((Data_Line_len
>= 10240) || (Data_Line_len
< 0))
1074 magic_number
= Get_int();
1076 | if magic number not right, reverse byte order and check again
1078 if (magic_number
!= 282)
1083 magic_number
= Get_int();
1084 if (magic_number
!= 282)
1088 | get the number of each type in the terminfo data file
1090 Num_names
= Get_int();
1091 Num_bools
= Get_int();
1092 Num_ints
= Get_int();
1093 Num_strings
= Get_int();
1094 string_table_len
= Get_int();
1095 Strings
= malloc(string_table_len
);
1096 while (Num_names
> 0)
1105 Booleans
[counter
++] = *TERM_data_ptr
++;
1107 if (((unsigned int) TERM_data_ptr
) & 1) /* force alignment */
1113 Numbers
[counter
] = Get_int();
1116 temp_ptr
= TERM_data_ptr
+ Num_strings
+ Num_strings
;
1117 memcpy(Strings
, temp_ptr
, string_table_len
);
1122 if ((offset
=Get_int()) != -1)
1124 if (String_table
[counter
] == NULL
)
1125 String_table
[counter
] = Strings
+ offset
;
1128 String_table
[counter
] = NULL
;
1135 #endif /* ifndef CAP */
1138 AtoI(void) /* convert ascii text to integers */
1143 while ((*TERM_data_ptr
>= '0') && (*TERM_data_ptr
<= '9'))
1145 Temp
= (Temp
* 10) + (*TERM_data_ptr
- '0');
1152 Key_Get(void) /* create linked list with all key sequences obtained from terminal database */
1157 struct KEY_STACK
*Spoint
;
1162 while (key_def
<= kf63__
)
1164 if (key_def
== ke__
)
1166 else if (key_def
== (K5__
+ 1))
1168 else if (key_def
== (kcbt__
+ 1))
1170 else if (key_def
== (kUND__
+ 1))
1172 if (String_table
[key_def
] != NULL
)
1174 if (KEY_TOS
== NULL
)
1175 Spoint
= KEY_TOS
= (struct KEY_STACK
*) malloc(sizeof(struct KEY_STACK
));
1179 while (Spoint
->next
!= NULL
)
1180 Spoint
= Spoint
->next
;
1181 Spoint
->next
= (struct KEY_STACK
*) malloc(sizeof(struct KEY_STACK
));
1182 Spoint
= Spoint
->next
;
1184 Spoint
->next
= NULL
;
1185 Spoint
->element
= (struct KEYS
*) malloc(sizeof(struct KEYS
));
1186 Spoint
->element
->string
= String_table
[key_def
];
1187 Spoint
->element
->length
= strlen(String_table
[key_def
]);
1188 Spoint
->element
->value
= Key_vals
[Counter
];
1189 Klen
= strlen(Spoint
->element
->string
);
1190 if (Klen
> Max_Key_len
)
1193 | Some terminal types accept keystrokes of the form
1194 | \E[A and \EOA, substituting '[' for 'O'. Make a
1195 | duplicate of such key strings (since the
1196 | database will only have one version) so new_curse
1197 | can understand both.
1199 if ((Spoint
->element
->length
> 1) &&
1200 ((String_table
[key_def
][1] == '[') ||
1201 (String_table
[key_def
][1] == 'O')))
1203 Spoint
->next
= (struct KEY_STACK
*) malloc(sizeof(struct KEY_STACK
));
1204 Spoint
= Spoint
->next
;
1205 Spoint
->next
= NULL
;
1206 Spoint
->element
= (struct KEYS
*) malloc(sizeof(struct KEYS
));
1207 Spoint
->element
->length
= strlen(String_table
[key_def
]);
1208 Spoint
->element
->string
= malloc(Spoint
->element
->length
+ 1);
1209 strcpy(Spoint
->element
->string
, String_table
[key_def
]);
1210 Spoint
->element
->value
= Key_vals
[Counter
];
1211 Klen
= strlen(Spoint
->element
->string
);
1212 if (Klen
> Max_Key_len
)
1215 if (String_table
[key_def
][1] == '[')
1216 Spoint
->element
->string
[1] = 'O';
1218 Spoint
->element
->string
[1] = '[';
1227 | insert information about keys for a vt100 terminal
1235 struct KEY_STACK
*Spoint
;
1238 while (Spoint
->next
!= NULL
)
1239 Spoint
= Spoint
->next
;
1240 for (counter
= 0; vt100
[counter
].length
!= 0; counter
++)
1242 Spoint
->next
= (struct KEY_STACK
*) malloc(sizeof(struct KEY_STACK
));
1243 Spoint
= Spoint
->next
;
1244 Spoint
->next
= NULL
;
1245 Spoint
->element
= &vt100
[counter
];
1246 Klen
= strlen(Spoint
->element
->string
);
1247 if (Klen
> Max_Key_len
)
1254 String_Get(char *param
) /* read the string */
1262 while (*TERM_data_ptr
!= '=')
1264 Temp
= ++TERM_data_ptr
;
1266 while ((*Temp
!= ':') && (*Temp
!= (char)NULL
))
1271 if (Counter
== 1) /* no data */
1273 String
= Temp
= malloc(Counter
);
1274 while ((*TERM_data_ptr
!= ':') && (*TERM_data_ptr
!= (char)NULL
))
1276 if (*TERM_data_ptr
== '\\')
1279 if (*TERM_data_ptr
== 'n')
1281 else if (*TERM_data_ptr
== 't')
1283 else if (*TERM_data_ptr
== 'b')
1285 else if (*TERM_data_ptr
== 'r')
1287 else if (*TERM_data_ptr
== 'f')
1289 else if ((*TERM_data_ptr
== 'e') || (*TERM_data_ptr
== 'E'))
1290 *Temp
= '\033'; /* escape */
1291 else if (*TERM_data_ptr
== '\\')
1293 else if (*TERM_data_ptr
== '\'')
1295 else if ((*TERM_data_ptr
>= '0') && (*TERM_data_ptr
<= '9'))
1298 while ((*TERM_data_ptr
>= '0') && (*TERM_data_ptr
<= '9'))
1300 Counter
= (8 * Counter
) + (*TERM_data_ptr
- '0');
1301 TERM_data_ptr
++; /* ? */
1309 else if (*TERM_data_ptr
== '^')
1312 if ((*TERM_data_ptr
>= '@') && (*TERM_data_ptr
<= '_'))
1313 *Temp
= *TERM_data_ptr
- '@';
1314 else if (*TERM_data_ptr
== '?')
1320 *Temp
++ = *TERM_data_ptr
++;
1327 while ((*TERM_data_ptr
!= (char)NULL
) && (*TERM_data_ptr
!= ':'))
1334 tc_Get_int(int param
) /* read the integer */
1340 while ((*TERM_data_ptr
!= (char)NULL
) && (*TERM_data_ptr
!= '#'))
1348 while (*TERM_data_ptr
!= ':')
1355 Find_term(void) /* find terminal description in termcap file */
1360 Ftemp
= Name
= malloc(strlen(TERMINAL_TYPE
+ 1) + 1);
1361 strcpy(Name
, TERMINAL_TYPE
);
1362 while (*Ftemp
!= (char)NULL
)
1365 *Ftemp
= (char)NULL
;
1367 Data_Line_len
= strlen(TERMINAL_TYPE
) + 1;
1368 while ((!CFOUND
) && ((TERM_data_ptr
=fgets(Data_Line
, 512, TFP
)) != NULL
))
1370 if ((*TERM_data_ptr
!= ' ') && (*TERM_data_ptr
!= '\t') && (*TERM_data_ptr
!= '#'))
1372 while ((!CFOUND
) && (*TERM_data_ptr
!= (char)NULL
))
1374 CFOUND
= !strncmp(TERM_data_ptr
, Name
, Data_Line_len
);
1375 while ((*TERM_data_ptr
!= (char)NULL
) && (*TERM_data_ptr
!= '|') && (*TERM_data_ptr
!= '#') && (*TERM_data_ptr
!= ':'))
1377 if (*TERM_data_ptr
== '|')
1380 *TERM_data_ptr
= (char)NULL
;
1386 printf("terminal type %s not found\n", TERMINAL_TYPE
);
1392 CAP_PARSE(void) /* parse off the data in the termcap data file */
1399 while (*TERM_data_ptr
!= (char)NULL
)
1401 for (found
= FALSE
, offset
= 0; (!found
) && (offset
< 26); offset
++)
1403 if (!strncmp(TERM_data_ptr
, Boolean_names
[offset
], 2))
1406 Booleans
[offset
] = TRUE
;
1411 for (found
= FALSE
, offset
= 0; (!found
) && (offset
< lw__
); offset
++)
1413 if (!strncmp(TERM_data_ptr
, Number_names
[offset
], 3))
1416 Numbers
[offset
] = tc_Get_int(Numbers
[offset
]);
1422 for (found
= FALSE
, offset
= 0; (!found
) && (offset
< smgr__
); offset
++)
1424 if (!strncmp(TERM_data_ptr
, String_names
[offset
], 3))
1427 String_table
[offset
] = String_Get(String_table
[offset
]);
1432 if (!strncmp(TERM_data_ptr
, "tc=", 3))
1433 tc_
= String_Get(NULL
);
1434 while ((*TERM_data_ptr
!= ':') && (*TERM_data_ptr
!= (char)NULL
))
1436 if (*TERM_data_ptr
== ':')
1439 } while (((TERM_data_ptr
= fgets(Data_Line
, 512, TFP
)) != NULL
) && ((*TERM_data_ptr
== ' ') || (*TERM_data_ptr
== '\t')));
1442 TERMINAL_TYPE
= tc_
;
1452 #endif /* ifdef CAP */
1455 Screenalloc(int columns
)
1460 tmp
= (struct _line
*) malloc(sizeof (struct _line
));
1461 tmp
->row
= malloc(columns
+ 1);
1462 tmp
->attributes
= malloc(columns
+ 1);
1463 tmp
->prev_screen
= NULL
;
1464 tmp
->next_screen
= NULL
;
1465 for (i
= 0; i
< columns
; i
++)
1468 tmp
->attributes
[i
] = (char) NULL
;
1470 tmp
->scroll
= tmp
->changed
= FALSE
;
1471 tmp
->row
[0] = (char) NULL
;
1472 tmp
->attributes
[0] = (char) NULL
;
1473 tmp
->row
[columns
] = (char) NULL
;
1474 tmp
->attributes
[columns
] = (char) NULL
;
1480 lines, cols: number of lines and columns to be in window
1481 start_l, start_c: starting line and column to be in window
1484 newwin(int lines
, int cols
, int start_l
, int start_c
)
1487 struct _line
*temp_screen
;
1490 Ntemp
= (WINDOW
*) malloc(sizeof(WINDOW
));
1491 Ntemp
->SR
= start_l
;
1492 Ntemp
->SC
= start_c
;
1493 Ntemp
->Num_lines
= lines
;
1494 Ntemp
->Num_cols
= cols
;
1497 Ntemp
->scroll_down
= Ntemp
->scroll_up
= 0;
1498 Ntemp
->SCROLL_CLEAR
= FALSE
;
1499 Ntemp
->Attrib
= FALSE
;
1500 Ntemp
->first_line
= temp_screen
= Screenalloc(cols
);
1501 Ntemp
->first_line
->number
= 0;
1502 for (i
= 1; i
< lines
; i
++)
1504 temp_screen
->next_screen
= Screenalloc(cols
);
1505 temp_screen
->next_screen
->number
= i
;
1506 temp_screen
->next_screen
->prev_screen
= temp_screen
;
1507 temp_screen
= temp_screen
->next_screen
;
1509 Ntemp
->first_line
->prev_screen
= NULL
;
1510 temp_screen
->next_screen
= NULL
;
1516 p_list: stack of values
1517 place: place keeper of top of stack
1520 Cap_Out(char *string
, int *p_list
, int place
)
1521 /* interpret the output string if necessary */
1523 char *Otemp
; /* temporary string pointer to parse output */
1533 p1
= p_list
[--place
];
1534 p2
= p_list
[--place
];
1538 if ((*Otemp
>= '0') && (*Otemp
<= '9'))
1540 delay
= atoi(Otemp
);
1541 while ((*Otemp
>= '0') && (*Otemp
<= '9'))
1546 while (*Otemp
!= (char)NULL
)
1551 if ((*Otemp
== 'd') || (*Otemp
== '2') || (*Otemp
== '3') || (*Otemp
== '.') || (*Otemp
== '+'))
1555 else if (*Otemp
== '2')
1557 else if (*Otemp
== '3')
1559 else if (*Otemp
== '+')
1565 else if (*Otemp
== '.')
1570 else if (*Otemp
== '>')
1581 else if (*Otemp
== 'r')
1587 else if (*Otemp
== 'i')
1592 else if (*Otemp
== '%')
1594 else if (*Otemp
== 'n')
1599 else if (*Otemp
== 'B')
1601 p1
= (16 * (p1
/10)) + (p1
% 10);
1602 p2
= (16 * (p2
/10)) + (p2
% 10);
1604 else if (*Otemp
== 'D')
1606 p1
= (p1
- 2 * (p1
% 16));
1607 p2
= (p2
- 2 * (p2
% 16));
1616 chars
= delay
* chars_per_millisecond
;
1618 if ((chars
- delay
) > 0.0)
1620 for (; delay
> 0; delay
--)
1621 putchar(*String_table
[pc__
]);
1628 char *Otemp
; /* temporary string pointer to parse output */
1634 Operation(int *Temp_Stack
, int place
) /* handle conditional operations */
1641 temp
= Temp_Stack
[--place
];
1644 else if (!strncmp(Otemp
, "2d", 2))
1646 temp
= Temp_Stack
[--place
];
1647 printf("%2d", temp
);
1651 else if (!strncmp(Otemp
, "3d", 2))
1653 temp
= Temp_Stack
[--place
];
1654 printf("%0d", temp
);
1658 else if (!strncmp(Otemp
, "02d", 3))
1660 temp
= Temp_Stack
[--place
];
1661 printf("%02d", temp
);
1666 else if (!strncmp(Otemp
, "03d", 3))
1668 temp
= Temp_Stack
[--place
];
1669 printf("%03d", temp
);
1674 else if (*Otemp
== '+')
1677 temp
= Temp_Stack
[--place
];
1678 temp
+= Temp_Stack
[--place
];
1679 Temp_Stack
[place
++] = temp
;
1681 else if (*Otemp
== '-')
1684 temp
= Temp_Stack
[--place
];
1685 temp
-= Temp_Stack
[--place
];
1686 Temp_Stack
[place
++] = temp
;
1688 else if (*Otemp
== '*')
1691 temp
= Temp_Stack
[--place
];
1692 temp
*= Temp_Stack
[--place
];
1693 Temp_Stack
[place
++] = temp
;
1695 else if (*Otemp
== '/')
1698 temp
= Temp_Stack
[--place
];
1699 temp
/= Temp_Stack
[--place
];
1700 Temp_Stack
[place
++] = temp
;
1702 else if (*Otemp
== 'm')
1705 temp
= Temp_Stack
[--place
];
1706 temp
%= Temp_Stack
[--place
];
1707 Temp_Stack
[place
++] = temp
;
1709 else if (*Otemp
== '&')
1712 temp
= Temp_Stack
[--place
];
1713 temp
&= Temp_Stack
[--place
];
1714 Temp_Stack
[place
++] = temp
;
1716 else if (*Otemp
== '|')
1719 temp
= Temp_Stack
[--place
];
1720 temp
|= Temp_Stack
[--place
];
1721 Temp_Stack
[place
++] = temp
;
1723 else if (*Otemp
== '^')
1726 temp
= Temp_Stack
[--place
];
1727 temp
^= Temp_Stack
[--place
];
1728 Temp_Stack
[place
++] = temp
;
1730 else if (*Otemp
== '=')
1733 temp
= Temp_Stack
[--place
];
1734 temp
= (temp
== Temp_Stack
[--place
]);
1735 Temp_Stack
[place
++] = temp
;
1737 else if (*Otemp
== '>')
1740 temp
= Temp_Stack
[--place
];
1741 temp
= temp
> Temp_Stack
[--place
];
1742 Temp_Stack
[place
++] = temp
;
1744 else if (*Otemp
== '<')
1747 temp
= Temp_Stack
[--place
];
1748 temp
= temp
< Temp_Stack
[--place
];
1749 Temp_Stack
[place
++] = temp
;
1751 else if (*Otemp
== 'c')
1754 putchar(Temp_Stack
[--place
]);
1756 else if (*Otemp
== 'i')
1762 else if (*Otemp
== '%')
1767 else if (*Otemp
== '!')
1769 temp
= ! Temp_Stack
[--place
];
1770 Temp_Stack
[place
++] = temp
;
1773 else if (*Otemp
== '~')
1775 temp
= ~Temp_Stack
[--place
];
1776 Temp_Stack
[place
++] = temp
;
1779 else if (*Otemp
== 'p')
1782 Temp_Stack
[place
++] = p
[*Otemp
- '0'];
1785 else if (*Otemp
== 'P')
1788 Temp_Stack
[place
++] = variable
[*Otemp
- 'a'];
1791 else if (*Otemp
== 'g')
1794 variable
[*Otemp
- 'a'] = Temp_Stack
[--place
];
1797 else if (*Otemp
== '\'')
1800 Temp_Stack
[place
++] = *Otemp
;
1804 else if (*Otemp
== '{')
1808 Temp_Stack
[place
++] = temp
;
1809 while (*Otemp
!= '}')
1817 Info_Out(char *string
, int *p_list
, int place
)
1818 /* interpret the output string if necessary */
1825 int Cond_Stack
[128];
1848 for (temp
= 1; (place
!= 0); temp
++)
1850 p
[temp
] = p_list
[--place
];
1855 while (*Otemp
!= (char) NULL
)
1860 if ((*Otemp
== '?') || (*Otemp
== 't') || (*Otemp
== 'e') || (*Otemp
== ';'))
1870 | find the end of the
1871 | conditional statement
1873 while ((strncmp(Otemp
, "%t", 2)) && (*Otemp
!= (char) NULL
))
1879 Cond_place
= Operation(Cond_Stack
, Cond_place
);
1883 | if condition is true
1885 if ((Cond_place
> 0) && (Cond_Stack
[Cond_place
-1]))
1895 else /* condition is false */
1898 | find 'else' or end
1901 while ((strncmp(Otemp
, "%e", 2)) && (strncmp(Otemp
, "%;", 2)) && (*Otemp
!= (char) NULL
))
1904 | if an 'else' found
1906 if ((*Otemp
!= (char) NULL
) && (!strncmp(Otemp
, "%e", 2)))
1912 | check for 'then' part
1914 while ((*tchar
!= (char) NULL
) && (strncmp(tchar
, "%t", 2)) && (strncmp(tchar
, "%;", 2)))
1919 if (*tchar
== (char) NULL
)
1926 | if end of if found,
1930 else if (!strncmp(tchar
, "%;", 2))
1939 | if end of if found,
1943 else if ((*Otemp
!= (char) NULL
) && (!strncmp(Otemp
, "%;", 2)))
1949 else /* Otemp == NULL */
1963 while ((*Otemp
!= (char) NULL
) && (strncmp(Otemp
, "%;", 2)))
1965 if (*Otemp
!= (char) NULL
)
1977 Top_of_stack
= Operation(Stack
, Top_of_stack
);
1980 else if (!strncmp(Otemp
, "$<", 2))
1984 delay
= atoi(Otemp
);
1985 while (*Otemp
!= '>')
1988 chars
= delay
* chars_per_millisecond
;
1990 if ((chars
- delay
) > 0.0)
1992 if (String_table
[pc__
] == NULL
)
1995 temp
= *String_table
[pc__
];
1996 for (; delay
> 0; delay
--)
2010 wmove(WINDOW
*window
, int row
, int column
)
2011 /* move cursor to indicated position in window */
2013 if ((row
< window
->Num_lines
) && (column
< window
->Num_cols
))
2015 window
->LX
= column
;
2021 clear_line(struct _line
*line
, int column
, int cols
)
2025 if (column
> line
->last_char
)
2026 line
->row
[line
->last_char
] = ' ';
2027 line
->last_char
= column
;
2028 line
->row
[column
] = (char) NULL
;
2029 line
->attributes
[column
] = (char) NULL
;
2030 line
->changed
= TRUE
;
2031 for (j
= column
+ 1; j
< cols
; j
++)
2034 line
->attributes
[j
] = (char) NULL
;
2039 werase(WINDOW
*window
) /* clear the specified window */
2044 window
->SCROLL_CLEAR
= CLEAR
;
2045 window
->scroll_up
= window
->scroll_down
= 0;
2046 for (i
= 0, tmp
= window
->first_line
; i
< window
->Num_lines
; i
++, tmp
= tmp
->next_screen
)
2047 clear_line(tmp
, 0, window
->Num_cols
);
2051 wclrtoeol(WINDOW
*window
)
2052 /* erase from current cursor position to end of line */
2057 window
->SCROLL_CLEAR
= CHANGE
;
2058 column
= window
->LX
;
2060 for (row
= 0, tmp
= window
->first_line
; row
< window
->LY
; row
++)
2061 tmp
= tmp
->next_screen
;
2062 clear_line(tmp
, column
, window
->Num_cols
);
2066 wrefresh(WINDOW
*window
) /* flush all previous output */
2068 wnoutrefresh(window
);
2073 fprintf(stderr
, "columns=%d, lines=%d, SC=%d, SR=%d\n",window
->Num_cols
, window
->Num_lines
, window
->SC
, window
->SR
);
2074 for (value
= 0, temp
= window
->first_line
; value
< window
->Num_lines
; value
++, temp
= temp
->next_screen
)
2076 if (temp
->number
== -1)
2077 fprintf(stderr
, "line moved ");
2079 fprintf(stderr
, "scroll_x is set: ");
2080 fprintf(stderr
, "lc%d=%s|\n", temp
->last_char
, temp
->row
);
2082 fprintf(stderr
, "+-------------------- virtual screen ----------------------------------------+\n");
2083 fprintf(stderr
, "columns=%d, lines=%d \n",virtual_scr
->Num_cols
, virtual_scr
->Num_lines
);
2084 for (value
= 0, temp
= virtual_scr
->first_line
; value
< virtual_scr
->Num_lines
; value
++, temp
= temp
->next_screen
)
2086 if (temp
->number
== -1)
2087 fprintf(stderr
, "line moved ");
2089 fprintf(stderr
, "scroll_x is set: ");
2090 fprintf(stderr
, "lc%d=%s|\n", temp
->last_char
, temp
->row
);
2092 fprintf(stderr
, "columns=%d, lines=%d \n",curscr
->Num_cols
, curscr
->Num_lines
);
2093 for (value
= 0, temp
= curscr
->first_line
; value
< curscr
->Num_lines
; value
++, temp
= temp
->next_screen
)
2094 fprintf(stderr
, "line=%s|\n", temp
->row
);
2098 virtual_scr
->SCROLL_CLEAR
= FALSE
;
2099 virtual_scr
->scroll_down
= virtual_scr
->scroll_up
= 0;
2104 touchwin(WINDOW
*window
)
2106 struct _line
*user_line
;
2107 int line_counter
= 0;
2109 for (line_counter
= 0, user_line
= window
->first_line
;
2110 line_counter
< window
->Num_lines
; line_counter
++)
2112 user_line
->changed
= TRUE
;
2114 window
->SCROLL_CLEAR
= TRUE
;
2118 wnoutrefresh(WINDOW
*window
)
2120 struct _line
*user_line
;
2121 struct _line
*virtual_line
;
2122 int line_counter
= 0;
2126 if (window
->SR
>= virtual_scr
->Num_lines
)
2128 user_line
= window
->first_line
;
2129 virtual_line
= virtual_scr
->first_line
;
2130 virtual_scr
->SCROLL_CLEAR
= window
->SCROLL_CLEAR
;
2131 virtual_scr
->LX
= window
->LX
+ window
->SC
;
2132 virtual_scr
->LY
= window
->LY
+ window
->SR
;
2133 virtual_scr
->scroll_up
= window
->scroll_up
;
2134 virtual_scr
->scroll_down
= window
->scroll_down
;
2135 if ((last_window_refreshed
== window
) && (!window
->SCROLL_CLEAR
))
2137 for (line_counter
= 0; line_counter
< window
->SR
; line_counter
++)
2139 virtual_line
= virtual_line
->next_screen
;
2141 for (line_counter
= 0; (line_counter
< window
->Num_lines
)
2142 && ((line_counter
+ window
->SR
) < virtual_scr
->Num_lines
);
2145 if ((last_window_refreshed
!= window
) || (user_line
->changed
) || ((SCROLL
| CLEAR
) & window
->SCROLL_CLEAR
))
2147 for (user_col
= 0, virt_col
= window
->SC
;
2148 (virt_col
< virtual_scr
->Num_cols
)
2149 && (user_col
< window
->Num_cols
);
2150 virt_col
++, user_col
++)
2152 virtual_line
->row
[virt_col
] = user_line
->row
[user_col
];
2153 virtual_line
->attributes
[virt_col
] = user_line
->attributes
[user_col
];
2156 if (virtual_scr
->Num_cols
!= window
->Num_cols
)
2158 if (virtual_line
->last_char
< (user_line
->last_char
+ window
->SC
))
2160 if (virtual_line
->row
[virtual_line
->last_char
] == (char) NULL
)
2161 virtual_line
->row
[virtual_line
->last_char
] = ' ';
2162 virtual_line
->last_char
=
2163 min(virtual_scr
->Num_cols
,
2164 (user_line
->last_char
+ window
->SC
));
2166 else if (virtual_line
->last_char
> (user_line
->last_char
+ window
->SC
))
2168 virtual_line
->row
[min(virtual_scr
->Num_cols
,
2169 (user_line
->last_char
+ window
->SC
))] = ' ';
2173 virtual_line
->last_char
= user_line
->last_char
;
2174 virtual_line
->row
[virtual_line
->last_char
] = (char) NULL
;
2175 virtual_line
->changed
= user_line
->changed
;
2176 virtual_line
= virtual_line
->next_screen
;
2177 user_line
= user_line
->next_screen
;
2179 window
->SCROLL_CLEAR
= FALSE
;
2180 window
->scroll_up
= window
->scroll_down
= 0;
2181 last_window_refreshed
= window
;
2185 flushinp(void) /* flush input */
2190 ungetch(int c
) /* push a character back on input */
2193 in_buff
[bufp
++] = c
;
2208 tv
.tv_usec
= 500000; /* half a second */
2210 Time_Out
= FALSE
; /* just in case */
2212 ret_val
= select(nfds
, &fds
, 0, 0, &tv
);
2215 | if ret_val is less than zero, there was no input
2216 | otherwise, get a character and return it
2225 return(read(0, &temp
, 1)? temp
: -1);
2230 wgetch(WINDOW
*window
) /* get character from specified window */
2240 in_value
= ((bufp
> 0) ? in_buff
[--bufp
] : timed_getchar());
2242 in_value
= ((bufp
> 0) ? in_buff
[--bufp
] : read(0, &temp
, 1)? temp
: -1);
2243 #else /* BSD_SELECT */
2245 in_value
= ((bufp
> 0) ? in_buff
[--bufp
] :
2246 (read(0, &temp
, 1)> 0) ? temp
: -1);
2251 old_arg
= fcntl(0, F_GETFL
, 0);
2252 in_value
= fcntl(0, F_SETFL
, old_arg
| FNDELAY
);
2254 in_value
= ((bufp
> 0) ? in_buff
[--bufp
] : read(0, &temp
, 1)? temp
: -1);
2257 fcntl(0, F_SETFL
, old_arg
);
2262 #endif /* BSD_SELECT */
2267 if ((Parity
) && (Num_bits
< 8))
2268 /* strip eighth bit if parity in use */
2271 else if (interrupt_flag
)
2273 interrupt_flag
= FALSE
;
2274 in_value
= wgetch(window
);
2277 if ((in_value
== '\033') || (in_value
== '\037'))/* escape character */
2278 in_value
= Get_key(in_value
);
2284 Clear(int arg
) /* notify that time out has occurred */
2288 fprintf(stderr
, "inside Clear()\n");
2292 #endif /* BSD_SELECT */
2294 /* first_char: first character of sequence */
2296 Get_key(int first_char
) /* try to decode key sequence */
2304 struct termio Gterminal
;
2306 struct sgttyb Gterminal
;
2308 struct KEY_STACK
*St_point
;
2309 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2311 #endif /* BSD_SELECT */
2315 string
[Count
++] = first_char
;
2316 string
[Count
] = (char) NULL
;
2319 signal(SIGALRM
, Clear
);
2321 #endif /* BSD_SELECT */
2324 Gterminal
.c_cc
[VTIME
] = 0; /* timeout value */
2325 Gterminal
.c_lflag
&= ~ICANON
; /* disable canonical operation */
2326 Gterminal
.c_lflag
&= ~ECHO
; /* disable echo */
2330 while ((Count
< Max_Key_len
) && (!Time_Out
) && (!Found
))
2332 in_char
= wgetch(stdscr
);
2334 fprintf(stderr
, "back in GetKey()\n");
2339 string
[Count
++] = in_char
;
2340 string
[Count
] = (char) NULL
;
2342 while ((St_point
!= NULL
) && (!Found
))
2344 if (!strcmp(string
, St_point
->element
->string
))
2347 St_point
= St_point
->next
;
2354 #endif /* BSD_SELECT */
2356 /* value = ioctl(0, TCSETA, &Terminal);*/
2358 value
= ioctl(0, TIOCSETP
, &Terminal
);
2359 /* value = fcntl(0, F_SETFL, old_arg);*/
2364 return(St_point
->element
->value
);
2370 if ((string
[--Count
] != -1) &&
2371 ((unsigned char) (string
[Count
]) != 255))
2374 fprintf(stderr
, "ungetting character %d\n", string
[Count
]);fflush(stdout
);
2376 ungetch(string
[Count
]);
2384 waddch(WINDOW
*window
, int c
) /* output the character in the specified window */
2387 int shift
; /* number of spaces to shift if a tab */
2388 struct _line
*tmpline
;
2391 /*printf("starting waddch \n");fflush(stdout);*/
2394 column
= window
->LX
;
2397 shift
= (column
+ 1) % 8;
2405 waddch(window
, ' ');
2408 else if ((column
< window
->Num_cols
) && (row
< window
->Num_lines
))
2410 if ((c
== '~') && (Booleans
[hz__
]))
2413 if (( c
!= '\b') && (c
!= '\n') && (c
!= '\r'))
2416 tmpline
= window
->first_line
;
2417 while (row
< window
->LY
)
2420 tmpline
= tmpline
->next_screen
;
2422 tmpline
->row
[column
] = c
;
2423 tmpline
->attributes
[column
] = window
->Attrib
;
2424 tmpline
->changed
= TRUE
;
2425 if (column
>= tmpline
->last_char
)
2427 if (column
> tmpline
->last_char
)
2428 tmpline
->row
[tmpline
->last_char
] = ' ';
2429 tmpline
->row
[column
+ 1] = (char) NULL
;
2430 tmpline
->attributes
[column
+ 1] = (char) NULL
;
2431 tmpline
->last_char
= column
+ 1;
2437 window
->LX
= window
->Num_cols
;
2446 if (window
->LX
>= window
->Num_cols
)
2450 if (window
->LY
>= window
->Num_lines
)
2452 window
->LY
= window
->Num_lines
- 1;
2453 /* window->LY = row;
2454 wmove(window, 0, 0);
2456 wmove(window, row, 0);*/
2459 window
->SCROLL_CLEAR
= CHANGE
;
2463 winsertln(WINDOW
*window
) /* insert a blank line into the specified window */
2469 window
->scroll_down
+= 1;
2470 window
->SCROLL_CLEAR
= SCROLL
;
2471 column
= window
->LX
;
2473 for (row
= 0, tmp
= window
->first_line
; (row
< window
->Num_lines
) && (tmp
->next_screen
!= NULL
); row
++)
2474 tmp
= tmp
->next_screen
;
2475 if (tmp
->prev_screen
!= NULL
)
2476 tmp
->prev_screen
->next_screen
= NULL
;
2478 clear_line(tmp1
, 0, window
->Num_cols
);
2480 for (row
= 0, tmp
= window
->first_line
; (row
< window
->LY
) && (tmp
->next_screen
!= NULL
); row
++)
2481 tmp
= tmp
->next_screen
;
2482 if ((window
->LY
== (window
->Num_lines
- 1)) && (window
->Num_lines
> 1))
2484 tmp1
->next_screen
= tmp
->next_screen
;
2485 tmp
->next_screen
= tmp1
;
2486 tmp
->changed
= TRUE
;
2487 tmp
->next_screen
->prev_screen
= tmp
;
2489 else if (window
->Num_lines
> 1)
2491 if (tmp
->prev_screen
!= NULL
)
2492 tmp
->prev_screen
->next_screen
= tmp1
;
2493 tmp1
->prev_screen
= tmp
->prev_screen
;
2494 tmp
->prev_screen
= tmp1
;
2495 tmp1
->next_screen
= tmp
;
2496 tmp
->changed
= TRUE
;
2499 if (window
->LY
== 0)
2500 window
->first_line
= tmp1
;
2504 wdeleteln(WINDOW
*window
) /* delete a line in the specified window */
2508 struct _line
*tmpline
;
2510 if (window
->Num_lines
> 1)
2512 window
->scroll_up
+= 1;
2513 window
->SCROLL_CLEAR
= SCROLL
;
2514 column
= window
->LX
;
2516 for (row
= 0, tmp
= window
->first_line
; row
< window
->LY
; row
++)
2517 tmp
= tmp
->next_screen
;
2518 if (window
->LY
== 0)
2519 window
->first_line
= tmp
->next_screen
;
2520 if (tmp
->prev_screen
!= NULL
)
2521 tmp
->prev_screen
->next_screen
= tmp
->next_screen
;
2522 if (tmp
->next_screen
!= NULL
)
2524 tmp
->next_screen
->changed
= TRUE
;
2525 tmp
->next_screen
->scroll
= UP
;
2526 tmp
->next_screen
->prev_screen
= tmp
->prev_screen
;
2529 clear_line(tmpline
, 0, window
->Num_cols
);
2530 tmpline
->number
= -1;
2531 for (row
= 0, tmp
= window
->first_line
; tmp
->next_screen
!= NULL
; row
++)
2532 tmp
= tmp
->next_screen
;
2535 tmp
->next_screen
= tmpline
;
2536 tmp
->next_screen
->prev_screen
= tmp
;
2537 tmp
->changed
= TRUE
;
2538 tmp
= tmp
->next_screen
;
2542 tmp
->next_screen
= NULL
;
2546 clear_line(window
->first_line
, 0, window
->Num_cols
);
2551 wclrtobot(WINDOW
*window
)
2552 /* delete from current position to end of the window */
2557 window
->SCROLL_CLEAR
|= CLEAR
;
2558 column
= window
->LX
;
2560 for (row
= 0, tmp
= window
->first_line
; row
< window
->LY
; row
++)
2561 tmp
= tmp
->next_screen
;
2562 clear_line(tmp
, column
, window
->Num_cols
);
2563 for (row
= (window
->LY
+ 1); row
< window
->Num_lines
; row
++)
2565 tmp
= tmp
->next_screen
;
2566 clear_line(tmp
, 0, window
->Num_cols
);
2568 wmove(window
, row
, column
);
2572 wstandout(WINDOW
*window
) /* begin standout mode in window */
2574 if (Numbers
[sg__
] < 1) /* if not magic cookie glitch */
2575 window
->Attrib
|= A_STANDOUT
;
2579 wstandend(WINDOW
*window
) /* end standout mode in window */
2581 window
->Attrib
&= ~A_STANDOUT
;
2585 waddstr(WINDOW
*window
, char *string
) /* write 'string' in window */
2589 for (wstring
= string
; *wstring
!= (char) NULL
; wstring
++)
2590 waddch(window
, *wstring
);
2594 clearok(WINDOW
*window
, int flag
) /* erase screen and redraw at next refresh */
2596 Repaint_screen
= TRUE
;
2601 echo(void) /* turn on echoing */
2606 Terminal
.c_lflag
|= ECHO
; /* enable echo */
2607 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2609 Terminal
.sg_flags
|= ECHO
; /* enable echo */
2610 value
= ioctl(0, TIOCSETP
, &Terminal
); /* set characteristics */
2615 noecho(void) /* turn off echoing */
2620 Terminal
.c_lflag
&= ~ECHO
; /* disable echo */
2621 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2623 Terminal
.sg_flags
&= ~ECHO
; /* disable echo */
2624 value
= ioctl(0, TIOCSETP
, &Terminal
); /* set characteristics */
2629 raw(void) /* set to read characters immediately */
2634 Intr
= Terminal
.c_cc
[VINTR
]; /* get the interrupt character */
2635 Terminal
.c_lflag
&= ~ICANON
; /* disable canonical operation */
2636 Terminal
.c_lflag
&= ~ISIG
; /* disable signal checking */
2638 Terminal
.c_lflag
&= ~FLUSHO
;
2641 Terminal
.c_lflag
&= ~PENDIN
;
2644 Terminal
.c_lflag
&= ~IEXTEN
;
2646 Terminal
.c_cc
[VMIN
] = 1; /* minimum of one character */
2647 Terminal
.c_cc
[VTIME
] = 255; /* timeout value */
2648 Terminal
.c_cc
[VINTR
] = 0; /* eliminate interrupt */
2649 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2651 Terminal
.sg_flags
|= RAW
; /* enable raw mode */
2652 value
= ioctl(0, TIOCSETP
, &Terminal
); /* set characteristics */
2657 noraw(void) /* set to normal character read mode */
2662 Terminal
.c_lflag
|= ICANON
; /* enable canonical operation */
2663 Terminal
.c_lflag
|= ISIG
; /* enable signal checking */
2664 Terminal
.c_cc
[VEOF
] = 4; /* EOF character = 4 */
2665 Terminal
.c_cc
[VEOL
] = (char) NULL
; /* EOL = 0 */
2666 Terminal
.c_cc
[VINTR
] = Intr
; /* reset interrupt char */
2667 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2669 Terminal
.sg_flags
&= ~RAW
; /* disable raw mode */
2670 value
= ioctl(0, TIOCSETP
, &Terminal
); /* set characteristics */
2671 /* old_arg = fcntl(0, F_GETFL, 0);
2672 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2682 Terminal
.c_iflag
|= ICRNL
; /* enable carriage-return to line-feed mapping */
2683 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2693 Terminal
.c_iflag
&= ~ICRNL
; /* disable carriage-return to line-feed mapping */
2694 Terminal
.c_iflag
&= ~IGNCR
; /* do not ignore carriage-return */
2695 value
= ioctl(0, TCSETA
, &Terminal
); /* set characteristics */
2715 nodelay(WINDOW
*window
, int flag
)
2720 idlok(WINDOW
*window
, int flag
)
2725 keypad(WINDOW
*window
, int flag
)
2728 String_Out(String_table
[ks__
], NULL
, 0);
2730 String_Out(String_table
[ke__
], NULL
, 0);
2734 savetty(void) /* save current tty stats */
2739 value
= ioctl(0, TCGETA
, &Saved_tty
); /* set characteristics */
2741 value
= ioctl(0, TIOCGETP
, &Saved_tty
); /* set characteristics */
2746 resetty(void) /* restore previous tty stats */
2751 value
= ioctl(0, TCSETA
, &Saved_tty
); /* set characteristics */
2753 value
= ioctl(0, TIOCSETP
, &Saved_tty
); /* set characteristics */
2758 endwin(void) /* end windows */
2760 keypad(stdscr
, FALSE
);
2761 initialized
= FALSE
;
2763 delwin(virtual_scr
);
2768 /* old_arg = fcntl(0, F_GETFL, 0);
2769 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2775 delwin(WINDOW
*window
) /* delete the window structure */
2779 for (i
= 1; (i
< window
->Num_lines
) && (window
->first_line
->next_screen
!= NULL
); i
++)
2781 window
->first_line
= window
->first_line
->next_screen
;
2782 free(window
->first_line
->prev_screen
->row
);
2783 free(window
->first_line
->prev_screen
->attributes
);
2784 free(window
->first_line
->prev_screen
);
2786 if (window
== last_window_refreshed
)
2787 last_window_refreshed
= 0;
2788 if (window
->first_line
!= NULL
)
2790 free(window
->first_line
->row
);
2791 free(window
->first_line
->attributes
);
2792 free(window
->first_line
);
2798 wprintw(WINDOW
*window
, const char *format
, ...)
2805 va_start(ap
, format
);
2807 fpoint
= (char *) format
;
2808 while (*fpoint
!= (char) NULL
)
2815 value
= va_arg(ap
, int);
2816 iout(window
, value
);
2818 else if (*fpoint
== 'c')
2820 value
= va_arg(ap
, int);
2821 waddch(window
, value
);
2823 else if (*fpoint
== 's')
2825 wtemp
= va_arg(ap
, char *);
2826 waddstr(window
, wtemp
);
2830 else if (*fpoint
== '\\')
2834 waddch(window
, '\n');
2835 else if ((*fpoint
>= '0') && (*fpoint
<= '9'))
2838 while ((*fpoint
>= '0') && (*fpoint
<= '9'))
2840 value
= (value
* 8) + (*fpoint
- '0');
2843 waddch(window
, value
);
2848 waddch(window
, *fpoint
++);
2854 iout(WINDOW
*window
, int value
) /* output characters */
2858 if ((i
= value
/ 10) != 0)
2860 waddch(window
, ((value
% 10) + '0'));
2864 Comp_line(struct _line
*line1
, struct _line
*line2
) /* compare lines */
2873 att1
= line1
->attributes
;
2874 att2
= line2
->attributes
;
2875 count2
= strlen(c1
) + 1;
2876 count1
= strlen(c2
) + 1;
2877 if (count1
> count2
)
2883 if (count2
> (count1
+ count1
))
2886 while ((c1
[i
] != (char) NULL
) && (c2
[i
] != (char) NULL
) && (c1
[i
] == c2
[i
]) && (att1
[i
] == att2
[i
]))
2889 if ((count1
== 1) && (count2
== 1))
2890 count1
= 0; /* both lines blank */
2891 else if (count2
== count1
)
2892 count1
= -1; /* equal */
2894 count1
= count2
/ count1
; /* lines unequal */
2899 Insert_line(int row
, int end_row
, WINDOW
*window
) /* insert line into screen */
2905 for (i
= 0, tmp
= curscr
->first_line
; i
< window
->SR
; i
++)
2906 tmp
= tmp
->next_screen
;
2907 if ((end_row
+ window
->SR
) == 0)
2908 curscr
->first_line
= curscr
->first_line
->next_screen
;
2911 | find bottom line to delete
2913 for (i
= 0, tmp
= top_of_win
; (tmp
->next_screen
!= NULL
) && (i
< end_row
); i
++)
2914 tmp
= tmp
->next_screen
;
2915 if (tmp
->prev_screen
!= NULL
)
2916 tmp
->prev_screen
->next_screen
= tmp
->next_screen
;
2917 if (tmp
->next_screen
!= NULL
)
2918 tmp
->next_screen
->prev_screen
= tmp
->prev_screen
;
2921 | clear deleted line
2923 clear_line(tmp
, 0, window
->Num_cols
);
2925 for (i
= 0, tmp
= curscr
->first_line
; (tmp
->next_screen
!= NULL
) && (i
< window
->SR
); i
++)
2926 tmp
= tmp
->next_screen
;
2928 for (i
= 0, tmp
= top_of_win
; i
< row
; i
++)
2929 tmp
= tmp
->next_screen
;
2930 if ((tmp
->prev_screen
!= NULL
) && (window
->Num_lines
> 0))
2931 tmp
->prev_screen
->next_screen
= tmp1
;
2932 tmp1
->prev_screen
= tmp
->prev_screen
;
2933 tmp
->prev_screen
= tmp1
;
2934 tmp1
->next_screen
= tmp
;
2935 if ((row
+ window
->SR
) == 0)
2936 curscr
->first_line
= tmp1
;
2937 if (tmp1
->next_screen
!= NULL
)
2938 tmp1
= tmp1
->next_screen
;
2940 if ((!String_table
[cs__
]) && (end_row
< window
->Num_lines
))
2942 Position(window
, (window
->SR
+ end_row
), 0);
2943 String_Out(String_table
[dl__
], NULL
, 0);
2945 Position(window
, (window
->SR
+ row
), 0);
2946 if (String_table
[al__
] != NULL
)
2947 String_Out(String_table
[al__
], NULL
, 0);
2949 String_Out(String_table
[sr__
], NULL
, 0);
2951 for (i
= 0, top_of_win
= curscr
->first_line
; (top_of_win
->next_screen
!= NULL
) && (i
< window
->SR
); i
++)
2952 top_of_win
= top_of_win
->next_screen
;
2958 Delete_line(int row
, int end_row
, struct _line
*window
)
2959 /* delete a line on screen */
2967 tmp
= curscr
->first_line
;
2968 while (i
< window
->SR
)
2971 tmp
= tmp
->next_screen
;
2974 | find line to delete
2977 if ((row
+ window
->SR
) == 0)
2978 curscr
->first_line
= top_of_win
->next_screen
;
2979 for (i
= 0, tmp
= top_of_win
; i
< row
; i
++)
2980 tmp
= tmp
->next_screen
;
2981 if (tmp
->prev_screen
!= NULL
)
2982 tmp
->prev_screen
->next_screen
= tmp
->next_screen
;
2983 if (tmp
->next_screen
!= NULL
)
2984 tmp
->next_screen
->prev_screen
= tmp
->prev_screen
;
2985 tmp2
= tmp
->next_screen
;
2988 | clear deleted line
2990 clear_line(tmp1
, 0, window
->Num_cols
);
2993 | find location to insert deleted line
2995 for (i
= 0, tmp
= curscr
->first_line
; (tmp
->next_screen
!= NULL
) && (i
< window
->SR
); i
++)
2996 tmp
= tmp
->next_screen
;
2998 for (i
= 0, tmp
= top_of_win
; (i
< end_row
) && (tmp
->next_screen
!= NULL
); i
++)
2999 tmp
= tmp
->next_screen
;
3000 tmp1
->next_screen
= tmp
;
3001 tmp1
->prev_screen
= tmp
->prev_screen
;
3002 if (tmp1
->prev_screen
!= NULL
)
3003 tmp1
->prev_screen
->next_screen
= tmp1
;
3004 tmp
->prev_screen
= tmp1
;
3006 Position(window
, (window
->SR
+ row
), 0);
3007 String_Out(String_table
[dl__
], NULL
, 0);
3008 if ((!String_table
[cs__
]) && (end_row
< window
->Num_lines
))
3010 Position(window
, (window
->SR
+ end_row
), 0);
3011 String_Out(String_table
[al__
], NULL
, 0);
3013 else if ((String_table
[cs__
] != NULL
) && (String_table
[dl__
] == NULL
))
3015 Position(window
, (window
->SR
+ end_row
), 0);
3019 if (row
== (window
->Num_lines
-1))
3021 if ((row
+ window
->SR
) == 0)
3022 curscr
->first_line
= top_of_win
= tmp2
;
3027 CLEAR_TO_EOL(WINDOW
*window
, int row
, int column
)
3032 for (y
= 0, tmp1
= curscr
->first_line
; (y
< (window
->SR
+row
)) && (tmp1
->next_screen
!= NULL
); y
++)
3033 tmp1
= tmp1
->next_screen
;
3034 for (x
= column
; x
<window
->Num_cols
; x
++)
3037 tmp1
->attributes
[x
] = (char) NULL
;
3039 tmp1
->row
[column
] = (char) NULL
;
3040 tmp1
->last_char
= column
;
3046 Position(window
, row
, column
);
3049 if (String_table
[ce__
] != NULL
)
3050 String_Out(String_table
[ce__
], NULL
, 0);
3053 for (x
= column
; x
< window
->Num_cols
; x
++)
3061 check_delete(WINDOW
*window
, int line
, int offset
, struct _line
*pointer_new
,
3062 struct _line
*pointer_old
)
3074 new_lin
= pointer_new
->row
;
3075 new_att
= pointer_new
->attributes
;
3076 old_lin
= pointer_old
->row
;
3077 old_att
= pointer_old
->attributes
;
3078 end_old
= end_new
= offset
;
3079 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
))
3081 if (old_lin
[end_old
] != (char) NULL
)
3084 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))
3086 if ((k
> 8) || ((new_lin
[end_new
+k
] == (char) NULL
) && (k
!= 0)))
3088 if (new_lin
[end_new
+k
] == (char) NULL
)
3090 Position(window
, line
, (end_new
+k
));
3091 CLEAR_TO_EOL(window
, line
, (end_new
+k
));
3093 Position(window
, line
, offset
);
3094 for (k
= offset
; k
< end_old
; k
++)
3095 Char_del(old_lin
, old_att
, offset
, window
->Num_cols
);
3096 while ((old_lin
[offset
] != (char) NULL
) && (offset
< COLS
))
3098 pointer_old
->last_char
= offset
;
3106 | Check if characters were inserted in the middle of a line, and if
3111 check_insert(WINDOW
*window
, int line
, int offset
, struct _line
*pointer_new
,
3112 struct _line
*pointer_old
)
3115 int end_old
, end_new
;
3126 new_lin
= pointer_new
->row
;
3127 new_att
= pointer_new
->attributes
;
3128 old_lin
= pointer_old
->row
;
3129 old_att
= pointer_old
->attributes
;
3130 end_old
= end_new
= offset
;
3131 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
))
3133 if (new_lin
[end_new
] != (char) NULL
)
3136 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))
3139 | check for commonality between rest of lines (are the old
3140 | and new lines the same, except for a chunk in the middle?)
3141 | if the rest of the lines are common, do not insert text
3144 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
]))
3146 if ((old_lin
[old_off
] == new_lin
[old_off
]) && (old_att
[old_off
] == new_att
[old_off
]))
3148 if ((!same
) && ((k
> 8) || ((new_lin
[end_new
+k
] == (char) NULL
) && (k
!= 0))))
3150 Position(window
, line
, offset
);
3152 if (String_table
[ic__
] == NULL
)
3154 String_Out(String_table
[im__
], NULL
, 0);
3157 for (k
= offset
; k
< end_new
; k
++)
3160 String_Out(String_table
[ic__
], NULL
, 0);
3161 Char_ins(old_lin
, old_att
, new_lin
[k
], new_att
[k
], k
, window
->Num_cols
);
3164 String_Out(String_table
[ei__
], NULL
, 0);
3165 while ((old_lin
[offset
] != (char) NULL
) && (offset
< COLS
))
3167 pointer_old
->last_char
= offset
;
3180 int begin_old
, begin_new
;
3181 int end_old
, end_new
;
3183 int from_top
, tmp_ft
, offset
;
3203 char NC_chinese
= FALSE
; /* flag to indicate handling Chinese */
3205 window
= virtual_scr
;
3207 if ((nc_attributes
& A_NC_BIG5
) != 0)
3212 if (String_table
[cl__
])
3213 String_Out(String_table
[cl__
], NULL
, 0);
3217 while (from_top
< LINES
)
3219 Position(curscr
, from_top
, 0);
3220 if (String_table
[ce__
] != NULL
)
3221 String_Out(String_table
[ce__
], NULL
, 0);
3224 for (j
= 0; j
< window
->Num_cols
; j
++)
3230 for (from_top
= 0, curr
= curscr
->first_line
; from_top
< curscr
->Num_lines
; from_top
++, curr
= curr
->next_screen
)
3232 Position(curscr
, from_top
, 0);
3233 for (j
= 0; (curr
->row
[j
] != (char) NULL
) && (j
< curscr
->Num_cols
); j
++)
3235 Char_out(curr
->row
[j
], curr
->attributes
[j
], curr
->row
, curr
->attributes
, j
);
3240 Position(curscr
, from_top
, j
);
3244 Repaint_screen
= FALSE
;
3249 top_of_win
= curscr
->first_line
;
3251 for (from_top
= 0, curr
= top_of_win
, virt
= window
->first_line
;
3252 from_top
< window
->Num_lines
; from_top
++)
3254 virtual_lines
[from_top
] = TRUE
;
3255 if ((similar
= Comp_line(curr
, virt
)) > 0)
3257 virtual_lines
[from_top
] = FALSE
;
3260 curr
= curr
->next_screen
;
3261 virt
= virt
->next_screen
;
3265 virt
= window
->first_line
;
3269 | if the window has lines that are different, check for scrolling
3275 for (first_same
= window
->Num_lines
;
3276 (first_same
> from_top
) && (virtual_lines
[first_same
- 1]);
3279 count1
= first_same
- 1;
3281 (last_same
< window
->Num_lines
) && (virtual_lines
[last_same
]== FALSE
);
3284 while ((from_top
< first_same
) && nc_scrolling_ability
)
3285 /* check entire lines for diffs */
3289 if (from_top
>= last_same
)
3291 for (last_same
= from_top
;
3292 (last_same
< window
->Num_lines
) &&
3293 (virtual_lines
[last_same
] == FALSE
);
3297 if (!virtual_lines
[from_top
])
3301 | check for lines deleted (scroll up)
3303 for (tmp_ft
= from_top
+1, old
= curr
->next_screen
;
3304 ((window
->scroll_up
) && (diff
) &&
3305 (tmp_ft
< last_same
) &&
3306 (!virtual_lines
[tmp_ft
]));
3309 if ((Comp_line(old
, virt
) == -1) && (!virtual_lines
[from_top
]))
3311 if (String_table
[cs__
]) /* scrolling region */
3314 list
[0] = min((last_same
- 1), (window
->Num_lines
- 1));
3315 String_Out(String_table
[cs__
], list
, 2);
3316 Curr_y
= Curr_x
= -1;
3319 for (offset
= (tmp_ft
- from_top
); (offset
> 0); offset
--)
3321 old
= Delete_line(from_top
, min((last_same
- 1), (window
->Num_lines
- 1)), window
);
3325 if (String_table
[cs__
]) /* scrolling region */
3328 list
[0] = LINES
- 1;
3329 String_Out(String_table
[cs__
], list
, 2);
3330 Curr_y
= Curr_x
= -1;
3333 top_of_win
= curscr
->first_line
;
3335 for (offset
= 0; offset
< from_top
; offset
++)
3336 curr
= curr
->next_screen
;
3337 for (offset
= from_top
, old
=curr
, new=virt
;
3338 offset
< window
->Num_lines
;
3339 old
=old
->next_screen
, new=new->next_screen
,
3342 similar
= Comp_line(old
, new);
3343 virtual_lines
[offset
] = (similar
> 0 ? FALSE
: TRUE
);
3347 old
= old
->next_screen
;
3350 | check for lines inserted (scroll down)
3352 for (tmp_ft
= from_top
-1, old
= curr
->prev_screen
;
3353 ((window
->scroll_down
) && (tmp_ft
>= 0) &&
3355 (!virtual_lines
[tmp_ft
]));
3358 if (Comp_line(old
, virt
) == -1)
3360 if (String_table
[cs__
]) /* scrolling region */
3363 list
[0] = min((last_same
- 1), (window
->Num_lines
- 1));
3364 String_Out(String_table
[cs__
], list
, 2);
3365 Curr_y
= Curr_x
= -1;
3368 for (offset
= (from_top
- tmp_ft
); (offset
> 0); offset
--)
3370 old
= Insert_line(tmp_ft
, min((last_same
- 1), (window
->Num_lines
-1)), window
);
3374 if (String_table
[cs__
]) /* scrolling region */
3377 list
[0] = LINES
- 1;
3378 String_Out(String_table
[cs__
], list
, 2);
3379 Curr_y
= Curr_x
= -1;
3382 top_of_win
= curscr
->first_line
;
3384 for (offset
= 0; offset
< from_top
; offset
++)
3385 curr
= curr
->next_screen
;
3386 for (offset
= from_top
, old
=curr
, new=virt
;
3387 offset
< window
->Num_lines
;
3388 old
=old
->next_screen
, new=new->next_screen
,
3391 similar
= Comp_line(old
, new);
3392 virtual_lines
[offset
] = (similar
> 0 ? FALSE
: TRUE
);
3396 old
= old
->prev_screen
;
3400 curr
= curr
->next_screen
;
3401 virt
= virt
->next_screen
;
3407 | Scrolling done, now need to insert, delete, or modify text
3411 for (from_top
= 0, curr
= curscr
->first_line
; from_top
< window
->SR
; from_top
++)
3412 curr
= curr
->next_screen
;
3414 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
)
3418 | If either 'insert mode' or 'insert char' are
3419 | available, enter the following 'if' statement,
3420 | else, need to simply rewrite the contents of the line
3421 | at the point where the contents of the line change.
3424 if (((String_table
[ic__
]) || (String_table
[im__
])) &&
3425 (String_table
[dc__
]) && (curr
->row
[0] != (char) NULL
) &&
3430 vrt_lin
= virt
->row
;
3431 vrt_att
= virt
->attributes
;
3432 cur_lin
= curr
->row
;
3433 cur_att
= curr
->attributes
;
3434 while ((vrt_lin
[j
] != (char) NULL
) && (j
< window
->Num_cols
))
3436 if ((STAND
) && (Booleans
[xs__
]))
3438 while ((vrt_lin
[j
] == cur_lin
[j
]) && (vrt_att
[j
] == cur_att
[j
]) && (vrt_lin
[j
] != (char) NULL
) && (vrt_att
[j
]))
3440 if ((STAND
) && (!vrt_att
[j
]))
3443 Position(window
, from_top
, j
);
3450 while ((vrt_lin
[j
] == cur_lin
[j
]) && (vrt_att
[j
] == cur_att
[j
]) && (vrt_lin
[j
] != (char) NULL
))
3453 if ((vrt_att
[j
] != cur_att
[j
]) && (cur_att
[j
]) && (Booleans
[xs__
]))
3455 Position(window
, from_top
, j
);
3456 /* CLEAR_TO_EOL(window, from_top, j);*/
3460 if (vrt_lin
[j
] != (char) NULL
)
3466 if ((first_time
) && (virt
->changed
))
3468 if (curr
->last_char
<= virt
->last_char
)
3469 changed
= check_insert(window
, from_top
, j
, virt
, curr
);
3471 changed
= check_delete(window
, from_top
, j
, virt
, curr
);
3473 virt
->changed
= FALSE
;
3475 changed
= check_insert(window
, from_top
, j
, virt
, curr
);
3476 if (((!changed
) || (cur_lin
[j
] != vrt_lin
[j
]) || (cur_att
[j
] != vrt_att
[j
])) && (j
< window
->Num_cols
))
3478 if ((vrt_lin
[j
] == ' ') && (cur_lin
[j
] == (char) NULL
) && (vrt_att
[j
] == cur_att
[j
]))
3482 Position(window
, from_top
, j
);
3483 Char_out(vrt_lin
[j
], vrt_att
[j
], cur_lin
, cur_att
, j
);
3486 if ((vrt_lin
[j
] != (char) NULL
))
3489 if ((STAND
) && (!vrt_att
[j
]))
3492 Position(window
, from_top
, j
);
3496 if ((vrt_lin
[j
] == (char) NULL
) && (cur_lin
[j
] != (char) NULL
))
3498 Position(window
, from_top
, j
);
3499 CLEAR_TO_EOL(window
, from_top
, j
);
3502 else /*if ((similar != -1) && (similar != 0))*/
3506 att1
= curr
->attributes
;
3508 att2
= virt
->attributes
;
3509 while ((j
< window
->Num_cols
) && (c2
[j
] != (char) NULL
))
3511 while ((c1
[j
] == c2
[j
]) && (att1
[j
] == att2
[j
]) && (j
< window
->Num_cols
) && (c2
[j
] != (char) NULL
))
3515 | if previous character is an eight bit
3516 | char, start redraw from that character
3519 if ((NC_chinese
) && (highbitset(c1
[j
- 1])))
3523 if ((j
< window
->Num_cols
) && (c2
[j
] != (char) NULL
))
3525 Position(window
, from_top
, begin_old
);
3526 CLEAR_TO_EOL(window
, from_top
, j
);
3527 Position(window
, from_top
, begin_old
);
3528 for (j
= begin_old
; (c2
[j
] != (char) NULL
) && (j
< window
->Num_cols
); j
++)
3529 Char_out(c2
[j
], att2
[j
], c1
, att1
, j
);
3532 if ((c2
[j
] == (char) NULL
) && (c1
[j
] != (char) NULL
))
3534 Position(window
, from_top
, j
);
3535 CLEAR_TO_EOL(window
, from_top
, j
);
3541 Position(window
, from_top
, j
);
3544 virt
->number
= from_top
;
3546 Position(window
, window
->LY
, window
->LX
);
3550 Position(WINDOW
*window
, int row
, int col
)
3551 /* position the cursor for output on the screen */
3559 pos_row
= row
+ window
->SR
;
3560 pos_column
= col
+ window
->SC
;
3561 if ((pos_row
!= Curr_y
) || (pos_column
!= Curr_x
))
3563 if (String_table
[cm__
] != NULL
) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3566 list
[place
++] = pos_column
;
3567 list
[place
++] = pos_row
;
3568 String_Out(String_table
[cm__
], list
, place
);
3569 if ((STAND
) && (!Booleans
[ms__
]))
3572 Curr_x
= pos_column
;
3578 Char_del(char *line
, char *attrib
, int offset
, int maxlen
)
3579 /* delete chars from line */
3583 for (one
= offset
, two
= offset
+1; (line
[one
] != (char) NULL
) && (one
< maxlen
); one
++, two
++)
3585 line
[one
] = line
[two
];
3586 attrib
[one
] = attrib
[two
];
3588 String_Out(String_table
[dc__
], NULL
, 0);
3592 Char_ins(char *line
, char *attrib
, char newc
, char newatt
, int offset
,
3593 int maxlen
) /* insert chars in line */
3598 while ((line
[one
] != (char) NULL
) && (one
< (maxlen
- 2)))
3600 for (two
= one
+ 1; (two
> offset
); one
--, two
--)
3602 line
[two
] = line
[one
];
3603 attrib
[two
] = attrib
[one
];
3605 line
[offset
] = newc
;
3606 attrib
[offset
] = newatt
;
3607 Char_out(newc
, newatt
, line
, attrib
, offset
);
3613 if (String_table
[sa__
])
3615 attributes_set
[0] = 1;
3616 String_Out(String_table
[sa__
], attributes_set
, 1);
3618 else if (String_table
[so__
])
3619 String_Out(String_table
[so__
], NULL
, 0);
3625 if (String_table
[me__
])
3626 String_Out(String_table
[me__
], NULL
, 0);
3627 else if (String_table
[sa__
])
3629 attributes_set
[0] = 0;
3630 String_Out(String_table
[sa__
], attributes_set
, 1);
3632 else if (String_table
[se__
])
3633 String_Out(String_table
[se__
], NULL
, 0);
3637 Char_out(char newc
, char newatt
, char *line
, char *attrib
, int offset
)
3638 /* output character with proper attribute */
3642 if ((newatt
) && (!STAND
))
3647 else if ((STAND
) && (!newatt
))
3653 if ((newatt
) && (STAND
) && (Booleans
[xs__
]))
3658 if (!((Curr_y
>= (LINES
- 1)) && (Curr_x
>= (COLS
- 1))))
3661 line
[offset
] = newc
;
3662 attrib
[offset
] = newatt
;
3669 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3670 | hacks that notify new_curse to handle characters that have the high
3671 | bit set as the first of two bytes of a multi-byte string.
3676 nc_setattrib(int flag
)
3678 nc_attributes
|= flag
;
3682 nc_clearattrib(int flag
)
3684 nc_attributes
&= ~flag
;