1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-02 08:57:19 -04:00

[screen] Added struct bitfield dirty to screen

This commit is contained in:
Witold Filipczyk 2022-12-14 22:04:01 +01:00
parent 2259b74047
commit 571cb05e05
2 changed files with 24 additions and 6 deletions

View File

@ -24,6 +24,7 @@
#ifdef CONFIG_TERMINFO #ifdef CONFIG_TERMINFO
#include "terminal/terminfo.h" #include "terminal/terminfo.h"
#endif #endif
#include "util/bitfield.h"
#include "util/conv.h" #include "util/conv.h"
#include "util/error.h" #include "util/error.h"
#include "util/memory.h" #include "util/memory.h"
@ -442,6 +443,16 @@ static const struct screen_driver_opt *const screen_driver_opts[] = {
static INIT_LIST_OF(struct screen_driver, active_screen_drivers); static INIT_LIST_OF(struct screen_driver, active_screen_drivers);
void
set_screen_dirty(struct terminal_screen *screen, int from, int to)
{
for (unsigned int i = from; i <= to; i++) {
set_bitfield_bit(screen->dirty, i);
}
int_upper_bound(&screen->dirty_from, from);
int_lower_bound(&screen->dirty_to, to);
}
/** Set screen_driver.opt according to screen_driver.type and @a term_spec. /** Set screen_driver.opt according to screen_driver.type and @a term_spec.
* Other members of @a *driver need not have been initialized. * Other members of @a *driver need not have been initialized.
* *
@ -1312,6 +1323,7 @@ add_char_true(struct string *screen, struct screen_driver *driver,
int_upper_bound(&screen->dirty_to, ymax); \ int_upper_bound(&screen->dirty_to, ymax); \
\ \
for (; y <= screen->dirty_to; y++) { \ for (; y <= screen->dirty_to; y++) { \
if (!test_bitfield_bit(screen->dirty, y)) continue; \
int ypos = y * (term_)->width; \ int ypos = y * (term_)->width; \
struct screen_char *current = &screen->last_image[ypos]; \ struct screen_char *current = &screen->last_image[ypos]; \
struct screen_char *pos = &screen->image[ypos]; \ struct screen_char *pos = &screen->image[ypos]; \
@ -1319,6 +1331,7 @@ add_char_true(struct string *screen, struct screen_driver *driver,
int is_last_line = (y == ymax); \ int is_last_line = (y == ymax); \
int x = 0; \ int x = 0; \
int dirty = 0; \ int dirty = 0; \
clear_bitfield_bit(screen->dirty, y); \
\ \
for (; x <= xmax; x++, current++, pos++) { \ for (; x <= xmax; x++, current++, pos++) { \
/* Workaround for terminals without /* Workaround for terminals without
@ -1494,6 +1507,7 @@ resize_screen(struct terminal *term, int width, int height)
{ {
struct terminal_screen *screen; struct terminal_screen *screen;
struct screen_char *image; struct screen_char *image;
struct bitfield *new_dirty;
size_t size, bsize; size_t size, bsize;
assert(term && term->screen); assert(term && term->screen);
@ -1506,6 +1520,9 @@ resize_screen(struct terminal *term, int width, int height)
size = width * height; size = width * height;
if (size <= 0) return; if (size <= 0) return;
new_dirty = init_bitfield(height);
if (!new_dirty) return;
bsize = size * sizeof(*image); bsize = size * sizeof(*image);
image = (struct screen_char *)mem_realloc(screen->image, bsize * 2); image = (struct screen_char *)mem_realloc(screen->image, bsize * 2);
@ -1519,6 +1536,8 @@ resize_screen(struct terminal *term, int width, int height)
term->width = width; term->width = width;
term->height = height; term->height = height;
mem_free_set(&screen->dirty, new_dirty);
set_screen_dirty(screen, 0, height); set_screen_dirty(screen, 0, height);
} }
@ -1526,6 +1545,7 @@ void
done_screen(struct terminal_screen *screen) done_screen(struct terminal_screen *screen)
{ {
mem_free_if(screen->image); mem_free_if(screen->image);
mem_free(screen->dirty);
mem_free(screen); mem_free(screen);
} }

View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
struct bitfield;
struct module; struct module;
struct screen_char; struct screen_char;
struct terminal; struct terminal;
@ -24,15 +25,12 @@ struct terminal_screen {
/** The range of line numbers that are out of sync with the physical /** The range of line numbers that are out of sync with the physical
* screen. #dirty_from > #dirty_to means not dirty. */ * screen. #dirty_from > #dirty_to means not dirty. */
int dirty_from, dirty_to; int dirty_from, dirty_to;
struct bitfield *dirty;
}; };
/** Mark the screen ready for redrawing. */ /** Mark the screen ready for redrawing. */
static inline void void set_screen_dirty(struct terminal_screen *screen, int from, int to);
set_screen_dirty(struct terminal_screen *screen, int from, int to)
{
int_upper_bound(&screen->dirty_from, from);
int_lower_bound(&screen->dirty_to, to);
}
/** Initializes a screen. Returns NULL upon allocation failure. */ /** Initializes a screen. Returns NULL upon allocation failure. */
struct terminal_screen *init_screen(void); struct terminal_screen *init_screen(void);