summaryrefslogtreecommitdiffstats
path: root/sys/dev/vt
diff options
context:
space:
mode:
authorray <ray@FreeBSD.org>2013-11-11 13:25:49 +0000
committerray <ray@FreeBSD.org>2013-11-11 13:25:49 +0000
commit2edf4bd36a1bcf199f982208521c438c82bfaab0 (patch)
treec4eea4a6ee6d4aac6f61044cfb30c41dce126a02 /sys/dev/vt
parent792e20c4dea7988e9a6a0d8d5db0687e3f9eef07 (diff)
downloadFreeBSD-src-2edf4bd36a1bcf199f982208521c438c82bfaab0.zip
FreeBSD-src-2edf4bd36a1bcf199f982208521c438c82bfaab0.tar.gz
Update vd_bitbltchr_t type to handle operation mask (to not touch pixels which
is not defined in mask) and bpl (bytes per source line). Only vt_fb driver handle handle bpl yet. Add protector for case when blitting image can be drawn partially out of screen, like mouse cursor. Mouse cursor and its movements works fine, copy/paste not yet. Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/dev/vt')
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.c30
-rw-r--r--sys/dev/vt/hw/ofwfb/ofwfb.c22
-rw-r--r--sys/dev/vt/hw/vga/vga.c11
-rw-r--r--sys/dev/vt/hw/xboxfb/xboxfb.c22
-rw-r--r--sys/dev/vt/vt.h4
-rw-r--r--sys/dev/vt/vt_core.c11
6 files changed, 76 insertions, 24 deletions
diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
index 5207d5f..0513127 100644
--- a/sys/dev/vt/hw/fb/vt_fb.c
+++ b/sys/dev/vt/hw/fb/vt_fb.c
@@ -92,29 +92,46 @@ vt_fb_blank(struct vt_device *vd, term_color_t color)
}
void
-vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src,
- vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
- term_color_t fg, term_color_t bg)
+vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
+ int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+ unsigned int height, term_color_t fg, term_color_t bg)
{
struct fb_info *info;
uint32_t fgc, bgc, cc, o;
int c, l, bpp;
u_long line;
- uint8_t b;
+ uint8_t b, m;
+ const uint8_t *ch;
- b = 0;
info = vd->vd_softc;
bpp = FBTYPE_GET_BYTESPP(info);
fgc = info->fb_cmap[fg];
bgc = info->fb_cmap[bg];
+ if (bpl == 0)
+ bpl = (width + 7) >> 3; /* Bytes per sorce line. */
+
+ /* Don't try to put off screen pixels */
+ if (((left + width) > info->fb_width) || ((top + height) >
+ info->fb_height))
+ return;
line = (info->fb_stride * top) + (left * bpp);
for (l = 0; l < height; l++) {
+ ch = src;
for (c = 0; c < width; c++) {
if (c % 8 == 0)
- b = *src++;
+ b = *ch++;
else
b <<= 1;
+ if (mask != NULL) {
+ if (c % 8 == 0)
+ m = *mask++;
+ else
+ m <<= 1;
+ /* Skip pixel write, if mask has no bit set. */
+ if ((m & 0x80) == 0)
+ continue;
+ }
o = line + (c * bpp);
cc = b & 0x80 ? fgc : bgc;
@@ -140,6 +157,7 @@ vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src,
}
}
line += info->fb_stride;
+ src += bpl;
}
}
diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c
index 6409515..5a23d69 100644
--- a/sys/dev/vt/hw/ofwfb/ofwfb.c
+++ b/sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -98,19 +98,24 @@ ofwfb_blank(struct vt_device *vd, term_color_t color)
}
static void
-ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src,
- vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
- term_color_t fg, term_color_t bg)
+ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
+ int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+ unsigned int height, term_color_t fg, term_color_t bg)
{
struct ofwfb_softc *sc = vd->vd_softc;
u_long line;
uint32_t fgc, bgc;
int c;
- uint8_t b = 0;
+ uint8_t b, m;
fgc = sc->sc_colormap[fg];
bgc = sc->sc_colormap[bg];
+ /* Don't try to put off screen pixels */
+ if (((left + width) > info->fb_width) || ((top + height) >
+ info->fb_height))
+ return;
+
line = (sc->sc_stride * top) + left * sc->sc_depth/8;
for (; height > 0; height--) {
for (c = 0; c < width; c++) {
@@ -118,6 +123,15 @@ ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src,
b = *src++;
else
b <<= 1;
+ if (mask != NULL) {
+ if (c % 8 == 0)
+ m = *mask++;
+ else
+ m <<= 1;
+ /* Skip pixel write, if mask has no bit set. */
+ if ((m & 0x80) == 0)
+ continue;
+ }
switch(sc->sc_depth) {
case 8:
*(uint8_t *)(sc->sc_addr + line + c) =
diff --git a/sys/dev/vt/hw/vga/vga.c b/sys/dev/vt/hw/vga/vga.c
index b7b56eb..f658dc5 100644
--- a/sys/dev/vt/hw/vga/vga.c
+++ b/sys/dev/vt/hw/vga/vga.c
@@ -169,9 +169,9 @@ vga_bitblt_draw(struct vt_device *vd, const uint8_t *src,
}
static void
-vga_bitbltchr(struct vt_device *vd, const uint8_t *src,
- vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
- term_color_t fg, term_color_t bg)
+vga_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
+ int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+ unsigned int height, term_color_t fg, term_color_t bg)
{
struct vga_softc *sc = vd->vd_softc;
u_long dst;
@@ -180,6 +180,11 @@ vga_bitbltchr(struct vt_device *vd, const uint8_t *src,
dst = (VT_VGA_WIDTH * top + left) / 8;
shift = left % 8;
+ /* Don't try to put off screen pixels */
+ if (((left + width) > VT_VGA_WIDTH) || ((top + height) >
+ VT_VGA_HEIGHT))
+ return;
+
if (sc->vga_curcolor == fg) {
vga_bitblt_draw(vd, src, dst, shift, width, height, fg, 0);
vga_bitblt_draw(vd, src, dst, shift, width, height, bg, 1);
diff --git a/sys/dev/vt/hw/xboxfb/xboxfb.c b/sys/dev/vt/hw/xboxfb/xboxfb.c
index c3186d7..d8a9057 100644
--- a/sys/dev/vt/hw/xboxfb/xboxfb.c
+++ b/sys/dev/vt/hw/xboxfb/xboxfb.c
@@ -106,19 +106,24 @@ xbox_blank(struct vt_device *vd, term_color_t color)
}
static void
-xbox_bitbltchr(struct vt_device *vd, const uint8_t *src,
- vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
- term_color_t fg, term_color_t bg)
+xbox_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
+ int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+ unsigned int height, term_color_t fg, term_color_t bg)
{
struct xbox_softc *sc = vd->vd_softc;
u_long line;
uint32_t fgc, bgc;
int c;
- uint8_t b = 0;
+ uint8_t b, m;
fgc = colormap[fg];
bgc = colormap[bg];
+ /* Don't try to put off screen pixels */
+ if (((left + width) > info->fb_width) || ((top + height) >
+ info->fb_height))
+ return;
+
line = (VT_XBOX_WIDTH * top + left) * 4;
for (; height > 0; height--) {
for (c = 0; c < width; c++) {
@@ -126,6 +131,15 @@ xbox_bitbltchr(struct vt_device *vd, const uint8_t *src,
b = *src++;
else
b <<= 1;
+ if (mask != NULL) {
+ if (c % 8 == 0)
+ m = *mask++;
+ else
+ m <<= 1;
+ /* Skip pixel write, if mask has no bit set. */
+ if ((m & 0x80) == 0)
+ continue;
+ }
MEM_WRITE4(sc, line + c * 4, b & 0x80 ? fgc : bgc);
}
line += VT_XBOX_WIDTH * 4;
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 7a1cfae..9ade99f 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -256,8 +256,8 @@ typedef int vd_init_t(struct vt_device *vd);
typedef void vd_postswitch_t(struct vt_device *vd);
typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
typedef void vd_bitbltchr_t(struct vt_device *vd, const uint8_t *src,
- vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
- term_color_t fg, term_color_t bg);
+ const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left,
+ unsigned int width, unsigned int height, term_color_t fg, term_color_t bg);
typedef void vd_putchar_t(struct vt_device *vd, term_char_t,
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg);
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 077da5f..15277b0 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -640,7 +640,7 @@ vt_bitblt_char(struct vt_device *vd, struct vt_font *vf, term_char_t c,
top = row * vf->vf_height + vd->vd_offset.tp_row;
left = col * vf->vf_width + vd->vd_offset.tp_col;
- vd->vd_driver->vd_bitbltchr(vd, src, top, left,
+ vd->vd_driver->vd_bitbltchr(vd, src, NULL, 0, top, left,
vf->vf_width, vf->vf_height, fg, bg);
} else {
vd->vd_driver->vd_putchar(vd, TCHAR_CHARACTER(c),
@@ -659,7 +659,7 @@ vt_flush(struct vt_device *vd)
term_rect_t tarea;
term_pos_t size;
term_char_t *r;
- int h, w;
+ int bpl, h, w;
if (vd->vd_flags & VDF_SPLASH || vw->vw_flags & VWF_BUSY)
return;
@@ -700,6 +700,7 @@ vt_flush(struct vt_device *vd)
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;
@@ -708,7 +709,7 @@ vt_flush(struct vt_device *vd)
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_bitbltchr(vd, m->map,
+ vd->vd_driver->vd_bitbltchr(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);
@@ -764,8 +765,8 @@ vtterm_splash(struct vt_device *vd)
switch (vt_logo_depth) {
case 1:
/* XXX: Unhardcode colors! */
- vd->vd_driver->vd_bitbltchr(vd, vt_logo_image, top, left,
- vt_logo_width, vt_logo_height, 0xf, 0x0);
+ vd->vd_driver->vd_bitbltchr(vd, vt_logo_image, NULL, 0,
+ top, left, vt_logo_width, vt_logo_height, 0xf, 0x0);
}
vd->vd_flags |= VDF_SPLASH;
}
OpenPOWER on IntegriCloud