/* $NetBSD: ip_funcs.c,v 1.5 2018/08/07 08:05:47 rin Exp $ */ /*- * Copyright (c) 1996 * Keith Bostic. All rights reserved. * * See the LICENSE file for redistribution information. */ #include "config.h" #include #if 0 #ifndef lint static const char sccsid[] = "Id: ip_funcs.c,v 8.23 2001/06/25 15:19:23 skimo Exp (Berkeley) Date: 2001/06/25 15:19:23 "; #endif /* not lint */ #else __RCSID("$NetBSD: ip_funcs.c,v 1.5 2018/08/07 08:05:47 rin Exp $"); #endif #include #include #include #include #include #include #include #include #include "../common/common.h" #include "../vi/vi.h" #include "../ipc/ip.h" /* * ip_addstr -- * Add len bytes from the string at the cursor, advancing the cursor. * * PUBLIC: int ip_waddstr __P((SCR *, const CHAR_T *, size_t)); */ int ip_waddstr(SCR *sp, const CHAR_T *str, size_t len) { IP_BUF ipb; IP_PRIVATE *ipp; int rval; ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_WADDSTR; ipb.len1 = len * sizeof(CHAR_T); ipb.str1 = __UNCONST(str); rval = vi_send(ipp->o_fd, "a", &ipb); /* XXXX */ ipp->col += len; return (rval); } /* * 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(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. */ memset(&ipb, 0, sizeof(ipb)); 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 = SI_ADDSTR; ipb.len1 = len; ipb.str1 = str; rval = vi_send(ipp->o_fd, "a", &ipb); /* XXXX */ ipp->col += len; 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(SCR *sp, scr_attr_t attribute, int on) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); if (attribute == SA_ALTERNATE) { if (on) F_SET(ipp, IP_ON_ALTERNATE); else F_CLR(ipp, IP_ON_ALTERNATE); } ipb.code = SI_ATTRIBUTE; ipb.val1 = attribute; ipb.val2 = on; return (vi_send(ipp->o_fd, "12", &ipb)); } /* * ip_baud -- * Return the baud rate. * * PUBLIC: int ip_baud __P((SCR *, u_long *)); */ int ip_baud(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(SCR *sp) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_BELL; return (vi_send(ipp->o_fd, NULL, &ipb)); } /* * ip_busy -- * Display a busy message. * * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t)); */ void ip_busy(SCR *sp, const char *str, busy_t bval) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); switch (bval) { case BUSY_ON: ipb.code = SI_BUSY_ON; ipb.str1 = str; ipb.len1 = strlen(str); (void)vi_send(ipp->o_fd, "a", &ipb); break; case BUSY_OFF: ipb.code = SI_BUSY_OFF; (void)vi_send(ipp->o_fd, NULL, &ipb); break; case BUSY_UPDATE: break; } return; } /* * ip_child -- * Prepare child. * * PUBLIC: int ip_child __P((SCR *)); */ int ip_child(SCR *sp) { IP_PRIVATE *ipp = IPP(sp); if (ipp->t_fd != -1) { dup2(ipp->t_fd, 0); dup2(ipp->t_fd, 1); dup2(ipp->t_fd, 2); close(ipp->t_fd); } return 0; } /* * ip_clrtoeol -- * Clear from the current cursor to the end of the line. * * PUBLIC: int ip_clrtoeol __P((SCR *)); */ int ip_clrtoeol(SCR *sp) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); /* Temporary hack until we can pass screen pointers * or name screens */ memset(&ipb, 0, sizeof(ipb)); if (IS_VSPLIT(sp)) { size_t x, y, spcnt; int error; y = ipp->row; x = ipp->col; error = 0; for (spcnt = sp->cols - x; spcnt > 0 && ! error; --spcnt) error = ip_addstr(sp, " ", 1); if (sp->coff == 0) error |= ip_addstr(sp, "|", 1); error |= ip_move(sp, y, x); return error; } ipb.code = SI_CLRTOEOL; return (vi_send(ipp->o_fd, NULL, &ipb)); } /* * ip_cursor -- * Return the current cursor position. * * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *)); */ int ip_cursor(SCR *sp, size_t *yp, size_t *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(SCR *sp) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); /* * 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. */ memset(&ipb, 0, sizeof(ipb)); if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) { ipb.code = SI_REWRITE; ipb.val1 = RLNO(sp, LASTLINE(sp)); if (vi_send(ipp->o_fd, "1", &ipb)) return (1); } /* * The bottom line is expected to be blank after this operation, * and other screens must support that semantic. */ ipb.code = SI_DELETELN; return (vi_send(ipp->o_fd, NULL, &ipb)); } /* * ip_discard -- * Discard a screen. * * PUBLIC: int ip_discard __P((SCR *, SCR **)); */ int ip_discard(SCR *discardp, SCR **acquirep) { return (0); } /* * ip_ex_adjust -- * Adjust the screen for ex. * * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t)); */ int ip_ex_adjust(SCR *sp, exadj_t action) { abort(); /* NOTREACHED */ } #ifdef IMCTRL /* * ip_imctrl -- * XXX not implemented yet. * * PUBLIC: #ifdef IMCTRL * PUBLIC: void ip_imctrl __P((SCR *, imctrl_t)); * PUBLIC: #endif */ void ip_imctrl(SCR *sp, imctrl_t action) { return; } #endif /* * ip_insertln -- * Push down the current line, discarding the bottom line. * * PUBLIC: int ip_insertln __P((SCR *)); */ int ip_insertln(SCR *sp) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_INSERTLN; return (vi_send(ipp->o_fd, 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(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(SCR *sp, size_t lno, size_t cno) { IP_PRIVATE *ipp; IP_BUF ipb; ipp = IPP(sp); ipp->row = lno; ipp->col = cno; memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_MOVE; ipb.val1 = RLNO(sp, lno); ipb.val2 = RCNO(sp, cno); return (vi_send(ipp->o_fd, "12", &ipb)); } /* * PUBLIC: void ip_msg __P((SCR *, mtype_t, char *, size_t)); */ void ip_msg(SCR *sp, mtype_t mtype, char *line, size_t len) { IP_PRIVATE *ipp = IPP(sp); if (F_ISSET(ipp, IP_ON_ALTERNATE)) vs_msg(sp, mtype, line, len); else { write(ipp->t_fd, line, len); F_CLR(sp, SC_EX_WAIT_NO); } } /* * ip_refresh -- * Refresh the screen. * * PUBLIC: int ip_refresh __P((SCR *, int)); */ int ip_refresh(SCR *sp, int repaint) { IP_BUF ipb; IP_PRIVATE *ipp; db_recno_t total; ipp = IPP(sp); /* * If the scroll bar information has changed since we last sent * it, resend it. Currently, we send three values: * * top The line number of the first line in the screen. * num The number of lines visible on the screen. * total The number of lines in the file. * * XXX * This is a gross violation of layering... we're looking at data * structures at which we have absolutely no business whatsoever * looking... */ memset(&ipb, 0, sizeof(ipb)); ipb.val1 = HMAP->lno; ipb.val2 = TMAP->lno - HMAP->lno; if (sp->ep != NULL && sp->ep->db != NULL) (void)db_last(sp, &total); ipb.val3 = total == 0 ? 1 : total; if (ipb.val1 != ipp->sb_top || ipb.val2 != ipp->sb_num || ipb.val3 != ipp->sb_total) { ipb.code = SI_SCROLLBAR; (void)vi_send(ipp->o_fd, "123", &ipb); ipp->sb_top = ipb.val1; ipp->sb_num = ipb.val2; ipp->sb_total = ipb.val3; } /* Refresh/repaint the screen. */ ipb.code = repaint ? SI_REDRAW : SI_REFRESH; return (vi_send(ipp->o_fd, NULL, &ipb)); } /* * ip_rename -- * Rename the file. * * PUBLIC: int ip_rename __P((SCR *, char *, int)); */ int ip_rename(SCR *sp, char *name, int on) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_RENAME; ipb.str1 = name; ipb.len1 = name ? strlen(name) : 0; return (vi_send(ipp->o_fd, "a", &ipb)); } /* * ip_reply -- * Reply to a message. * * PUBLIC: int ip_reply __P((SCR *, int, char *)); */ int ip_reply(SCR *sp, int status, char *msg) { IP_BUF ipb; IP_PRIVATE *ipp = IPP(sp); memset(&ipb, 0, sizeof(ipb)); ipb.code = SI_REPLY; ipb.val1 = status; ipb.str1 = msg == NULL ? "" : msg; ipb.len1 = strlen(ipb.str1); return (vi_send(ipp->o_fd, "1a", &ipb)); } /* * ip_split -- * Split a screen. * * PUBLIC: int ip_split __P((SCR *, SCR *)); */ int ip_split(SCR *origp, SCR *newp) { return (0); } /* * ip_suspend -- * Suspend a screen. * * PUBLIC: int ip_suspend __P((SCR *, int *)); */ int ip_suspend(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(void) { #define USAGE "\ usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n" (void)fprintf(stderr, "%s", USAGE); #undef USAGE }