Example #1
0
/*
 * cl_deleteln --
 *	Delete the current line, scrolling all lines below it.
 *
 * PUBLIC: int cl_deleteln __P((SCR *));
 */
int
cl_deleteln(SCR *sp)
{
	CHAR_T ch;
	CL_PRIVATE *clp;
	WINDOW *win;
	size_t col, lno, spcnt, y, x;

	clp = CLP(sp);
	win = CLSP(sp) ? CLSP(sp) : stdscr;

	/*
	 * 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.
	 *
	 * Check for the existence of a chgat function; XSI requires it, but
	 * historic implementations of System V curses don't.   If it's not
	 * a #define, we'll fall back to doing it by hand, which is slow but
	 * acceptable.
	 *
	 * By hand means walking through the line, retrieving and rewriting
	 * each character.  Curses has no EOL marker, so track strings of
	 * spaces, and copy the trailing spaces only if there's a non-space
	 * character following.
	 */
	if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) {
		getyx(win, y, x);
#ifdef mvchgat
		mvwchgat(win, RLNO(sp, LASTLINE(sp)), 0, -1, A_NORMAL, 0, NULL);
#else
		for (lno = RLNO(sp, LASTLINE(sp)), col = spcnt = 0;;) {
			(void)wmove(win, lno, col);
			ch = winch(win);
			if (isblank(ch))
				++spcnt;
			else {
				(void)wmove(win, lno, col - spcnt);
				for (; spcnt > 0; --spcnt)
					(void)waddch(win, ' ');
				(void)waddch(win, ch);
			}
			if (++col >= sp->cols)
				break;
		}
#endif
		(void)wmove(win, y, x);
	}

	/*
	 * The bottom line is expected to be blank after this operation,
	 * and other screens must support that semantic.
	 */
	return (wdeleteln(win) == ERR);
}
Example #2
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.
	 */
	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));
}
Example #3
0
static int 
addstr4(SCR *sp, const void *str, size_t len, int wide)
{
	WINDOW *win;
	size_t y, x;
	int iv;

	win = CLSP(sp) ? CLSP(sp) : stdscr;

	/*
	 * 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;
	getyx(win, y, x);
	__USE(x);
	if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
	    y == RLNO(sp, LASTLINE(sp)) && IS_SPLIT(sp)) {
		iv = 1;
		(void)wstandout(win);
	}

#ifdef USE_WIDECHAR
	if (wide) {
	    if (waddnwstr(win, str, len) == ERR)
		return (1);
	} else 
#endif
	    if (waddnstr(win, str, len) == ERR)
		    return (1);

	if (iv)
		(void)wstandend(win);
	return (0);
}
Example #4
0
/*
 * cl_move --
 *	Move the cursor.
 *
 * PUBLIC: int cl_move __P((SCR *, size_t, size_t));
 */
int
cl_move(SCR *sp, size_t lno, size_t cno)
{
	WINDOW *win;
	win = CLSP(sp) ? CLSP(sp) : stdscr;
	/* See the comment in cl_cursor. */
	if (wmove(win, RLNO(sp, lno), RCNO(sp, cno)) == ERR) {
		msgq(sp, M_ERR, "Error: move: l(%zu + %zu) c(%zu + %zu)",
		    lno, sp->roff, cno, sp->coff);
		return (1);
	}
	return (0);
}
Example #5
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;

	ipb.code = SI_MOVE;
	ipb.val1 = RLNO(sp, lno);
	ipb.val2 = RCNO(sp, cno);
	return (vi_send(ipp->o_fd, "12", &ipb));
}
Example #6
0
/*
 * cl_screen --
 *	Switch screen types.
 *
 * PUBLIC: int cl_screen __P((SCR *, u_int32_t));
 */
int
cl_screen(SCR *sp, u_int32_t flags)
{
	CL_PRIVATE *clp;
	WINDOW *win;
	GS *gp;
	int ret, error;
	sigset_t oset;

	gp = sp->gp;
	clp = CLP(sp);
	win = CLSP(sp) ? CLSP(sp) : stdscr;

	ret = 0;

	/*
	 * During initialization of the screen, block signals to make sure that
	 * curses/terminfo routines are not interrupted.
	 */
	error = sigprocmask(SIG_BLOCK, &__sigblockset, &oset);

	/* See if the current information is incorrect. */
	if (F_ISSET(gp, G_SRESTART)) {
		if (CLSP(sp)) {
		    delwin(CLSP(sp));
		    sp->cl_private = NULL;
		}
		if (cl_quit(gp)) {
			ret = 1;
			goto end;
		}
		F_CLR(gp, G_SRESTART);
	}
	
	/* See if we're already in the right mode. */
	if ((LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX)) ||
	    (LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI)))
		goto end;

	/*
	 * Fake leaving ex mode.
	 *
	 * We don't actually exit ex or vi mode unless forced (e.g. by a window
	 * size change).  This is because many curses implementations can't be
	 * called twice in a single program.  Plus, it's faster.  If the editor
	 * "leaves" vi to enter ex, when it exits ex we'll just fall back into
	 * vi.
	 */
	if (F_ISSET(sp, SC_SCR_EX))
		F_CLR(sp, SC_SCR_EX);

	/*
	 * Fake leaving vi mode.
	 *
	 * Clear out the rest of the screen if we're in the middle of a split
	 * screen.  Move to the last line in the current screen -- this makes
	 * terminal scrolling happen naturally.  Note: *don't* move past the
	 * end of the screen, as there are ex commands (e.g., :read ! cat file)
	 * that don't want to.  Don't clear the info line, its contents may be
	 * valid, e.g. :file|append.
	 */
	if (F_ISSET(sp, SC_SCR_VI)) {
		F_CLR(sp, SC_SCR_VI);

		if (TAILQ_NEXT(sp, q) != NULL) {
			(void)wmove(win, RLNO(sp, sp->rows), 0);
			wclrtobot(win);
		}
		(void)wmove(win, RLNO(sp, sp->rows) - 1, 0);
		wrefresh(win);
	}

	/* Enter the requested mode. */
	if (LF_ISSET(SC_EX)) {
		if (cl_ex_init(sp)) {
			ret = 1;
			goto end;
		}
		F_SET(clp, CL_IN_EX | CL_SCR_EX_INIT);

		/*
		 * If doing an ex screen for ex mode, move to the last line
		 * on the screen.
		 */
		if (F_ISSET(sp, SC_EX) && clp->cup != NULL)
			tputs(tgoto(clp->cup,
			    0, O_VAL(sp, O_LINES) - 1), 1, cl_putchar);
	} else {
		if (cl_vi_init(sp)) {
			ret = 1;
			goto end;
		}
		F_CLR(clp, CL_IN_EX);
		F_SET(clp, CL_SCR_VI_INIT);
	}
end:
	/* Unblock signals. */
	if (error == 0)
		(void)sigprocmask(SIG_SETMASK, &oset, NULL);
	return ret;
}