--- sourceforge.net/trunk/rdesktop/xwin.c 2004/04/26 23:00:25 679 +++ sourceforge.net/trunk/rdesktop/xwin.c 2004/06/11 22:37:05 709 @@ -45,6 +45,7 @@ Window g_wnd; extern uint32 g_embed_wnd; BOOL g_enable_compose = False; +BOOL g_Unobscured; /* used for screenblt */ static GC g_gc = NULL; static Visual *g_visual; static int g_depth; @@ -171,9 +172,9 @@ split_colour15(uint32 colour) { PixelColour rv; - rv.red = (colour & 0x7c00) >> 7; - rv.green = (colour & 0x03e0) >> 2; - rv.blue = (colour & 0x001f) << 3; + rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); + rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); + rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); return rv; } @@ -181,9 +182,9 @@ split_colour16(uint32 colour) { PixelColour rv; - rv.red = (colour & 0xf800) >> 8; - rv.green = (colour & 0x07e0) >> 3; - rv.blue = (colour & 0x001f) << 3; + rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); + rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); + rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); return rv; } @@ -229,8 +230,25 @@ return make_colour(pc); } +/* indent is confused by UNROLL8 */ +/* *INDENT-OFF* */ + +/* repeat and unroll, similar to bitmap.c */ +/* potentialy any of the following translate */ +/* functions can use repeat but just doing */ +/* the most common ones */ + #define UNROLL8(stm) { stm stm stm stm stm stm stm stm } -#define REPEAT(stm) \ +/* 2 byte output repeat */ +#define REPEAT2(stm) \ +{ \ + while (out <= end - 8 * 2) \ + UNROLL8(stm) \ + while (out < end) \ + { stm } \ +} +/* 4 byte output repeat */ +#define REPEAT4(stm) \ { \ while (out <= end - 8 * 4) \ UNROLL8(stm) \ @@ -251,7 +269,13 @@ uint16 value; if (g_arch_match) - REPEAT(*(((uint16*)out)++) = g_colmap[*(data++)];) + { + REPEAT2 + ( + *((uint16 *) out) = g_colmap[*(data++)]; + out += 2; + ) + } else if (g_xserver_be) { while (out < end) @@ -306,7 +330,13 @@ uint32 value; if (g_arch_match) - REPEAT(*(((uint32*)out)++) = g_colmap[*(data++)];) + { + REPEAT4 + ( + *((uint32 *) out) = g_colmap[*(data++)]; + out += 4; + ) + } else if (g_xserver_be) { while (out < end) @@ -331,6 +361,8 @@ } } +/* *INDENT-ON* */ + static void translate15to16(uint16 * data, uint8 * out, uint8 * end) { @@ -1005,6 +1037,7 @@ XMaskEvent(g_display, VisibilityChangeMask, &xevent); } while (xevent.type != VisibilityNotify); + g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured; g_focused = False; g_mouse_in_wnd = False; @@ -1025,6 +1058,7 @@ ui_resize_window() { XSizeHints *sizehints; + Pixmap bs; sizehints = XAllocSizeHints(); if (sizehints) @@ -1040,6 +1074,17 @@ { XResizeWindow(g_display, g_wnd, g_width, g_height); } + + /* create new backstore pixmap */ + if (g_backstore != 0) + { + bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth); + XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen)); + XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height); + XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0); + XFreePixmap(g_display, g_backstore); + g_backstore = bs; + } } void @@ -1103,6 +1148,9 @@ switch (xevent.type) { + case VisibilityNotify: + g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured; + break; case ClientMessage: /* the window manager told us to quit */ if ((xevent.xclient.message_type == g_protocol_atom) @@ -1799,7 +1847,7 @@ { case 0: /* Solid */ SET_FOREGROUND(fgcolour); - FILL_RECTANGLE(x, y, cx, cy); + FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); break; case 2: /* Hatch */ @@ -1810,7 +1858,7 @@ XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); - FILL_RECTANGLE(x, y, cx, cy); + FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); @@ -1820,15 +1868,12 @@ for (i = 0; i != 8; i++) ipattern[7 - i] = brush->pattern[i]; fill = (Pixmap) ui_create_glyph(8, 8, ipattern); - SET_FOREGROUND(bgcolour); SET_BACKGROUND(fgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); - - FILL_RECTANGLE(x, y, cx, cy); - + FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); @@ -1839,6 +1884,9 @@ } RESET_FUNCTION(opcode); + + if (g_ownbackstore) + XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); } void @@ -1849,8 +1897,18 @@ SET_FUNCTION(opcode); if (g_ownbackstore) { - XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); - XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y); + if (g_Unobscured) + { + XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); + XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, + y); + } + else + { + XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); + XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, + y); + } } else {