--- sourceforge.net/trunk/rdesktop/xwin.c 2004/02/25 18:28:52 617 +++ sourceforge.net/trunk/rdesktop/xwin.c 2004/03/25 22:58:45 644 @@ -43,6 +43,7 @@ static int g_x_socket; static Screen *g_screen; Window g_wnd; +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; @@ -169,9 +171,9 @@ split_colour15(uint32 colour) { PixelColour rv; - rv.red = (colour & 0x7c00) >> 7; + rv.red = (colour & 0x7c00) >> 7; rv.green = (colour & 0x03e0) >> 2; - rv.blue = (colour & 0x001f) << 3; + rv.blue = (colour & 0x001f) << 3; return rv; } @@ -179,9 +181,9 @@ split_colour16(uint32 colour) { PixelColour rv; - rv.red = (colour & 0xf800) >> 8; + rv.red = (colour & 0xf800) >> 8; rv.green = (colour & 0x07e0) >> 3; - rv.blue = (colour & 0x001f) << 3; + rv.blue = (colour & 0x001f) << 3; return rv; } @@ -189,9 +191,9 @@ split_colour24(uint32 colour) { PixelColour rv; - rv.blue = (colour & 0xff0000) >> 16; + rv.blue = (colour & 0xff0000) >> 16; rv.green = (colour & 0x00ff00) >> 8; - rv.red = (colour & 0x0000ff); + rv.red = (colour & 0x0000ff); return rv; } @@ -239,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; } @@ -262,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; @@ -286,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; @@ -587,9 +598,21 @@ 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_depth > 8) + if (g_arch_match) + if (g_depth == g_server_bpp) + return data; + + size = width * height * (g_bpp / 8); + out = (uint8 *) xmalloc(size); + end = out + size; switch (g_server_bpp) { @@ -727,6 +750,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 */ @@ -753,6 +780,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); @@ -792,10 +824,6 @@ g_ownbackstore = True; } - test = 1; - g_host_be = !(BOOL) (*(uint8 *) (&test)); - g_xserver_be = (ImageByteOrder(g_display) == MSBFirst); - /* * Determine desktop size */ @@ -925,6 +953,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; @@ -1366,7 +1399,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; } @@ -1405,7 +1438,7 @@ } XFree(image); - if (!g_owncolmap) + if (tdata != data) xfree(tdata); } @@ -1922,6 +1955,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);