diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2008-09-25 20:08:57 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2008-09-25 20:08:57 +0000 |
commit | efe557313aef555b415fa2ea2c9a50c4404ed788 (patch) | |
tree | 4a197ade3d901f79bc8b0b990f9756d3da7f5f01 /screen-display.c | |
parent | 9edb4d4b85a8714162817f2ae428e654e6bf1f31 (diff) | |
download | rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.tar.gz rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.tar.bz2 rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.zip |
Internal screen data rewrite for better 256 colour/UTF-8 support.
Diffstat (limited to 'screen-display.c')
-rw-r--r-- | screen-display.c | 477 |
1 files changed, 0 insertions, 477 deletions
diff --git a/screen-display.c b/screen-display.c deleted file mode 100644 index 4760d8ee..00000000 --- a/screen-display.c +++ /dev/null @@ -1,477 +0,0 @@ -/* $Id: screen-display.c,v 1.21 2008-09-09 22:16:36 nicm Exp $ */ - -/* - * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> - -#include <string.h> - -#include "tmux.h" - -/* Get a cell. */ -void -screen_display_get_cell(struct screen *s, - u_int px, u_int py, u_char *data, u_short *attr, u_char *fg, u_char *bg) -{ - screen_get_cell( - s, screen_x(s, px), screen_y(s, py), data, attr, fg, bg); -} - -/* Set a cell. */ -void -screen_display_set_cell(struct screen *s, - u_int px, u_int py, u_char data, u_short attr, u_char fg, u_char bg) -{ - screen_set_cell( - s, screen_x(s, px), screen_y(s, py), data, attr, fg, bg); -} - -/* Create a region of lines. */ -void -screen_display_make_lines(struct screen *s, u_int py, u_int ny) -{ - if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - screen_make_lines(s, screen_y(s, py), ny); - if (s->attr != 0 || s->fg != 8 || s->bg != 8) { - screen_display_fill_area( - s, 0, py, screen_size_x(s), ny, ' ', s->attr, s->fg, s->bg); - } -} - -/* Free a region of lines. */ -void -screen_display_free_lines(struct screen *s, u_int py, u_int ny) -{ - if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - screen_free_lines(s, screen_y(s, py), ny); -} - -/* Move a set of lines. */ -void -screen_display_move_lines(struct screen *s, u_int dy, u_int py, u_int ny) -{ - if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) { - SCREEN_DEBUG3(s, dy, py, ny); - return; - } - if (!screen_in_y(s, dy) || !screen_in_y(s, dy + ny - 1) || dy == py) { - SCREEN_DEBUG3(s, dy, py, ny); - return; - } - screen_move_lines(s, screen_y(s, dy), screen_y(s, py), ny); -} - -/* Fill a set of cells. */ -void -screen_display_fill_area(struct screen *s, u_int px, u_int py, - u_int nx, u_int ny, u_char data, u_short attr, u_char fg, u_char bg) -{ - if (nx == 0 || ny == 0) { - SCREEN_DEBUG4(s, px, py, nx, ny); - return; - } - if (!screen_in_x(s, px) || !screen_in_y(s, py)) { - SCREEN_DEBUG4(s, px, py, nx, ny); - return; - } - if (!screen_in_x(s, px + nx - 1) || !screen_in_y(s, py + ny - 1)) { - SCREEN_DEBUG4(s, px, py, nx, ny); - return; - } - screen_fill_area( - s, screen_x(s, px), screen_y(s, py), nx, ny, data, attr, fg, bg); -} - -/* Scroll region up. */ -void -screen_display_scroll_region_up(struct screen *s) -{ - u_int ny, sy; - - /* - * If the region is the entire screen, this is easy-peasy. Allocate - * a new line and adjust the history size. - * XXX should this be done somewhere else? - */ - if (s->rupper == 0 && s->rlower == screen_last_y(s)) { - if (s->hsize == s->hlimit) { - /* If the limit is hit, free 10% and shift up. */ - ny = s->hlimit / 10; - if (ny < 1) - ny = 1; - - sy = screen_size_y(s) + s->hsize; - screen_free_lines(s, 0, ny); - screen_move_lines(s, 0, ny, sy - ny); - - s->hsize -= ny; - } - s->hsize++; - - sy = screen_size_y(s) + s->hsize; - s->grid_data = xrealloc(s->grid_data, sy, sizeof *s->grid_data); - s->grid_attr = xrealloc(s->grid_attr, sy, sizeof *s->grid_attr); - s->grid_fg = xrealloc(s->grid_fg, sy, sizeof *s->grid_fg); - s->grid_bg = xrealloc(s->grid_bg, sy, sizeof *s->grid_fg); - s->grid_size = xrealloc(s->grid_size, sy, sizeof *s->grid_size); - screen_display_make_lines(s, screen_last_y(s), 1); - return; - } - - /* - * Scroll scrolling region up: - * - delete rupper - * - move rupper + 1 to rlower to rupper - * - make new line at rlower - * - * Example: region is 12 to 24. - * rlower = 24, rupper = 12 - * screen_free_lines(s, 12, 1); - * screen_move_lines(s, 12, 13, 12); - * screen_make_lines(s, 24, 1); - */ - - screen_display_free_lines(s, s->rupper, 1); - - if (s->rupper != s->rlower) { - screen_display_move_lines(s, - s->rupper, s->rupper + 1, s->rlower - s->rupper); - } - - screen_display_make_lines(s, s->rlower, 1); -} - -/* Scroll region down. */ -void -screen_display_scroll_region_down(struct screen *s) -{ - /* - * Scroll scrolling region down: - * - delete rlower - * - move rupper to rlower - 1 to rupper + 1 - * - make new line at rupper - * - * Example: region is 12 to 24. - * rlower = 24, rupper = 12 - * screen_free_lines(s, 24, 1); - * screen_move_lines(s, 13, 12, 12); - * screen_make_lines(s, 12, 1); - */ - - screen_display_free_lines(s, s->rlower, 1); - - if (s->rupper != s->rlower) { - screen_display_move_lines(s, - s->rupper + 1, s->rupper, s->rlower - s->rupper); - } - - screen_display_make_lines(s, s->rupper, 1); -} - -/* Insert lines. */ -void -screen_display_insert_lines(struct screen *s, u_int py, u_int ny) -{ - if (!screen_in_y(s, py)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - if (py + ny > screen_last_y(s)) - ny = screen_size_y(s) - py; - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - /* - * Insert range of ny lines at py: - * - Free ny lines from end of screen. - * - Move from py to end of screen - ny to py + ny. - * - Create ny lines at py. - * - * Example: insert 2 lines at 4. - * sy = 10, py = 4, ny = 2 - * screen_free_lines(s, 8, 2); - delete lines 8,9 - * screen_move_lines(s, 6, 4, 4); - move 4,5,6,7 to 6,7,8,9 - * screen_make_lines(s, 4, 2); - make lines 4,5 - */ - - screen_display_free_lines(s, screen_size_y(s) - ny, ny); - - if (py + ny != screen_size_y(s)) { - screen_display_move_lines( - s, py + ny, py, screen_size_y(s) - py - ny); - } - - screen_display_make_lines(s, py, ny); -} - -/* Insert lines in region. */ -void -screen_display_insert_lines_region(struct screen *s, u_int py, u_int ny) -{ - if (!screen_in_region(s, py)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - if (py + ny > s->rlower) - ny = (s->rlower + 1) - py; - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - /* - * Insert range of ny lines at py: - * - Free ny lines from end of screen. - * - Move from py to end of screen - ny to py + ny. - * - Create ny lines at py. - * - * Example: insert 2 lines at 4. - * ryu = 11, ryl = 16, py = 13, ny = 2 - * screen_free_lines(s, 15, 2); - delete lines 15,16 - * screen_move_lines(s, 13, 15, 2);- move 13,14 to 15,16 - * screen_make_lines(s, 13, 2); - make lines 13,14 - */ - - screen_display_free_lines(s, (s->rlower + 1) - ny, ny); - - if (py + ny != s->rlower + 1) { - screen_display_move_lines( - s, py + ny, py, (s->rlower + 1) - py - ny); - } - - screen_display_make_lines(s, py, ny); -} - -/* Delete lines. */ -void -screen_display_delete_lines(struct screen *s, u_int py, u_int ny) -{ - if (!screen_in_y(s, py)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - if (py + ny > screen_last_y(s)) - ny = screen_size_y(s) - py; - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - /* - * Delete range of ny lines at py: - * - Free ny lines at py. - * - Move from py + ny to end of screen to py. - * - Free and recreate last ny lines. - * - * Example: delete lines 3,4. - * sy = 10, py = 3, ny = 2 - * screen_free_lines(s, 3, 2); - delete lines 3,4 - * screen_move_lines(s, 3, 5, 5); - move 5,6,7,8,9 to 3 - * screen_make_lines(s, 8, 2); - make lines 8,9 - */ - - screen_display_free_lines(s, py, ny); - - if (py + ny != screen_size_y(s)) { - screen_display_move_lines( - s, py, py + ny, screen_size_y(s) - py - ny); - } - - screen_display_make_lines(s, screen_size_y(s) - ny, ny); -} - -/* Delete lines inside scroll region. */ -void -screen_display_delete_lines_region(struct screen *s, u_int py, u_int ny) -{ - if (!screen_in_region(s, py)) { - SCREEN_DEBUG2(s, py, ny); - return; - } - if (ny == 0) { - SCREEN_DEBUG2(s, py, ny); - return; - } - - if (py + ny > s->rlower) - ny = (s->rlower + 1) - py; - if (ny == 0) - return; - - /* - * Delete range of ny lines at py: - * - Free ny lines at py. - * - Move from py + ny to end of region to py. - * - Free and recreate last ny lines. - * - * Example: delete lines 13,14. - * ryu = 11, ryl = 16, py = 13, ny = 2 - * screen_free_lines(s, 13, 2); - delete lines 13,14 - * screen_move_lines(s, 15, 16, 2);- move 15,16 to 13 - * screen_make_lines(s, 15, 16); - make lines 15,16 - */ - - screen_display_free_lines(s, py, ny); - - if (py + ny != s->rlower + 1) { - screen_display_move_lines( - s, py, py + ny, (s->rlower + 1) - py - ny); - } - - screen_display_make_lines(s, (s->rlower + 1) - ny, ny); -} - -/* Insert characters. */ -void -screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx) -{ - u_int mx; - - if (!screen_in_x(s, px) || !screen_in_y(s, py)) { - SCREEN_DEBUG3(s, px, py, nx); - return; - } - - if (px + nx > screen_last_x(s)) - nx = screen_last_x(s) - px; - - py = screen_y(s, py); - - /* XXX Cheat and make the line a full line. */ - if (s->grid_size[py] < screen_size_x(s)) - screen_expand_line(s, py, screen_size_x(s)); - - /* - * Inserting a range of nx at px. - * - * - Move sx - (px + nx) from px to px + nx. - * - Clear the range at px to px + nx. - */ - - if (px + nx != screen_last_x(s)) { - mx = screen_last_x(s) - (px + nx); - memmove(&s->grid_data[py][px + nx], - &s->grid_data[py][px], mx * sizeof **s->grid_data); - memmove(&s->grid_attr[py][px + nx], - &s->grid_attr[py][px], mx * sizeof **s->grid_attr); - memmove(&s->grid_fg[py][px + nx], - &s->grid_fg[py][px], mx * sizeof **s->grid_fg); - memmove(&s->grid_bg[py][px + nx], - &s->grid_bg[py][px], mx * sizeof **s->grid_bg); - } - - memset(&s->grid_data[py][px], ' ', nx); - memset(&s->grid_attr[py][px], s->attr, nx); - memset(&s->grid_fg[py][px], s->fg, nx); - memset(&s->grid_bg[py][px], s->bg, nx); -} - -/* Delete characters. */ -void -screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx) -{ - u_int mx; - - if (!screen_in_x(s, px) || !screen_in_y(s, py)) { - SCREEN_DEBUG3(s, px, py, nx); - return; - } - - if (px + nx > screen_last_x(s)) - nx = screen_last_x(s) - px; - - py = screen_y(s, py); - - /* XXX Cheat and make the line a full line. */ - if (s->grid_size[py] < screen_size_x(s)) - screen_expand_line(s, py, screen_size_x(s)); - - /* - * Deleting the range from px to px + nx. - * - * - Move sx - (px + nx) from px + nx to px. - * - Clear the range from sx - nx to sx. - */ - - if (px + nx != screen_last_x(s)) { - mx = screen_last_x(s) - (px + nx); - memmove(&s->grid_data[py][px], &s->grid_data[py][px + nx], mx); - memmove(&s->grid_attr[py][px], &s->grid_attr[py][px + nx], mx); - memmove(&s->grid_fg[py][px], &s->grid_fg[py][px + nx], mx); - memmove(&s->grid_bg[py][px], &s->grid_bg[py][px + nx], mx); - } - - memset(&s->grid_data[py][screen_size_x(s) - nx], ' ', nx); - memset(&s->grid_attr[py][screen_size_x(s) - nx], s->attr, nx); - memset(&s->grid_fg[py][screen_size_x(s) - nx], s->fg, nx); - memset(&s->grid_bg[py][screen_size_x(s) - nx], s->bg, nx); -} - -/* Fill cells from another screen, with an offset. */ -void -screen_display_copy_area(struct screen *dst, struct screen *src, - u_int px, u_int py, u_int nx, u_int ny, u_int ox, u_int oy) -{ - u_int i, j; - u_short attr; - u_char data, fg, bg; - - if (nx == 0 || ny == 0) { - SCREEN_DEBUG4(dst, px, py, nx, ny); - return; - } - if (!screen_in_x(dst, px) || !screen_in_y(dst, py)) { - SCREEN_DEBUG4(dst, px, py, nx, ny); - return; - } - if (!screen_in_x(dst, px + nx - 1) || !screen_in_y(dst, py + ny - 1)) { - SCREEN_DEBUG4(dst, px, py, nx, ny); - return; - } - - for (i = py; i < py + ny; i++) { - for (j = px; j < px + nx; j++) { - screen_get_cell(src, - screen_x(src, j) + ox, screen_y(src, i) - oy, - &data, &attr, &fg, &bg); - screen_display_set_cell(dst, j, i, data, attr, fg, bg); - } - } -} |