--- sourceforge.net/trunk/rdesktop/xwin.c 2004/02/16 20:28:09 609 +++ sourceforge.net/trunk/rdesktop/xwin.c 2004/04/15 20:12:42 651 @@ -43,6 +43,7 @@ static int g_x_socket; static Screen *g_screen; Window g_wnd; +extern uint32 g_embed_wnd; BOOL g_enable_compose = False; static GC g_gc = NULL; static Visual *g_visual; @@ -56,6 +57,7 @@ static Atom g_protocol_atom, g_kill_atom; static BOOL g_focused; static BOOL g_mouse_in_wnd; +static BOOL g_arch_match = False; /* set to True if RGB XServer and little endian */ /* endianness */ static BOOL g_host_be; @@ -64,7 +66,7 @@ static int g_red_shift_l, g_blue_shift_l, g_green_shift_l; /* software backing store */ -BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ +extern BOOL g_ownbackstore; static Pixmap g_backstore = 0; /* Moving in single app mode */ @@ -113,7 +115,7 @@ } /* colour maps */ -BOOL g_owncolmap = False; +extern BOOL g_owncolmap; static Colormap g_xcolmap; static uint32 *g_colmap = NULL; @@ -169,12 +171,9 @@ split_colour15(uint32 colour) { PixelColour rv; - rv.red = (colour & 0x7c00) >> 10; - rv.red = (rv.red * 0xff) / 0x1f; - rv.green = (colour & 0x03e0) >> 5; - rv.green = (rv.green * 0xff) / 0x1f; - rv.blue = (colour & 0x1f); - rv.blue = (rv.blue * 0xff) / 0x1f; + rv.red = (colour & 0x7c00) >> 7; + rv.green = (colour & 0x03e0) >> 2; + rv.blue = (colour & 0x001f) << 3; return rv; } @@ -182,12 +181,9 @@ split_colour16(uint32 colour) { PixelColour rv; - rv.red = (colour & 0xf800) >> 11; - rv.red = (rv.red * 0xff) / 0x1f; - rv.green = (colour & 0x07e0) >> 5; - rv.green = (rv.green * 0xff) / 0x3f; - rv.blue = (colour & 0x001f); - rv.blue = (rv.blue * 0xff) / 0x1f; + rv.red = (colour & 0xf800) >> 8; + rv.green = (colour & 0x07e0) >> 3; + rv.blue = (colour & 0x001f) << 3; return rv; } @@ -196,8 +192,8 @@ { PixelColour rv; rv.blue = (colour & 0xff0000) >> 16; - rv.green = (colour & 0xff00) >> 8; - rv.red = (colour & 0xff); + rv.green = (colour & 0x00ff00) >> 8; + rv.red = (colour & 0x0000ff); return rv; } @@ -245,17 +241,20 @@ { uint16 value; - while (out < end) + if (g_xserver_be) { - value = (uint16) g_colmap[*(data++)]; - - if (g_xserver_be) + while (out < end) { + value = (uint16) g_colmap[*(data++)]; *(out++) = value >> 8; *(out++) = value; } - else + } + else + { + while (out < end) { + value = (uint16) g_colmap[*(data++)]; *(out++) = value; *(out++) = value >> 8; } @@ -268,18 +267,21 @@ { uint32 value; - while (out < end) + if (g_xserver_be) { - value = g_colmap[*(data++)]; - - if (g_xserver_be) + while (out < end) { + value = g_colmap[*(data++)]; *(out++) = value >> 16; *(out++) = value >> 8; *(out++) = value; } - else + } + else + { + while (out < end) { + value = g_colmap[*(data++)]; *(out++) = value; *(out++) = value >> 8; *(out++) = value >> 16; @@ -292,19 +294,22 @@ { uint32 value; - while (out < end) + if (g_xserver_be) { - value = g_colmap[*(data++)]; - - if (g_xserver_be) + while (out < end) { + value = g_colmap[*(data++)]; *(out++) = value >> 24; *(out++) = value >> 16; *(out++) = value >> 8; *(out++) = value; } - else + } + else + { + while (out < end) { + value = g_colmap[*(data++)]; *(out++) = value; *(out++) = value >> 8; *(out++) = value >> 16; @@ -593,9 +598,24 @@ static uint8 * translate_image(int width, int height, uint8 * data) { - int size = width * height * g_bpp / 8; - uint8 *out = (uint8 *) xmalloc(size); - uint8 *end = out + size; + int size; + uint8 *out; + uint8 *end; + + /* if server and xserver bpp match, */ + /* and arch(endian) matches, no need to translate */ + /* just return data */ + if (g_arch_match) + { + if (g_depth == 15 && g_server_bpp == 15) + return data; + if (g_depth == 16 && g_server_bpp == 16) + return data; + } + + size = width * height * (g_bpp / 8); + out = (uint8 *) xmalloc(size); + end = out + size; switch (g_server_bpp) { @@ -733,6 +753,10 @@ TrueColorVisual = True; } + test = 1; + g_host_be = !(BOOL) (*(uint8 *) (&test)); + g_xserver_be = (ImageByteOrder(g_display) == MSBFirst); + if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8))) { /* we use a colourmap, so the default visual should do */ @@ -759,6 +783,11 @@ calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l); calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l); calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l); + + /* if RGB video and averything is little endian */ + if (vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) + if (!g_xserver_be && !g_host_be) + g_arch_match = True; } pfm = XListPixmapFormats(g_display, &i); @@ -798,10 +827,6 @@ g_ownbackstore = True; } - test = 1; - g_host_be = !(BOOL) (*(uint8 *) (&test)); - g_xserver_be = (ImageByteOrder(g_display) == MSBFirst); - /* * Determine desktop size */ @@ -931,6 +956,11 @@ XFree(sizehints); } + if (g_embed_wnd) + { + XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0); + } + input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | VisibilityChangeMask | FocusChangeMask; @@ -1372,7 +1402,7 @@ XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height); XFree(image); - if (!g_owncolmap) + if (tdata != data) xfree(tdata); return (HBITMAP) bitmap; } @@ -1411,7 +1441,7 @@ } XFree(image); - if (!g_owncolmap) + if (tdata != data) xfree(tdata); } @@ -1928,6 +1958,12 @@ SET_FOREGROUND(bgcolour); + /* Sometimes, the boxcx value is something really large, like + 32691. This makes XCopyArea fail with Xvnc. The code below + is a quick fix. */ + if (boxx + boxcx > g_width) + boxcx = g_width - boxx; + if (boxcx > 1) { FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);