void vt_fb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, const term_rect_t *area) { unsigned int col, row, x, y; struct vt_font *vf; term_char_t c; term_color_t fg, bg; const uint8_t *pattern; vf = vw->vw_font; for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) { for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col; ++col) { x = col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col; y = row * vf->vf_height + vw->vw_draw_area.tr_begin.tp_row; c = VTBUF_GET_FIELD(&vw->vw_buf, row, col); pattern = vtfont_lookup(vf, c); vt_determine_colors(c, VTBUF_ISCURSOR(&vw->vw_buf, row, col), &fg, &bg); vt_fb_bitblt_bitmap(vd, vw, pattern, NULL, vf->vf_width, vf->vf_height, x, y, fg, bg); } } #ifndef SC_NO_CUTPASTE if (!vd->vd_mshown) return; term_rect_t drawn_area; drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width; drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height; drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width; drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height; if (vt_is_cursor_in_area(vd, &drawn_area)) { vt_fb_bitblt_bitmap(vd, vw, vd->vd_mcursor->map, vd->vd_mcursor->mask, vd->vd_mcursor->width, vd->vd_mcursor->height, vd->vd_mx_drawn + vw->vw_draw_area.tr_begin.tp_col, vd->vd_my_drawn + vw->vw_draw_area.tr_begin.tp_row, vd->vd_mcursor_fg, vd->vd_mcursor_bg); } #endif }
static void vt_flush(struct vt_device *vd) { struct vt_window *vw; struct vt_font *vf; struct vt_bufmask tmask; unsigned int row, col; term_rect_t tarea; term_pos_t size; term_char_t *r; #ifndef SC_NO_CUTPASTE struct mouse_cursor *m; int bpl, h, w; #endif vw = vd->vd_curwindow; if (vw == NULL) return; vf = vw->vw_font; if (((vd->vd_flags & VDF_TEXTMODE) == 0) && (vf == NULL)) return; if (vd->vd_flags & VDF_SPLASH || vw->vw_flags & VWF_BUSY) return; vtbuf_undirty(&vw->vw_buf, &tarea, &tmask); vt_termsize(vd, vf, &size); /* Force a full redraw when the screen contents are invalid. */ if (vd->vd_flags & VDF_INVALID) { tarea.tr_begin.tp_row = tarea.tr_begin.tp_col = 0; tarea.tr_end = size; tmask.vbm_row = tmask.vbm_col = VBM_DIRTY; vd->vd_flags &= ~VDF_INVALID; } #ifndef SC_NO_CUTPASTE if ((vw->vw_flags & VWF_MOUSE_HIDE) == 0) { /* Mark last mouse position as dirty to erase. */ vtbuf_mouse_cursor_position(&vw->vw_buf, vd->vd_mdirtyx, vd->vd_mdirtyy); } #endif for (row = tarea.tr_begin.tp_row; row < tarea.tr_end.tp_row; row++) { if (!VTBUF_DIRTYROW(&tmask, row)) continue; r = VTBUF_GET_ROW(&vw->vw_buf, row); for (col = tarea.tr_begin.tp_col; col < tarea.tr_end.tp_col; col++) { if (!VTBUF_DIRTYCOL(&tmask, col)) continue; vt_bitblt_char(vd, vf, r[col], VTBUF_ISCURSOR(&vw->vw_buf, row, col), row, col); } } #ifndef SC_NO_CUTPASTE /* Mouse disabled. */ if (vw->vw_flags & VWF_MOUSE_HIDE) return; /* No mouse for DDB. */ if (kdb_active || panicstr != NULL) return; if ((vd->vd_flags & (VDF_MOUSECURSOR|VDF_TEXTMODE)) == VDF_MOUSECURSOR) { m = &vt_default_mouse_pointer; bpl = (m->w + 7) >> 3; /* Bytes per sorce line. */ w = m->w; h = m->h; if ((vd->vd_mx + m->w) > (size.tp_col * vf->vf_width)) w = (size.tp_col * vf->vf_width) - vd->vd_mx - 1; if ((vd->vd_my + m->h) > (size.tp_row * vf->vf_height)) h = (size.tp_row * vf->vf_height) - vd->vd_my - 1; vd->vd_driver->vd_maskbitbltchr(vd, m->map, m->mask, bpl, vd->vd_offset.tp_row + vd->vd_my, vd->vd_offset.tp_col + vd->vd_mx, w, h, TC_WHITE, TC_BLACK); /* Save point of last mouse cursor to erase it later. */ vd->vd_mdirtyx = vd->vd_mx / vf->vf_width; vd->vd_mdirtyy = vd->vd_my / vf->vf_height; }