home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i051: Terminal emulator for NeWS window system, Part04/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: hoptoad!gnu (John Gilmore)
- Posting-number: Volume 16, Issue 51
- Archive-name: psterm/part04
-
- : psterm part 4 of 4
- : To unbundle, sh this file
- echo tcap.cps
- cat >tcap.cps <<'@@@ Fin de tcap.cps'
- %
- % This file is a product of Sun Microsystems, Inc. and is provided for
- % unrestricted use provided that this legend is included on all tape
- % media and as a part of the software program in whole or part.
- % Users may copy, modify or distribute this file at will.
- %
- % THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- % WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- % PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- %
- % This file is provided with no support and without any obligation on the
- % part of Sun Microsystems, Inc. to assist in its use, correction,
- % modification or enhancement.
- %
- % SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- % INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
- % OR ANY PART THEREOF.
- %
- % In no event will Sun Microsystems, Inc. be liable for any lost revenue
- % or profits or other special, indirect and consequential damages, even
- % if Sun has been advised of the possibility of such damages.
- %
- % Sun Microsystems, Inc.
- % 2550 Garcia Avenue
- % Mountain View, California 94043
- %
- % Modifications to the original Sun Microsystems, Inc. source code
- % made by the Grasshopper Group are in the Public Domain.
- %
- % Extensions to this file by Eric Messick of the Grasshopper Group.
- %
- % Grasshopper Group
- % 212 Clayton St
- % San Francisco, CA 94117
- %
- %
- %
- % "@(#)tcap.cps 9.5 88/01/19 SMI
- % "@(#)$Header: tcap.cps,v 2.2 88/10/04 05:59:57 gnu Release $
- %
- % Copyright (c) 1985 by Sun Microsystems, Inc.
- %/
-
- cdef PSDefs(reload)
- systemdict /LoadingPSTerm known {
- createevent dup begin
- /Name [/PSTimer /PSTermLoaded] def
- end expressinterest
- createevent dup begin
- /Name /PSTimer def
- /TimeStamp currenttime .5 add def
- end sendevent awaitevent pop
- } if pause
- systemdict /PSTermDict known not reload 0 ne or {
- systemdict /LoadingPSTerm true put
- systemdict /PSTermDict undef
- (psterm.ps) LoadFile pop
- } if pause
-
- cdef PSInitCode(string userinit)
- PSTermDict /UserCodeLoaded known not {
- (.pstermrc) LoadFile pop
- PSTermDict /UserCodeLoaded true put
- systemdict /LoadingPSTerm undef
- createevent dup begin
- /Name /PSTermLoaded def
- /TimeStamp currenttime def
- end sendevent
- } if pause
- userdict end PSTermDict begin begin
- % PSTermDict begin dictstackexch
- PSTermInit
- PSTermDict userinit known { userinit cvx exec } if
-
- cdef CreateWindow(x, y, fs, col, lines, string framelabel,
- string iconlabel, string initialfont, starticonic, iconx, icony)
- x y fs col lines
- framelabel iconlabel initialfont starticonic iconx icony
- createwindow
-
- cdef StartInput() startinput
- cdef ReInitialize() resetscale
-
- cdef CursorUp(x,y,cstring c) c x y CU
- cdef CursorDown(x,y,cstring c) c x y CD
-
- cdef PaintUnderRev(cstring s) s UR
- cdef PaintUnderNor(cstring s) s UN
- cdef PaintRev(cstring s) s PR
- cdef PaintNor(cstring s) s PN
- cdef MoveTo(x, y) x y MT
- cdef ClearToEndOfLine() CE
- cdef CopyLines(yfrom, yby, w, nl) yby w yfrom nl CL
-
- cdef BeginRepair() BRP
- cdef EndRepair() ERP
- cdef EndRefresh() EOR
-
- cdef SetFrameLabel(string str) str SL
- cdef SetSelContents(r, s, l, cstring str) str s l r setselcontents
- cdef RingBell() VB % no audible bell as yet
- cdef VisibleBell() VB
- cdef SetPageMode(onoff) onoff PM
- cdef SetAutoMargins(onoff) onoff AM
-
- cdef StartHiLighting(strokeit) strokeit [
- cdef HiLightLine(length) length
- cdef EndHiLighting(endcol, startcol, startrow) endcol ] startcol startrow HL
- cdef ClearSelectionPath() clearselectionpath
- cdef RePaintHiLight() PaintHiLight
- cdef StrHiLightLine(cstring s) s
- cdef StrEndHiLighting(cstring ends, cstring starts,
- startrow) ends ] starts startrow HL
- cdef TakeDownOutline() takedownoutline
- cdef StartSavingSelection() startselset
- cdef SaveSelectionPiece(cstring s) s extsel
- cdef FinishSavingSelection() finishselset
- cdef HiLightRect(startcol, startrow, endcol, endrow, strokeit)
- strokeit startcol startrow endcol endrow HiLightRect
-
- cdef ToggleScrollBar(len) len TSB
- cdef SetScrollBarValue(len, pos) len pos SSBV
-
- cdef PopMsg(string str)
- gsave framebuffer setcanvas currentcursorlocation str popmsg grestore
- @@@ Fin de tcap.cps
- echo tcap_ops.c
- cat >tcap_ops.c <<'@@@ Fin de tcap_ops.c'
- /*
- * This file is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.
- * Users may copy, modify or distribute this file at will.
- *
- * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * This file is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even
- * if Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- *
- * Modifications to the original Sun Microsystems, Inc. source code
- * made by the Grasshopper Group are in the Public Domain.
- *
- * Extensions to this file by Eric Messick of the Grasshopper Group.
- *
- * Grasshopper Group
- * 212 Clayton St
- * San Francisco, CA 94117
- *
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)tcap_ops.c 9.6 88/01/19 Copyright 1985 Sun Micro";
- static char RCSid[] =
- "@(#)$Header: tcap_ops.c,v 2.3 88/10/04 05:59:59 gnu Release $";
- #endif
-
- /*
- * Copyright (c) 1985 by Sun Microsystems, Inc.
- */
-
- /*-
- tcap_ops.c
-
- tcap_ops.c, Mon Mar 24 11:52:31 1986
-
- David Rosenthal,
- Sun Microsystems
- */
-
-
- #include <stdio.h>
- #include <sys/types.h>
- #ifdef REF
- #include <ref/config.h>
- #endif
- #include "termcap.h"
- #include "tcap.h"
-
- /*
- * Termcap operations module.
- *
- * The external interface of this module is the array T[] and its
- * number of elements Ts, plus the initialization routine:
- * tc_init_ops()
- */
-
- #include "screen.h"
- extern int CharsPerLine;
- extern int LinesPerScreen;
- extern struct pair Dot;
- extern struct tcap T[];
- extern int Ts;
- extern char *malloc();
- #ifndef bcopy
- extern void bcopy();
- #endif
- #ifndef bzero
- extern void bzero();
- #endif
- extern char *strncpy();
- static struct tcap *tc_lookup();
-
- static u_short TopLineOfScrollRegion, BottomLineOfScrollRegion;
- static struct pair SavedCursor;
- static u_short ScrollNLKludge = 0;
- struct tcap *CheckCR = 0;
- struct tcap *CheckNL = 0;
- struct tcap *CheckBS = 0;
- struct tcap *CheckTAB = 0;
-
- static unsigned int PermanentModes = 0, TemporaryModes = 0;
-
- static char *FrameLabel;
- static u_short FLindex;
- static int (*prevInput)();
-
- struct tcap interruptedOp = { 0 };
- struct line *lastInputLine;
- int PageFull = 0;
- static int PrevPageMode = -1;
- extern int PageMode;
- extern int userLinesPerScreen;
- extern int userCharsPerLine;
-
- static int al_op(), clear_body(), ce_op(), cm_in(), cs_op();
- static int dc_op(), dl_op(), ic_op(), nl_op(), sf_op();
-
- tc_init_ops()
- {
- struct tcap *me, *tc;
-
- if (userLinesPerScreen > 0)
- LinesPerScreen = userLinesPerScreen;
- if (userCharsPerLine > 0)
- CharsPerLine = userCharsPerLine;
- Dot.x = 0 ;
- Dot.y = LinesPerScreen - 1 ;
- TopLineOfScrollRegion = 0;
- BottomLineOfScrollRegion = LinesPerScreen - 1;
- FrameLabel = malloc((unsigned)CharsPerLine+1);
- /*
- * Beware of termcap entries that define ue and/or se identical
- * to me (turn off ALL attributes). Since we just pattern
- * match, it's likely we won't get me_op in normal operation,
- * so force the entries here. (known for vt100)
- */
- me = tc_lookup("me");
- if (me) {
- tc = tc_lookup("ue");
- if (tc && tc->t_size == me->t_size &&
- bcmp(me->t_text, tc->t_text, (int)tc->t_size) == 0)
- tc->t_op = me->t_op;
- tc = tc_lookup("se");
- if (tc && tc->t_size == me->t_size &&
- bcmp(me->t_text, tc->t_text, (int)tc->t_size) == 0)
- tc->t_op = me->t_op;
- }
- /*
- * Check for sf == \n, if so we must kludge things so that
- * sf_op will call nl_op as needed (exists on bitgraph).
- */
- tc = tc_lookup("sf");
- if (tc && tc->t_size == 1 && tc->t_text[0] == '\n')
- ScrollNLKludge = 1;
- /*
- * To minimize the number of times the regular text processing
- * is stopped to invoke the pattern matcher we check the most
- * strings CR, NL, BS, and TAB to see if they are \r, \n, \b,,
- * and \t, respectively. If any are, a quick check on the character
- * is made before the pattern matching machinery is invoked.
- */
- tc = tc_lookup("cr");
- if (tc && tc->t_size == 1 && tc->t_text[0] == '\r')
- CheckCR = tc;
- tc = tc_lookup("nl");
- if (tc && tc->t_size == 1 && tc->t_text[0] == '\n')
- CheckNL = tc;
- tc = tc_lookup("bc");
- if (tc && tc->t_size == 1 && tc->t_text[0] == '\b')
- CheckBS = tc;
- tc = tc_lookup("ta");
- if (tc && tc->t_size == 1 && tc->t_text[0] == '\t')
- CheckTAB = tc;
- }
-
- tc_initmodemenu()
- {
-
- /*
- * Insure menu items properly reflect initial settings.
- */
- SetPageMode(PageMode);
- SetAutoMargins(PermanentModes & AutoMarginMode);
- }
-
- static struct tcap *
- tc_lookup(key)
- char *key;
- {
- register struct tcap *tp;
-
- for (tp = T; *tp->t_key; tp++)
- if (strcmp(tp->t_key, key) == 0)
- return (tp);
- return ((struct tcap *)0);
- }
-
- /*
- * scrollreset is called whenever keyboard input is seen, in order to
- * do deferred scrolling and remember the last line on which the user
- * typed something.
- */
-
- scrollreset(l)
- int l;
- {
- int n = PageFull;
-
- PageFull = 0;
- lastInputLine = (l == 1) ? screen[1] : 0;
- while (n-- > 0 && !PageFull)
- sf_op((struct tcap *) 0);
- if (lastInputLine == 0)
- lastInputLine = screen[Dot.y];
- }
-
- toggleautomargins()
- {
-
- PermanentModes ^= (unsigned int) AutoMarginMode;
- SetAutoMargins(PermanentModes & AutoMarginMode);
- FlushPostScript();
- }
-
- togglepagemode()
- {
- SetPageMode(PageMode = !PageMode);
- FlushPostScript();
- }
-
- resetscreensize(row, col)
- int row, col;
- {
- struct tcap t;
- int dotx, doty;
-
- dotx = Dot.x ;
- if (dotx >= col) dotx = col - 1;
-
- doty = Dot.y - LinesPerScreen + row ;
- if (doty >= row) doty = row - 1;
- if (doty < 0) doty = 0 ;
-
- if (PageMode) {
- /* no scroll stop line */
- lastInputLine = screen[doty - row + LinesPerScreen];
- }
-
- CharsPerLine = col ;
- LinesPerScreen = row ;
-
- t.t_x = LinesPerScreen - 1 ;
- t.t_y = 0 ;
- cs_op(&t); /* change scrolling region to full screen */
- /* if it wasn't full screen before, then it's the
- * program's responsibility to change it after
- * getting the sigwinch
- * note that this trashes Dot, so we save it.
- */
- Dot.x = dotx ;
- Dot.y = doty ;
- }
-
- #ifdef notdef
- static
- trace(s, t)
- register char *s;
- register struct tcap *t;
- {
- register char *q = t->t_text;
-
- fprintf(stderr, "%s: ", s);
- fprintf(stderr, "[%s,", t->t_key);
- if (q == NULL)
- fprintf(stderr, "(nil)");
- else while (*q) {
- if (*q < ' ') {
- fprintf(stderr, "^%c", *q + '@');
- } else {
- fprintf(stderr, "%c", *q);
- }
- q++;
- }
- fprintf(stderr, ",%d,(%d,%d)]\n", t->t_index, t->t_x, t->t_y);
- }
- #endif
-
- #ifndef notdef
- #define trace(X, Y) (void)(X, Y)
- #endif
- #define ChangeScreen()
- #define MoveCursor()
-
- #ifdef notdef
- static
- PrintScreen()
- {
- register int y;
-
- for (y = 0; y < LinesPerScreen; y++) {
- register struct line *l = screen[y];
- register int x;
-
- if (l == NULL)
- fprintf(stderr, "(nil)");
- else for (x = 0; x < l->length; x++) {
- if (x == Dot.x && y == Dot.y)
- fprintf(stderr, "+");
- else if (x == l->changeposition)
- fprintf(stderr, "|");
- else
- fprintf(stderr, "%c", (l->body[x] == ' ' ? '.' : l->body[x]));
- }
- fprintf(stderr, "\n");
- }
- fprintf(stderr, "\n");
- }
- #endif
-
- showc(t)
- struct tcap *t;
- {
- register char *cp = t->t_text;
- register struct line *l;
- register int dotx, c;
- register unsigned Modes = PermanentModes | TemporaryModes;
- int n = t->t_size;
- register char *bp;
- register u_char *pp;
-
- trace("==", t);
- TemporaryModes = 0;
- dotx = Dot.x;
- while (n > 0 && !PageFull) {
- l = screen[Dot.y];
- if (l->changeposition > dotx)
- l->changeposition = dotx;
- if (l->length < dotx)
- l->length = dotx;
- bp = &l->body[dotx] ;
- pp = &l->prop[dotx] ;
- if (Modes & InsertMode && l->length > dotx) {
- n-- ;
- c = *cp++;
- if (c < ' ' || c >= 0177)
- continue;
- if (l->length < CharsPerLine)
- l->length++;
-
- bcopy((char *)pp, (char *)pp+1,(int)(l->length-dotx-1));
- bcopy( bp, bp+1,(int)(l->length-dotx-1));
-
- l->end_of_changes = CharsPerLine + 1 ;
- *bp = c;
- *pp = (Modes & Attributes);
- if (++dotx >= CharsPerLine) {
- if (Modes & AutoMarginMode) {
- trace("cr", t);
- l->end_of_changes = CharsPerLine + 1 ;
- l->flags |= LINE_WRAPPED ;
- if (l->length < dotx)
- l->length = dotx ;
- dotx = 0;
- MoveCursor();
- nl_op(t);
- TemporaryModes |= WrapJustHappenedMode;
- }
- else dotx = CharsPerLine - 1;
- }
- }
- else {
- while (n-- > 0 && !PageFull) {
- c = *cp++;
- if (c < ' ' || c >= 0177)
- continue;
- *bp++ = c;
- *pp++ = (Modes & Attributes);
- if (++dotx >= CharsPerLine) {
- if (Modes & AutoMarginMode) {
- trace("cr", t);
- l->end_of_changes =
- CharsPerLine + 1 ;
- l->flags |= LINE_WRAPPED ;
- if (l->length < dotx)
- l->length = dotx ;
- dotx = 0;
- MoveCursor();
- nl_op(t);
- TemporaryModes |=
- WrapJustHappenedMode;
- break;
- }
- else dotx = CharsPerLine - 1;
- }
- }
- }
- if (l->length < dotx)
- l->length = dotx ;
- if (l->end_of_changes < dotx)
- l->end_of_changes = dotx;
- }
- Dot.x = dotx;
- ChangeScreen();
- /*
- * If we were interrupted by nl_op setting PageFull, set up
- * interruptedOp with a tcap that can be used to finish this later.
- */
- if (PageFull && ++n > 0) {
- interruptedOp = *t;
- interruptedOp.t_text += (t->t_size - n);
- interruptedOp.t_size = n;
- }
- else interruptedOp.t_op = 0;
- }
-
- static int
- AL_op(t) /* add multiple blank lines */
- struct tcap *t;
- {
- trace("AL", t);
- /* cheat for now */
- while (t->t_y-- > 0)
- al_op(t);
- ChangeScreen();
- }
-
- static int
- DC_op(t)
- struct tcap *t;
- {
- trace("DC", t);
- /* cheat for now */
- while (t->t_y-- > 0)
- dc_op(t);
- ChangeScreen();
- }
-
- static int
- DL_op(t) /* delete multiple lines */
- struct tcap *t;
- {
- trace("DL", t);
- /* cheat for now */
- while (t->t_y-- > 0)
- dl_op(t);
- ChangeScreen();
- }
-
- static int
- DO_in(t) /* move cursor down n lines */
- struct tcap *t;
- {
- trace("DO", t);
- return (cm_in(t)); /* Neat! It might even work */
- }
-
- static int
- DO_op(t) /* move cursor down n lines */
- register struct tcap *t;
- {
- trace("DO", t);
- if (t->t_y >= 0 && (Dot.y + t->t_y) < LinesPerScreen)
- Dot.y += t->t_y;
- MoveCursor();
- }
-
- static int
- IC_op(t)
- struct tcap *t;
- {
- trace("IC", t);
- /* cheat for now */
- while (t->t_y-- > 0)
- ic_op(t);
- ChangeScreen();
- }
-
- static int
- LE_in(t) /* move cursor left n characters */
- struct tcap *t;
- {
- trace("LE", t);
- return (cm_in(t)); /* Neat! It might even work */
- }
-
- static int
- LE_op(t) /* move cursor left n characters */
- register struct tcap *t;
- {
- trace("LE", t);
- if ((Dot.x - t->t_y) >= 0)
- Dot.x -= t->t_y;
- MoveCursor();
- }
-
- static int
- RI_in(t) /* move cursor right n characters */
- struct tcap *t;
- {
- trace("RI", t);
- return (cm_in(t)); /* Neat! It might even work */
- }
-
- static int
- RI_op(t) /* move cursor right n characters */
- register struct tcap *t;
- {
- trace("RI", t);
- if (t->t_y >= 0 && (Dot.x + t->t_y) <= CharsPerLine)
- Dot.x += t->t_y;
- MoveCursor();
- }
-
- static int
- UP_in(t) /* move cursor up n lines */
- struct tcap *t;
- {
- trace("UP", t);
- return (cm_in(t)); /* Neat! It might even work */
- }
-
- static int
- UP_op(t) /* move cursor up n lines */
- register struct tcap *t;
- {
- trace("UP", t);
- if ((Dot.y - t->t_y) >= 0)
- Dot.y -= t->t_y;
- MoveCursor();
- }
-
- static int
- al_op(t) /* Add new blank line */
- struct tcap *t;
- {
- register struct line **p, **current;
- register struct line *old;
-
- trace("al", t);
- current = &screen[Dot.y];
- p = &screen[BottomLineOfScrollRegion];
- old = *p;
- for (; p > current; p--)
- *p = *(p-1);
- *p = old;
- clear_body(old, 0);
- old->length = 0;
- old->changeposition = 0;
- old->end_of_changes = CharsPerLine;
- old->usedtobe = LinesPerScreen;
- ChangeScreen();
- }
-
- static int
- am_in(t) /* Has auto-margins */
- struct tcap *t;
- {
- trace("am", t);
- if (t->t_x) PermanentModes |= AutoMarginMode;
- return (0);
- }
-
- static int
- bc_op(t) /* back-character */
- struct tcap *t;
- {
- trace("bc", t);
- if (Dot.x > 0)
- Dot.x--;
- MoveCursor();
- }
-
- static int
- bl_op(t) /* Bell character */
- struct tcap *t;
- {
- trace("bl", t);
- RingBell();
- }
-
- /*
- * Clearing the whole line body for the clear ops may be excessive
- * but nothing short of it seems to work for programs which do a lot
- * of cursor manipulation, such as rogue or hack.
- */
- static int
- clear_body(l, x)
- struct line *l;
- int x;
- {
- register int len = l->buffer_length - x;
- register char *cp;
-
- bzero((char *)&l->prop[x], len);
- l->flags = 0 ;
- for (cp = &l->body[x]; len-- > 0;)
- *cp++ = ' ';
- }
-
- static int
- cd_op(t) /* Clear to end of display */
- struct tcap *t;
- {
- register struct line **p, **last;
- register struct line *l;
-
- trace("cd", t);
- ce_op(t);
- last = &screen[LinesPerScreen];
- for (p = &screen[Dot.y+1]; p < last; p++) {
- (l = *p)->length = 0;
- l->changeposition = 0;
- l->end_of_changes = CharsPerLine ;
- clear_body(l, 0);
- }
- ChangeScreen();
- }
-
- static int
- ce_op(t) /* Clear to end of line */
- struct tcap *t;
- {
- register struct line *l = screen[Dot.y];
-
- trace("ce", t);
- l->length = Dot.x;
- if (l->changeposition > Dot.x)
- l->changeposition = Dot.x;
- l->end_of_changes = CharsPerLine ;
- clear_body(l, (int)l->length);
- ChangeScreen();
- }
-
- static int
- cl_op(t) /* Clear screen */
- struct tcap *t;
- {
- register struct line **p, **last;
- register struct line *l;
-
- trace("cl", t);
- Dot.x = Dot.y = 0;
- last = &screen[LinesPerScreen];
- for (p = &screen[0]; p < last; p++) {
- (l = *p)->length = 0;
- l->changeposition = 0;
- l->end_of_changes = CharsPerLine ;
- clear_body(l, 0);
- }
- ChangeScreen();
- if (PageMode)
- lastInputLine = screen[Dot.y]; /* no scroll stop line */
- }
-
- #ifdef HAVE_TERMCAP
- static int
- cm_in(t) /* Cursor motion */
- register struct tcap *t;
- {
- register u_char c;
- char buf[128];
- register char *cp = t->t_text, *bp = buf;
-
- trace("cm", t);
-
- if (cp == NULL)
- return(0);
- /* Pre-process out parts of the % escapes */
- while ((c = *cp++) != '\0') {
- if (c == '%') {
- register u_char c2 = *cp++;
-
- switch (c2) {
- case '+': /* Subtract next then %. */
- switch (t->t_2nd + t->t_pc_r) {
- case 0:
- case 2:
- t->t_yi = *cp++;
- break;
- case 1:
- t->t_xi = *cp++;
- break;
- }
- c2 = '.';
- goto percent_dot;
- case '>':
- switch (t->t_2nd + t->t_pc_r) {
- case 1:
- t->t_xilim = *cp++;
- t->t_xi = *cp++;
- t->t_xilim += t->t_xi + 1;
- break;
- case 0:
- case 2:
- t->t_yilim = *cp++;
- t->t_yi = *cp++;
- t->t_yilim += t->t_yi + 1;
- break;
- }
- t->t_2nd = !t->t_2nd;
- break;
- case 'r':
- t->t_pc_r = 1;
- break;
- case 'i':
- t->t_xi++;
- t->t_yi++;
- break;
- case 'n':
- t->t_pc_n = 1;
- break;
- case 'B':
- t->t_pc_B = 1;
- break;
- case 'D':
- t->t_pc_D = 1;
- break;
- /* The following ones will be interpreted on the fly */
- case 'd': /* series of decimal digits */
- case '2': /* two decimal digits */
- case '3': /* three decimal digits */
- case '.': /* binary character */
- percent_dot:
- case '%':
- *bp++ = c;
- *bp++ = c2;
- t->t_2nd = !t->t_2nd;
- break;
- default: /* Bad % escape */
- return (1);
- }
- }
- else {
- *bp++ = c;
- }
- }
- *bp++ = '\0';
- if (bp-buf > 1) {
- if ((t->t_text = malloc((unsigned)(bp-buf+1))) == NULL)
- return (2);
- strncpy(t->t_text, buf, bp-buf);
- t->t_size = bp-buf - 1;
- } else {
- t->t_text = NULL;
- }
- t->t_2nd = 0;
- return (0);
- }
-
- #else /* !HAVE_TERMCAP */
-
- static int
- cm_in(t) /* Cursor motion */
- register struct tcap *t;
- {
- register u_char c;
- char buf[128];
- register char *cp = t->t_text, *bp = buf;
-
- trace("cm", t);
-
- if (cp == NULL)
- return(0);
- /* Pre-process out parts of the % escapes */
- while ((c = *cp++) != '\0') {
- static int seen1 = 0;
-
- if (c == '%') {
- register u_char c2 = *cp++;
-
- switch (c2) {
- case 'p':
- switch (*cp++) {
- case '1':
- seen1++;
- t->t_2nd = 0;
- break;
- case '2':
- if (!seen1)
- t->t_pc_r = 1;
- t->t_2nd = 1;
- break;
- /*
- * This capability is not available in termcap so we will
- * assume that it is not present in terminfo either. This
- * means that terminal that send more than two pieces of
- * variable data with the "cm" directive will not work.
- * Currently for "cm" only two variables are defined.
- */
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return(1);
- }
- break;
-
- case '\'': /* store constant for future operator */
- switch (t->t_2nd + t->t_pc_r) {
- case 0:
- case 2:
- t->t_yi = *cp++;
- break;
- case 1:
- t->t_xi = *cp++;
- break;
- }
- if (*cp == '\'')
- cp++; /* blow past the trailing '\'' */
- else
- return(1);
- break;
- case '{': /* store decimal constant for future operator */
- switch (t->t_2nd + t->t_pc_r) {
- case 0:
- case 2:
- t->t_yi = ((*cp++) * 10) + (*cp++);
- break;
- case 1:
- t->t_xi = ((*cp++) * 10) + (*cp++);
- break;
- }
- if (*cp == '}')
- cp++; /* blow past trailing '}' */
- else
- return(1);
- break;
- /* the following will not work do to the simplifications here */
- case '?': /* if */
- case 't': /* then */
- case 'e': /* else */
- return(1); /* lets not delude ourselves, the data
- * structures were set up to deal with termcap
- * not the complexities of terminfo.
- */
- case 'i':
- t->t_xi++;
- t->t_yi++;
- break;
- case '+':
- if (*cp++ != '%')
- return(1);
- if (*cp++ != 'c')
- return(1);
- *bp++ = '%'; /* make it look like termcap */
- *bp++ = '.';
- break;
- /* use the simpified model of termcap so some of this
- * stuff is not valid
- */
- case '\b': /* flags in format string */
- case ':': /* needed for '-' and '+' flags */
- case '#': /* flags in format string */
- case '.': /* if only fract part of precision */
- return(1);
- /* just leave a 'd' */
- case '0': /* numeric part of precision */
- case '1': /* numeric part of precision */
- case '4': /* numeric part of precision */
- case '5': /* numeric part of precision */
- case '6': /* numeric part of precision */
- case '7': /* numeric part of precision */
- case '8': /* numeric part of precision */
- case '9': /* numeric part of precision */
- /* skip past the end of this definition, leave %d in its place*/
- while (*cp != 'd' && *cp != 'o' && *cp != 'x'
- && *cp != 'X' && *cp != 's')
- cp++;
- /* don't support anything but 'd' */
- if (*cp != 'd')
- return(1);
- *bp++ = c; /* '%' */
- *bp++ = *cp++; /* 'd' */
- /* The following ones will be interpreted on the fly. */
- case '2': /* numeric part of precision */
- case '3': /* numeric part of precision */
- /* remove %[23]->[doxXs], put %[23] in bp */
- *bp++ = c;
- *bp++ = c2;
- /* skip any factional part of the precision */
- while (*cp != 'd' && *cp != 'o' && *cp != 'x'
- && *cp != 'X' && *cp != 's')
- cp++;
- /* don't support anything but 'd' */
- if (*cp != 'd')
- return(1);
- *cp++; /* get rid of the 'd' */
- break;
- /* not suported by termcap, so not supported here */
- case 'o': /* octal: no other formating is present */
- case 'x': /* hex: no other formating is present */
- case 'X': /* HEX: no other formating is present */
- case 's': /* String: no other formating is present */
- case 'c': /* binary character */
- case 'l': /* strlen() operator */
- case '=': /* equal operator */
- case '>': /* greater than operator */
- case '<': /* less than operator */
- case '-': /* subtract operator */
- case '*': /* multiply operator */
- case '/': /* divide operator */
- case 'm': /* modula operator */
- case '&': /* bitwise and operator */
- case '|': /* bitwise or operator */
- case '^': /* bitwise xor operator */
- case '~': /* bitwise not operator */
- case 'A': /* logical and operator */
- case 'O': /* logical or operator */
- case '!': /* logical not operator */
- return(1);
- /* include the string "%A" where A = one of the following cases */
- case 'd': /* decimal: no other formating is present */
- case '%':
- *bp++ = c;
- *bp++ = c2;
- break;
- default: /* Bad % escape */
- return (1);
- }
- }
- else {
- *bp++ = c;
- }
- }
- *bp++ = '\0';
- if (bp-buf > 1) {
- if ((t->t_text = malloc(bp-buf+1)) == NULL)
- return (2);
- strncpy(t->t_text, buf, bp-buf);
- t->t_size = bp-buf - 1;
- } else {
- t->t_text = NULL;
- }
- t->t_2nd = 0;
- return (0);
- }
- #endif /* !HAVE_TERMCAP */
-
- static int
- cm_op(t) /* Cursor motion */
- register struct tcap *t;
- {
-
- trace("cm", t);
- lastInputLine = 0; /* no scroll stop line */
- if (t->t_x >= 0 && t->t_x < CharsPerLine)
- Dot.x = t->t_x;
- if (t->t_y >= 0 && t->t_y < LinesPerScreen)
- Dot.y = t->t_y;
- MoveCursor();
- }
-
- static int
- co_in(t) /* number of columns */
- struct tcap *t;
- {
- trace("co", t);
- if (userCharsPerLine < 1)
- CharsPerLine = t->t_x;
- return (0);
- }
-
- static int
- cr_op(t) /* carriage return */
- struct tcap *t;
- {
- trace("cr", t);
- Dot.x = 0;
- MoveCursor();
- }
-
- static int
- cs_in(t) /* change scroll region */
- struct tcap *t;
- {
- trace("cs", t);
- return (cm_in(t)); /* Neat! It might even work */
- }
-
- static int
- cs_op(t) /* change scroll region */
- register struct tcap *t;
- {
- trace("cs", t);
- if (t->t_y >= t->t_x || t->t_x >= LinesPerScreen)
- return;
- Dot.x = 0;
- Dot.y = t->t_y;
- TopLineOfScrollRegion = t->t_y;
- BottomLineOfScrollRegion = t->t_x;
- lastInputLine = 0; /* no scroll stop line */
- MoveCursor();
- }
-
- static int
- dc_op(t) /* delete character */
- struct tcap *t;
- {
- register struct line *l = screen[Dot.y];
- register int dotx = Dot.x;
- int len;
-
- trace("dc", t);
- if (l->changeposition > dotx)
- l->changeposition = dotx;
- if (dotx < l->length) {
- l->length--;
- len = l->length - dotx;
- bcopy((char *)&l->prop[dotx+1], (char *)&l->prop[dotx], len);
- l->prop[l->length] = 0 ;
- bcopy(&l->body[dotx+1], &l->body[dotx], len);
- l->body[l->length] = ' ' ;
- }
- l->end_of_changes = CharsPerLine ;
- ChangeScreen();
- }
-
- static int
- dl_op(t) /* delete line */
- struct tcap *t;
- {
- register struct line **p, **bottom;
- register struct line *old = screen[Dot.y];
-
- trace("dl", t);
- lastInputLine = 0; /* no scroll stop line */
- bottom = &screen[BottomLineOfScrollRegion];
- for (p = &screen[Dot.y]; p < bottom; p++)
- *p = *(p+1);
- *p = old;
- clear_body(old, 0);
- old->length = 0;
- old->changeposition = 0;
- old->end_of_changes = CharsPerLine ;
- old->usedtobe = LinesPerScreen ;
- ChangeScreen();
- }
-
- static int
- do_op(t) /* down one line */
- struct tcap *t;
- {
- trace("do", t);
- if (PermanentModes & IgnoreNewlineAfterWrapMode) {
- if (TemporaryModes & WrapJustHappenedMode) {
- TemporaryModes &= ~WrapJustHappenedMode;
- return;
- }
- }
- if (Dot.y < LinesPerScreen - 1)
- Dot.y++;
- else {
- sf_op(t);
- }
- MoveCursor();
- }
-
- static int
- ei_op(t) /* end insert mode */
- struct tcap *t;
- {
- trace("ei", t);
- PermanentModes &= ~InsertMode;
- }
-
- static int
- el_op(t) /* end frame label definition mode */
- struct tcap *t;
- {
- if (FrameLabel) {
- FrameLabel[FLindex] = '\0';
- SetFrameLabel(FrameLabel);
- }
- t = T+Ts;
- t->t_op = prevInput;
- }
-
- static int
- ke_op(t) /* leave keyboard transmit mode */
- struct tcap *t;
- {
- trace("ke", t);
- }
-
- static int
- ks_op(t) /* enter keyboard transmit mode */
- struct tcap *t;
- {
- trace("ks", t);
- }
-
- static int
- ho_op(t) /* home cursor */
- struct tcap *t;
- {
-
- trace("ho", t);
- lastInputLine = 0; /* no scroll stop line */
- Dot.x = Dot.y = 0;
- MoveCursor();
- }
-
- static int
- ic_op(t) /* insert character */
- struct tcap *t;
- {
- trace("ic", t);
- TemporaryModes |= InsertMode;
- }
-
- static int
- im_op(t) /* enter insert mode */
- struct tcap *t;
- {
- trace("im", t);
- PermanentModes |= InsertMode;
- }
-
- static int
- le_op(t) /* cursor left */
- struct tcap *t;
- {
- trace("le", t);
- if (Dot.x > 0)
- Dot.x--;
- MoveCursor();
- }
-
- static int
- li_in(t) /* number of lines */
- struct tcap *t;
- {
- trace("li", t);
- if (userLinesPerScreen < 1)
- LinesPerScreen = t->t_x;
- return (0);
- }
-
- static int
- ll_op(t) /* last line first column */
- struct tcap *t;
- {
- trace("ll", t);
- Dot.x = 0;
- Dot.y = LinesPerScreen - 1;
- MoveCursor();
- }
-
- static int
- lm_op(t) /* label mode input */
- register struct tcap *t;
- {
- trace("lm", t);
- if (FLindex + t->t_size >= CharsPerLine)
- t->t_size = CharsPerLine - FLindex;
- if (t->t_size > 0) {
- if (FrameLabel)
- strncpy(&FrameLabel[FLindex], t->t_text, (int)t->t_size);
- FLindex += t->t_size;
- }
- }
-
- static int
- mb_op(t) /* enable blink */
- struct tcap *t;
- {
- trace("mb", t);
- PermanentModes |= BlinkMode;
- }
-
- static int
- md_op(t) /* enter bold mode */
- struct tcap *t;
- {
- trace("md", t);
- PermanentModes |= BoldMode;
- }
-
- static int
- me_op(t) /* turn off attributes */
- struct tcap *t;
- {
- trace("me", t);
- PermanentModes &= ~(Attributes);
- }
-
- static int
- mr_op(t) /* enter reverse video */
- struct tcap *t;
- {
- trace("mr", t);
- PermanentModes |= ReverseVideoMode;
- }
-
- static int
- nd_op(t) /* cursor right */
- struct tcap *t;
- {
- trace("nd", t);
- if (Dot.x < (CharsPerLine - 1))
- Dot.x++;
- MoveCursor();
- }
-
- static int
- nl_op(t) /* newline */
- struct tcap *t;
- {
- trace("nl", t);
- if (PermanentModes & IgnoreNewlineAfterWrapMode) {
- if (TemporaryModes & WrapJustHappenedMode) {
- TemporaryModes &= ~WrapJustHappenedMode;
- return;
- }
- }
- if (Dot.y < LinesPerScreen - 1)
- Dot.y++;
- else {
- sf_op(t);
- }
- MoveCursor();
- }
-
- static int
- rc_op(t) /* restore cursor */
- struct tcap *t;
- {
- trace("rc", t);
- Dot = SavedCursor;
- MoveCursor();
- }
-
- static int
- sc_op(t) /* save cursor */
- struct tcap *t;
- {
- trace("sc", t);
- SavedCursor = Dot;
- MoveCursor();
- }
-
- static int
- se_op(t) /* leave stand-out */
- struct tcap *t;
- {
- trace("se", t);
- PermanentModes &= ~StandOutMode;
- }
-
- static int
- so_op(t) /* enter stand-out */
- struct tcap *t;
- {
- trace("so", t);
- PermanentModes |= StandOutMode;
- }
-
- static int
- sf_op(t) /* scroll forwards */
- struct tcap *t;
- {
- register struct line **p, **bottom;
- register struct line *old;
- static int SFrecur = 0;
-
- trace("sf", t);
- /*
- * When sf is "\n", nl_op won't be called, so we emulate
- * it's actions here (beware of recursion).
- */
- if (ScrollNLKludge && !SFrecur) {
- SFrecur++; nl_op(t); SFrecur--;
- return (1); /* XXX */
- }
- p = &screen[TopLineOfScrollRegion];
- if (PageMode && *p == lastInputLine) {
- PageFull++; /* can't scroll this line */
- return (0);
- }
- ScrollSaveLine(*p);
- bottom = &screen[BottomLineOfScrollRegion];
- p = &screen[TopLineOfScrollRegion];
- old = *p;
- for (; p < bottom; p++)
- *p = *(p+1);
- *p = old;
- clear_body(old, 0);
- old->length = 0;
- old->changeposition = 0;
- old->end_of_changes = CharsPerLine ;
- old->usedtobe = LinesPerScreen;
- ChangeScreen();
- return (1);
- }
-
- static int
- sl_op(t) /* start defining new frame label */
- register struct tcap *t;
- {
- trace("sl", t);
- FLindex = 0;
- t = T+Ts;
- prevInput = t->t_op;
- t->t_op = lm_op;
- }
-
- static int
- sr_op(t) /* scroll reverse */
- struct tcap *t;
- {
- register struct line **p, **top;
- register struct line *old;
-
- trace("sr", t);
- lastInputLine = 0; /* no scroll stop line */
- top = &screen[TopLineOfScrollRegion];
- p = &screen[BottomLineOfScrollRegion];
- old = *p;
- for (; p > top; p--)
- *p = *(p-1);
- *p = old;
- clear_body(old, 0);
- old->length = 0;
- old->changeposition = 0;
- old->end_of_changes = CharsPerLine ;
- old->usedtobe = LinesPerScreen;
- ChangeScreen();
- }
-
- static int
- ta_op(t) /* tab */
- struct tcap *t;
- {
- trace("ta", t);
- Dot.x = (Dot.x & ~07) + 010;
- if (Dot.x >= CharsPerLine - 1)
- Dot.x = CharsPerLine - 1;
- MoveCursor();
- }
-
- static int
- te_op(t) /* end use of termcap */
- struct tcap *t;
- {
- trace("te", t);
- if (PrevPageMode != -1) {
- PageMode = PrevPageMode;
- PrevPageMode = -1;
- }
- }
-
- static int
- ti_op(t) /* begin use of termcap */
- {
- trace("ti", t);
- /*
- * Turn off page mode when using termcap.
- */
- if (PrevPageMode == -1) {
- PrevPageMode = PageMode;
- PageMode = 0;
- }
- }
-
- static int
- ue_op(t) /* end underline */
- struct tcap *t;
- {
- trace("ue", t);
- PermanentModes &= ~UnderlineMode;
- }
-
- static int
- up_op(t) /* cursor up */
- struct tcap *t;
- {
- trace("up", t);
- if (Dot.y > 0)
- Dot.y--;
- else /* vi will never do this, but some ll caps may */
- Dot.y = LinesPerScreen - 1;
- MoveCursor();
- }
-
- static int
- us_op(t) /* start underline */
- struct tcap *t;
- {
- trace("us", t);
- PermanentModes |= UnderlineMode;
- }
-
- static int
- vb_op(t) /* visibile bell */
- struct tcap *t;
- {
- trace("bl", t);
- VisibleBell();
- }
-
- static int
- xn_in(t)
- struct tcap *t;
- {
- trace("xn", t);
- if (t->t_x) PermanentModes |= IgnoreNewlineAfterWrapMode;
- return (0);
- }
-
- /* These capabilities are numeric or boolean - they dont have ops */
- #define am_op NULL
- #define bs_op NULL
- #define co_op NULL
- #define li_op NULL
- #define pc_op NULL
- #define xn_op NULL
-
- /* These capabilities are strings that dont need initialization */
- #define al_in NULL
- #define bc_in NULL
- #define bl_in NULL
- #define cd_in NULL
- #define ce_in NULL
- #define cl_in NULL
- #define cr_in NULL
- #define dc_in NULL
- #define dl_in NULL
- #define do_in NULL
- #define ei_in NULL
- #define ke_in NULL
- #define ks_in NULL
- #define ho_in NULL
- #define ic_in NULL
- #define im_in NULL
- #define le_in NULL
- #define ll_in NULL
- #define mb_in NULL
- #define md_in NULL
- #define me_in NULL
- #define mr_in NULL
- #define nd_in NULL
- #define nl_in NULL
- #define pc_in NULL
- #define rc_in NULL
- #define sc_in NULL
- #define se_in NULL
- #define sf_in NULL
- #define so_in NULL
- #define sr_in NULL
- #define ta_in NULL
- #define ue_in NULL
- #define up_in NULL
- #define us_in NULL
-
- #define s string
- #define n num
- #define b bool
-
- struct tcap T[] = {
- /*
- * key ty op in text deftx sz in tmp tf
- * x xi xl y yi yl r n B D 2
- */
- {"AL", s, AL_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
- {"DL", s, DL_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
- {"DC", s, DC_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
- {"DO", s, DO_op, DO_in, NULL, NULL, 0, 0, NULL, 0},
- {"IC", s, IC_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
- {"LE", s, LE_op, LE_in, NULL, NULL, 0, 0, NULL, 0},
- {"RI", s, RI_op, RI_in, NULL, NULL, 0, 0, NULL, 0},
- {"UP", s, UP_op, UP_in, NULL, NULL, 0, 0, NULL, 0},
- {"al", s, al_op, al_in, NULL, NULL, 0, 0, NULL, 0},
- {"am", b, am_op, am_in, NULL, NULL, 0, 0, NULL, 0},
- {"bc", s, bc_op, bc_in, NULL, "\10", 0, 0, NULL, 0},
- {"bl", s, bl_op, bl_in, NULL, "\7", 0, 0, NULL, 0},
- {"cd", s, cd_op, cd_in, NULL, NULL, 0, 0, NULL, 0},
- {"ce", s, ce_op, ce_in, NULL, NULL, 0, 0, NULL, 0},
- {"cl", s, cl_op, cl_in, NULL, NULL, 0, 0, NULL, 0},
- {"cm", s, cm_op, cm_in, NULL, NULL, 0, 0, NULL, 0},
- {"co", n, co_op, co_in, NULL, NULL, 0, 0, NULL, 0},
- {"cr", s, cr_op, cr_in, NULL, "\015", 0, 0, NULL, 0},
- {"cs", s, cs_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
- {"dc", s, dc_op, dc_in, NULL, NULL, 0, 0, NULL, 0},
- {"dl", s, dl_op, dl_in, NULL, NULL, 0, 0, NULL, 0},
- {"do", s, do_op, do_in, NULL, NULL, 0, 0, NULL, 0},
- {"ei", s, ei_op, ei_in, NULL, NULL, 0, 0, NULL, 0},
- {"el", s, el_op, NULL, NULL,"\033\\",0, 0, NULL, 0}, /* end label */
- {"ke", s, ke_op, ke_in, NULL, NULL, 0, 0, NULL, 0},
- {"ks", s, ks_op, ks_in, NULL, NULL, 0, 0, NULL, 0},
- {"ho", s, ho_op, ho_in, NULL, NULL, 0, 0, NULL, 0},
- {"ic", s, ic_op, ic_in, NULL, NULL, 0, 0, NULL, 0},
- {"im", s, im_op, im_in, NULL, NULL, 0, 0, NULL, 0},
- {"le", s, le_op, le_in, NULL, NULL, 0, 0, NULL, 0},
- {"li", n, li_op, li_in, NULL, NULL, 0, 0, NULL, 0},
- {"ll", s, ll_op, ll_in, NULL, NULL, 0, 0, NULL, 0},
- {"lm", s, lm_op, NULL, NULL, NULL, 0, 0, NULL, 0}, /* label mode input */
- {"mb", s, mb_op, mb_in, NULL, NULL, 0, 0, NULL, 0},
- {"md", s, md_op, md_in, NULL, NULL, 0, 0, NULL, 0},
- {"me", s, me_op, me_in, NULL, NULL, 0, 0, NULL, 0},
- {"mr", s, mr_op, mr_in, NULL, NULL, 0, 0, NULL, 0},
- {"nd", s, nd_op, nd_in, NULL, NULL, 0, 0, NULL, 0},
- {"nl", s, nl_op, nl_in, NULL, "\012", 0, 0, NULL, 0},
- {"pc", s, pc_op, pc_in, NULL, "\200", 0, 0, NULL, 0},
- {"rc", s, rc_op, rc_in, NULL, NULL, 0, 0, NULL, 0},
- {"sc", s, sc_op, sc_in, NULL, NULL, 0, 0, NULL, 0},
- {"se", s, se_op, se_in, NULL, NULL, 0, 0, NULL, 0},
- {"sf", s, sf_op, sf_in, NULL, NULL, 0, 0, NULL, 0},
- {"sl", s, sl_op, NULL, NULL,"\033]l",0, 0, NULL, 0}, /* start label */
- {"so", s, so_op, so_in, NULL, NULL, 0, 0, NULL, 0},
- {"sr", s, sr_op, sr_in, NULL, NULL, 0, 0, NULL, 0},
- {"ta", s, ta_op, ta_in, NULL, "\011", 0, 0, NULL, 0}, /* XXX */
- {"te", s, te_op, NULL, NULL, NULL, 0, 0, NULL, 0},
- {"ti", s, ti_op, NULL, NULL, NULL, 0, 0, NULL, 0},
- {"ue", s, ue_op, ue_in, NULL, NULL, 0, 0, NULL, 0},
- {"up", s, up_op, up_in, NULL, NULL, 0, 0, NULL, 0},
- {"us", s, us_op, us_in, NULL, NULL, 0, 0, NULL, 0},
- {"vb", s, vb_op, NULL, NULL, NULL, 0, 0, NULL, 0},
- {"xn", b, xn_op, xn_in, NULL, NULL, 0, 0, NULL, 0},
- {"", s, showc, NULL, NULL, NULL, 0, 0, NULL, 0},
- };
-
- /* T[Ts] is a special case - its the display-character operation */
- int Ts = (sizeof T)/(sizeof T[0]) - 1;
- @@@ Fin de tcap_ops.c
- echo tcap_parse.c
- cat >tcap_parse.c <<'@@@ Fin de tcap_parse.c'
- /*
- * This file is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.
- * Users may copy, modify or distribute this file at will.
- *
- * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * This file is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even
- * if Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- *
- * Modifications to the original Sun Microsystems, Inc. source code
- * made by the Grasshopper Group are in the Public Domain.
- *
- * Extensions to this file by Eric Messick of the Grasshopper Group.
- *
- * Grasshopper Group
- * 212 Clayton St
- * San Francisco, CA 94117
- *
- */
-
- #ifndef lint
- static char sccsid[] =
- "@(#)tcap_parse.c 9.5 88/01/19 Copyright 1985 Sun Micro";
- static char RCSid[] =
- "@(#)$Header: tcap_parse.c,v 2.3 88/10/04 06:00:03 gnu Release $";
- #endif
-
-
- /*
- * Copyright (c) 1985 by Sun Microsystems, Inc.
- */
-
- /*-
- tcap_parse.c: Parse termcap output based on termcap entry.
-
- tcap_parse.c, Mon Mar 24 11:25:44 1986
-
- David Rosenthal,
- Sun Microsystems
- */
- /* XXX - remember longest outstanding partial match? */
- /* XXX - overlapping partial matches? */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #ifdef REF
- #include <ref/config.h>
- #endif
- #include "termcap.h"
-
- extern char *malloc();
- #ifndef bcopy
- extern void bcopy();
- #endif
-
- static int TerminalIsBraindamaged = 0;
- /* Import these from tcap_ops.c */
- extern struct tcap T[];
- extern int Ts;
- extern struct tcap *CheckCR;
- extern struct tcap *CheckNL;
- extern struct tcap *CheckTAB;
- extern struct tcap *CheckBS;
- extern int PageFull;
- extern int PageMode;
-
- static char *unpad();
- static int tc_init_stacks();
-
- /*
- * Initialize the display system from the TERMCAP entry.
- * We parse the entry and build the tcap structures
- * describing the operations supported by this type of
- * terminal. These descriptions are then used by tc_display()
- * in interpreting the data stream generated by the
- * application
- */
- int
- tc_initialize(term)
- char *term;
- {
- #ifdef SUNTGETENT
- static void tc_fix_tcap_ent();
- #endif
- static char tcapbuf[1024], tcaparea[1024];
- char *areap = tcaparea;
- extern int tgetent(), tgetnum(), tgetflag();
- extern char *tgetstr();
- register struct tcap *tp;
-
- if (tgetent(tcapbuf, term) != 1) { /* unknown terminal type? */
- fprintf(stderr, "tgetent failed\n");
- return (1);
- }
- #ifdef SUNTGETENT
- tc_fix_tcap_ent(tcapbuf);
- #endif
- set_environment_var("TERMCAP", tcapbuf);
- for (tp = T; tp < T+Ts; tp++) {
- switch (tp->t_type) {
- case string:
- tp->t_text = unpad(tgetstr(tp->t_key, &areap));
- if (tp->t_text == NULL)
- tp->t_text = tp->t_deftext;
- if (tp->t_text) {
- tp->t_size = strlen(tp->t_text);
- if (isprint(tp->t_text[0]))
- TerminalIsBraindamaged = 1;
- } else
- tp->t_size = 0;
- break;
- case num:
- tp->t_x = tgetnum(tp->t_key);
- break;
- case bool:
- tp->t_x = tgetflag(tp->t_key);
- break;
- }
- /* invoke any initialize routine */
- if (tp->t_in && (*tp->t_in)(tp)) {
- fprintf(stderr, "termcap init failed for %s\n", tp->t_key);
- return (1);
- }
- }
- tc_init_ops();
- return tc_init_stacks();
- }
-
- #ifdef HAVE_TERMCAP
- static char *
- unpad(s)
- register char *s;
- {
-
- if (s) {
- register pad = 0;
-
- while (isdigit(*s))
- pad++, s++;
- if (pad && *s == '*')
- s++;
- }
- return (s);
- }
-
- #else /* !HAVE_TERMCAP, ie next code is for TERMINFO */
-
- /*
- * Remove the substring of the form "$<x^>" where x = number, and ^ = characters
- * in the set [* /]. This is the terminfo way of specifying delays or padding.
- */
- static char *
- unpad(s)
- register char *s;
- {
-
- if (s) {
- register char *spt = s;
- register char *spt1, *spt2;
- char *strchr();
-
- while (spt1 = strchr(spt, '$')) {
- if (*(spt1 + 1) == '<') { /* found the '$<' pair */
- if (spt2 = strchr(spt1, '>')) {
- strcpy(spt1, ++spt2); /* found end '>' */
- spt = spt1; /* copy tail of */
- continue; /* string over */
- /* '$<..', look */
- /* for more */
- } else
- break; /* no match for '$<' so quit */
- } else {
- spt = spt1 + 1; /* found '$' but no '<', */
- continue; /* look for more */
- }
-
- }
- }
- return (s);
- }
- #endif /* !HAVE_TERMCAP */
-
-
- #ifdef SUNTGETENT
- #define TCAPBUFSIZE 1024
- #define SPECIALSIZE 2
-
- static struct {
- char *last;
- char str[3];
- } tcapSpecials[SPECIALSIZE] = {
- NULL, "co",
- NULL, "li"
- };
-
- /*
- * Stomp on the first "co" and "li" entries in the termcap entry
- * to avoid braindamage in the Sun version of the termcap library.
- * Apparently the Sun version of tgetent() looks at the terminal
- * state and uses this to prepend extra line+column spec's that
- * reflect the terminal's current state. This is not what we want,
- * so our only recourse is to undo the this braindamage here.
- */
- static void
- tc_fix_tcap_ent(buf)
- char *buf;
- {
- char *bp = buf;
- #ifndef SYSVREF
- char *index();
- #else
- #define index(s, c) (char *)strchr(s, c)
- #endif
- int i;
-
- /* for each item in buf ... */
- for (bp = index(bp, ':'); bp && *(bp+1); bp = index(bp, ':')) {
- ++bp;
- /* for each special tcap code ... */
- for (i = 0; i < SPECIALSIZE; i++) {
- if (strncmp(tcapSpecials[i].str, bp, 2) == 0) {
- if (tcapSpecials[i].last)
- strncpy(tcapSpecials[i].last, "xx", 2);
- tcapSpecials[i].last = bp;
- break;
- }
- }
- }
- }
- #endif /* SUNTGETENT */
-
- /*
- * Matching is performed with a push-down automata implemented
- * with dual stacks. An initial stack is loaded with all the
- * potential matches from the termcap structure. Matching then
- * takes place by popping each potential match off the ``current
- * stack'' and, if a successful match for the current character
- * occurs, pushing the match on the ``other stack''. When the
- * ``current stack'' is empty (all elements have been examined),
- * the stacks are swapped and the process restarted. This continues
- * until a completed match or the stack of potential matches has
- * been exhausted.
- */
- static struct tcap **curstack, **cursp; /* ``potential match'' stack */
- static struct tcap **otherstack, **othersp; /* ``match this pass'' stack */
- static struct tcap **resetstack; /* prototype curstack */
- static int stacksize; /* # of potential matches */
- static int MatchInProgress; /* for fast check */
-
- #define PushMatch(tp) (*--othersp = tp)
- #define PopMatch() (*cursp++)
- #define PopMatched() (*othersp++)
- #define SwapStacks() { \
- struct tcap **t; \
- t = curstack, curstack = otherstack, otherstack = t; \
- cursp = othersp, othersp = otherstack + stacksize; \
- MatchInProgress = 1; \
- }
- #define ResetMatchStack() { \
- bcopy((char *)resetstack, (char *)curstack, \
- stacksize*sizeof (struct tcap *)); \
- cursp = curstack; \
- MatchInProgress = 0; \
- }
- #define FlushStack(sp, stack) { \
- while (sp < stack+stacksize) { \
- tp = *sp++; \
- tp->t_index = 0; \
- tp->t_param = 0 ; \
- tp->t_matched = 0; \
- tp->t_2nd = 0; \
- } \
- }
- #define FlushMatchStack() FlushStack(cursp, curstack)
- #define FlushMatchedStack() FlushStack(othersp, otherstack);
- #define MatchStackEmpty() (cursp >= curstack+stacksize)
- #define MatchedStackEmpty() (othersp >= otherstack+stacksize)
-
- /*
- * Reset the pattern matching stack and load
- * it with all the potential matching entries.
- */
- static int
- tc_init_stacks()
- {
- register struct tcap *tp;
-
- for (tp = T; tp < T+Ts; tp++)
- if (tp->t_text != NULL)
- stacksize++;
- curstack = (struct tcap **)malloc((unsigned)
- (3*sizeof(struct tcap *) * stacksize));
- if (!curstack)
- return 1;
- otherstack = curstack+stacksize;
- resetstack = otherstack+stacksize;
- othersp = resetstack+stacksize;
- for (tp = T; tp < T+Ts; tp++)
- if (tp->t_text != NULL)
- PushMatch(tp);
- othersp = otherstack+stacksize;
- ResetMatchStack();
- return 0;
- }
-
- extern struct tcap interruptedOp;
-
- /*
- * Interpret data from the application. We match data against
- * the ``escape sequences'' expected for this termcap description
- * and, if successful, invoke the routines used to emulate the
- * capabilities on the window.
- */
- tc_display(cp, n)
- u_char *cp;
- register int n;
- {
- register int c, j;
- register struct tcap *tp;
- static char dbuf[256], *dp = dbuf;
- int restart, lim;
-
- /*
- * If we're blocked with a page full, indicate
- * nothing was sent to the screen. We should
- * never be called when already blocked, but
- * just in case, turn scrolling on again so we
- * don't lost any data.
- */
- if (PageFull) {
- if (interruptedOp.t_key == 0)
- return (n);
- scrollreset(0); /* XXX */
- }
- /*
- * If we have previous output, process it first.
- * Check on completion to see if we filled the screen.
- */
- if (interruptedOp.t_key) {
- (*interruptedOp.t_op)(&interruptedOp);
- if (PageFull)
- return (n);
- interruptedOp.t_key = 0;
- }
- /*
- * For each input character, look for potential
- * matches in the tcap structure. For each possible
- * match, construct the resultant output buffer.
- * On first match process the operation (e.g. invoke
- * internal routine) and flush extraneous matches.
- * If input doesn't match any capability, send it to
- * the window.
- */
- while (n > 0 && !PageFull) {
- /*
- * If we're not in the middle of a match, then
- * try and bypass the pattern matcher by performing
- * special checks on the most common input.
- */
- if (!MatchInProgress) {
- while (n > 0 && !PageFull) {
- /*
- * If terminal has only non-printing escape sequences,
- * then process printable characters w/o matching against
- * the termcap strings.
- */
- if (!TerminalIsBraindamaged) {
- for (dp = (char *)cp; n > 0 && isprint((int)*cp); n--)
- cp++;
- if ((char *)cp > dp) {
- tp = T+Ts;
- tp->t_text = dp; /* use original storage */
- tp->t_size = (char *)cp - dp;
- (*tp->t_op)(tp);
- if (PageFull)
- return (n);
- continue;
- }
- }
- /*
- * Make quick checks for standard NL, CR, BS, and TAB
- * characters. This speeds up scrolling for most
- * terminal types.
- */
- c = *cp;
- if (CheckNL && c == '\n')
- tp = CheckNL;
- else if (CheckCR && c == '\r')
- tp = CheckCR;
- else if (CheckTAB && c == '\t')
- tp = CheckTAB;
- else if (CheckBS && c == '\b')
- tp = CheckBS;
- else
- break;
- cp++, n--;
- (*tp->t_op)(tp);
- if (PageFull)
- return (n);
- }
- dp = dbuf;
- if (n == 0)
- break;
- }
- c = *dp++ = *cp++, n--;
- while (!MatchStackEmpty()) {
- tp = PopMatch();
- again:
- j = tp->t_index;
- restart = 0;
- /*
- * Check match against numeric %[d23] specification.
- */
- if (tp->t_text[j] == '%') {
- switch (tp->t_text[j+1]) {
- case 'd': /* series of decimal digits */
- lim = 127;
- goto digit;
- case '2': /* two decimal digits */
- lim = 2;
- goto digit;
- case '3': /* three decimal digits */
- lim = 3;
- /* fall thru.. */
- digit:
- if (isdigit(c) && tp->t_matched < lim) {
- tp->t_matched++;
- tp->t_param = tp->t_param*10 + (c-'0');
- goto plainmatch;
- } else {
- if (tp->t_matched == 0)
- tp->t_param = 1 ;
- tp->t_matched = 0;
- restart = !isdigit(c);
- goto gotvalue;
- }
- /*NOTREACHED*/
- break;
- case '.': /* binary character */
- tp->t_param = c;
- gotvalue:
- switch (tp->t_2nd + tp->t_pc_r) {
- case 0:
- case 2:
- if ((tp->t_y = tp->t_param) >= tp->t_yilim)
- tp->t_y -= tp->t_yi;
- break;
- case 1:
- if ((tp->t_x = tp->t_param) >= tp->t_xilim)
- tp->t_x -= tp->t_xi;
- break;
- }
- tp->t_2nd = !tp->t_2nd;
- tp->t_index += 2;
- tp->t_param = 0 ;
- goto plainmatch;
- case '%':
- if ((c & 0177) == '%') {
- tp->t_index += 2;
- goto plainmatch;
- } else
- goto nomatch;
- default:
- abort(); /* XXX */
- /* NOTREACHED */
- }
- } else if ((c & 0177) == (tp->t_text[j] & 0177)) {
- tp->t_index++;
- plainmatch: /* plain match */
- if (tp->t_index >= tp->t_size) {/* match completed */
- if (tp->t_op)
- (*tp->t_op)(tp);
- dp = dbuf;
- tp->t_index = 0;
- tp->t_matched = 0;
- tp->t_param = 0 ;
- tp->t_2nd = 0;
- goto done;
- }
- /*
- * The end of a %d match is the only case where a
- * character must be pushed-back and re-parsed.
- */
- if (restart)
- goto again;
- PushMatch(tp); /* push partial match */
- } else {
- nomatch: /* failed match */
- tp->t_index = 0;
- tp->t_param = 0 ;
- tp->t_matched = 0;
- tp->t_2nd = 0;
- }
- }
- if (!MatchedStackEmpty()) {
- SwapStacks();
- continue;
- }
- done:
- /*
- * Come here either because no partial matches were
- * found in the table, or because a match completed.
- * In the first case we send the input data off
- * immediately. In the second case we reset the
- * state machines and go on to the next character.
- */
- if (dp - dbuf) { /* flush output */
- tp = T+Ts;
- tp->t_text = dbuf;
- tp->t_size = dp - dbuf;
- (*tp->t_op)(tp);
- dp = dbuf;
- }
- FlushMatchedStack(); /* reset partial matches */
- FlushMatchStack(); /* reset unchecked partials */
- ResetMatchStack(); /* re-init match stack */
- }
- return (n); /* return number of chars processed */
- }
- @@@ Fin de tcap_parse.c
- echo termcap.h
- cat >termcap.h <<'@@@ Fin de termcap.h'
- /*
- * This file is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.
- * Users may copy, modify or distribute this file at will.
- *
- * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * This file is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even
- * if Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- *
- * Modifications to the original Sun Microsystems, Inc. source code
- * made by the Grasshopper Group are in the Public Domain.
- *
- * Extensions to this file by Eric Messick of the Grasshopper Group.
- *
- * Grasshopper Group
- * 212 Clayton St
- * San Francisco, CA 94117
- *
- */
- /*
- * "@(#)termcap.h 9.4 88/01/19 SMI
- * "@(#)$Header: termcap.h,v 2.0 88/09/16 00:19:39 eric Release $
- *
- * Copyright (c) 1985 by Sun Microsystems, Inc.
- */
-
-
-
- enum tct { string, num, bool};
-
- struct tcap {
- char * t_key; /* Capability name */
- enum tct t_type; /* Capability type */
- int (*t_op)(/* struct tcap * */);
- int (*t_in)(/* struct tcap * */);
- char * t_text; /* Capability text */
- char * t_deftext; /* Default text */
- u_short t_size; /* Length of t_text */
- u_short t_index; /* Posn. in t_text */
- int t_param; /* parameter value for %match */
- u_short t_matched; /* Length of matched string */
- u_short t_x; /* Coordinate for cm= etc. */
- u_short t_xi; /* Offset to subtract from t_x */
- u_short t_xilim; /* If t_x >= t_xilim subtract t_xi */
- u_short t_y;
- u_short t_yi;
- u_short t_yilim;
- unsigned t_pc_r : 1; /* %r present */
- unsigned t_pc_n : 1; /* %n present */
- unsigned t_pc_B : 1; /* %B present */
- unsigned t_pc_D : 1; /* %D present */
- unsigned t_2nd : 1; /* On second coord */
- };
- @@@ Fin de termcap.h
- exit 0
-
-