home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-06-21 | 49.4 KB | 2,275 lines |
- Newsgroups: comp.sources.misc
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Subject: v07i051: CRISP release 1.9 part 30/32
- Organization: Reuters Ltd PLC, Marlow, England
- Reply-To: fox@marlow.UUCP (Paul Fox)
-
- Posting-number: Volume 7, Issue 51
- Submitted-by: fox@marlow.UUCP (Paul Fox)
- Archive-name: crisp1.9/part31
-
-
-
- #!/bin/sh
- # this is part 10 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file ./tty.c continued
- #
- CurArch=10
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file ./tty.c"
- sed 's/^X//' << 'SHAR_EOF' >> ./tty.c
- X char *bg[16];
- X } COLORS;
- XCOLORS colors = {
- X {"\033[0;30m", "\033[0;34m", "\033[0;32m", "\033[0;36m", /* Foreground. */
- X "\033[0;31m", "\033[0;35m", "\033[0;33m", "\033[0;37m",
- X "\033[30;1m", "\033[34;1m", "\033[32;1m", "\033[36;1m",
- X "\033[31;1m", "\033[35;1m", "\033[33;1m", "\033[37;1m"},
- X {"\033[40m", "\033[44m", "\033[42m", "\033[46m", /* Background. */
- X "\033[41m", "\033[45m", "\033[43m", "\033[47m",
- X "\033[40;1m", "\033[44;1m", "\033[42;1m", "\033[46;1m",
- X "\033[41;1m", "\033[45;1m", "\033[43;1m", "\033[47;1m"},
- X };
- X
- Xint LI; /* standard # lines */
- Xint AM; /* Has auto-margins. */
- Xchar
- X *AL, /* add line */
- X *BC, /* Backspace character. */
- X *CD, /* Clear to end of display. */
- X *CE, /* Clear to end of line. */
- X *CL, /* Clear screen */
- X *CM, /* Cursor motion */
- X *CS, /* set scroll region */
- X *DC, /* Delete a character. */
- X *DL, /* del line */
- X *EI, /* end insert mode */
- X *HO, /* Home cursor. */
- X *IC, /* insert a single space */
- X *IM, /* insert mode */
- X *IS, /* Init sequence. */
- X *MB, /* Turn on blinking. */
- X *MD, /* Make bold */
- X *ME, /* Turn off all attributes. */
- X *RS, /* Reset sequence. */
- X *SE, /* End standout mode. */
- X *SO, /* Start standout mode. */
- X *SR, /* back index (used with scroll region */
- X *TE, /* term end --- end using cursor motion */
- X *TI, /* term init -- start using cursor motion */
- X *UP, /* Cursor up. */
- X *pAL, /* parameterized add line */
- X *pDL; /* parameterized delete line */
- X
- Xchar *K[NFKEYS]; /* other function key codes */
- Xchar *KS, *KE; /* enter keypad mode, exit keypad mode */
- Xint SG; /* number of glitches, 0 for invisable, -1 for none */
- Xchar *termcap_strings =
- X"AL DL al bc cd ce cl cm cs dc dl ei ho ic im is ks ke mb me mr rs se so sr te ti up ";
- Xchar **termcap_ptrs[] = {
- X &pAL, &pDL,
- X &AL, &BC, &CD, &CE, &CL, &CM, &CS, &DC, &DL, &EI, &HO, &IC,
- X &IM, &IS, &KS, &KE, &MB, &MD, &ME, &RS, &SE, &SO, &SR, &TE, &TI, &UP
- X };
- X
- X/*
- X * Initialize the terminal when the editor
- X * gets started up.
- X */
- Xstatic char tcbuf[TCAPSLEN];
- X
- Xvoid
- Xttinit()
- X{
- X char *ggetenv();
- X char *p, *tgetstr();
- X char *tv_stype;
- X char *tptr;
- X char ***cptr;
- X char *cp;
- X
- X if ((tv_stype = ggetenv("TERM")) == NULL)
- X panic("Environment variable TERM not defined!");
- X
- X if((tgetent(tcbuf, tv_stype)) != 1) {
- X extern char *termcap_dir;
- X fprintf(stderr,
- X "Terminal type '%s' not found in %s.\n",
- X tv_stype, termcap_dir);
- X exit(1);
- X }
- X
- X p = tcapbuf;
- X
- X LI = tgetnum("li");
- X AM = tgetflag("am");
- X SG = tgetnum("sg");
- X
- X cptr = termcap_ptrs;
- X for (tptr = termcap_strings; *tptr; tptr += 3) {
- X char *cp;
- X char tmpbuf[3];
- X tmpbuf[0] = tptr[0];
- X tmpbuf[1] = tptr[1];
- X tmpbuf[2] = 0;
- X if ((cp = tgetstr(tmpbuf, &p)) && *cp)
- X **cptr = cp;
- X cptr++;
- X }
- X /*PC = pc ? *pc : 0;*/
- X if (cp = tgetstr("kh", &p))
- X K[KEY_HOME - KFIRST] = cp;
- X if (cp = tgetstr("ku", &p))
- X K[KEY_UP - KFIRST] = cp;
- X if (cp = tgetstr("kd", &p))
- X K[KEY_DOWN - KFIRST] = cp;
- X if (cp = tgetstr("kl", &p))
- X K[KEY_LEFT - KFIRST] = cp;
- X if (cp = tgetstr("kr", &p))
- X K[KEY_RIGHT - KFIRST] = cp;
- X if (cp = tgetstr("EN", &p))
- X K[KEY_END - KFIRST] = cp;
- X if (cp = tgetstr("PU", &p))
- X K[KEY_PAGEUP - KFIRST] = cp;
- X if (cp = tgetstr("PD", &p))
- X K[KEY_PAGEDOWN - KFIRST] = cp;
- X
- X if (CM == NULL)
- X panic("No cursor move (cm) capability in termcap.");
- X if (UP == NULL)
- X panic("No upline (up) capability in termcap.");
- X# if defined(SIGWINCH)
- X {void ttwinch();
- X signal(SIGWINCH, ttwinch);
- X }
- X# endif
- X
- X if(!CE) tceeol = ncol;
- X else tceeol = charcost(CE);
- X
- X /* Estimate cost of inserting a line */
- X if (CS && SR) tcinsl = charcost(CS)*2 + charcost(SR);
- X else if (pAL) tcinsl = charcost(pAL);
- X else if (AL) tcinsl = charcost(AL);
- X else tcinsl = HUGE; /* make this cost high enough */
- X
- X /* Estimate cost of deleting a line */
- X if (CS) tcdell = charcost(CS)*2 + 1;
- X else if (pDL) tcdell = charcost(pDL);
- X else if (DL) tcdell = charcost(DL);
- X else tcdell = HUGE; /* make this cost high enough */
- X
- X /* Flag to indicate that we can both insert and delete lines */
- X insdel = (AL || pAL) && (DL || pDL);
- X
- X if (p >= &tcapbuf[TCAPSLEN])
- X panic("Terminal description too big!\n");
- X
- X /* tgoto() doesnt work properly with real termcap -- leave *
- X /* this in for now. */
- X# if 1 || defined(MY_TERMCAP)
- X {
- X void close_termcap();
- X close_termcap();
- X }
- X# endif
- X}
- Xttinit1()
- X{
- X ttresize(); /* set nrow & ncol */
- X flush_col_cache();
- X if (TI)
- X putpad (TI); /* init the term */
- X if (IS)
- X putpad (IS); /* init the term */
- X if (KS)
- X putpad(KS);
- X}
- X/*----------------------------------------
- X/* Routine to decypher termcap style strings.
- X/* Needed by code in set_term_escapes.
- X/*----------------------------------------*/
- X
- X# define XDIGIT(x) (x <= '9' ? x - '0' : \
- X (x >= 'a' && x <= 'z') ? x - 'a' + 10 : \
- X (x - 'A' + 10))
- Xchar *
- Xtcopy_string(dp, bp, delim)
- Xregister char *dp, *bp;
- X{ register int n;
- X
- X while (*bp != delim && *bp) {
- X if (*bp == '^') {
- X *dp++ = *++bp & 0x1f;
- X bp++;
- X continue;
- X }
- X if (*bp != '\\') {
- X *dp++ = *bp++;
- X continue;
- X }
- X switch (*++bp) {
- X case 'E': *dp++ = 0x1b; break;
- X case 'r': *dp++ = '\r'; break;
- X case 'n': *dp++ = '\n'; break;
- X case 't': *dp++ = '\t'; break;
- X case 'b': *dp++ = '\b'; break;
- X case 'f': *dp++ = '\f'; break;
- X case '0': case '1': case '2': case '3':
- X n = 0;
- X while (*bp >= '0' && *bp <= '7')
- X n = 8*n + *bp++ - '0';
- X bp--;
- X *dp++ = (char) n;
- X break;
- X case 'x':
- X bp++;
- X n = XDIGIT(*bp);
- X bp++;
- X n = n * 16 + XDIGIT(*bp);
- X *dp++ = (char) n;
- X break;
- X default: *dp++ = *bp; break;
- X }
- X bp++;
- X }
- X *dp++ = NULL;
- X return dp;
- X}
- X
- X/*
- X * Clean up the terminal, in anticipation of
- X * a return to the command interpreter. This is a no-op
- X * on the ANSI display. On the SCALD display, it sets the
- X * window back to half screen scrolling. Perhaps it should
- X * query the display for the increment, and put it
- X * back to what it was.
- X */
- Xvoid
- Xtttidy()
- X{
- X if (RS && *RS) putpad (RS); /* set the term back to normal mode */
- X if (TE && *TE) putpad (TE); /* set the term back to normal mode */
- X if (KE)
- X putpad(KE);
- X}
- X
- X/*
- X * Move the cursor to the specified
- X * origin 0 row and column position. Try to
- X * optimize out extra moves; redisplay may
- X * have left the cursor in the right
- X * location last time!
- X */
- Xvoid
- Xttmove(row, col)
- Xu_int16 row;
- Xu_int16 col;
- X{
- X char *tgoto();
- X extern char *HO;
- X if (ttrow == row && ttcol == col)
- X return;
- X
- X if (col == 0 && row == 0 && HO)
- X putpad(HO);
- X else if (ttcol == col && row == ttrow+1)
- X ttputpad('\n');
- X else if (ttcol == col+1 && row == ttrow+1) {
- X ttputpad('\n');
- X ttputpad('\b');
- X }
- X else if (ttcol-1 == col && row == ttrow)
- X ttputpad('\b');
- X else if (ttrow == row && pt.pt_escC[0] && col > ttcol && ttcol > 1) {
- X putpad(tgoto(pt.pt_escC, 0, col - ttcol));
- X }
- X else {
- X char *cp = tgoto(CM, (int) col, (int) row);
- X/* int len = strlen(cp);
- X if (row == ttrow && col + len < ttcol) {
- X int i;
- X for (i = 0; i++ < ttcol - col; i++)
- X ttputpad('\b');
- X }
- X else*/
- X putpad(cp);
- X }
- X ttrow = row;
- X ttcol = col;
- X}
- X/*
- X * Erase to end of line.
- X */
- Xvoid
- Xtteeol()
- X{
- X if(CE) putpad(CE);
- X else {
- X register int i=ncol-ttcol;
- X while(i--) ttputc(' ');
- X ttrow = ttcol = HUGE;
- X }
- X}
- X
- Xttclear()
- X{
- X if (CL == NULL) {
- X ttmove((u_int16) 0, (u_int16) 0);
- X tteeop();
- X }
- X else {
- X ttrow = 0;
- X ttcol = 0;
- X putpad(CL);
- X }
- X}
- X/*
- X * Erase to end of page.
- X */
- Xvoid
- Xtteeop()
- X{
- X if(CD) putpad(CD);
- X else {
- X putpad(CE);
- X if (insdel) ttdell(ttrow + 1, LI, LI - ttrow - 1);
- X else { /* do it by hand */
- X register int line;
- X for (line = ttrow + 1; line <= LI; ++line) {
- X ttmove((u_int16) line, (u_int16) 0);
- X tteeol();
- X }
- X }
- X ttrow = ttcol = HUGE;
- X }
- X}
- X
- X/*
- X * Make a noise.
- X */
- Xvoid
- Xttbeep()
- X{
- X ttputc(BEL);
- X /*----------------------------------------
- X /* Adjust cursor because ttputc() thinks
- X /* BEL moves the cursor.
- X /*----------------------------------------*/
- X ttcol--;
- X ttflush();
- X}
- Xbeep()
- X{
- X ttbeep();
- X return 0;
- X}
- X
- X/*
- X * Insert nchunk blank line(s) onto the
- X * screen, scrolling the last line on the
- X * screen off the bottom. Use the scrolling
- X * region if possible for a smoother display.
- X * If no scrolling region, use a set
- X * of insert and delete line sequences
- X */
- Xttinsl(row, bot, nchunk)
- X{
- X register int i;
- X
- X if (row == bot) { /* Case of one line insert is special */
- X ttmove((u_int16) row, (u_int16) 0);
- X tteeol();
- X return TRUE;
- X }
- X if (CS && SR) { /* Use scroll region and back index */
- X ttwindow(row,bot);
- X ttmove((u_int16) row, (u_int16) 0);
- X while (nchunk--) putpad(SR);
- X /*ttnowindow();*/
- X return TRUE;
- X }
- X if (insdel) {
- X ttmove((u_int16) (1+bot-nchunk), (u_int16) 0);
- X if (pDL)
- X putpad (tgoto(pDL, 0, nchunk));
- X else
- X for (i=0; i<nchunk; i++)/* For all lines in the chunk */
- X putpad(DL);
- X ttmove((u_int16) row, (u_int16) 0);
- X if (pAL)
- X putpad (tgoto(pAL, 0, nchunk));
- X else
- X for (i=0; i<nchunk; i++)/* For all lines in the chunk*/
- X putpad(AL);
- X ttrow = HUGE;
- X ttcol = HUGE;
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * Delete nchunk line(s) from "row", replacing the
- X * bottom line on the screen with a blank line.
- X * Unless we're using the scrolling region, this is
- X * done with a crafty sequences of insert and delete
- X * lines. The presence of the echo area makes a
- X * boundry condition go away.
- X */
- Xttdell(row, bot, nchunk)
- X{ register int i;
- X
- X if (row == bot) { /* One line special case */
- X ttmove((u_int16) row, (u_int16) 0);
- X tteeol();
- X return TRUE;
- X }
- X if (CS) { /* scrolling region */
- X ttwindow(row, bot);
- X ttmove((u_int16) bot, (u_int16) 0);
- X while (nchunk--) ttputc(LF);
- X return TRUE;
- X }
- X if(insdel) {
- X ttmove((u_int16) row, (u_int16) 0);
- X if (pDL)
- X putpad (tgoto(pDL, 0, nchunk));
- X else
- X for (i=0; i<nchunk; i++)
- X putpad(DL);
- X ttmove((u_int16) (1+bot-nchunk), (u_int16) 0);
- X if (pAL)
- X putpad (tgoto(pAL, 0, nchunk));
- X else
- X for (i=0; i<nchunk; i++)
- X putpad(AL);
- X ttrow = HUGE;
- X ttcol = HUGE;
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * This routine sets the scrolling window
- X * on the display to go from line "top" to line
- X * "bot" (origin 0, inclusive). The caller checks
- X * for the pathalogical 1 line scroll window that
- X * doesn't work right, and avoids it. The "ttrow"
- X * and "ttcol" variables are set to a crazy value
- X * to ensure that the next call to "ttmove" does
- X * not turn into a no-op (the window adjustment
- X * moves the cursor).
- X *
- X */
- Xvoid
- Xttwindow(top, bot)
- X{
- X if (CS && (tttop!=top || ttbot!=bot)) {
- X putpad(tgoto(CS, bot, top));
- X ttrow = HUGE; /* Unknown. */
- X ttcol = HUGE;
- X tttop = top; /* Remember region. */
- X ttbot = bot;
- X }
- X}
- X
- X/*
- X * Set the current writing color to the
- X * specified color. Watch for color changes that are
- X * not going to do anything (the color is already right)
- X * and don't send anything to the display.
- X * The rainbow version does this in putline.s on a
- X * line by line basis, so don't bother sending
- X * out the color shift.
- X */
- Xstatic int tthue = -1;
- Xstatic int tt_fg = -1;
- Xstatic int tt_bg = -1;
- Xstatic int gso = FALSE;
- Xvoid
- Xflush_col_cache()
- X{
- X tthue = tt_fg = tt_bg = -1;
- X}
- Xvoid
- Xttcolor(color)
- X{ int fg, bg;
- X
- X if (tthue == color)
- X return;
- X tthue = color;
- X if (!pt.pt_color) {
- X if (color == FG(col_table.c_normal) ||
- X color == FG(col_table.c_messages)) {
- X putpad(SE);
- X }
- X else if (color == FG(col_table.c_select) ||
- X color == FG(col_table.c_error)) {
- X putpad(SE);
- X putpad(MD);
- X }
- X else {
- X putpad(SO);
- X }
- X return;
- X }
- X fg = (color & FG_COLOR) >> FG_SHIFT;
- X bg = (color & BG_COLOR) >> BG_SHIFT;
- X if (fg != tt_fg) {
- X putpad(colors.fg[fg]);
- X tt_fg = fg;
- X }
- X if (bg != tt_bg) {
- X putpad(colors.bg[bg]);
- X tt_bg = bg;
- X }
- X}
- Xvoid
- Xttresize()
- X{
- X setttysize();
- X if (nrow < 1)
- X nrow = 1;
- X if (ncol < 1)
- X ncol = 1;
- X}
- Xvoid
- Xttwinch()
- X{
- X# if defined(SIGWINCH)
- X void ttwinch1();
- X
- X int oncol = ncol;
- X int onrow = nrow;
- X ttresize();
- X signal(SIGWINCH, ttwinch);
- X update();
- X# endif
- X}
- Xvoid
- Xttwinch1(oncol, onrow, ncol, nrow)
- X{ register WINDOW *wp;
- X extern int sgarbf;
- X int diffcol, diffrow;
- X
- X vtinit1();
- X diffcol = ncol - oncol;
- X diffrow = nrow - onrow;
- X for (wp = wheadp; wp; wp = wp->w_wndp) {
- X int right_edge;
- X int last_line;
- X /*----------------------------------------
- X /* Adjust window width only if its right
- X /* hand edge touches the right hand edge
- X /* of the window.
- X /*----------------------------------------*/
- X right_edge = wp->w_x + wp->w_w;
- X last_line = wp->w_y + wp->w_h;
- X if (wp->w_tiled)
- X right_edge++;
- X if (right_edge == oncol)
- X wp->w_w += diffcol;
- X /*----------------------------------------
- X /* Adjust window height if window's
- X /* bottom line touches bottom of screen.
- X /*----------------------------------------*/
- X if (last_line == onrow - 3)
- X wp->w_h += diffrow;
- X }
- X sgarbf = TRUE;
- X}
- X
- Xstatic int cci;
- X
- Xstatic void /* fake char output for charcost() */
- Xfakec(c) char c;
- X{
- X#ifdef lint
- X c++;
- X#endif
- X cci++;
- X}
- X
- X/* calculate the cost of doing string s */
- Xcharcost (s) char *s;
- X{
- X cci = 0;
- X
- X tputs(s, nrow, fakec);
- X return cci;
- X}
- Xvoid
- Xputpad(str)
- Xchar *str;
- X{
- X if (str == NULL)
- X return;
- X/* if (str == SO) {
- X if (gso)
- X return;
- X gso = TRUE;
- X }
- X else if (str == SE) {
- X if (!gso)
- X return;
- X gso = FALSE;
- X } */
- X tputs(str, 1, ttputpad);
- X}
- Xvoid
- Xttspace(n, space, stay)
- X{ u_int16 oldrow = ttrow;
- X u_int16 oldcol = ttcol;
- X
- X if (n <= 0)
- X return;
- X ttputc(space);
- X if (--n <= 0)
- X return;
- X if (pt.pt_space[0]) {
- X putpad(tgoto(pt.pt_space, 0, n));
- X if (!stay)
- X ttmove(oldrow, oldcol + n + 1);
- X }
- X else {
- X while (n-- > 0)
- X ttputc(space);
- X }
- X if (stay)
- X ttmove(oldrow, oldcol);
- X
- X}
- Xttrepeat(ch, n)
- X{
- X if (n > 12 && pt.pt_repeat[0]) {
- X ttputc(ch);
- X putpad(tgoto(pt.pt_repeat, 0, n-1));
- X ttmove(ttrow, ttcol + n - 1);
- X }
- X while (n-- > 0)
- X ttputc(ch);
- X
- X
- X}
- X
- SHAR_EOF
- echo "File ./tty.c is complete"
- chmod 0444 ./tty.c || echo "restore of ./tty.c fails"
- mkdir . >/dev/null 2>&1
- echo "x - extracting ./ttyio.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > ./ttyio.c &&
- X/**************************************************************
- X *
- X * CRISP - Custom Reduced Instruction Set Programmers Editor
- X *
- X * (C) Paul Fox, 1989
- X * 43, Jerome Close Tel: +44 6284 4222
- X * Marlow
- X * Bucks.
- X * England SL7 1TX
- X *
- X *
- X * Please See COPYRIGHT notice.
- X *
- X **************************************************************/
- X
- X# include "list.h"
- XSCCSID("@(#) ttyio.c 1.15, (C) P. Fox");
- X
- X# if defined(SUN)
- X# include <sys/time.h>
- X# include <termio.h>
- X# endif
- X# if defined(XENIX)
- X# include <termio.h>
- X# endif
- X
- X
- X
- X# define TTY_FD 0
- X# define BIT(x) (1 << (x))
- X
- X# if defined(SELECT)
- X# include <sys/types.h>
- X# include <sys/time.h>
- X
- X# endif
- Xlong sel_bits = BIT(TTY_FD);
- X
- X# define CENTISECONDS 5 /* x .01 seconds */
- Xvoid ttflush();
- X
- X#define NOBUF 136 /* Output buffer size. */
- X
- Xlong st_charout; /* Number of characters output. */
- X
- Xchar obuf[NOBUF+10]; /* Output buffer. */
- Xint nobuf; /* buffer count */
- Xint timeout_flag = FALSE; /* TRUE when we are in VMIN/VTIME mode.*/
- Xint reading_char;
- Xunsigned char kbdq = 0;
- Xextern int ega43_flag;
- Xint old_ega_flag = -1;
- X
- Xu_int16 nrow; /* Terminal size, rows. */
- Xu_int16 ncol; /* Terminal size, columns. */
- X
- X/*
- X * This function gets called once, to set up
- X * the terminal channel. This version turns off flow
- X * control. This may be wrong for your system, but no
- X * good solution has really been found (daveb).
- X */
- Xvoid
- Xttopen()
- X{
- X sys_open();
- X ttinit1();
- X}
- Xvoid
- Xtttimeout(yes)
- X{
- X if (yes == timeout_flag)
- X return;
- X timeout_flag = yes;
- X sys_timeout(yes);
- X}
- X/*
- X * This function gets called just
- X * before we go back home to the shell. Put all of
- X * the terminal parameters back.
- X */
- Xvoid
- Xttclose()
- X{
- X ttflush();
- X sys_close();
- X old_ega_flag = -1;
- X}
- X
- X/*
- X * Write character to the display.
- X * Characters are buffered up, to make things
- X * a little bit more efficient.
- X */
- Xvoid
- Xttputpad(c)
- X{
- X if (nobuf >= NOBUF)
- X ttflush();
- X obuf[nobuf++] = (char) c;
- X}
- Xvoid
- Xttputs(str)
- Xregister char *str;
- X{
- X while (*str)
- X ttputc(*str++);
- X}
- Xvoid
- Xttputc(c)
- Xregister int c;
- X{
- X extern int scr_attr;
- X register int color = c & COLOR_MASK;
- X extern int AM;
- X
- X if (nobuf >= NOBUF)
- X ttflush();
- X
- X ttcolor(color);
- X
- X c &= 0xff;
- X/* if (c & 0x80 && c < (0x80 + ' ')) {*/
- X if (c & 0x80) {
- X if (c >= CH_MIN && c <= CH_MAX) {
- X char *cp = "?";
- X switch (c) {
- X case CH_HORIZONTAL: cp = pt.pt_horizontal; break;
- X case CH_VERTICAL: cp = pt.pt_vertical; break;
- X case CH_TOP_LEFT: cp = pt.pt_top_left; break;
- X case CH_TOP_RIGHT: cp = pt.pt_top_right; break;
- X case CH_BOT_LEFT: cp = pt.pt_bot_left; break;
- X case CH_BOT_RIGHT: cp = pt.pt_bot_right; break;
- X case CH_TOP_JOIN: cp = pt.pt_top_join; break;
- X case CH_BOT_JOIN: cp = pt.pt_bot_join; break;
- X case CH_LEFT_JOIN: cp = pt.pt_left_join; break;
- X case CH_RIGHT_JOIN: cp = pt.pt_right_join; break;
- X case CH_CROSS: cp = pt.pt_cross; break;
- X }
- X strcpy(obuf + nobuf, cp);
- X nobuf += strlen(cp);
- X }
- X else if (c >= 0x80 + ' ')
- X goto hell;
- X else {
- X c &= 0x7f;
- X if (c == 0x1b && pt.pt_escape[0])
- X strcpy(obuf+nobuf, pt.pt_escape);
- X else
- X sprintf(obuf+nobuf, pt.pt_character, c ? c : 0x80);
- X nobuf += strlen(obuf+nobuf);
- X }
- X goto end_of_function;
- X }
- X if (c == 0)
- X return;
- Xhell:
- X obuf[nobuf++] = (char) c;
- X if (c == '\b') {
- X ttcol--;
- X return;
- X }
- Xend_of_function:
- X if (++ttcol >= ncol && AM) {
- X ttcol = 0;
- X ttrow++;
- X }
- X}
- X
- Xvoid
- Xttflush()
- X{ extern int background;
- X
- X if (nobuf != 0) {
- X st_charout += nobuf;
- X if (background == FALSE)
- X sys_write(1, obuf, nobuf);
- X nobuf = 0;
- X }
- X}
- XKEY
- Xgetkey()
- X{
- X int n;
- X unsigned char ch;
- X extern int num_pty;
- X extern long time_last_key_pressed;
- X KEY key;
- X static unsigned char buf[32]; /* Buffer for current key being read in */
- X static unsigned char *bufptr = NULL;
- X unsigned char *cp = buf;
- X int pass2 = FALSE;
- X extern int push_cnt;
- X# if defined(SELECT)
- X struct timeval timeout;
- X struct timeval *tp = NULL;
- X
- X timeout.tv_sec = 0;
- X timeout.tv_usec = 0;
- X# endif
- X
- X if (push_cnt)
- X return get_push();
- X
- X if (bufptr) {
- X ch = *bufptr++;
- X if (*bufptr == NULL)
- X bufptr = NULL;
- X return ch;
- X }
- X
- X while (1) {
- X extern int child_sig;
- X extern void proc_wait();
- X /*----------------------------------------
- X /* Check to see if clock has gone off
- X /* and we need to call somebody. We can
- X /* only safely do this whilst we are NOT
- X /* reading a character from the keyboard.
- X /*----------------------------------------*/
- X clock_check();
- X if (kbdq) {
- X ch = kbdq;
- X kbdq = 0;
- X goto got_char;
- X }
- X /*----------------------------------------
- X /* If SIGCLD gone off then we should be
- X /* safe here to go and process it.
- X /*----------------------------------------*/
- X if (child_sig)
- X proc_wait(-1);
- X
- X reading_char = TRUE;
- X# if defined(SELECT)
- X if (pass2) {
- X timeout.tv_usec = CENTISECONDS * 100 * 1000;
- X tp = &timeout;
- X }
- X if (tp || num_pty) {
- X int fd, bits;
- X long readbits = sel_bits;
- X long kbd_ready;
- X long pty_ready;
- X int nfds = select(32, &readbits, (long *) NULL, (long *) NULL,
- X tp);
- X if (nfds < 0)
- X continue;
- X kbd_ready = BIT(TTY_FD) & readbits;
- X pty_ready = FALSE;
- X /*----------------------------------------
- X /* Handle all pty's first.
- X /*----------------------------------------*/
- X for (fd = 0, bits = 0; readbits && bits < 32;
- X bits++, readbits >>= 1, fd++) {
- X if (fd == TTY_FD)
- X continue;
- X if ((BIT(fd) & readbits) == 0)
- X continue;
- X p_poll();
- X pty_ready = TRUE;
- X }
- X if (kbdq)
- X continue;
- X if (!kbd_ready) {
- X if (tp && pty_ready == FALSE)
- X goto return_ch;
- X continue;
- X }
- X }
- X# endif
- X# if !defined(SELECT)
- X tttimeout(pass2);
- X# endif
- X /*----------------------------------------
- X /* Check to see if we have anything in
- X /* playback buffer, before finally going
- X /* to the keyboard for a character.
- X /*----------------------------------------*/
- X if ((ch = grab_char()) == 0) {
- X if (sys_getchar(TTY_FD, &ch, 1) != 1) {
- X if (pass2)
- X goto return_ch;
- X continue;
- X }
- X }
- X
- Xgot_char:
- X reading_char = FALSE;
- X *cp++ = ch;
- X *cp = NULL;
- X time_last_key_pressed = time((long *) 0);
- X key = check_key(buf, cp - buf);
- X if (key > 0) {
- X store_char(key);
- X return key;
- X }
- X if (key == 0) {
- Xreturn_ch:
- X if (buf[1])
- X bufptr = &buf[1];
- X store_char (buf[0]);
- X return buf[0];
- X }
- X pass2 = TRUE;
- X }
- X}
- X
- Xtypeahead()
- X{
- X if (kbdq)
- X return kbdq;
- X
- X if (kbdq = grab_char())
- X return kbdq;
- X
- X kbdq = sys_checkc();
- X return kbdq;
- X}
- X
- X
- Xvoid
- Xpanic(s)
- Xchar *s;
- X{
- X u_close();
- X vttidy();
- X fprintf(stderr, "CRISP PANIC: %s\r\n", s);
- X exit(1);
- X}
- X
- Xdo_ega()
- X{ int arg = argv[1].l_flags == F_NULL ? 0 : argv[1].l_int;
- X
- X accumulator = ega43_flag ? 43 : 25;
- X if (argv[1].l_flags == F_NULL)
- X return;
- X
- X if (arg == 43)
- X arg = 1;
- X else if (arg == 25)
- X arg = 0;
- X ega_switch(arg);
- X}
- Xvoid
- Xsetttysize()
- X{ extern char *ggetenv();
- X extern int AM;
- X
- X#ifdef TIOCGWINSZ
- X struct winsize winsize;
- X
- X if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
- X nrow = winsize.ws_row;
- X ncol = winsize.ws_col;
- X }
- X if (nrow == 0 || ncol == 0)
- X#endif
- X if ((nrow= (u_int16) tgetnum ("li")) == 0
- X || (ncol= (u_int16) tgetnum ("co")) == 0) {
- X nrow = 24;
- X ncol = 80;
- X }
- X# if defined(CONS_GET)
- X {extern int console_mode;
- X if (console_mode > 0) {
- X switch (console_mode) {
- X case M_ENH_C80x43:
- X ega_switch(1);
- X nrow = 43;
- X break;
- X case M_ENH_C80x25:
- X ega_switch(0);
- X nrow = 25;
- X break;
- X }
- X }
- X }
- X# endif
- X if (ggetenv("LINES")) {
- X nrow = atoi(ggetenv("LINES"));
- X AM = FALSE;
- X }
- X if (ggetenv("COLUMNS")) {
- X ncol = atoi(ggetenv("COLUMNS"));
- X AM = FALSE;
- X }
- X}
- Xega_switch(flag)
- X{ extern int sgarbf;
- X extern void ttwinch1();
- X int onrow = nrow;
- X
- X if (flag)
- X flag = 1;
- X
- X if (old_ega_flag == flag)
- X return;
- X
- X old_ega_flag = ega43_flag = flag;
- X if (flag) {
- X# if defined(SW_ENHC80x43)
- X ioctl(1, SW_ENHC80x43, 1);
- X nrow = 43;
- X# endif
- X ttwinch1(ncol, onrow, ncol, nrow);
- X }
- X else {
- X# if defined(SW_ENHC80x25)
- X ioctl(1, SW_ENHC80x25, 1);
- X nrow = 25;
- X# endif
- X ttwinch1(ncol, onrow, ncol, nrow);
- X }
- X flush_col_cache();
- X}
- X
- SHAR_EOF
- chmod 0444 ./ttyio.c || echo "restore of ./ttyio.c fails"
- mkdir . >/dev/null 2>&1
- echo "x - extracting ./ttykbd.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > ./ttykbd.c &&
- X/**************************************************************
- X *
- X * CRISP - Custom Reduced Instruction Set Programmers Editor
- X *
- X * (C) Paul Fox, 1989
- X * 43, Jerome Close Tel: +44 6284 4222
- X * Marlow
- X * Bucks.
- X * England SL7 1TX
- X *
- X *
- X * Please See COPYRIGHT notice.
- X *
- X **************************************************************/
- X# include "list.h"
- X# include "alt.h"
- X
- XSCCSID("@(#) ttykbd.c 1.11, (C) P. Fox");
- X
- X/*
- X0x80-0x8b 128-139 F1-F12
- X0x8c-0x97 140-151 SHIFT-F1 - SHIFT-F12
- X0x98-0xA3 152-163 CTRL-F1 - CTRL-F12
- X0xA4-0xAF 164-175 ALT-F1 - ALT-F12
- X0xB0-0xC9 176-201 ALT-A - ALT-Z
- X0xCA-0xD3 202-211 Key-0, Key-9
- X 0xCA/202=INS
- X 0xCB/203=END, 0xCC/204=DOWN, 0xCD/205=PgDn,
- X 0xCE/206=LEFT, 0xCF/207=5, 0xD0/208=RIGHT,
- X 0xD1/209=HOME, 0xD2/210=UP, 0xD3/211=PgUp
- X0xD4/212=DEL, 0xD5/213=+, 0xD6/214=-, 0xD7/215=*
- X0xD8-0xE5 216-229 CTRL-0 .. CTRL-9, DEL, +, -, *
- X 0xDF/223=Ctrl-Home 0xD9/217=Ctrl-End
- X 0xE1/225=Ctrl-PgUp 0xDB/219=Ctrl-Pgdn
- X 0xDC/220=Ctrl-<- 0xDE/222=Ctrl- ->
- X0xE6 230 Back-tab
- X*/
- X# define MAX_PUSHBACK 12
- X
- Xint reading_char = FALSE;
- Xstatic u_char key_buf[16];
- Xextern long time_last_key_pressed;
- Xu_char push_buf[MAX_PUSHBACK];
- Xint push_cnt = 0;
- Xchar user_call[64]; /* Last macro called from keyboard by user*/
- X
- Xchar *aitokey();
- Xstatic short akeytoi();
- Xtypedef char *KEYBOARD[NKEYS];
- Xtypedef struct MAP {
- X char *m_keys; /* Key sequence. */
- X char *m_value; /* String assigned to. */
- X int m_flags; /* Tells us whether m_value is a */
- X /* string or a list. */
- X } MAP;
- X
- X# define K_ALLOC 0x01 /* Key has been alloc'ed and should*/
- X /* be freed when finished with. */
- X# define K_LIST 0x02 /* Key is assigned to a list. */
- Xstruct kbd_stk {
- X int k_id;
- X int k_ref; /* Reference count for this keyboard. */
- X /* When this becomes zero, we may free*/
- X /* it. Otherwise, it still exists in */
- X /* the keyboard stack. */
- X u_char k_flags[NKEYS];
- X KEYBOARD k_keys;
- X Head_p k_maps; /* Multicharacter key combinations. */
- X };
- X
- XHead_p hd_kbd;
- XHead_p hd_kstk;
- Xstruct kbd_stk *kp;
- X#define KFIRST 0x0080 /* First special. */
- Xextern char *K[];
- Xchar character;
- Xint kid = 1;
- X
- Xextern struct k_tbl k_tbl[];
- Xvoid
- Xkey_init()
- X{ extern char *chk_alloc();
- X int i;
- X struct kbd_stk *kptr;
- X
- X hd_kbd = ll_init();
- X hd_kstk = ll_init();
- X
- X kptr = (struct kbd_stk *) chk_alloc(sizeof (struct kbd_stk));
- X kptr->k_id = kid++;
- X kptr->k_ref = 1;
- X kptr->k_maps = ll_init();
- X for (i = 0; i < NKEYS; i++) {
- X kptr->k_keys[i] = NULL;
- X kptr->k_flags[i] = 0;
- X }
- X for (i = 0; k_tbl[i].name; i++) {
- X kptr->k_keys[k_tbl[i].key] = k_tbl[i].name;
- X kptr->k_flags[k_tbl[i].key] = 0;
- X }
- X ll_push(hd_kbd, (char *) kptr);
- X kp = kptr;
- X K[BACK_TAB - KFIRST] = strdup("\033[Z");
- X}
- Xkbd_type()
- X{
- X register int i;
- X
- X for (i = 0; i < 127; i++) {
- X if (kp->k_keys[i] && kp->k_flags[i] & K_ALLOC)
- X chk_free(kp->k_keys[i]);
- X kp->k_keys[i] = NULL;
- X }
- X
- X return 0;
- X}
- Xpush_back()
- X{
- X push_back1((int) argv[1].l_int);
- X
- X return 0;
- X}
- Xpush_back1(ch)
- X{
- X if (push_cnt < MAX_PUSHBACK)
- X push_buf[push_cnt++] = ch;
- X}
- Xget_push()
- X{ int ch;
- X register int i;
- X if (push_cnt) {
- X ch = push_buf[0];
- X for (i = 0; i < MAX_PUSHBACK - 1; i++)
- X push_buf[i] = push_buf[i+1];
- X push_cnt--;
- X return ch;
- X }
- X return 0;
- X}
- Xassign_to_key()
- X{ int key;
- X char *cp;
- X char *macro_name;
- X int flags = K_ALLOC;
- X char buf1[80];
- X char buf[BUFSIZ];
- X
- X if ((cp = get_arg1("Enter key: ", buf, sizeof buf)) == NULL)
- X return;
- X key = akeytoi(cp);
- X
- X if (argc < 3 || argv[2].l_flags == F_NULL) {
- X if (ereply("Enter macro name to assign: ", buf1, sizeof buf1)
- X != TRUE)
- X return;
- X macro_name = strdup(buf1);
- X }
- X else if (argv[2].l_flags == F_LIST) {
- X LIST *copy_list();
- X macro_name = (char *) copy_list(argv[2].l_list);
- X flags = K_LIST | K_ALLOC;
- X }
- X else
- X macro_name = strdup(get_str(2));
- X
- X if (key >= 0) {
- X free_key(key);
- X kp->k_keys[key] = macro_name;
- X kp->k_flags[key] = flags;
- X }
- X else {
- X MAP *mp = (MAP *) chk_alloc (sizeof (MAP));
- X mp->m_keys = strdup(key_buf);
- X mp->m_value = macro_name;
- X mp->m_flags = flags;
- X ll_push(kp->k_maps, (char *) mp);
- X return;
- X }
- X}
- X
- Xfree_key(key)
- X{
- X if (kp->k_flags[key] & K_ALLOC)
- X chk_free(kp->k_keys[key]);
- X}
- Xstatic short
- Xakeytoi(cp)
- Xregister char *cp;
- X{
- X int width;
- X
- X for (width = 0; *cp; width++) {
- X if (*cp == '<') {
- X key_buf[width] = (u_char) new_akeytoi(cp);
- X while (*cp)
- X if (*cp++ == '>')
- X break;
- X }
- X else if (*cp == '#') {
- X key_buf[width] = (u_char) atoi(++cp);
- X while (isdigit(*cp))
- X cp++;
- X }
- X else {
- X key_buf[width] = 0;
- X if (*cp == '%')
- X cp++;
- X if (*cp == '\\')
- X key_buf[width] = (u_char) *++cp;
- X else if (*cp == '^')
- X key_buf[width] = (u_char) *++cp & 0x1f;
- X else
- X key_buf[width] = (u_char) *cp;
- X cp++;
- X }
- X if (width >= sizeof key_buf)
- X break;
- X }
- X if (width == 1)
- X return key_buf[0];
- X key_buf[width] = 0;
- X return -1;
- X}
- Xkey_to_int()
- X{
- X accumulator = akeytoi(get_str(1));
- X return 0;
- X}
- Xint_to_key()
- X{
- X strl_acc_assign(aitokey((short) argv[1].l_int));
- X return 0;
- X}
- Xcheck_key(buf, len)
- Xchar *buf;
- X{
- X register char **cpp;
- X List_p lp;
- X KEY key;
- X
- X /*--------------------------------------
- X * Check for normal function keys first.
- X *--------------------------------------*/
- X for (cpp = K; cpp < &K[NFKEYS]; cpp++) {
- X if (*cpp == NULL)
- X continue;
- X if (strcmp(*cpp, buf) == 0)
- X return (KEY) (cpp - K + KFIRST);
- X if (strncmp(*cpp, buf, len) == 0)
- X return -1;
- X }
- X /*--------------------------------------
- X * Check for multiple characters key
- X * sequences.
- X *--------------------------------------*/
- X for (key = KFIRST + NFKEYS, lp = ll_first(kp->k_maps); lp;
- X key++, lp = ll_next(lp)) {
- X MAP *mp = (MAP *) ll_elem(lp);
- X if (strcmp(buf, mp->m_keys) == 0)
- X return key;
- X if (strcmp(buf, mp->m_keys, len) == 0)
- X return -1;
- X }
- X return 0;
- X}
- X# if 0
- XKEY
- Xgetkey()
- X{ register char **cpp;
- X static unsigned char buf[12];
- X static unsigned char *bufptr = NULL;
- X static unsigned char *cp;
- X static int l;
- X int i;
- X unsigned char ch;
- X int timeout = FALSE;
- X List_p lp;
- X KEY key;
- X int ambiguous;
- X
- X if (push_cnt) {
- X ch = push_buf[0];
- X for (i = 0; i < MAX_PUSHBACK - 1; i++)
- X push_buf[i] = push_buf[i+1];
- X push_cnt--;
- X return ch;
- X }
- X
- X if (bufptr) {
- X ch = *bufptr++;
- X if (*bufptr == NULL)
- X bufptr = NULL;
- X return ch;
- X }
- X cp = buf;
- X l = 0;
- X while (1) {
- X tttimeout(timeout);
- X
- X reading_char = TRUE;
- X if (ch = *cp = (char) ttgetc()) {
- X extern long time();
- X store_char(*cp++);
- X *cp = NULL;
- X l++;
- X time_last_key_pressed = time((long *) 0);
- X }
- X reading_char = FALSE;
- X /*--------------------------------------
- X * Check for normal function keys first.
- X *--------------------------------------*/
- X ambiguous = FALSE;
- X for (cpp = K; cpp < &K[NFKEYS]; cpp++) {
- X if (*cpp == NULL)
- X continue;
- X if (strcmp(*cpp, buf) == 0)
- X return (KEY) (cpp - K + KFIRST);
- X if (strncmp(*cpp, buf, l) == 0) {
- X ambiguous = TRUE;
- X break;
- X }
- X }
- X /*--------------------------------------
- X * Check for multiple characters key
- X * sequences.
- X *--------------------------------------*/
- X if (!ambiguous) {
- X for (key = KFIRST + NFKEYS, lp = ll_first(kp->k_maps); lp;
- X key++, lp = ll_next(lp)) {
- X MAP *mp = (MAP *) ll_elem(lp);
- X if (strcmp(buf, mp->m_keys) == 0)
- X return key;
- X if (strncmp(buf, mp->m_keys, l) == 0) {
- X ambiguous = TRUE;
- X ch = 1; /* Non-zero. */
- X break;
- X }
- X }
- X }
- X if (ch == 0 || !ambiguous) {
- X if (buf[1])
- X bufptr = &buf[1];
- X tttimeout(FALSE);
- X return buf[0];
- X }
- X timeout = TRUE;
- X }
- X
- X}
- X# endif
- Xinq_command()
- X{
- X strl_acc_assign(user_call);
- X return 0;
- X}
- Xexec_key(c)
- X{ register char *cp;
- X int list_flag;
- X char *get_key_assignment();
- X
- X u_chain();
- X cp = get_key_assignment(c, &list_flag);
- X character = (char) c;
- X
- X remember_macro(cp, list_flag);
- X
- X if (list_flag) {
- X LISTV result;
- X eval((LIST *) cp, &result);
- X return 0;
- X }
- X
- X if (cp[0] != '_')
- X strcpy(user_call, cp);
- X trace_log("\nKEY_EXEC: %s\n", cp);
- X return str_exec(cp);
- X}
- Xchar *
- Xget_key_assignment(c, list_flagp)
- Xint *list_flagp;
- X{
- X register List_p lp;
- X register char *cp;
- X *list_flagp = TRUE;
- X
- X if (c >= KFIRST + NFKEYS) {
- X int i = c - KFIRST - NFKEYS;
- X MAP *mp;
- X for (lp = ll_first(kp->k_maps); i-- > 0 && lp; )
- X lp = ll_next(lp);
- X mp = (MAP *) ll_elem(lp);
- X cp = mp->m_value;
- X if (mp->m_flags & K_LIST)
- X return cp;
- X }
- X else if (curbp->b_keyboard) {
- X cp = curbp->b_keyboard->k_keys[c];
- X if (curbp->b_keyboard->k_flags[c] & K_LIST)
- X return cp;
- X if (cp && strcmp(cp, "nothing") == 0) {
- X cp = kp->k_keys[c];
- X if (kp->k_flags[c] & K_LIST)
- X return cp;
- X }
- X }
- X else {
- X cp = kp->k_keys[c];
- X if (kp->k_flags[c] & K_LIST)
- X return cp;
- X }
- X *list_flagp = FALSE;
- X return cp ? cp : "self_insert";
- X}
- Xinq_keyboard()
- X{
- X accumulator = kp->k_id;
- X return 0;
- X}
- Xinq_local_keyboard()
- X{
- X accumulator = curbp->b_keyboard ? curbp->b_keyboard->k_id : 0;
- X return 0;
- X}
- Xkbd_push()
- X{ register int i = argv[1].l_flags == F_NULL ? 0 : (int) argv[1].l_int;
- X register int j;
- X
- X if (i) {
- X List_p lp;
- X for (lp = ll_first(hd_kbd); lp; lp = ll_next(lp)) {
- X kp = (struct kbd_stk *) ll_elem(lp);
- X if (kp->k_id == i) {
- X kp->k_ref++;
- X break;
- X }
- X }
- X if (lp == NULL) {
- X for (lp = ll_first(hd_kstk); lp; lp = ll_next(lp)) {
- X kp = (struct kbd_stk *) ll_elem(lp);
- X if (kp->k_id == i) {
- X ll_delete(lp);
- X break;
- X }
- X }
- X }
- X if (lp == NULL)
- X errorf("keyboard_push: %d not found.", i);
- X }
- X else {
- X kp = (struct kbd_stk *) chk_alloc(sizeof (struct kbd_stk));
- X kp->k_id = kid++;
- X kp->k_maps = ll_init();
- X for (j = 0; j < NKEYS; j++) {
- X kp->k_keys[j] = i ? (char *) NULL : "nothing";
- X kp->k_flags[j] = 0;
- X }
- X }
- X ll_push(hd_kbd, (char *) kp);
- X
- X return 0;
- X
- X}
- Xkbd_pop()
- X{ int i = argv[1].l_flags == F_NULL ? 0 : (int) argv[1].l_int;
- X register int j;
- X List_p lp = ll_first(hd_kbd);
- X
- X if (lp == NULL)
- X return 0;
- X kp = (struct kbd_stk *) ll_elem(lp);
- X (void) ll_pop(hd_kbd);
- X
- X if (i == 0) {
- X if (--kp->k_ref <= 0) {
- X for (j = 0; j < NKEYS; j++)
- X if (kp->k_keys[j] && kp->k_flags[j] & K_ALLOC)
- X chk_free(kp->k_keys[j]);
- X for (lp = ll_first(kp->k_maps); lp;
- X lp = ll_next(lp)) {
- X MAP *mp = (MAP *) ll_elem(lp);
- X chk_free(mp->m_keys);
- X chk_free(mp->m_value);
- X }
- X ll_clear(kp->k_maps);
- X ll_free(kp->k_maps);
- X chk_free((char *) kp);
- X }
- X }
- X else {
- X ll_append(hd_kstk, (char *) kp);
- X }
- X lp = ll_first(hd_kbd);
- X kp = lp ? (struct kbd_stk *) ll_elem(lp) : NULL;
- X
- X return 0;
- X}
- Xuse_local_keyboard()
- X{
- X struct kbd_stk *kp;
- X register List_p lp;
- X
- X accumulator = 0;
- X if (argv[1].l_int == 0) {
- X curbp->b_keyboard = NULL;
- X return 0;
- X }
- X for (lp = ll_first(hd_kstk); lp; lp = ll_next(lp)) {
- X kp = (struct kbd_stk *) ll_elem(lp);
- X if (kp->k_id == argv[1].l_int) {
- X curbp->b_keyboard = kp;
- X return 0;
- X }
- X }
- X accumulator = -1;
- X return 0;
- X}
- Xinq_assignment()
- X{ char *cp;
- X short key;
- X int from_key = argv[2].l_flags == F_NULL || argv[2].l_int == 0;
- X
- X if (from_key) {
- X if (argv[1].l_flags == F_INT)
- X key = argv[1].l_int;
- X else
- X key = akeytoi(get_str(1));
- X if (key >= 0) {
- X if (curbp->b_keyboard) {
- X cp = curbp->b_keyboard->k_keys[key];
- X if (cp && strcmp(cp, "nothing") == 0)
- X cp = kp->k_keys[key];
- X }
- X else
- X cp = kp->k_keys[key];
- X }
- X else
- X cp = "nothing";
- X if (cp == NULL) {
- X character = (char) key;
- X cp = "self_insert";
- X }
- X strl_acc_assign(cp);
- X return 0;
- X }
- X str_acc_assign("", 0);
- X if (curbp->b_keyboard)
- X find_assignment(curbp->b_keyboard->k_keys);
- X find_assignment(kp->k_keys);
- X
- X if (saccumulator[0] == NULL)
- X strl_acc_assign("nothing", 7);
- X return 0;
- X}
- Xfind_assignment(cpp)
- Xregister char **cpp;
- X{ char buf[BUFSIZ];
- X char *sp;
- X short key;
- X char *str1 = get_str(1);
- X
- X strcpy(buf, saccumulator);
- X sp = buf + strlen(buf);
- X
- X for (key = 0; key < NKEYS; key++, cpp++) {
- X if (*cpp && strcmp(*cpp, str1) == 0) {
- X if (sp != buf) {
- X strcpy(sp, "<-also>");
- X sp += 7;
- X }
- X strcpy(sp, aitokey(key));
- X sp += strlen(sp);
- X }
- X }
- X strl_acc_assign(buf);
- X}
- X# undef PLUS
- X# undef MINUS
- X# define CTRL 0x0100
- X# define SHIFT 0x0200
- X# define ALT 0x0400
- X# define KEYPAD 0x0800
- X
- X# define ALL (CTRL|SHIFT|ALT|KEYPAD)
- X
- X# define UP 210
- X# define DOWN 204
- X# define LEFT 206
- X# define RIGHT 208
- X# define HOME 209
- X# define END 203
- X# define PGUP 211
- X# define PGDN 205
- X# define STAR 42
- X# define MINUS 169
- X# define PLUS 168
- X# define DEL 152
- X# define INS KEY_0
- X/*
- X# define F1 128
- X# define F2 129
- X# define F3 130
- X# define F4 131
- X# define F5 132
- X# define F6 133
- X# define F7 134
- X# define F8 135
- X# define F9 136
- X# define F10 137
- X*/
- X# define F11 138
- X# define F12 139
- X# define BACKSPACE 8
- X# define ENTER '\r'
- Xstruct map {
- X int len;
- X char *name;
- X short value;
- X };
- Xstruct map special[] = {
- X {0, "<Ctrl-Home>", 223},
- X {0, "<Ctrl-End>", 217},
- X {0, "<Ctrl-PgUp>", 225},
- X {0, "<Ctrl-PgDn>", 219},
- X {0, "<Ctrl-Left arrow>", 220},
- X {0, "<Ctrl-Right arrow>", 222},
- X {0, "<Ins>", KEY_0},
- X {0, "<Del>", 212},
- X {0, "<Delete>", 127},
- X {0, "<Keypad-plus>", 213},
- X {0, "<Keypad-minus>", 214},
- X {0, "<Keypad-star>", 215},
- X {0}
- X };
- X
- Xstruct map stoi[] = {
- X {3, "ESC", 0x1b},
- X {1, "{", '{'},
- X {1, "}", '}'},
- X {5, "SPACE", ' '},
- X {5, "ENTER", ENTER},
- X {3, "TAB", 0x09},
- X {5, "ARROW", 0},
- X {4, "CTRL", CTRL},
- X {5, "SHIFT", SHIFT},
- X {3, "ALT", ALT},
- X {6, "KEYPAD", KEYPAD},
- X {4, "GREY", KEYPAD},
- X {2, "UP", UP},
- X {4, "DOWN", DOWN},
- X {4, "LEFT", LEFT},
- X {5, "RIGHT", RIGHT},
- X {4, "HOME", HOME},
- X {3, "END", END},
- X {4, "PGUP", PGUP},
- X {4, "PGDN", PGDN},
- X {4, "STAR", STAR},
- X {5, "MINUS", MINUS},
- X {4, "PLUS", PLUS},
- X {3, "DEL", DEL},
- X {3, "INS", INS},
- X {3, "F12", F12},
- X {3, "F11", F11},
- X {3, "F10", F10},
- X {2, "F9", F9},
- X {2, "F8", F8},
- X {2, "F7", F7},
- X {2, "F6", F6},
- X {2, "F5", F5},
- X {2, "F4", F4},
- X {2, "F3", F3},
- X {2, "F2", F2},
- X {2, "F1", F1},
- X {9, "BACKSPACE", BACKSPACE},
- X 0
- X };
- Xchar *
- Xaitokey(key)
- Xshort key;
- X{
- X struct map *mp;
- X static char buf[32];
- X register char *cp;
- X int alpha_cnt = 0;
- X
- X if (key >= ALT_A && key <= ALT_Z) {
- X sprintf(buf, "<Alt-%c>", key - ALT_A + 'A');
- X return buf;
- X }
- X if (key >= SHIFT_F1 && key <= SHIFT_F1+11) {
- X sprintf(buf, "<Shift-F%d>", key - SHIFT_F1 + 1);
- X return buf;
- X }
- X if (key >= CTRL_F1 && key <= CTRL_F1+11) {
- X sprintf(buf, "<Ctrl-F%d>", key - CTRL_F1 + 1);
- X return buf;
- X }
- X if (key >= ALT_F1 && key <= ALT_F1+11) {
- X sprintf(buf, "<Alt-F%d>", key - ALT_F1 + 1);
- X return buf;
- X }
- X if (key >= ALT_0 && key <= ALT_0+9) {
- X sprintf(buf, "<Alt-%d>", key - ALT_0);
- X return buf;
- X }
- X if (key == BACK_TAB)
- X return "<Shift-Tab>";
- X
- X for (mp = special; mp->name; mp++)
- X if (mp->value == key)
- X return mp->name;
- X
- X for (mp = stoi; mp->name; mp++)
- X if (mp->value == (short) (key & 0xff)) {
- X sprintf(buf, "<%s>", mp->name);
- X for (cp = buf; *cp; cp++)
- X if (*cp >= 'A' && *cp <= 'Z')
- X if (alpha_cnt++)
- X *cp += 0x20;
- X return buf;
- X }
- X if (key < ' ')
- X sprintf(buf, "<Ctrl-%c>", key + 'A' - 1);
- X else
- X sprintf(buf, "#%d", key);
- X return buf;
- X}
- X
- Xnew_akeytoi(string)
- Xchar *string;
- X{ char str[80];
- X register char *cp;
- X int flags = 0;
- X int ch;
- X register struct map *mp;
- X
- X strcpy(str, string+1);
- X for (cp = str; *cp; cp++)
- X if (islower(*cp))
- X *cp = toupper(*cp);
- X
- X for (cp = str; *cp && *cp != '>'; ) {
- X if (*cp == ' ' || *cp == '-' || *cp == '\t') {
- X cp++;
- X continue;
- X }
- X for (mp = stoi; mp->name; mp++)
- X if (strncmp(mp->name, cp, mp->len) == 0) {
- X cp += mp->len;
- X flags |= mp->value;
- X break;
- X }
- X if (mp->name == 0) {
- X flags |= *cp;
- X break;
- X }
- X }
- X ch = flags & 0xff;
- X switch (flags & ALL) {
- X case 0: return ch;
- X case SHIFT:
- X if (ch >= F1 && ch <= F12)
- X return ch + 12;
- X if (ch >= 'A' && ch <= 'Z')
- X return ch - 0x20;
- X if (ch == UP || ch == DOWN || ch == LEFT || ch == RIGHT)
- X return 0;
- X if (ch == '\t')
- X return BACK_TAB;
- X if (isdigit(ch))
- X return 0;
- X return ch;
- X case CTRL:
- X if (ch == ENTER)
- X return '\n';
- X if (ch >= F1 && ch <= F12)
- X return ch + 24;
- X if (ch >= 'A' && ch <= 'Z')
- X return ch & 0x1f;
- X if (ch == UP || ch == DOWN || ch == LEFT || ch == RIGHT)
- X return ch + 14;
- X if (ch == '{' || ch == '}')
- X return 0;
- X if (isdigit(ch))
- X return 0;
- X return ch;
- X case ALT:
- X if (ch >= F1 && ch <= F12)
- X return ch + 32;
- X if (ch >= 'A' && ch <= 'Z')
- X return (ch - 'A') + ALT_A;
- X if (isdigit(ch))
- X return (ch - '0') + ALT_0;
- X return ch;
- X case KEYPAD:
- X switch (ch) {
- X case MINUS: return 214;
- X case PLUS: return 213;
- X default:
- X return 0;
- X }
- X case SHIFT|KEYPAD:
- X return 0;
- X }
- X ewprintf("Not decoded - %s", string);
- X return 0;
- X}
- SHAR_EOF
- chmod 0444 ./ttykbd.c || echo "restore of ./ttykbd.c fails"
- mkdir . >/dev/null 2>&1
- echo "x - extracting ./undo.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > ./undo.c &&
- X/**************************************************************
- X *
- X * CRISP - Custom Reduced Instruction Set Programmers Editor
- X *
- X * (C) Paul Fox, 1989
- X * 43, Jerome Close Tel: +44 6284 4222
- X * Marlow
- X * Bucks.
- X * England SL7 1TX
- X *
- X *
- X * Please See COPYRIGHT notice.
- X *
- X * Code to implement the undo and redo facilities.
- X **************************************************************/
- X# include "list.h"
- XSCCSID("@(#) undo.c 1.14, (C) 1989, P. Fox");
- Xstatic void re_goto();
- Xstatic void u_write();
- Xstatic undo_check();
- X
- Xenum undo_opcodes {
- X GOTO = 0,
- X INSERT = 1,
- X DELETE = 2,
- X RAISE = 3,
- X DROP = 4,
- X SCRAP = 5, /* Operation should do an undo on the scrap */
- X /* buffer. */
- X };
- X
- Xextern long ftell();
- Xextern char *mktemp();
- Xextern doing_selfinsert;
- Xstatic read_last_undo();
- Xstatic int undoing_scrap = FALSE; /* If TRUE stops us printing */
- X /* 'Undone.' twice. */
- XFILE *ufp = NULL;
- Xenum undo_state {
- X NORMAL,
- X REDO,
- X UNDO
- X } undo_state = NORMAL;
- X
- Xstruct undo {
- X enum undo_opcodes u_opcode;
- X int u_line;
- X int u_col;
- X ANCHOR u_anchor;
- X RSIZE u_length;
- X long u_last1; /* Used for backing up over (write_buffer) */
- X /* mark. */
- X long u_last; /* tell() position of previous undo */
- X int u_chain; /* Non-zero if part of a single */
- X /* undo. */
- X };
- Xchar *u_fname;
- Xint u_atend = FALSE; /* If TRUE dont fseek to eof. */
- Xvoid
- Xu_init()
- X{ char temp_file[64];
- X char *get_tmpdir();
- X char *sys_delim();
- X
- X sprintf(temp_file, "%s%sundoXXXXXX", get_tmpdir(), sys_delim());
- X u_fname = mktemp(temp_file);
- X
- X if ((ufp = fopen(u_fname, "w+")) == NULL) {
- X printf("Cannot create undo file:\n");
- X perror(u_fname);
- X gr_exit();
- X }
- X /*-------------------------*/
- X /* Ensure ftell(ufp) != 0) */
- X /*-------------------------*/
- X fwrite("Undo", 4, 1, ufp);
- X unlink(u_fname);
- X}
- Xchar *
- Xget_tmpdir()
- X{ extern char *ggetenv();
- X char *cp;
- X
- X if ((cp = ggetenv("BTMP")) != NULL)
- X return cp;
- X if ((cp = ggetenv("TMP")) != NULL)
- X return cp;
- X# if defined(VMS)
- X return "[-]";
- X# else
- X return "/tmp";
- X# endif
- X}
- Xvoid
- Xu_close()
- X{
- X if (ufp)
- X unlink(u_fname);
- X}
- Xvoid
- Xu_insert(n)
- XRSIZE n;
- X{ register LINE *clp;
- X register int cbo;
- X register int line;
- X struct undo undo_buf;
- X
- X if (n == 0 || undo_check())
- X return;
- X
- X if (undo_state == NORMAL)
- X curbp->b_nummod++;
- X undo_buf.u_opcode = INSERT;
- X undo_buf.u_length = n;
- X
- X u_write(&undo_buf);
- X
- X line = *cur_line;
- X cbo = current_offset(*cur_col, FALSE);
- X for ( ; line < curbp->b_numlines && n > 0; line++, cbo = 0) {
- X RSIZE x,w;
- X clp = vm_lock_line(line);
- X x = llength(clp) - cbo;
- X w = x;
- X if (x >= n)
- X w = n;
- X fwrite(<ext(clp)[cbo], (int) w, 1, ufp);
- X vm_unlock(line);
- X if (n -= w) {
- X fputc('\n', ufp);
- X n--;
- X }
- X }
- X
- X
- X}
- Xvoid
- Xu_delete(n)
- XRSIZE n;
- X{ struct undo undo_buf1;
- X struct undo undo_buf;
- X undo_info *up;
- X
- X if (n == 0 || undo_check())
- X return;
- X up = undo_state == UNDO ? &curbp->b_redo : &curbp->b_undo;
- X if (doing_selfinsert && up->u_last) {
- X if (read_last_undo(&undo_buf1, up))
- X goto normal;
- X if (undo_buf1.u_opcode == DELETE) {
- X extern char character;
- X# ifdef DEBUG
- X {char buf[128];
- X extern int dflag;
- X if (dflag & DB_UNDO) {
- X sprintf(buf,
- X "undo(COLLAPSING, %d + %d => %d)\n",
- X undo_buf1.u_length, n,
- X undo_buf1.u_length + n);
- X trace_log(buf, (char *) NULL);
- X }
- X }
- X# endif
- X if ((isalnum(curbp->b_uchar) && isalnum(character)) ||
- X (isspace(curbp->b_uchar) && isspace(character)) ||
- X (curbp->b_uchar == 0x1B || character == 0x1B) ||
- X (ispunct(curbp->b_uchar) && ispunct(character))) {
- X undo_buf1.u_length += n;
- X if (!u_atend)
- X fseek(ufp, up->u_last, 0);
- X fwrite((char *) &undo_buf1, sizeof undo_buf1, 1, ufp);
- X fseek(ufp, 0l, 2);
- X u_atend = TRUE;
- X return;
- X }
- X }
- X }
- Xnormal:
- X if (undo_state == NORMAL)
- X curbp->b_nummod++;
- X undo_buf.u_opcode = DELETE;
- X undo_buf.u_length = n;
- X u_write(&undo_buf);
- X
- X}
- Xvoid
- Xu_chain()
- X{ extern int playing_back;
- X if (!playing_back) {
- X curbp->b_undo.u_chain = 0;
- X curbp->b_redo.u_chain = 0;
- X }
- X}
- Xvoid
- Xu_terminate()
- X{
- X undo_info *up = undo_state == NORMAL ? &curbp->b_undo : &curbp->b_redo;
- X
- X up->u_last1 = up->u_last;
- X up->u_last = 0;
- X}
- Xvoid
- Xu_dot()
- X{ struct undo undo_buf;
- X
- X if (undo_check())
- X return;
- X undo_buf.u_opcode = GOTO;
- X u_write(&undo_buf);
- X}
- X
- Xvoid
- Xu_raise()
- X{ struct undo undo_buf;
- X if (undo_check())
- X return;
- X undo_buf.u_opcode = RAISE;
- X u_write(&undo_buf);
- X}
- Xvoid
- Xu_drop()
- X{ struct undo undo_buf;
- X
- X if (undo_check())
- X return;
- X
- X undo_buf.u_opcode = DROP;
- X
- X undo_buf.u_anchor = *curbp->b_anchor;
- X u_write(&undo_buf);
- X}
- Xvoid
- Xu_scrap()
- X{ struct undo undo_buf;
- X
- X if (undo_check())
- X return;
- X undo_buf.u_opcode = SCRAP;
- X u_write(&undo_buf);
- X
- X}
- X/* Undo utility routines. */
- Xstatic
- Xundo_check()
- X{
- X if (/*undo_state == REDO || */curbp->b_system || ufp == NULL)
- X return TRUE;
- X /*----------------------------------------
- X /* If user isn't undoing an undo
- X /* then terminate the redo chain so we
- X /* dont confuse user.
- X /*----------------------------------------*/
- X if (undo_state == NORMAL)
- X curbp->b_redo.u_last = 0;
- X return FALSE;
- X}
- Xstatic void
- Xu_write(undop)
- Xstruct undo *undop;
- X{ undo_info *up;
- X
- X if (undo_state == UNDO)
- X up = &curbp->b_redo;
- X else
- X up = &curbp->b_undo;
- X
- X undop->u_line = *cur_line;
- X undop->u_col = *cur_col;
- X undop->u_last1 = up->u_last1;
- X undop->u_last = up->u_last;
- X undop->u_chain = up->u_chain++;
- X if (!u_atend)
- X fseek(ufp, 0l, 2);
- X up->u_last = ftell(ufp);
- X
- X u_debug(undop, undo_state == NORMAL ? "normal" :
- X undo_state == UNDO ? "undo" : "redo");
- X fwrite((char *) undop, sizeof *undop, 1, ufp);
- X u_atend = TRUE;
- X}
- Xu_debug(undop, str)
- Xstruct undo *undop;
- Xchar *str;
- X{
- X# ifdef DEBUG
- X char buf[128];
- X extern int dflag;
- X if (dflag & DB_UNDO) {
- X sprintf(buf,
- X "%s(%s, line=%d, col=%d, len=%ld, last=%08lx, chain=%d)\n", str,
- X undop->u_opcode == GOTO ? "GOTO" :
- X undop->u_opcode == INSERT ? "INSERT" :
- X undop->u_opcode == DELETE ? "DELETE" :
- X undop->u_opcode == RAISE ? "RAISE" :
- X undop->u_opcode == DROP ? "DROP" :
- X undop->u_opcode == SCRAP ? "SCRAP" : "??",
- X undop->u_line, undop->u_col,
- X undop->u_length, undop->u_last, undop->u_chain);
- X trace_log(buf, (char *) NULL);
- X }
- X# endif
- X}
- Xundo()
- X{ int undo_mod = argv[1].l_flags == F_INT ? argv[1].l_int : 0;
- X int past_mark = argv[2].l_flags == F_INT ? argv[2].l_int : 0;
- X long num = -1;
- X static int sub_undo();
- X struct undo undo_buf;
- X enum undo_state saved_undo_state = undo_state;
- X int redo = argv[3].l_flags == F_INT;
- X undo_info *up = redo ? &curbp->b_redo : &curbp->b_undo;
- Xtrace_log(redo ? "doing redo\n" : "doing undo\n", (char *) NULL);
- X if (up->u_last == 0 && past_mark) {
- X up->u_last = up->u_last1;
- X up->u_last1 = 0;
- X }
- X undo_state = redo ? REDO : UNDO;
- X do {
- X if (sub_undo(&undo_buf, redo, up)) {
- X undo_state = NORMAL;
- X return;
- X }
- X if (num < 0 && undo_buf.u_chain > 2)
- X ewprintf("Undoing command...");
- X if (num < 0)
- X num = undo_buf.u_chain;
- X else if (num && undo_buf.u_chain)
- X percentage(num - undo_buf.u_chain, num, "Undoing", "command");
- X if (undo_mod &&
- X (undo_buf.u_opcode != INSERT &&
- X undo_buf.u_opcode != DELETE))
- X undo_buf.u_chain = 1;
- X }
- X while (undo_buf.u_chain);
- X undo_state = saved_undo_state;
- X if (!undoing_scrap)
- X ewprintf(redo ? "Redone." : "Undone.");
- X return;
- X}
- Xstatic
- Xsub_undo(undop, redo, up)
- Xstruct undo *undop;
- Xundo_info *up;
- X{ long pos;
- X char buf[64];
- X int n;
- X
- X if (up->u_last == 0) {
- X ewprintf("Nothing to %s.", redo ? "redo" : "undo");
- X curbp->b_flag &= ~BFCHG;
- X return -1;
- X }
- X if (read_last_undo(undop, up))
- X return -1;
- X u_debug(undop, "UNDOING");
- X up->u_last = undop->u_last;
- X up->u_last1 = undop->u_last1;
- X switch (undop->u_opcode) {
- X case INSERT:
- SHAR_EOF
- echo "End of part 10"
- echo "File ./undo.c is continued in part 11"
- echo "11" > s2_seq_.tmp
- exit 0
- --
- ===================== Reuters Ltd PLC,
- Tel: +44 628 891313 x. 212 Westthorpe House,
- UUCP: fox%marlow.uucp@idec.stc.co.uk Little Marlow,
- Bucks, England SL7 3RQ
-
-