summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2014-08-25 19:06:31 +0000
committerdumbbell <dumbbell@FreeBSD.org>2014-08-25 19:06:31 +0000
commita5aa919ddafe73ca47d77a8c52535f313fa8e778 (patch)
tree7b2b23dc301451432b594c056eba51ee37e7cb8e
parent9c2354b6686d5daebb9ee5966febe565b77063fa (diff)
downloadFreeBSD-src-a5aa919ddafe73ca47d77a8c52535f313fa8e778.zip
FreeBSD-src-a5aa919ddafe73ca47d77a8c52535f313fa8e778.tar.gz
vt(4): Store a rectangle for the drawable area, not just the top-left corner
This allows backends to verify they do not draw outside of this area. This fixes a bug in vt_vga where the text was happily drawn over the right and bottom margins, when using the Gallant font. MFC after: 1 week
-rw-r--r--sys/dev/fb/creator_vt.c14
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.c14
-rw-r--r--sys/dev/vt/hw/ofwfb/ofwfb.c14
-rw-r--r--sys/dev/vt/hw/vga/vt_vga.c53
-rw-r--r--sys/dev/vt/vt.h2
-rw-r--r--sys/dev/vt/vt_core.c22
6 files changed, 68 insertions, 51 deletions
diff --git a/sys/dev/fb/creator_vt.c b/sys/dev/fb/creator_vt.c
index 6bed29d..18a42b9 100644
--- a/sys/dev/fb/creator_vt.c
+++ b/sys/dev/fb/creator_vt.c
@@ -236,8 +236,10 @@ creatorfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
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_offset.tp_col;
- y = row * vf->vf_height + vw->vw_offset.tp_row;
+ 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);
@@ -257,13 +259,13 @@ creatorfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
term_rect_t drawn_area;
drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
if (vt_is_cursor_in_area(vd, &drawn_area)) {
creatorfb_bitblt_bitmap(vd, vw,
diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
index 04023c0..3cae588 100644
--- a/sys/dev/vt/hw/fb/vt_fb.c
+++ b/sys/dev/vt/hw/fb/vt_fb.c
@@ -331,8 +331,10 @@ vt_fb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
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_offset.tp_col;
- y = row * vf->vf_height + vw->vw_offset.tp_row;
+ 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);
@@ -352,13 +354,13 @@ vt_fb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
term_rect_t drawn_area;
drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
if (vt_is_cursor_in_area(vd, &drawn_area)) {
vt_fb_bitblt_bitmap(vd, vw,
diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c
index 2a31d16..835a07d 100644
--- a/sys/dev/vt/hw/ofwfb/ofwfb.c
+++ b/sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -209,8 +209,10 @@ ofwfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
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_offset.tp_col;
- y = row * vf->vf_height + vw->vw_offset.tp_row;
+ 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);
@@ -230,13 +232,13 @@ ofwfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw,
term_rect_t drawn_area;
drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width +
- vw->vw_offset.tp_col;
+ vw->vw_draw_area.tr_begin.tp_col;
drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height +
- vw->vw_offset.tp_row;
+ vw->vw_draw_area.tr_begin.tp_row;
if (vt_is_cursor_in_area(vd, &drawn_area)) {
ofwfb_bitblt_bitmap(vd, vw,
diff --git a/sys/dev/vt/hw/vga/vt_vga.c b/sys/dev/vt/hw/vga/vt_vga.c
index e21a9a1..135845d 100644
--- a/sys/dev/vt/hw/vga/vt_vga.c
+++ b/sys/dev/vt/hw/vga/vt_vga.c
@@ -556,16 +556,17 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd,
memset(pattern_2colors, 0, sizeof(pattern_2colors));
memset(pattern_ncolors, 0, sizeof(pattern_ncolors));
- if (i < vw->vw_offset.tp_col) {
+ if (i < vw->vw_draw_area.tr_begin.tp_col) {
/*
* i is in the margin used to center the text area on
* the screen.
*/
- i = vw->vw_offset.tp_col;
+ i = vw->vw_draw_area.tr_begin.tp_col;
}
- while (i < x + VT_VGA_PIXELS_BLOCK) {
+ while (i < x + VT_VGA_PIXELS_BLOCK &&
+ i < vw->vw_draw_area.tr_end.tp_col) {
/*
* Find which character is drawn on this pixel in the
* pixels block.
@@ -573,8 +574,8 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd,
* While here, record what colors it uses.
*/
- col = (i - vw->vw_offset.tp_col) / vf->vf_width;
- row = (y - vw->vw_offset.tp_row) / vf->vf_height;
+ col = (i - vw->vw_draw_area.tr_begin.tp_col) / vf->vf_width;
+ row = (y - vw->vw_draw_area.tr_begin.tp_row) / vf->vf_height;
c = VTBUF_GET_FIELD(vb, row, col);
src = vtfont_lookup(vf, c);
@@ -605,11 +606,15 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd,
* character.
*/
- src_x = i - (col * vf->vf_width + vw->vw_offset.tp_col);
- x_count = min(
- (col + 1) * vf->vf_width + vw->vw_offset.tp_col,
- x + VT_VGA_PIXELS_BLOCK);
- x_count -= col * vf->vf_width + vw->vw_offset.tp_col;
+ src_x = i -
+ (col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col);
+ x_count = min(min(
+ (col + 1) * vf->vf_width +
+ vw->vw_draw_area.tr_begin.tp_col,
+ x + VT_VGA_PIXELS_BLOCK),
+ vw->vw_draw_area.tr_end.tp_col);
+ x_count -= col * vf->vf_width +
+ vw->vw_draw_area.tr_begin.tp_col;
x_count -= src_x;
/* Copy a portion of the character. */
@@ -643,14 +648,16 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd,
unsigned int dst_x, src_y, dst_y, y_count;
cursor = vd->vd_mcursor;
- mx = vd->vd_mx_drawn + vw->vw_offset.tp_col;
- my = vd->vd_my_drawn + vw->vw_offset.tp_row;
+ mx = vd->vd_mx_drawn + vw->vw_draw_area.tr_begin.tp_col;
+ my = vd->vd_my_drawn + vw->vw_draw_area.tr_begin.tp_row;
/* Compute the portion of the cursor we want to copy. */
src_x = x > mx ? x - mx : 0;
dst_x = mx > x ? mx - x : 0;
- x_count = min(
- min(cursor->width - src_x, x + VT_VGA_PIXELS_BLOCK - mx),
+ x_count = min(min(min(
+ cursor->width - src_x,
+ x + VT_VGA_PIXELS_BLOCK - mx),
+ vw->vw_draw_area.tr_end.tp_col - mx),
VT_VGA_PIXELS_BLOCK);
/*
@@ -725,10 +732,10 @@ vga_bitblt_text_gfxmode(struct vt_device *vd, const struct vt_window *vw,
col = area->tr_begin.tp_col;
row = area->tr_begin.tp_row;
- x1 = (int)((col * vf->vf_width + vw->vw_offset.tp_col)
+ x1 = (int)((col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col)
/ VT_VGA_PIXELS_BLOCK)
* VT_VGA_PIXELS_BLOCK;
- y1 = row * vf->vf_height + vw->vw_offset.tp_row;
+ y1 = row * vf->vf_height + vw->vw_draw_area.tr_begin.tp_row;
/*
* Compute the bottom right pixel position, again, aligned with
@@ -740,19 +747,15 @@ vga_bitblt_text_gfxmode(struct vt_device *vd, const struct vt_window *vw,
col = area->tr_end.tp_col;
row = area->tr_end.tp_row;
- x2 = (int)((col * vf->vf_width + vw->vw_offset.tp_col
+ x2 = (int)((col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col
+ VT_VGA_PIXELS_BLOCK - 1)
/ VT_VGA_PIXELS_BLOCK)
* VT_VGA_PIXELS_BLOCK;
- y2 = row * vf->vf_height + vw->vw_offset.tp_row;
+ y2 = row * vf->vf_height + vw->vw_draw_area.tr_begin.tp_row;
- /*
- * Clip the area to the screen size.
- *
- * FIXME: Take vw_offset into account.
- */
- x2 = min(x2, vd->vd_width - 1);
- y2 = min(y2, vd->vd_height - 1);
+ /* Clip the area to the screen size. */
+ x2 = min(x2, vw->vw_draw_area.tr_end.tp_col);
+ y2 = min(y2, vw->vw_draw_area.tr_end.tp_row);
/*
* Now, we take care of N pixels line at a time (the first for
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 55c5b18..89d3de4 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -258,7 +258,7 @@ struct vt_window {
struct terminal *vw_terminal; /* (c) Terminal. */
struct vt_buf vw_buf; /* (u) Screen buffer. */
struct vt_font *vw_font; /* (d) Graphical font. */
- term_pos_t vw_offset; /* (?) Pixel offset. */
+ term_rect_t vw_draw_area; /* (?) Drawable area. */
unsigned int vw_number; /* (c) Window number. */
int vw_kbdmode; /* (?) Keyboard mode. */
char *vw_kbdsq; /* Escape sequence queue*/
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 32887c8..ae1e97b 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -828,8 +828,8 @@ vt_is_cursor_in_area(const struct vt_device *vd, const term_rect_t *area)
* We use the cursor position saved during the current refresh,
* in case the cursor moved since.
*/
- mx = vd->vd_mx_drawn + vd->vd_curwindow->vw_offset.tp_col;
- my = vd->vd_my_drawn + vd->vd_curwindow->vw_offset.tp_row;
+ mx = vd->vd_mx_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_col;
+ my = vd->vd_my_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_row;
x1 = area->tr_begin.tp_col;
y1 = area->tr_begin.tp_row;
@@ -1202,8 +1202,8 @@ vt_set_border(struct vt_window *vw, struct vt_font *vf, term_color_t c)
x = vd->vd_width - 1;
y = vd->vd_height - 1;
- off_x = vw->vw_offset.tp_col;
- off_y = vw->vw_offset.tp_row;
+ off_x = vw->vw_draw_area.tr_begin.tp_col;
+ off_y = vw->vw_draw_area.tr_begin.tp_row;
/* Top bar. */
if (off_y > 0)
@@ -1257,9 +1257,17 @@ vt_change_font(struct vt_window *vw, struct vt_font *vf)
vt_termsize(vd, vf, &size);
vt_winsize(vd, vf, &wsz);
- /* Save offset to font aligned area. */
- vw->vw_offset.tp_col = (vd->vd_width % vf->vf_width) / 2;
- vw->vw_offset.tp_row = (vd->vd_height % vf->vf_height) / 2;
+
+ /*
+ * Compute the drawable area, so that the text is centered on
+ * the screen.
+ */
+ vw->vw_draw_area.tr_begin.tp_col = (vd->vd_width % vf->vf_width) / 2;
+ vw->vw_draw_area.tr_begin.tp_row = (vd->vd_height % vf->vf_height) / 2;
+ vw->vw_draw_area.tr_end.tp_col = vw->vw_draw_area.tr_begin.tp_col +
+ vd->vd_width / vf->vf_width * vf->vf_width;
+ vw->vw_draw_area.tr_end.tp_row = vw->vw_draw_area.tr_begin.tp_row +
+ vd->vd_height / vf->vf_height * vf->vf_height;
/* Grow the screen buffer and terminal. */
terminal_mute(tm, 1);
OpenPOWER on IntegriCloud