Exemplo n.º 1
0
/* Move cursor to absolute position. */
void
tty_cursor(struct tty *tty, u_int cx, u_int cy)
{
	struct tty_term	*term = tty->term;
	u_int		 thisx, thisy;
	int		 change;

	if (cx > tty->sx - 1)
		cx = tty->sx - 1;

	thisx = tty->cx;
	thisy = tty->cy;

	/* No change. */
	if (cx == thisx && cy == thisy)
		return;

	/* Very end of the line, just use absolute movement. */
	if (thisx > tty->sx - 1)
		goto absolute;

	/* Move to home position (0, 0). */
	if (cx == 0 && cy == 0 && tty_term_has(term, TTYC_HOME)) {
		tty_putcode(tty, TTYC_HOME);
		goto out;
	}

	/* Zero on the next line. */
	if (cx == 0 && cy == thisy + 1 && thisy != tty->rlower) {
		tty_putc(tty, '\r');
		tty_putc(tty, '\n');
		goto out;
	}

	/* Moving column or row. */
	if (cy == thisy) {
		/*
		 * Moving column only, row staying the same.
		 */

		/* To left edge. */
		if (cx == 0)	{
			tty_putc(tty, '\r');
			goto out;
		}

		/* One to the left. */
		if (cx == thisx - 1 && tty_term_has(term, TTYC_CUB1)) {
			tty_putcode(tty, TTYC_CUB1);
			goto out;
		}

		/* One to the right. */
		if (cx == thisx + 1 && tty_term_has(term, TTYC_CUF1)) {
			tty_putcode(tty, TTYC_CUF1);
			goto out;
		}

		/* Calculate difference. */
		change = thisx - cx;	/* +ve left, -ve right */

		/*
		 * Use HPA if change is larger than absolute, otherwise move
		 * the cursor with CUB/CUF.
		 */
		if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) {
			tty_putcode1(tty, TTYC_HPA, cx);
			goto out;
		} else if (change > 0 && tty_term_has(term, TTYC_CUB)) {
			tty_putcode1(tty, TTYC_CUB, change);
			goto out;
		} else if (change < 0 && tty_term_has(term, TTYC_CUF)) {
			tty_putcode1(tty, TTYC_CUF, -change);
			goto out;
		}
	} else if (cx == thisx) {
		/*
		 * Moving row only, column staying the same.
		 */

		/* One above. */
		if (thisy != tty->rupper &&
		    cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) {
			tty_putcode(tty, TTYC_CUU1);
			goto out;
		}

		/* One below. */
		if (thisy != tty->rlower &&
		    cy == thisy + 1 && tty_term_has(term, TTYC_CUD1)) {
			tty_putcode(tty, TTYC_CUD1);
			goto out;
		}

		/* Calculate difference. */
		change = thisy - cy;	/* +ve up, -ve down */

		/*
		 * Try to use VPA if change is larger than absolute or if this
		 * change would cross the scroll region, otherwise use CUU/CUD.
		 */
		if ((u_int) abs(change) > cy ||
		    (change < 0 && cy - change > tty->rlower) ||
		    (change > 0 && cy - change < tty->rupper)) {
			    if (tty_term_has(term, TTYC_VPA)) {
				    tty_putcode1(tty, TTYC_VPA, cy);
				    goto out;
			    }
		} else if (change > 0 && tty_term_has(term, TTYC_CUU)) {
			tty_putcode1(tty, TTYC_CUU, change);
			goto out;
		} else if (change < 0 && tty_term_has(term, TTYC_CUD)) {
			tty_putcode1(tty, TTYC_CUD, -change);
			goto out;
		}
	}

absolute:
	/* Absolute movement. */
	tty_putcode2(tty, TTYC_CUP, cy, cx);

