diff --git a/cache.c b/cache.c index 8b1692f..965def1 100644 --- a/cache.c +++ b/cache.c @@ -154,8 +154,10 @@ void cache_put_text(uint8 cache_id, void *data, int length) static uint8 deskcache[0x38400]; /* Retrieve desktop data from the cache */ -uint8 *cache_get_desktop(uint32 offset, uint32 length) +uint8 *cache_get_desktop(uint32 offset, int cx, int cy) { + int length = cx * cy; + if ((offset + length) <= sizeof(deskcache)) { return &deskcache[offset]; @@ -166,11 +168,18 @@ uint8 *cache_get_desktop(uint32 offset, uint32 length) } /* Store desktop data in the cache */ -void cache_put_desktop(uint32 offset, uint32 length, uint8 *data) +void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, uint8 *data) { + int length = cx * cy; + if ((offset + length) <= sizeof(deskcache)) { - memcpy(&deskcache[offset], data, length); + while (cy--) + { + memcpy(&deskcache[offset], data, cx); + data += scanline; + offset += cx; + } } else { diff --git a/constants.h b/constants.h index 7724a85..2e325e5 100644 --- a/constants.h +++ b/constants.h @@ -163,6 +163,7 @@ enum RDP_INPUT_DEVICE #define ROP2_COPY 0xc #define ROP2_XOR 0x6 #define ROP2_AND 0x8 +#define ROP2_NXOR 0x9 #define ROP2_OR 0xe #define MIX_TRANSPARENT 0 diff --git a/proto.h b/proto.h index d13eea3..1d39056 100644 --- a/proto.h +++ b/proto.h @@ -63,8 +63,8 @@ FONTGLYPH *cache_get_font(uint8 font, uint16 character); void cache_put_font(uint8 font, uint32 character, uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap); DATABLOB *cache_get_text(uint8 cache_id); void cache_put_text(uint8 cache_id, void *data, int length); -uint8 *cache_get_desktop(uint32 offset, uint32 length); -void cache_put_desktop(uint32 offset, uint32 length, uint8 *data); +uint8 *cache_get_desktop(uint32 offset, int cx, int cy); +void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, uint8 *data); /* xwin.c */ BOOL ui_create_window(char *title); diff --git a/xwin.c b/xwin.c index 64f44b4..5814bdb 100644 --- a/xwin.c +++ b/xwin.c @@ -419,19 +419,23 @@ void ui_triblt(uint8 opcode, switch (opcode) { + case 0x69: /* PDSxxn */ + ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy); + ui_patblt(ROP2_NXOR, x, y, cx, cy, + brush, bgcolour, fgcolour); + break; + case 0xb8: /* PSDPxax */ ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour); - ui_memblt(ROP2_AND, x, y, cx, cy, - src, srcx, srcy); + ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy); ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour); break; default: NOTIMP("triblt 0x%x\n", opcode); - ui_memblt(ROP2_COPY, x, y, cx, cy, - brush, bgcolour, fgcolour); + ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy); } } @@ -523,13 +527,9 @@ void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy) { XImage *image; - int scanline; - scanline = (cx + 3) & ~3; - DEBUG("XGetImage(%p,%x,%d,%d,%d,%d,%x,%d)\n", display, wnd, x, y, - cx, cy, 0xffffffff, ZPixmap); image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap); - cache_put_desktop(offset, scanline*cy, image->data); + cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data); XFree(image->data); XFree(image); } @@ -537,16 +537,14 @@ void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy) void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy) { XImage *image; - int scanline; uint8 *data; - scanline = (cx + 3) & ~3; - data = cache_get_desktop(offset, scanline*cy); + data = cache_get_desktop(offset, cx, cy); if (data == NULL) return; image = XCreateImage(display, visual, 8, ZPixmap, 0, - data, cx, cy, 32, scanline); + data, cx, cy, 32, cx); XSetFunction(display, gc, GXcopy); XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy); XFree(image);