/* * 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. */ 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)); }
/* * set_opt -- * Send a set-edit-option message to core. */ static void set_opt(Widget w, XtPointer closure, XtPointer call_data) { optData *opt; Boolean set; IP_BUF ipb; String str; extern IPVI ipvi_motif; opt = closure; ipb.code = VI_EDITOPT; ipb.str1 = opt->name; ipb.len1 = strlen(opt->name); switch (opt->kind) { case optToggle: XtVaGetValues(w, XmNset, &set, 0); ipb.val1 = set; ipb.len2 = 0; vi_wsend(&ipvi_motif, "ab1", &ipb); if (ipb.val1) { opt->value = (void *)!set; /* * RAZ: * How do we turn off the button? We don't want to * go recursive where we set it and it calls set_opt * to tell the core. Is that possible? */ XtVaSetValues(w, XmNset, &set, 0); break; } if (strcmp(opt->name, "ruler") == 0) if (set) __vi_show_text_ruler_dialog( __vi_screen->area, "Ruler"); else __vi_clear_text_ruler_dialog(); break; case optInteger: str = XmTextFieldGetString(w); ipb.val1 = atoi(str); ipb.len2 = 0; vi_send(vi_ofd, "ab1", &ipb); break; case optFile: case optString: ipb.str2 = XmTextFieldGetString(w); ipb.len2 = strlen(ipb.str2); vi_send(vi_ofd, "ab1", &ipb); break; case optTerminator: abort(); } }
/* * 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. */ 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_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 */ if (IS_VSPLIT(sp)) { size_t x, y, spcnt; IP_PRIVATE *ipp; int error; ipp = IPP(sp); 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)); }
static void * run_editor(void * vp) { GS *gp; IP_PRIVATE *ipp; WIN *wp; EVENT ev; int rval; IP_BUF ipb; wp = (WIN *) vp; gp = wp->gp; ipp = wp->ip_private; /* Add the terminal type to the global structure. */ if ((OG_D_STR(gp, GO_TERM) = OG_STR(gp, GO_TERM) = strdup("ip_curses")) == NULL) perr(gp->progname, NULL); /* * Figure out how big the screen is -- read events until we get * the rows and columns. */ for (;;) { if (ip_wevent(wp, NULL, &ev, 0, 0)) return; if (ev.e_event == E_WRESIZE) break; if (ev.e_event == E_EOF || ev.e_event == E_ERR || ev.e_event == E_SIGHUP || ev.e_event == E_SIGTERM) return; if (ev.e_event == E_IPCOMMAND && ev.e_ipcom == VI_QUIT) return; } /* Run ex/vi. */ rval = editor(wp, ipp->argc, ipp->argv); /* Clean up the screen. */ (void)ip_quit(wp); /* Send the quit message. */ ipb.code = SI_QUIT; (void)vi_send(ipp->o_fd, NULL, &ipb); /* Give the screen a couple of seconds to deal with it. */ sleep(2); /* Remove window; correct place ? */ win_end(wp); #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY) free(ipp); #endif return NULL; }
/* * 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); ipb.code = SI_INSERTLN; return (vi_send(ipp->o_fd, NULL, &ipb)); }
/* * 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); ipb.code = SI_BELL; 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); 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); 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_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... */ 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_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); 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_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; ipb.code = SI_MOVE; ipb.val1 = RLNO(sp, lno); ipb.val2 = RCNO(sp, cno); return (vi_send(ipp->o_fd, "12", &ipb)); }
/* * 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); 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_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 iv, rval; ipp = IPP(sp); ipb.code = SI_WADDSTR; ipb.len1 = len * sizeof(CHAR_T); ipb.str1 = (char *)str; rval = vi_send(ipp->o_fd, "a", &ipb); /* XXXX */ ipp->col += len; return (rval); }
/* * vi_wsend -- * Construct and send an IP buffer, and wait for an answer. * * PUBLIC: int vi_wsend __P((IPVIWIN*, char *, IP_BUF *)); */ int vi_wsend(IPVIWIN *ipviwin, char *fmt, IP_BUF *ipbp) { fd_set rdfd; ssize_t nr; if (vi_send(ipviwin->ofd, fmt, ipbp)) return (1); FD_ZERO(&rdfd); ipbp->code = CODE_OOB; for (;;) { FD_SET(ipviwin->ifd, &rdfd); if (select(ipviwin->ifd + 1, &rdfd, NULL, NULL, NULL) != 0) return (-1); /* Read waiting vi messages and translate to X calls. */ switch (nr = read(ipviwin->ifd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) { case 0: return (0); case -1: return (-1); default: break; } ibuf_len += nr; /* Parse to data end or partial message. */ (void)vi_translate(ipviwin, ibuf, &ibuf_len, ipbp); if (ipbp->code != CODE_OOB) break; } return (0); }