diff options
| author | Toomas Soome <tsoome@FreeBSD.org> | 2021-03-06 10:19:43 +0000 |
|---|---|---|
| committer | Toomas Soome <tsoome@FreeBSD.org> | 2021-03-06 10:23:54 +0000 |
| commit | d708f23ebb06cfc9cf8f96f17a43eb63653b818a (patch) | |
| tree | 4d0fdf28cc44da7a7df147fd2d480c8709e476b2 | |
| parent | 9d3b2bcf761041bbe79da3de25f2e4142d90b46a (diff) | |
| -rw-r--r-- | stand/common/gfx_fb.c | 38 | ||||
| -rw-r--r-- | stand/common/gfx_fb.h | 2 |
2 files changed, 40 insertions, 0 deletions
diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c index 77cf1d39854f..3eae0a3a859e 100644 --- a/stand/common/gfx_fb.c +++ b/stand/common/gfx_fb.c @@ -978,6 +978,7 @@ gfx_fb_fill(void *arg, const teken_rect_t *r, teken_char_t c, static void gfx_fb_cursor_draw(teken_gfx_t *state, const teken_pos_t *p, bool on) { + unsigned x, y, width, height; const uint8_t *glyph; int idx; @@ -985,10 +986,47 @@ gfx_fb_cursor_draw(teken_gfx_t *state, const teken_pos_t *p, bool on) if (idx >= state->tg_tp.tp_col * state->tg_tp.tp_row) return; + width = state->tg_font.vf_width; + height = state->tg_font.vf_height; + x = state->tg_origin.tp_col + p->tp_col * width; + y = state->tg_origin.tp_row + p->tp_row * height; + + /* + * Save original display content to preserve image data. + */ + if (on) { + if (state->tg_cursor_image == NULL || + state->tg_cursor_size != width * height * 4) { + free(state->tg_cursor_image); + state->tg_cursor_size = width * height * 4; + state->tg_cursor_image = malloc(state->tg_cursor_size); + } + if (state->tg_cursor_image != NULL) { + if (gfxfb_blt(state->tg_cursor_image, + GfxFbBltVideoToBltBuffer, x, y, 0, 0, + width, height, 0) != 0) { + free(state->tg_cursor_image); + state->tg_cursor_image = NULL; + } + } + } else { + /* + * Restore display from tg_cursor_image. + * If there is no image, restore char from screen_buffer. + */ + if (state->tg_cursor_image != NULL && + gfxfb_blt(state->tg_cursor_image, GfxFbBltBufferToVideo, + 0, 0, x, y, width, height, 0) == 0) { + state->tg_cursor = *p; + return; + } + } + glyph = font_lookup(&state->tg_font, screen_buffer[idx].c, &screen_buffer[idx].a); gfx_bitblt_bitmap(state, glyph, &screen_buffer[idx].a, 0xff, on); gfx_fb_printchar(state, p); + state->tg_cursor = *p; } diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h index ac63d7939cef..89b060a02cf9 100644 --- a/stand/common/gfx_fb.h +++ b/stand/common/gfx_fb.h @@ -210,6 +210,8 @@ typedef struct teken_gfx { teken_t tg_teken; /* Teken core */ teken_pos_t tg_cursor; /* Where cursor was drawn */ bool tg_cursor_visible; + uint8_t *tg_cursor_image; /* Memory for cursor */ + size_t tg_cursor_size; teken_pos_t tg_tp; /* Terminal dimensions */ teken_pos_t tg_origin; /* Point of origin in pixels */ uint8_t *tg_glyph; /* Memory for glyph */ |
