Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: utzoo!decvax!bellcore!allegra!mit-eddie!genrad!sources From: sources@genrad.UUCP Newsgroups: mod.sources Subject: PD Terminfo/Curses (part 7 of 11) Message-ID: <539@genrad.UUCP> Date: Wed, 19-Dec-84 23:28:02 EST Article-I.D.: genrad.539 Posted: Wed Dec 19 23:28:02 1984 Date-Received: Thu, 20-Dec-84 21:26:54 EST Sender: john@genrad.UUCP Organization: GenRad, Inc., Bolton, Mass. Lines: 2213 Approved: john@genrad.UUCP This is part of a distribution of a public domain version of terminfo/curses It is a rather large distribution, so I have broken it up into 11 modules (each less than 64K long.) Each shar format module should end with the line "exit". This code is completely public domain, originally written by Pavel Curtis of Cornell University. This version has some small improvements and bug fixes. This unit contains: more source units of the library. Part 8 will be more source units of the library. ----------------- cut here ---------------- : Run this shell script with "sh" not "csh" PATH=:/bin:/usr/bin:/usr/ucb export PATH if test ! -d =src then echo 'Making directory "=src"' mkdir =src fi echo 'x - =src/lib_getch.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getch.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_getch.c ** ** The routine getch(). ** ** $Log: RCS/lib_getch.v $ * Revision 2.1 82/10/25 14:47:29 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:45:19 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_getch.v Revision 2.1 82/10/25 14:47:29 pavel Exp$"; #include#include "curses.h" #include "curses.priv.h" #define nextc() (SP->_backcnt > 0 ? SP->_backbuf[--SP->_backcnt] \ : getc(SP->_ifp)) #define putback(ch) SP->_backbuf[SP->_backcnt++] = ch wgetch(win) WINDOW *win; { bool setHere = FALSE; /* cbreak mode was set here */ short ch; /* 'short' because of keypad codes */ short kgetch(); #ifdef TRACE if (_tracing) _tracef("wgetch(%o) called", win); #endif if (! win->_scroll && (win->_flags & _FULLWIN) && win->_curx == win->_maxx && win->_cury == win->_maxy) return(ERR); #ifdef FIONREAD if (win->_nodelay) { long count; ioctl(fileno(SP->_ifp), FIONREAD, &count); if (! count) return(-1); } #endif if (SP->_echo && ! (SP->_raw || SP->_cbreak)) { cbreak(); setHere = TRUE; } if (win->_use_keypad) ch = kgetch(); else ch = nextc(); if (SP->_echo && ch < 0400) /* ch < 0400 => not a keypad key */ { mvwaddch(curscr, win->_begy + win->_cury, win->_begx + win->_curx, ch | win->_attrs); waddch(win, ch | win->_attrs); } if (setHere) nocbreak(); return(ch); } X/* ** short ** kgetch() ** ** Get an input character, but take care of keypad sequences, returning ** an appropriate code when one matches the input. After each character ** is received, set a one-second alarm call. If no more of the sequence ** is received by the time the alarm goes off, pass through the sequence ** gotten so far. ** */ static bool alarmed; static short kgetch() { struct try *ptr; char ch; char buffer[10]; /* Assume no sequences longer than 10 */ char *bufp = buffer; int (*oldsig)(); int sigalrm(); ptr = SP->_keytry; oldsig = signal(SIGALRM, sigalrm); alarmed = FALSE; do { ch = nextc(); if (ch != EOF) /* getc() returns EOF on error, too */ *(bufp++) = ch; if (alarmed) break; while (ptr != NULL && ptr->ch != ch) ptr = ptr->sibling; if (ptr != NULL) { if (ptr->value != NULL) { alarm(0); signal(SIGALRM, oldsig); return(ptr->value); } else { ptr = ptr->child; alarm(1); } } } while (ptr != NULL); alarm(0); signal(SIGALRM, oldsig); while (--bufp > buffer) putback(*bufp); return(*bufp); } static sigalrm() { alarmed = TRUE; signal(SIGALRM, sigalrm); } //go.sysin dd * echo 'x - =src/lib_getstr.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getstr.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_getstr.c ** ** The routine wgetstr(). ** ** $Log: RCS/lib_getstr.v $ * Revision 2.1 82/10/25 14:47:33 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:45:39 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_getstr.v Revision 2.1 82/10/25 14:47:33 pavel Exp$"; #include "curses.h" #include "curses.priv.h" #include "unctrl.h" #define backspace() { \ mvwaddstr(curscr, win->_begy + win->_cury, \ win->_begx + win->_curx, "\b \b");\ waddstr(win, "\b \b"); \ fputs("\b \b", SP->_ofp); \ fflush(SP->_ofp); \ } wgetstr(win,str) WINDOW *win; char *str; { bool oldnl, oldecho, oldraw, oldcbreak; char erasec; char killc; char *oldstr; #ifdef TRACE if (_tracing) _tracef("wgetstr(%o,%o) called", win, str); #endif oldnl = SP->_nl; oldecho = SP->_echo; oldraw = SP->_raw; oldcbreak = SP->_cbreak; nl(); noecho(); noraw(); cbreak(); erasec = erasechar(); killc = killchar(); oldstr = str; while ((*str = getc(SP->_ifp)) != ERR && *str != '\n') { if (*str == erasec) { if (str > oldstr) { str--; backspace(); if (*str < ' ' || *str == '\177') backspace(); } } else if (*str == killc) { while (str > oldstr) { str--; backspace(); if (*str < ' ' || *str == '\177') backspace(); } } else { mvwaddstr(curscr, win->_begy + win->_cury, win->_begx + win->_curx, unctrl(*str)); waddstr(win, unctrl(*str)); fputs(unctrl(*str), SP->_ofp); fflush(SP->_ofp); str++; } } if (! oldnl) nonl(); if (oldecho) echo(); if (oldraw) raw(); if (! oldcbreak) nocbreak(); if (*str == ERR) { *str = '\0'; return(ERR); } *str = '\0'; #ifdef TRACE if (_tracing) _tracef("\twgetstr returns %s", oldstr); #endif return(OK); } //go.sysin dd * echo 'x - =src/lib_initscr.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_initscr.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_initscr.c ** ** The routine initscr(). ** ** $Log: RCS/lib_initscr.v $ * Revision 2.1 82/10/25 14:47:36 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:45:54 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_initscr.v Revision 2.1 82/10/25 14:47:36 pavel Exp$"; #include "curses.h" #include "curses.priv.h" WINDOW * initscr() { #ifdef TRACE _init_trace(); if (_tracing) _tracef("initscr() called"); #endif if (newterm(getenv("TERM"), stdout) == ERR) return(ERR); else return(stdscr); } //go.sysin dd * echo 'x - =src/lib_insch.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insch.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_insch.c ** ** The routine winsch(). ** ** $Log: RCS/lib_insch.v $ * Revision 2.1 82/10/25 14:47:39 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:46:02 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_insch.v Revision 2.1 82/10/25 14:47:39 pavel Exp$"; #include "curses.h" #include "curses.priv.h" winsch(win, c) WINDOW *win; char c; { chtype *temp1, *temp2; chtype *end; #ifdef TRACE if (_tracing) _tracef("winsch(%o,'%c') called", win, c); #endif end = &win->_line[win->_cury][win->_curx]; temp1 = &win->_line[win->_cury][win->_maxx]; temp2 = temp1 - 1; while (temp1 > end) *temp1-- = *temp2--; *temp1 = c | win->_attrs; win->_lastchar[win->_cury] = win->_maxx; if (win->_firstchar[win->_cury] == _NOCHANGE || win->_firstchar[win->_cury] > win->_curx) win->_firstchar[win->_cury] = win->_curx; } //go.sysin dd * echo 'x - =src/lib_insertln.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insertln.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_insertln.c ** ** The routine winsertln(). ** ** $Log: RCS/lib_insertln.v $ * Revision 2.1 82/10/25 14:47:44 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:46:12 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_insertln.v Revision 2.1 82/10/25 14:47:44 pavel Exp$"; #include "curses.h" #include "curses.priv.h" winsertln(win) WINDOW *win; { chtype *temp, *end; int y; #ifdef TRACE if (_tracing) _tracef("winsertln(%o) called", win); #endif temp = win->_line[win->_regbottom]; win->_firstchar[win->_cury] = 0; win->_lastchar[win->_cury] = win->_maxx; for (y = win->_regbottom; y > win->_cury; y--) { win->_line[y] = win->_line[y-1]; win->_firstchar[y] = 0; win->_lastchar[y] = win->_maxx; } win->_line[win->_cury] = temp; for (end = &temp[win->_maxx]; temp <= end; temp++) *temp = ' ' | win->_attrs; } //go.sysin dd * echo 'x - =src/lib_longname.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_longname.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_longname.c ** ** The routine longname(). ** ** $Log: RCS/lib_longname.v $ * Revision 2.1 82/10/25 14:47:49 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:46:21 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_longname.v Revision 2.1 82/10/25 14:47:49 pavel Exp$"; #include "curses.h" #include "curses.priv.h" char * longname() { char *ptr; #ifdef TRACE if (_tracing) _tracef("longname() called"); #endif for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--) if (*ptr == '|') return(ptr + 1); return(ttytype); } //go.sysin dd * echo 'x - =src/lib_move.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_move.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_move.c ** ** The routine wmove(). ** ** $Log: RCS/lib_move.v $ * Revision 2.1 82/10/25 14:47:51 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:46:31 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_move.v Revision 2.1 82/10/25 14:47:51 pavel Exp$"; #include "curses.h" #include "curses.priv.h" wmove(win, y, x) WINDOW *win; int y, x; { #ifdef TRACE if (_tracing) _tracef("wmove(%o,%d,%d) called", win, y, x); #endif if (0 <= x && x <= win->_maxx && win->_regtop <= y && y <= win->_regbottom) { win->_curx = x; win->_cury = y; return(OK); } else return(ERR); } //go.sysin dd * echo 'x - =src/lib_mvcur.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvcur.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** ** lib_mvcur.c ** ** mvcur() and its subroutines ** ** $Log: RCS/lib_mvcur.v $ * Revision 2.1 82/10/25 14:47:54 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:46:40 pavel * Beta-one Test Release * ** ** Revisions needed: ** implement c_save instead of multiple tputs() calls ** routine revisions */ static char RCSid[] = "$Header: RCS/lib_mvcur.v Revision 2.1 82/10/25 14:47:54 pavel Exp$"; #include "term.h" #include "curses.h" #include "curses.priv.h" #define BUFSIZE 128 /* size of strategy buffer */ struct Sequence { int vec[BUFSIZE], /* vector of operations */ *end, /* end of vector */ cost; /* cost of vector */ }; X/* ** #define ** Make_seq_best(s1, s2) ** ** Make_seq_best() swaps the values ** of the pointers if s1->cost > s2->cost. */ #define Make_seq_best(s1, s2) \ if (s1->cost > s2->cost) \ { \ struct Sequence *temp; \ \ temp = s1; \ s1 = s2; \ s2 = temp; \ } XFILE *out_file; /* pointer to output file */ static int c_count; /* used for counting tputs output */ X/*rev c_save not yet used static char *c_save; /* used for saving tputs output */ #define INFINITY 1000 /* biggest, impossible sequence cost */ #define NUM_OPS 16 /* num. term. control sequences */ #define NUM_NPARM 9 /* num. ops wo/ parameters */ /* operator indexes into op_info */ #define CARRIAGE_RETURN 0 /* watch out for nl mapping */ #define CURS_DOWN 1 #define CURS_HOME 2 #define CURS_LEFT 3 #define CURS_RIGHT 4 #define CURS_TO_LL 5 #define CURS_UP 6 #define TAB 7 #define BACK_TAB 8 #define ROW_ADDR 9 #define COL_ADDR 10 #define P_DOWN_CURS 11 #define P_LEFT_CURS 12 #define P_RIGHT_CURS 13 #define P_UP_CURS 14 #define CURS_ADDR 15 static bool loc_init = FALSE; /* set if op_info is init'ed */ static bool rel_ok; /* set if we really know where we are */ X/* * op_info[NUM_OPS] * * op_info[] contains for operations with no parameters * the cost of the operation. These ops should be first in the array. * For operations with parameters, op_info[] contains * the negative of the number of parameters. */ static int op_info[NUM_OPS] = { 0, /* carriage_return */ 0, /* cursor_down */ 0, /* cursor_home */ 0, /* cursor_left */ 0, /* cursor_right */ 0, /* cursor_to_ll */ 0, /* cursor_up */ 0, /* tab */ 0, /* back_tab */ -1, /* row_address */ -1, /* column_address */ -1, /* parm_down_cursor */ -1, /* parm_left_cursor */ -1, /* parm_right_cursor */ -1, /* parm_up_cursor */ -2 /* cursor_address */ }; X/* ** ** mvcur(oldrow, oldcol, newrow, newcol) ** ** mvcur() optimally moves the cursor from the position ** specified by (oldrow, oldcol) to (newrow, newcol). If ** (oldrow, oldcol) == (-1, -1), mvcur() does not use relative ** cursor motions. If the coordinates are otherwise ** out of bounds, it mods them into range. ** ** Revisions needed: ** eat_newline_glitch, auto_right_margin */ mvcur(oldrow, oldcol, newrow, newcol) int oldrow, oldcol, newrow, newcol; { struct Sequence seqA, seqB, /* allocate work structures */ col0seq, /* sequence to get from col0 to nc */ *best, /* best sequence so far */ *try; /* next try */ #ifdef TRACE if (_tracing) _tracef("mvcur(%d,%d,%d,%d) called", oldrow, oldcol, newrow, newcol); #endif update_ops(); /* make sure op_info[] is current */ if (oldrow < 0 || oldcol < 0) rel_ok = FALSE; /* relative ops ok? */ else { rel_ok = TRUE; oldrow %= lines; /* mod values into range */ oldcol %= columns; } newrow %= lines; newcol %= columns; best = &seqA; try = &seqB; /* try out direct cursor addressing */ zero_seq(best); add_op(best, CURS_ADDR, newrow, newcol); /* try out independent row/column addressing */ if (rel_ok) { zero_seq(try); row(try, oldrow, newrow); column(try, oldcol, newcol); Make_seq_best(best, try); } zero_seq(&col0seq); /* store seq. to get from c0 to nc */ column(&col0seq, 0, newcol); if(col0seq.cost < INFINITY) /* can get from col0 to newcol */ { /* try out homing and then row/column */ if (! rel_ok || newcol < oldcol || newrow < oldrow) { zero_seq(try); add_op(try, CURS_HOME, 1); row(try, 0, newrow); add_seq(try, &col0seq); Make_seq_best(best, try); } /* try out homing to last line and then row/column */ if (! rel_ok || newcol < oldcol || newrow > oldrow) { zero_seq(try); add_op(try, CURS_TO_LL, 1); row(try, lines - 1, newrow); add_seq(try, &col0seq); Make_seq_best(best, try); } } #ifdef TRACE if (_tracing) _tracef("\tmvcur: result follows"); #endif out_seq(best); #ifdef TRACE if (_tracing) _tracef("\tmvcur: end of result"); #endif } X/* ** row(outseq, oldrow, newrow) ** ** row() adds the best sequence for moving ** the cursor from oldrow to newrow to seq. ** row() considers row_address, parm_up/down_cursor ** and cursor_up/down. */ static row(outseq, orow, nrow) int orow, nrow; /* old, new cursor locations */ struct Sequence *outseq; /* where to put the output */ { struct Sequence seqA, seqB, *best, /* best sequence so far */ *try; /* next try */ int parm_cursor, one_step; best = &seqA; try = &seqB; if (nrow == orow) return; if (nrow < orow) { parm_cursor = P_UP_CURS; one_step = CURS_UP; } else { parm_cursor = P_DOWN_CURS; one_step = CURS_DOWN; } /* try out direct row addressing */ zero_seq(best); add_op(best, ROW_ADDR, nrow); /* try out paramaterized up or down motion */ if (rel_ok) { zero_seq(try); add_op(try, parm_cursor, abs(orow - nrow)); Make_seq_best(best, try); } /* try getting there one step at a time... */ if (rel_ok) { zero_seq(try); add_op(try, one_step, abs(orow-nrow)); Make_seq_best(best, try); } add_seq(outseq, best); } X/* ** column(outseq, oldcol, newcol) ** ** column() adds the best sequence for moving ** the cursor from oldcol to newcol to outseq. ** column() considers column_address, parm_left/right_cursor, ** simp_col(), and carriage_return followed by simp_col(). */ static column(outseq, ocol, ncol) struct Sequence *outseq; /* where to put the output */ int ocol, ncol; /* old, new cursor column */ { struct Sequence seqA, seqB, *best, *try; int parm_cursor; /* set to either parm_up/down_cursor */ best = &seqA; try = &seqB; if (ncol == ocol) return; if (ncol < ocol) parm_cursor = P_LEFT_CURS; else parm_cursor = P_RIGHT_CURS; /* try out direct column addressing */ zero_seq(best); add_op(best, COL_ADDR, ncol); /* try carriage_return then simp_col() */ if (! rel_ok || (ncol < ocol)) { zero_seq(try); add_op(try, CARRIAGE_RETURN, 1); simp_col(try, 0, ncol); Make_seq_best(best, try); } if (rel_ok) { /* try out paramaterized left or right motion */ zero_seq(try); add_op(try, parm_cursor, abs(ocol - ncol)); Make_seq_best(best, try); /* try getting there with simp_col() */ zero_seq(try); simp_col(try, ocol, ncol); Make_seq_best(best, try); } add_seq(outseq, best); } X/* ** simp_col(outseq, oldcol, newcol) ** ** simp_col() adds the best simple sequence for getting ** from oldcol to newcol to outseq. ** simp_col() considers (back_)tab and cursor_left/right. ** ** Revisions needed: ** Simp_col asssumes that the cost of a (back_)tab ** is less then the cost of one-stepping to get to the same column. ** Should sometimes use overprinting instead of cursor_right. */ static simp_col(outseq, oc, nc) struct Sequence *outseq; /* place to put sequence */ int oc, nc; /* old column, new column */ { struct Sequence seqA, seqB, tabseq, *best, *try; int mytab, tabs, onepast, one_step, opp_step; if (! rel_ok) { outseq->cost = INFINITY; return; } if (oc == nc) return; best = &seqA; try = &seqB; if (oc < nc) { mytab = TAB; if (init_tabs > 0 && op_info[TAB] < INFINITY) { tabs = nc / init_tabs - oc / init_tabs; onepast = ((nc / init_tabs) + 1) * init_tabs; if (tabs) oc = onepast - init_tabs; /* consider it done */ } else tabs = 0; one_step = CURS_RIGHT; opp_step = CURS_LEFT; } else { mytab = BACK_TAB; if (init_tabs > 0 && op_info[BACK_TAB] < INFINITY) { tabs = oc / init_tabs - nc / init_tabs; onepast = ((nc - 1) / init_tabs) * init_tabs; if (tabs) oc = onepast + init_tabs; /* consider it done */ } else tabs = 0; one_step = CURS_LEFT; opp_step = CURS_RIGHT; } /* tab as close as possible to nc */ zero_seq(&tabseq); add_op(&tabseq, mytab, tabs); /* try extra tab and backing up */ zero_seq(best); if (onepast >= 0 && onepast < columns) { add_op(best, mytab, 1); add_op(best, opp_step, abs(onepast - nc)); } else best->cost = INFINITY; /* make sure of next swap */ /* try stepping to nc */ zero_seq(try); add_op(try, one_step, abs(nc - oc)); Make_seq_best(best, try); if (tabseq.cost < INFINITY) add_seq(outseq, &tabseq); add_seq(outseq, best); } X/* ** zero_seq(seq) ** add_seq(seq1, seq2) ** out_seq(seq) ** ** zero_seq() empties seq. ** add_seq() adds seq1 to seq2. ** out_seq() outputs a sequence. */ static zero_seq(seq) struct Sequence *seq; { seq->end = seq->vec; seq->cost = 0; } static add_seq(seq1, seq2) struct Sequence *seq1, *seq2; { int *vptr; if(seq1->cost >= INFINITY || seq2->cost >= INFINITY) seq1->cost = INFINITY; else { vptr = seq2->vec; while (vptr != seq2->end) *(seq1->end++) = *(vptr++); seq1->cost += seq2->cost; } } static out_seq(seq) struct Sequence *seq; { int *opptr, prm[9], ps, p, op, outc(); int count; char *sequence(); if (seq->cost >= INFINITY) return; for (opptr = seq->vec; opptr < seq->end; opptr++) { op = *opptr; /* grab operator */ ps = -op_info[op]; if(ps > 0) /* parameterized */ { for (p = 0; p < ps; p++) /* fill in needed parms */ prm[p] = *(++opptr); tputs(tparm(sequence(op), prm[0], prm[1], prm[2], prm[3], prm[4], prm[5], prm[6], prm[7], prm[8]), 1, outc); } else { count = *(++opptr); /*rev should save tputs output instead of mult calls */ while (count--) /* do count times */ tputs(sequence(op), 1, outc); } } } X/* ** update_ops() ** ** update_ops() makes sure that ** the op_info[] array is updated and initializes ** the cost array for SP if needed. */ static update_ops() { if (SP) /* SP structure exists */ { int op; out_file = SP->_ofp; /* set output file pointer */ if (! SP->_costinit) /* this term not yet assigned costs */ { loc_init = FALSE; /* if !SP in the future, new term */ init_costs(SP->_costs); /* fill term costs */ SP->_costinit = TRUE; } for (op = 0; op < NUM_NPARM; op++) op_info[op] = SP->_costs[op]; /* set up op_info */ /* check for newline that might be mapped... */ if (SP->_nlmapping && index(sequence(CURS_DOWN), '\n')) op_info[CURS_DOWN] = INFINITY; } else { out_file = stdout; if (! loc_init) /* using local costs */ { loc_init = TRUE; init_costs(op_info); /* set up op_info */ } /* check for newline that might be mapped... */ if (index(sequence(CURS_DOWN), '\n')) op_info[CURS_DOWN] = INFINITY; } } X/* ** init_costs(costs) ** ** init_costs() fills the array costs[NUM_NPARM] ** with costs calculated by doing tputs() calls. */ static init_costs(costs) int costs[]; { int i, countc(); for (i = 0; i < NUM_NPARM; i++) if(sequence(i) != (char *) 0) { #ifdef UNDEFINED if (_tracing) _tracef("\tinit_costs: pricing %d: '%s'", i, sequence(i)); #endif c_count = 0; tputs(sequence(i), 1, countc); costs[i] = c_count; } else costs[i] = INFINITY; } X/* ** countc() ** outc(c) ** savec(c) ** ** countc() increments global var c_count. ** outc() outputs a single character. ** savec() saves c in *c_save and increments c_save and c_count. */ static countc() { c_count++; } static outc(c) char c; { fputc(c, out_file); } X/*rev not yet needed static savec(c) char c; { *(c_save++) = c; c_count++; } */ X/* ** add_op(seq, op, p0, p1, ... , p8) ** ** add_op() adds the operator op and the appropriate ** number of paramaters to seq. It also increases the ** cost appropriately. ** if op has no parameters, p0 is taken to be a count. */ static add_op(seq, op, p0, p1, p2, p3, p4, p5, p6, p7, p8) struct Sequence *seq; int op, p0, p1, p2, p3, p4, p5, p6, p7, p8; { int num_ps, p; #ifdef UNDEFINED if (_tracing) _tracef("\tadd_op(%o,%d,%d,%d) called", seq, op, p0, p1); #endif num_ps = - op_info[op]; /* get parms or -cost */ *(seq->end++) = op; if (num_ps == (- INFINITY) || sequence(op) == (char *) 0) seq->cost = INFINITY; else if (num_ps <= 0) /* no parms, -cost */ { seq->cost -= p0 * num_ps; /* ADD count * cost */ *(seq->end++) = p0; } else { int pms[9]; pms[0] = p0; pms[1] = p1; pms[2] = p2; pms[3] = p3; pms[4] = p4; pms[5] = p5; pms[6] = p6; pms[7] = p7; pms[8] = p8; for(p = 0; p < num_ps; p++) *(seq->end++) = pms[p]; c_count = 0; tputs(tparm(sequence(op), p0, p1, p2, p3, p4, p5, p6, p7, p8), 1, countc); seq->cost += c_count; } } X/* ** char * ** sequence(op) ** ** sequence() returns a pointer to the op's ** terminal control sequence. */ static char * sequence(op) int op; { switch(op) { case CARRIAGE_RETURN: return (carriage_return); case CURS_DOWN: return (cursor_down); case CURS_HOME: return (cursor_home); case CURS_LEFT: return (cursor_left); case CURS_RIGHT: return (cursor_right); case CURS_TO_LL: return (cursor_to_ll); case CURS_UP: return (cursor_up); case TAB: return (tab); case BACK_TAB: return (back_tab); case ROW_ADDR: return (row_address); case COL_ADDR: return (column_address); case P_DOWN_CURS: return (parm_down_cursor); case P_LEFT_CURS: return (parm_left_cursor); case P_RIGHT_CURS: return (parm_right_cursor); case P_UP_CURS: return (parm_up_cursor); case CURS_ADDR: return (cursor_address); default: return ((char *) 0); } } //go.sysin dd * echo 'x - =src/lib_mvwin.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvwin.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_mvwin.c ** ** The routine mvwin(). ** ** $Log: RCS/lib_mvwin.v $ * Revision 2.1 82/10/25 14:48:10 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:47:03 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_mvwin.v Revision 2.1 82/10/25 14:48:10 pavel Exp$"; #include "curses.h" #include "curses.priv.h" mvwin(win, by, bx) WINDOW *win; int by, bx; { #ifdef TRACE if (_tracing) _tracef("mvwin(%o,%d,%d) called", win, by, bx); #endif if (by + win->_maxy > LINES -1 || bx + win->_maxx > COLS - 1) return(ERR); win->_begy = by; win->_begx = bx; touchwin(win); return(OK); } //go.sysin dd * echo 'x - =src/lib_newterm.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newterm.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_newterm.c ** ** The newterm() function. ** ** $Log: RCS/lib_newterm.v $ * Revision 2.1 82/10/25 14:48:14 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:47:11 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_newterm.v Revision 2.1 82/10/25 14:48:14 pavel Exp$"; #include #include #include "curses.h" #include "term.h" #include "curses.priv.h" struct screen * newterm(term, fp) char *term; XFILE *fp; { int errret; int tstp(); #ifdef TRACE _init_trace(); if (_tracing) _tracef("newterm(%s,%o) called", term, fp); #endif if (setupterm(term, fileno(fp), &errret) != 1) return(ERR); if ((SP = (struct screen *) malloc(sizeof *SP)) == NULL) return(ERR); if (fp == stdout) { SP->_ofp = stdout; SP->_ifp = stdin; } else { SP->_ofp = fp; SP->_ifp = fp; } SP->_term = cur_term; SP->_cursrow = -1; SP->_curscol = -1; SP->_keytry = UNINITIALISED; SP->_nl = TRUE; SP->_raw = FALSE; SP->_cbreak = FALSE; SP->_echo = TRUE; SP->_nlmapping = TRUE; SP->_costinit = FALSE; LINES = lines; COLS = columns; if (enter_ca_mode) putp(enter_ca_mode); if ((newscr = newwin(lines, columns, 0, 0)) == ERR) return(ERR); if ((curscr = newwin(lines, columns, 0, 0)) == ERR) return(ERR); SP->_newscr = newscr; SP->_curscr = curscr; newscr->_clear = TRUE; curscr->_clear = FALSE; signal(SIGTSTP, tstp); if (stdscr == NULL) if ((stdscr = newwin(lines, columns, 0, 0)) == ERR) return(ERR); #ifdef TRACE if (_tracing) _tracef("\tnewterm returns %o", SP); #endif return(SP); } //go.sysin dd * echo 'x - =src/lib_newwin.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newwin.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_newwin.c ** ** The routines newwin(), subwin() and their dependent ** ** $Log: RCS/lib_newwin.v $ * Revision 2.1 82/10/25 14:48:18 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:47:18 pavel * Beta-one Test Release * ** */ #include "term.h" #include "curses.h" #include "curses.priv.h" short *calloc(); WINDOW *malloc(); static WINDOW *makenew(); WINDOW * newwin(num_lines, num_columns, begy, begx) int num_lines, num_columns, begy, begx; { WINDOW *win; chtype *ptr; int i, j; #ifdef TRACE if (_tracing) _tracef("newwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx); #endif if (num_lines == 0) num_lines = lines - begy; if (num_columns == 0) num_columns = columns - begx; if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR) return(ERR); for (i = 0; i < num_lines; i++) { if ((win->_line[i] = (chtype *) calloc(num_columns, sizeof(chtype))) == NULL) { for (j = 0; j < i; j++) cfree(win->_line[j]); cfree(win->_firstchar); cfree(win->_lastchar); cfree(win->_line); cfree(win); return(ERR); } else for (ptr = win->_line[i]; ptr < win->_line[i] + num_columns; ) *ptr++ = ' '; } #ifdef TRACE if (_tracing) _tracef("\tnewwin: returned window is %o", win); #endif return(win); } WINDOW * subwin(orig, num_lines, num_columns, begy, begx) WINDOW *orig; int num_lines, num_columns, begy, begx; { WINDOW *win; int i, j, k; #ifdef TRACE if (_tracing) _tracef("subwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx); #endif /* ** make sure window fits inside the original one */ if (begy < orig->_begy || begx < orig->_begx || begy + num_lines > orig->_maxy || begx + num_columns > orig->_maxx) return(ERR); if (num_lines == 0) num_lines = orig->_maxy - orig->_begy - begy; if (num_columns == 0) num_columns = orig->_maxx - orig->_begx - begx; if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR) return(ERR); j = orig->_begy + begy; k = orig->_begx + begx; for (i = 0; i < num_lines; i++) win->_line[i] = &orig->_line[j++][k]; win->_flags = _SUBWIN; #ifdef TRACE if (_tracing) _tracef("\tsubwin: returned window is %o", win); #endif return(win); } static WINDOW * makenew(num_lines, num_columns, begy, begx) int num_lines, num_columns, begy, begx; { int i; WINDOW *win; if ((win = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) return ERR; if ((win->_line = (chtype **) calloc(num_lines, sizeof (chtype *))) == NULL) { cfree(win); return(ERR); } if ((win->_firstchar = calloc(num_lines, sizeof(short))) == NULL) { cfree(win); cfree(win->_line); return(ERR); } if ((win->_lastchar = calloc(num_lines, sizeof(short))) == NULL) { cfree(win); cfree(win->_line); cfree(win->_firstchar); return(ERR); } if ((win->_numchngd = calloc(num_lines, sizeof(short))) == NULL) { cfree(win); cfree(win->_line); cfree(win->_firstchar); cfree(win->_lastchar); return(ERR); } win->_curx = 0; win->_cury = 0; win->_maxy = num_lines - 1; win->_maxx = num_columns - 1; win->_begy = begy; win->_begx = begx; win->_flags = 0; win->_attrs = A_NORMAL; win->_clear = (num_lines == lines && num_columns == columns); win->_scroll = FALSE; win->_leave = FALSE; win->_use_keypad = FALSE; win->_use_meta = FALSE; win->_nodelay = FALSE; win->_regtop = 0; win->_regbottom = num_lines - 1; for (i = 0; i < num_lines; i++) { win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE; win->_numchngd[i] = 0; } if (begx + num_columns == columns) { win->_flags |= _ENDLINE; if (begx == 0 && num_lines == lines && begy == 0) win->_flags |= _FULLWIN; if (begy + num_lines == lines) win->_flags |= _SCROLLWIN; } return(win); } //go.sysin dd * echo 'x - =src/lib_options.c' sed 's/^X//' <<'//go.sysin dd *' >=src/lib_options.c X/********************************************************************* * COPYRIGHT NOTICE * ********************************************************************** * This software is copyright (C) 1982 by Pavel Curtis * * * * Permission is granted to reproduce and distribute * * this file by any means so long as no fee is charged * * above a nominal handling fee and so long as this * * notice is always included in the copies. * * * * Other rights are reserved except as explicitly granted * * by written permission of the author. * * Pavel Curtis * * Computer Science Dept. * * 405 Upson Hall * * Cornell University * * Ithaca, NY 14853 * * * * Ph- (607) 256-4934 * * * * Pavel.Cornell@Udel-Relay (ARPAnet) * * decvax!cornell!pavel (UUCPnet) * *********************************************************************/ X/* ** lib_options.c ** ** The routines to handle option setting. ** ** $Log: RCS/lib_options.v $ * Revision 2.1 82/10/25 14:48:24 pavel * Added Copyright Notice * * Revision 2.0 82/10/25 13:47:45 pavel * Beta-one Test Release * ** */ static char RCSid[] = "$Header: RCS/lib_options.v Revision 2.1 82/10/25 14:48:24 pavel Exp$"; #include "term.h" #include "curses.h" #include "curses.priv.h" static outc(ch) char ch; { putc(ch, SP->_ofp); } idlok(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("idlok(%o,%d) called", win, flag); #endif if ((insert_line && delete_line) #ifdef UNIMPLEMENTED || (change_scroll_region) #endif ) curscr->_idlok = flag; } clearok(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("clearok(%o,%d) called", win, flag); #endif if (win == curscr) newscr->_clear = flag; else win->_clear = flag; } leaveok(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("leaveok(%o,%d) called", win, flag); #endif win->_leave = flag; } scrollok(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("scrollok(%o,%d) called", win, flag); #endif win->_scroll = flag; } nodelay(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("nodelay(%o,%d) called", win, flag); #endif win->_nodelay = flag; } keypad(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("keypad(%o,%d) called", win, flag); #endif win->_use_keypad = flag; if (flag && keypad_xmit) tputs(keypad_xmit, 1, outc); else if (! flag && keypad_local) tputs(keypad_local, 1, outc); if (SP->_keytry == UNINITIALISED) init_keytry(); } meta(win, flag) WINDOW *win; int flag; { #ifdef TRACE if (_tracing) _tracef("meta(%o,%d) called", win, flag); #endif win->_use_meta = flag; if (flag && meta_on) tputs(meta_on, 1, outc); else if (! flag && meta_off) tputs(meta_off, 1, outc); } X/* ** init_keytry() ** ** Construct the try for the current terminal's keypad keys. ** */ static struct try *newtry; static init_keytry() { newtry = NULL; add_to_try(key_backspace, KEY_BACKSPACE); add_to_try(key_catab, KEY_CATAB); add_to_try(key_clear, KEY_CLEAR); add_to_try(key_ctab, KEY_CTAB); add_to_try(key_dc, KEY_DC); add_to_try(key_dl, KEY_DL); add_to_try(key_down, KEY_DOWN); add_to_try(key_eic, KEY_EIC); add_to_try(key_eol, KEY_EOL); add_to_try(key_eos, KEY_EOS); add_to_try(key_f0, KEY_F(0)); add_to_try(key_f1, KEY_F(1)); add_to_try(key_f2, KEY_F(2)); add_to_try(key_f3, KEY_F(3)); add_to_try(key_f4, KEY_F(4)); add_to_try(key_f5, KEY_F(5)); add_to_try(key_f6, KEY_F(6)); add_to_try(key_f7, KEY_F(7)); add_to_try(key_f8, KEY_F(8)); add_to_try(key_f9, KEY_F(9)); add_to_try(key_f10, KEY_F(10)); add_to_try(key_home, KEY_HOME); add_to_try(key_ic, KEY_IC); add_to_try(key_il, KEY_IL); add_to_try(key_left, KEY_LEFT); add_to_try(key_npage, KEY_NPAGE); add_to_try(key_ppage, KEY_PPAGE); add_to_try(key_right, KEY_RIGHT); add_to_try(key_sf, KEY_SF); add_to_try(key_sr, KEY_SR); add_to_try(key_stab, KEY_STAB); add_to_try(key_up, KEY_UP); SP->_keytry = newtry; } add_to_try(str, code) char *str; short code; { static bool out_of_memory = FALSE; struct try *ptr, *savedptr; struct try *malloc(); if (! str || out_of_memory) return; if (newtry != NULL) { ptr = newtry; for (;;) { while (ptr->ch != *str && ptr->sibling != NULL) ptr = ptr->sibling; if (ptr->ch == *str) { if (*(++str)) { if (ptr->child != NULL) ptr = ptr->child; else break; } else { ptr->value = code; return; } } else { if ((ptr->sibling = malloc(sizeof *ptr)) == NULL) { out_of_memory = TRUE; return; } savedptr = ptr = ptr->sibling; ptr->child = ptr->sibling = NULL; ptr->ch = *str++; ptr->value = NULL; break; } } /* end for (;;) */ } else /* newtry == NULL :: First sequence to be added */ { savedptr = ptr = newtry = malloc(sizeof *ptr); if (ptr == NULL) { out_of_memory = TRUE; return; } ptr->child = ptr->sibling = NULL; ptr->ch = *(str++); ptr->value = NULL; } /* at this point, we are adding to the try. ptr->child == NULL */ while (*str) { ptr->child = malloc(sizeof *ptr); ptr = ptr->child; if (ptr == NULL) { out_of_memory = TRUE; ptr = savedptr; while (ptr != NULL) { savedptr = ptr->child; free(ptr); ptr = savedptr; } return; } ptr->child = ptr->sibling = NULL; ptr->ch = *(str++); ptr->value = NULL; } ptr->value = code; return; } //go.sysin dd * exit