out:
	tty->cx = cx;
	tty->cy = cy;
}
Exemplo n.º 2
0
void
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
{
	const struct grid_cell	*gc;
	struct grid_line	*gl;
	struct grid_cell	 tmpgc;
	const struct grid_utf8	*gu;
	u_int			 i, sx;

	tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);

	sx = screen_size_x(s);
	if (sx > s->grid->linedata[s->grid->hsize + py].cellsize)
		sx = s->grid->linedata[s->grid->hsize + py].cellsize;
	if (sx > tty->sx)
		sx = tty->sx;

	/*
	 * Don't move the cursor to the start permission if it will wrap there
	 * itself.
	 */
	gl = NULL;
	if (py != 0)
		gl = &s->grid->linedata[s->grid->hsize + py - 1];
	if (oy + py == 0 || gl == NULL || !(gl->flags & GRID_LINE_WRAPPED) ||
	    tty->cx < tty->sx || ox != 0 ||
	    (oy + py != tty->cy + 1 && tty->cy != s->rlower + oy))
		tty_cursor(tty, ox, oy + py);

	for (i = 0; i < sx; i++) {
		gc = grid_view_peek_cell(s->grid, i, py);

		gu = NULL;
		if (gc->flags & GRID_FLAG_UTF8)
			gu = grid_view_peek_utf8(s->grid, i, py);

		if (screen_check_selection(s, i, py)) {
			memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
			tmpgc.data = gc->data;
			tmpgc.flags = gc->flags &
			    ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
			tmpgc.flags |= s->sel.cell.flags &
			    (GRID_FLAG_FG256|GRID_FLAG_BG256);
			tty_cell(tty, &tmpgc, gu);
		} else
			tty_cell(tty, gc, gu);
	}

	if (sx >= tty->sx) {
		tty_update_mode(tty, tty->mode, s);
		return;
	}
	tty_reset(tty);

	tty_cursor(tty, ox + sx, oy + py);
	if (screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL))
		tty_putcode(tty, TTYC_EL);
	else {
		for (i = sx; i < screen_size_x(s); i++)
			tty_putc(tty, ' ');
	}
	tty_update_mode(tty, tty->mode, s);
}
Exemplo n.º 3
0
void
tty_attributes(struct tty *tty, const struct grid_cell *gc)
{
	struct grid_cell	*tc = &tty->cell, gc2;
	u_char			 changed;

	memcpy(&gc2, gc, sizeof gc2);

	/*
	 * If no setab, try to use the reverse attribute as a best-effort for a
	 * non-default background. This is a bit of a hack but it doesn't do
	 * any serious harm and makes a couple of applications happier.
	 */
	if (!tty_term_has(tty->term, TTYC_SETAB)) {
		if (gc2.attr & GRID_ATTR_REVERSE) {
			if (gc2.fg != 7 && gc2.fg != 8)
				gc2.attr &= ~GRID_ATTR_REVERSE;
		} else {
			if (gc2.bg != 0 && gc2.bg != 8)
				gc2.attr |= GRID_ATTR_REVERSE;
		}
	}

	/* Fix up the colours if necessary. */
	tty_check_fg(tty, &gc2);
	tty_check_bg(tty, &gc2);

	/* If any bits are being cleared, reset everything. */
	if (tc->attr & ~gc2.attr)
		tty_reset(tty);

	/*
	 * Set the colours. This may call tty_reset() (so it comes next) and
	 * may add to (NOT remove) the desired attributes by changing new_attr.
	 */
	tty_colours(tty, &gc2);

	/* Filter out attribute bits already set. */
	changed = gc2.attr & ~tc->attr;
	tc->attr = gc2.attr;

	/* Set the attributes. */
	if (changed & GRID_ATTR_BRIGHT)
		tty_putcode(tty, TTYC_BOLD);
	if (changed & GRID_ATTR_DIM)
		tty_putcode(tty, TTYC_DIM);
	if (changed & GRID_ATTR_ITALICS)
	{
		if (tty_term_has(tty->term, TTYC_SITM))
			tty_putcode(tty, TTYC_SITM);
		else
			tty_putcode(tty, TTYC_SMSO);
	}
	if (changed & GRID_ATTR_UNDERSCORE)
		tty_putcode(tty, TTYC_SMUL);
	if (changed & GRID_ATTR_BLINK)
		tty_putcode(tty, TTYC_BLINK);
	if (changed & GRID_ATTR_REVERSE) {
		if (tty_term_has(tty->term, TTYC_REV))
			tty_putcode(tty, TTYC_REV);
		else if (tty_term_has(tty->term, TTYC_SMSO))
			tty_putcode(tty, TTYC_SMSO);
	}
	if (changed & GRID_ATTR_HIDDEN)
		tty_putcode(tty, TTYC_INVIS);
	if ((changed & GRID_ATTR_CHARSET) && tty_use_acs(tty))
		tty_putcode(tty, TTYC_SMACS);
}
Exemplo n.º 4
0
void
tty_colours(struct tty *tty, const struct grid_cell *gc)
{
	struct grid_cell	*tc = &tty->cell;
	u_char			 fg = gc->fg, bg = gc->bg, flags = gc->flags;
	int			 have_ax, fg_default, bg_default;

	/* No changes? Nothing is necessary. */
	if (fg == tc->fg && bg == tc->bg &&
	    ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0)
		return;

	/*
	 * Is either the default colour? This is handled specially because the
	 * best solution might be to reset both colours to default, in which
	 * case if only one is default need to fall onward to set the other
	 * colour.
	 */
	fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256));
	bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256));
	if (fg_default || bg_default) {
		/*
		 * If don't have AX but do have op, send sgr0 (op can't
		 * actually be used because it is sometimes the same as sgr0
		 * and sometimes isn't). This resets both colours to default.
		 *
		 * Otherwise, try to set the default colour only as needed.
		 */
		have_ax = tty_term_has(tty->term, TTYC_AX);
		if (!have_ax && tty_term_has(tty->term, TTYC_OP))
			tty_reset(tty);
		else {
			if (fg_default &&
			    (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
				if (have_ax)
					tty_puts(tty, "\033[39m");
				else if (tc->fg != 7 ||
				    tc->flags & GRID_FLAG_FG256)
					tty_putcode1(tty, TTYC_SETAF, 7);
				tc->fg = 8;
				tc->flags &= ~GRID_FLAG_FG256;
			}
			if (bg_default &&
			    (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) {
				if (have_ax)
					tty_puts(tty, "\033[49m");
				else if (tc->bg != 0 ||
				    tc->flags & GRID_FLAG_BG256)
					tty_putcode1(tty, TTYC_SETAB, 0);
				tc->bg = 8;
				tc->flags &= ~GRID_FLAG_BG256;
			}
		}
	}

	/* Set the foreground colour. */
	if (!fg_default && (fg != tc->fg ||
	    ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256))))
		tty_colours_fg(tty, gc);

	/*
	 * Set the background colour. This must come after the foreground as
	 * tty_colour_fg() can call tty_reset().
	 */
	if (!bg_default && (bg != tc->bg ||
	    ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256))))
		tty_colours_bg(tty, gc);
}
Exemplo n.º 5
0
Arquivo: tty.c Projeto: UNGLinux/Obase
void
tty_update_mode(struct tty *tty, int mode, struct screen *s)
{
	int	changed;

	if (strcmp(s->ccolour, tty->ccolour))
		tty_force_cursor_colour(tty, s->ccolour);

	if (tty->flags & TTY_NOCURSOR)
		mode &= ~MODE_CURSOR;

	changed = mode ^ tty->mode;
	if (changed & MODE_CURSOR) {
		if (mode & MODE_CURSOR)
			tty_putcode(tty, TTYC_CNORM);
		else
			tty_putcode(tty, TTYC_CIVIS);
	}
	if (tty->cstyle != s->cstyle) {
		if (tty_term_has(tty->term, TTYC_CS1)) {
			if (s->cstyle == 0 &&
			    tty_term_has(tty->term, TTYC_CSR1))
				tty_putcode(tty, TTYC_CSR1);
			else
				tty_putcode1(tty, TTYC_CS1, s->cstyle);
		}
		tty->cstyle = s->cstyle;
	}
	if (changed & ALL_MOUSE_MODES) {
		if (mode & ALL_MOUSE_MODES) {
			if (mode & MODE_MOUSE_UTF8)
				tty_puts(tty, "\033[?1005h");
			if (mode & MODE_MOUSE_ANY)
				tty_puts(tty, "\033[?1003h");
			else if (mode & MODE_MOUSE_BUTTON)
				tty_puts(tty, "\033[?1002h");
			else if (mode & MODE_MOUSE_STANDARD)
				tty_puts(tty, "\033[?1000h");
		} else {
			if (tty->mode & MODE_MOUSE_ANY)
				tty_puts(tty, "\033[?1003l");
			else if (tty->mode & MODE_MOUSE_BUTTON)
				tty_puts(tty, "\033[?1002l");
			else if (tty->mode & MODE_MOUSE_STANDARD)
				tty_puts(tty, "\033[?1000l");
			if (tty->mode & MODE_MOUSE_UTF8)
				tty_puts(tty, "\033[?1005l");
		}
	}
	if (changed & MODE_KKEYPAD) {
		if (mode & MODE_KKEYPAD)
			tty_putcode(tty, TTYC_SMKX);
		else
			tty_putcode(tty, TTYC_RMKX);
	}
	if (changed & MODE_BRACKETPASTE) {
		if (mode & MODE_BRACKETPASTE)
			tty_puts(tty, "\033[?2004h");
		else
			tty_puts(tty, "\033[?2004l");
	}
	tty->mode = mode;
}