diff options
Diffstat (limited to 'contrib/nvi/ip/ip_funcs.c')
-rw-r--r-- | contrib/nvi/ip/ip_funcs.c | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/contrib/nvi/ip/ip_funcs.c b/contrib/nvi/ip/ip_funcs.c new file mode 100644 index 0000000..c92f1ed --- /dev/null +++ b/contrib/nvi/ip/ip_funcs.c @@ -0,0 +1,443 @@ +/*- + * Copyright (c) 1996 + * Keith Bostic. All rights reserved. + * + * See the LICENSE file for redistribution information. + */ + +#include "config.h" + +#ifndef lint +static const char sccsid[] = "@(#)ip_funcs.c 8.4 (Berkeley) 10/13/96"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/time.h> + +#include <bitstring.h> +#include <stdio.h> + +#include "../common/common.h" +#include "../vi/vi.h" +#include "ip.h" + +static int ip_send __P((SCR *, char *, IP_BUF *)); + +/* + * ip_addstr -- + * Add len bytes from the string at the cursor, advancing the cursor. + * + * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t)); + */ +int +ip_addstr(sp, str, len) + SCR *sp; + const char *str; + size_t len; +{ + IP_BUF ipb; + IP_PRIVATE *ipp; + int iv, rval; + + ipp = IPP(sp); + + /* + * If ex isn't in control, it's the last line of the screen and + * it's a split screen, use inverse video. + */ + iv = 0; + if (!F_ISSET(sp, SC_SCR_EXWROTE) && + ipp->row == LASTLINE(sp) && IS_SPLIT(sp)) { + iv = 1; + ip_attr(sp, SA_INVERSE, 1); + } + ipb.code = IPO_ADDSTR; + ipb.len = len; + ipb.str = str; + rval = ip_send(sp, "s", &ipb); + + if (iv) + ip_attr(sp, SA_INVERSE, 0); + return (rval); +} + +/* + * ip_attr -- + * Toggle a screen attribute on/off. + * + * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int)); + */ +int +ip_attr(sp, attribute, on) + SCR *sp; + scr_attr_t attribute; + int on; +{ + IP_BUF ipb; + + ipb.code = IPO_ATTRIBUTE; + ipb.val1 = attribute; + ipb.val2 = on; + + return (ip_send(sp, "12", &ipb)); +} + +/* + * ip_baud -- + * Return the baud rate. + * + * PUBLIC: int ip_baud __P((SCR *, u_long *)); + */ +int +ip_baud(sp, ratep) + SCR *sp; + u_long *ratep; +{ + *ratep = 9600; /* XXX: Translation: fast. */ + return (0); +} + +/* + * ip_bell -- + * Ring the bell/flash the screen. + * + * PUBLIC: int ip_bell __P((SCR *)); + */ +int +ip_bell(sp) + SCR *sp; +{ + IP_BUF ipb; + + ipb.code = IPO_BELL; + + return (ip_send(sp, NULL, &ipb)); +} + +/* + * ip_busy -- + * Display a busy message. + * + * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t)); + */ +void +ip_busy(sp, str, bval) + SCR *sp; + const char *str; + busy_t bval; +{ + IP_BUF ipb; + + ipb.code = IPO_BUSY; + if (str == NULL) { + ipb.len = 0; + ipb.str = ""; + } else { + ipb.len = strlen(str); + ipb.str = str; + } + ipb.val1 = bval; + + (void)ip_send(sp, "s1", &ipb); +} + +/* + * ip_clrtoeol -- + * Clear from the current cursor to the end of the line. + * + * PUBLIC: int ip_clrtoeol __P((SCR *)); + */ +int +ip_clrtoeol(sp) + SCR *sp; +{ + IP_BUF ipb; + + ipb.code = IPO_CLRTOEOL; + + return (ip_send(sp, NULL, &ipb)); +} + +/* + * ip_cursor -- + * Return the current cursor position. + * + * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *)); + */ +int +ip_cursor(sp, yp, xp) + SCR *sp; + size_t *yp, *xp; +{ + IP_PRIVATE *ipp; + + ipp = IPP(sp); + *yp = ipp->row; + *xp = ipp->col; + return (0); +} + +/* + * ip_deleteln -- + * Delete the current line, scrolling all lines below it. + * + * PUBLIC: int ip_deleteln __P((SCR *)); + */ +int +ip_deleteln(sp) + SCR *sp; +{ + IP_BUF ipb; + + /* + * This clause is required because the curses screen uses reverse + * video to delimit split screens. If the screen does not do this, + * this code won't be necessary. + * + * If the bottom line was in reverse video, rewrite it in normal + * video before it's scrolled. + */ + if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) { + ipb.code = IPO_REWRITE; + ipb.val1 = RLNO(sp, LASTLINE(sp)); + if (ip_send(sp, "1", &ipb)) + return (1); + } + + /* + * The bottom line is expected to be blank after this operation, + * and other screens must support that semantic. + */ + ipb.code = IPO_DELETELN; + return (ip_send(sp, NULL, &ipb)); +} + +/* + * ip_ex_adjust -- + * Adjust the screen for ex. + * + * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t)); + */ +int +ip_ex_adjust(sp, action) + SCR *sp; + exadj_t action; +{ + abort(); + /* NOTREACHED */ +} + +/* + * ip_insertln -- + * Push down the current line, discarding the bottom line. + * + * PUBLIC: int ip_insertln __P((SCR *)); + */ +int +ip_insertln(sp) + SCR *sp; +{ + IP_BUF ipb; + + ipb.code = IPO_INSERTLN; + + return (ip_send(sp, NULL, &ipb)); +} + +/* + * ip_keyval -- + * Return the value for a special key. + * + * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *)); + */ +int +ip_keyval(sp, val, chp, dnep) + SCR *sp; + scr_keyval_t val; + CHAR_T *chp; + int *dnep; +{ + /* + * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990, + * VWERASE is a 4BSD extension. + */ + switch (val) { + case KEY_VEOF: + *dnep = '\004'; /* ^D */ + break; + case KEY_VERASE: + *dnep = '\b'; /* ^H */ + break; + case KEY_VKILL: + *dnep = '\025'; /* ^U */ + break; +#ifdef VWERASE + case KEY_VWERASE: + *dnep = '\027'; /* ^W */ + break; +#endif + default: + *dnep = 1; + break; + } + return (0); +} + +/* + * ip_move -- + * Move the cursor. + * + * PUBLIC: int ip_move __P((SCR *, size_t, size_t)); + */ +int +ip_move(sp, lno, cno) + SCR *sp; + size_t lno, cno; +{ + IP_PRIVATE *ipp; + IP_BUF ipb; + + ipp = IPP(sp); + ipp->row = lno; + ipp->col = cno; + + ipb.code = IPO_MOVE; + ipb.val1 = RLNO(sp, lno); + ipb.val2 = cno; + return (ip_send(sp, "12", &ipb)); +} + +/* + * ip_refresh -- + * Refresh the screen. + * + * PUBLIC: int ip_refresh __P((SCR *, int)); + */ +int +ip_refresh(sp, repaint) + SCR *sp; + int repaint; +{ + IP_BUF ipb; + + ipb.code = repaint ? IPO_REDRAW : IPO_REFRESH; + + return (ip_send(sp, NULL, &ipb)); +} + +/* + * ip_rename -- + * Rename the file. + * + * PUBLIC: int ip_rename __P((SCR *)); + */ +int +ip_rename(sp) + SCR *sp; +{ + IP_BUF ipb; + + ipb.code = IPO_RENAME; + ipb.len = strlen(sp->frp->name); + ipb.str = sp->frp->name; + + return (ip_send(sp, "s", &ipb)); +} + +/* + * ip_suspend -- + * Suspend a screen. + * + * PUBLIC: int ip_suspend __P((SCR *, int *)); + */ +int +ip_suspend(sp, allowedp) + SCR *sp; + int *allowedp; +{ + *allowedp = 0; + return (0); +} + +/* + * ip_usage -- + * Print out the ip usage messages. + * + * PUBLIC: void ip_usage __P((void)); + */ +void +ip_usage() +{ +#define USAGE "\ +usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n" + (void)fprintf(stderr, "%s", USAGE); +#undef USAGE +} + +/* + * ip_send -- + * Construct and send an IP buffer. + */ +static int +ip_send(sp, fmt, ipbp) + SCR *sp; + char *fmt; + IP_BUF *ipbp; +{ + IP_PRIVATE *ipp; + size_t blen, off; + u_int32_t ilen; + int nlen, n, nw, rval; + char *bp, *p; + + ipp = IPP(sp); + + GET_SPACE_RET(sp, bp, blen, 128); + + p = bp; + nlen = 0; + *p++ = ipbp->code; + nlen += IPO_CODE_LEN; + + if (fmt != NULL) + for (; *fmt != '\0'; ++fmt) + switch (*fmt) { + case '1': /* Value 1. */ + ilen = htonl(ipbp->val1); + goto value; + case '2': /* Value 2. */ + ilen = htonl(ipbp->val2); +value: nlen += IPO_INT_LEN; + off = p - bp; + ADD_SPACE_RET(sp, bp, blen, nlen); + p = bp + off; + memmove(p, &ilen, IPO_INT_LEN); + p += IPO_INT_LEN; + break; + case 's': /* String. */ + ilen = ipbp->len; /* XXX: conversion. */ + ilen = htonl(ilen); + nlen += IPO_INT_LEN + ipbp->len; + off = p - bp; + ADD_SPACE_RET(sp, bp, blen, nlen); + p = bp + off; + memmove(p, &ilen, IPO_INT_LEN); + p += IPO_INT_LEN; + memmove(p, ipbp->str, ipbp->len); + p += ipbp->len; + break; + } + + + rval = 0; + for (n = p - bp, p = bp; n > 0; n -= nw, p += nw) + if ((nw = write(ipp->o_fd, p, n)) < 0) { + rval = 1; + break; + } + + FREE_SPACE(sp, bp, blen); + + return (rval); +} |