コード例 #1
0
ファイル: check_line.c プロジェクト: xaphiriron/beyond
END_TEST

START_TEST (test_line_flip) {
  line_coordsAtT (j, -1.1, &f.x, &f.y);
  line_coordsAtT (j, 4.3, &g.x, &g.y);
  line_resize (j, 4.3, -1.1);
  line_coordsAtT (j, 0, &h.x, &h.y);
  line_coordsAtT (j, 1, &i.x, &i.y);
  fail_unless (
    vector_cmp (&f, &i) == true &&
    vector_cmp (&g, &h) == true,
    "A new t-0 that is smaller than the t-1 is allowed, and should flip the line's direction as well as changing its length."
  );
}
コード例 #2
0
ファイル: check_line.c プロジェクト: xaphiriron/beyond
END_TEST

START_TEST (test_line_shrink) {
  line_coordsAtT (j, 0, &f.x, &f.y);
  line_coordsAtT (j, 1, &g.x, &g.y);
  fail_unless (
    line_resize (j, 5, 5) == false,
    "The same t-value is not allowed as both the t-0 point and the t-1 point."
  );
  line_coordsAtT (j, 0, &h.x, &h.y);
  line_coordsAtT (j, 1, &i.x, &i.y);
  fail_unless (
    vector_cmp (&f, &h) == true &&
    vector_cmp (&g, &i) == true,
    "An invalid resize attempt cannot alter the line's dimensions"
  );
}
コード例 #3
0
ファイル: tsm_screen.c プロジェクト: carld/libtsm
SHL_EXPORT
int tsm_screen_resize(struct tsm_screen *con, unsigned int x,
		      unsigned int y)
{
	struct line **cache;
	unsigned int i, j, width, diff, start;
	int ret;
	bool *tab_ruler;

	if (!con || !x || !y)
		return -EINVAL;

	if (con->size_x == x && con->size_y == y)
		return 0;

	/* First make sure the line buffer is big enough for our new screen.
	 * That is, allocate all new lines and make sure each line has enough
	 * cells to hold the new screen or the current screen. If we fail, we
	 * can safely return -ENOMEM and the buffer is still valid. We must
	 * allocate the new lines to at least the same size as the current
	 * lines. Otherwise, if this function fails in later turns, we will have
	 * invalid lines in the buffer. */
	if (y > con->line_num) {
		/* resize main buffer */
		cache = realloc(con->main_lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		if (con->lines == con->main_lines)
			con->lines = cache;
		con->main_lines = cache;

		/* resize alt buffer */
		cache = realloc(con->alt_lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		if (con->lines == con->alt_lines)
			con->lines = cache;
		con->alt_lines = cache;

		/* allocate new lines */
		if (x > con->size_x)
			width = x;
		else
			width = con->size_x;

		while (con->line_num < y) {
			ret = line_new(con, &con->main_lines[con->line_num],
				       width);
			if (ret)
				return ret;

			ret = line_new(con, &con->alt_lines[con->line_num],
				       width);
			if (ret) {
				line_free(con->main_lines[con->line_num]);
				return ret;
			}

			++con->line_num;
		}
	}

	/* Resize all lines in the buffer if we increase screen width. This
	 * will guarantee that all lines are big enough so we can resize the
	 * buffer without reallocating them later. */
	if (x > con->size_x) {
		tab_ruler = realloc(con->tab_ruler, sizeof(bool) * x);
		if (!tab_ruler)
			return -ENOMEM;
		con->tab_ruler = tab_ruler;

		for (i = 0; i < con->line_num; ++i) {
			ret = line_resize(con, con->main_lines[i], x);
			if (ret)
				return ret;

			ret = line_resize(con, con->alt_lines[i], x);
			if (ret)
				return ret;
		}
	}

	screen_inc_age(con);

	/* clear expansion/padding area */
	start = x;
	if (x > con->size_x)
		start = con->size_x;
	for (j = 0; j < con->line_num; ++j) {
		/* main-lines may go into SB, so clear all cells */
		i = 0;
		if (j < con->size_y)
			i = start;

		for ( ; i < con->main_lines[j]->size; ++i)
			screen_cell_init(con, &con->main_lines[j]->cells[i]);

		/* alt-lines never go into SB, only clear visible cells */
		i = 0;
		if (j < con->size_y)
			i = con->size_x;

		for ( ; i < x; ++i)
			screen_cell_init(con, &con->alt_lines[j]->cells[i]);
	}

	/* xterm destroys margins on resize, so do we */
	con->margin_top = 0;
	con->margin_bottom = con->size_y - 1;

	/* reset tabs */
	for (i = 0; i < x; ++i) {
		if (i % 8 == 0)
			con->tab_ruler[i] = true;
		else
			con->tab_ruler[i] = false;
	}

	/* We need to adjust x-size first as screen_scroll_up() and friends may
	 * have to reallocate lines. The y-size is adjusted after them to avoid
	 * missing lines when shrinking y-size.
	 * We need to carefully look for the functions that we call here as they
	 * have stronger invariants as when called normally. */

	con->size_x = x;
	if (con->cursor_x >= con->size_x)
		move_cursor(con, con->size_x - 1, con->cursor_y);

	/* scroll buffer if screen height shrinks */
	if (y < con->size_y) {
		diff = con->size_y - y;
		screen_scroll_up(con, diff);
		if (con->cursor_y > diff)
			move_cursor(con, con->cursor_x, con->cursor_y - diff);
		else
			move_cursor(con, con->cursor_x, 0);
	}

	con->size_y = y;
	con->margin_bottom = con->size_y - 1;
	if (con->cursor_y >= con->size_y)
		move_cursor(con, con->cursor_x, con->size_y - 1);

	return 0;
}
コード例 #4
0
ファイル: tsm_screen.c プロジェクト: keszybz/kmscon
int tsm_screen_resize(struct tsm_screen *con, unsigned int x,
			  unsigned int y)
{
	struct line **cache;
	unsigned int i, j, width, diff;
	int ret;
	bool *tab_ruler;

	if (!con || !x || !y)
		return -EINVAL;

	if (con->size_x == x && con->size_y == y)
		return 0;

	/* First make sure the line buffer is big enough for our new screen.
	 * That is, allocate all new lines and make sure each line has enough
	 * cells to hold the new screen or the current screen. If we fail, we
	 * can safely return -ENOMEM and the buffer is still valid. We must
	 * allocate the new lines to at least the same size as the current
	 * lines. Otherwise, if this function fails in later turns, we will have
	 * invalid lines in the buffer. */
	if (y > con->line_num) {
		cache = realloc(con->lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		con->lines = cache;
		if (x > con->size_x)
			width = x;
		else
			width = con->size_x;

		while (con->line_num < y) {
			ret = line_new(con, &cache[con->line_num], width);
			if (ret)
				return ret;
			++con->line_num;
		}
	}

	/* Resize all lines in the buffer if we increase screen width. This
	 * will guarantee that all lines are big enough so we can resize the
	 * buffer without reallocating them later. */
	if (x > con->size_x) {
		tab_ruler = realloc(con->tab_ruler, sizeof(bool) * x);
		if (!tab_ruler)
			return -ENOMEM;
		con->tab_ruler = tab_ruler;

		for (i = 0; i < con->line_num; ++i) {
			ret = line_resize(con, con->lines[i], x);
			if (ret)
				return ret;
		}
	}

	/* When resizing, we need to reset all the new cells, otherwise, the old
	 * data that was written there will reoccur on the screen.
	 * TODO: we overwrite way to much here; most of it should already be
	 * cleaned. Maybe it does more sense cleaning when _allocating_ or when
	 * _shrinking_, then we never clean twice (for performance reasons). */
	for (j = 0; j < con->line_num; ++j) {
		if (j >= con->size_y)
			i = 0;
		else
			i = con->size_x;
		if (x < con->lines[j]->size)
			width = x;
		else
			width = con->lines[j]->size;
		for (; i < width; ++i)
			cell_init(con, &con->lines[j]->cells[i]);
	}

	/* xterm destroys margins on resize, so do we */
	con->margin_top = 0;
	con->margin_bottom = con->size_y - 1;

	/* reset tabs */
	for (i = 0; i < x; ++i) {
		if (i % 8 == 0)
			con->tab_ruler[i] = true;
		else
			con->tab_ruler[i] = false;
	}

	/* We need to adjust x-size first as screen_scroll_up() and friends may
	 * have to reallocate lines. The y-size is adjusted after them to avoid
	 * missing lines when shrinking y-size.
	 * We need to carefully look for the functions that we call here as they
	 * have stronger invariants as when called normally. */

	con->size_x = x;
	if (con->cursor_x >= con->size_x)
		con->cursor_x = con->size_x - 1;

	/* scroll buffer if screen height shrinks */
	if (con->size_y != 0 && y < con->size_y) {
		diff = con->size_y - y;
		screen_scroll_up(con, diff);
		if (con->cursor_y > diff)
			con->cursor_y -= diff;
		else
			con->cursor_y = 0;
	}

	con->size_y = y;
	con->margin_bottom = con->size_y - 1;
	if (con->cursor_y >= con->size_y)
		con->cursor_y = con->size_y - 1;

	return 0;
}
コード例 #5
0
static void test_term_line_ops(void) {
        term_line *l;
        term_attr attr_regular = { };
        term_attr attr_bold = { .bold = true };
        term_attr attr_italic = { .italic = true };

        assert_se(term_line_new(&l) >= 0);
        line_resize(l, 8, NULL, 0);
        assert_se(l->n_cells == 8);

        LINE_ASSERT(l, "| | | | | | | | |", 0);

        term_line_write(l, 4, TERM_CHAR_NULL, 0, NULL, TERM_AGE_NULL, 0);
        LINE_ASSERT(l, "| | | | | | | | |", 5);

        term_line_write(l, 1, PACK1('A'), 1, NULL, TERM_AGE_NULL, 0);
        LINE_ASSERT(l, "| |A| | | | | | |", 5);

        term_line_write(l, 8, PACK2('A', 'B'), 1, NULL, TERM_AGE_NULL, 0);
        LINE_ASSERT(l, "| |A| | | | | | |", 5);

        term_line_write(l, 7, PACK2('A', 'B'), 1, &attr_regular, 10, 0);
        LINE_ASSERT(l, "| |A| | | | | | 10 AB |", 8);

        term_line_write(l, 7, PACK2('A', 'B'), 1, &attr_bold, 10, 0);
        LINE_ASSERT(l, "| |A| | | | | | 10 *AB* |", 8);

        term_line_reset(l, NULL, TERM_AGE_NULL);

        LINE_ASSERT(l, "|   |   |          |          |          |   |   |   |", 0);
        line_set(l, 2, "*wxyz* 8", 0);
        line_set(l, 3, "/wxyz/ 8", 0);
        LINE_ASSERT(l, "|   |   | *wxyz* 8 | /wxyz/ 8 |          |   |   |   |", 4);
        line_set(l, 2, "*abc* 9", true);
        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 9 | 9 |", 5);
        line_set(l, 7, "*abc* 10", true);
        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 9 | *abc* 10 |", 8);

        term_line_erase(l, 6, 1, NULL, 11, 0);
        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 11 | *abc* 10 |", 8);
        term_line_erase(l, 6, 2, &attr_italic, 12, 0);
        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 12 // | 12 // |", 6);
        term_line_erase(l, 7, 2, &attr_regular, 13, 0);
        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 12 // | 13 |", 6);
        term_line_delete(l, 1, 3, &attr_bold, 14);
        LINE_ASSERT(l, "|   | /wxyz/ 14 | 14 | 14 // | 14 | 14 ** | 14 ** | 14 ** |", 3);
        term_line_insert(l, 2, 2, &attr_regular, 15);
        LINE_ASSERT(l, "|   | /wxyz/ 14 | 15 | 15 | 15 | 15 // | 15 | 15 ** |", 5);

        assert_se(!term_line_free(l));
}

int main(int argc, char *argv[]) {
        test_term_char_misc();
        test_term_char_packing();
        test_term_char_allocating();

        test_term_line_misc();
        test_term_line_ops();

        return 0;
}