diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-04-30 21:28:36 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-04-30 21:28:36 +0000 |
commit | 24236869fbff210b356b6626e6e9e9eadc8a976c (patch) | |
tree | f32404f6a854711decf8dc51a224b08fd5ae939c /hw/cirrus_vga.c | |
parent | a46e4035e22c81cd3942b936cebe6f6037e17ec2 (diff) |
VNC server (Anthony Liguori)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1869 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/cirrus_vga.c')
-rw-r--r-- | hw/cirrus_vga.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 934cde9905..d186d797ac 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -644,15 +644,90 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) (s->cirrus_blt_srcaddr & ~7)); } -static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) +static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) { + int sx, sy; + int dx, dy; + int width, height; + int depth; + int notify = 0; + + depth = s->get_bpp((VGAState *)s) / 8; + s->get_resolution((VGAState *)s, &width, &height); + + /* extra x, y */ + sx = (src % (width * depth)) / depth; + sy = (src / (width * depth)); + dx = (dst % (width *depth)) / depth; + dy = (dst / (width * depth)); + + /* normalize width */ + w /= depth; + + /* if we're doing a backward copy, we have to adjust + our x/y to be the upper left corner (instead of the lower + right corner) */ + if (s->cirrus_blt_dstpitch < 0) { + sx -= (s->cirrus_blt_width / depth) - 1; + dx -= (s->cirrus_blt_width / depth) - 1; + sy -= s->cirrus_blt_height - 1; + dy -= s->cirrus_blt_height - 1; + } + + /* are we in the visible portion of memory? */ + if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && + (sx + w) <= width && (sy + h) <= height && + (dx + w) <= width && (dy + h) <= height) { + notify = 1; + } + + /* make to sure only copy if it's a plain copy ROP */ + if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src && + *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src) + notify = 0; + + /* we have to flush all pending changes so that the copy + is generated at the appropriate moment in time */ + if (notify) + vga_hw_update(); + (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, s->vram_ptr + s->cirrus_blt_srcaddr, s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, s->cirrus_blt_width, s->cirrus_blt_height); - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, - s->cirrus_blt_dstpitch, s->cirrus_blt_width, - s->cirrus_blt_height); + + if (notify) + s->ds->dpy_copy(s->ds, + sx, sy, dx, dy, + s->cirrus_blt_width / depth, + s->cirrus_blt_height); + + /* we don't have to notify the display that this portion has + changed since dpy_copy implies this */ + + if (!notify) + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_width, + s->cirrus_blt_height); +} + +static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) +{ + if (s->ds->dpy_copy) { + cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr, + s->cirrus_blt_srcaddr - s->start_addr, + s->cirrus_blt_width, s->cirrus_blt_height); + } else { + (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, + s->vram_ptr + s->cirrus_blt_srcaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_width, + s->cirrus_blt_height); + } + return 1; } |