Applied patch #1390148 from Ilya Konstantinov: Refactoring of color depth code.
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1041 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
960a02dfeb
commit
acffcd7e9c
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
|
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
|
||||||
|
|
||||||
extern int g_server_bpp;
|
extern int g_server_depth;
|
||||||
extern BOOL g_bitmap_cache;
|
extern BOOL g_bitmap_cache;
|
||||||
extern BOOL g_bitmap_cache_persist_enable;
|
extern BOOL g_bitmap_cache_persist_enable;
|
||||||
extern BOOL g_bitmap_cache_precache;
|
extern BOOL g_bitmap_cache_precache;
|
||||||
@ -131,8 +131,8 @@ pstcache_enumerate(uint8 id, HASH_KEY * keylist)
|
|||||||
{
|
{
|
||||||
memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
|
memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
|
||||||
|
|
||||||
/* Pre-cache (not possible for 8bpp because 8bpp needs a colourmap) */
|
/* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */
|
||||||
if (g_bitmap_cache_precache && cellhdr.stamp && g_server_bpp > 8)
|
if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8)
|
||||||
pstcache_load_bitmap(id, idx);
|
pstcache_load_bitmap(id, idx);
|
||||||
|
|
||||||
/* Sort by stamp */
|
/* Sort by stamp */
|
||||||
@ -179,7 +179,7 @@ pstcache_init(uint8 cache_id)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pstcache_Bpp = (g_server_bpp + 7) / 8;
|
g_pstcache_Bpp = (g_server_depth + 7) / 8;
|
||||||
sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
|
sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
|
||||||
DEBUG(("persistent bitmap cache file: %s\n", filename));
|
DEBUG(("persistent bitmap cache file: %s\n", filename));
|
||||||
|
|
||||||
|
11
rdesktop.c
11
rdesktop.c
@ -69,7 +69,7 @@ int g_pos = 0; /* 0 position unspecified,
|
|||||||
2 xpos neg,
|
2 xpos neg,
|
||||||
4 ypos neg */
|
4 ypos neg */
|
||||||
extern int g_tcp_port_rdp;
|
extern int g_tcp_port_rdp;
|
||||||
int g_server_bpp = 8;
|
int g_server_depth = 8;
|
||||||
int g_win_button_size = 0; /* If zero, disable single app mode */
|
int g_win_button_size = 0; /* If zero, disable single app mode */
|
||||||
BOOL g_bitmap_compression = True;
|
BOOL g_bitmap_compression = True;
|
||||||
BOOL g_sendmotion = True;
|
BOOL g_sendmotion = True;
|
||||||
@ -590,11 +590,12 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
g_server_bpp = strtol(optarg, NULL, 10);
|
g_server_depth = strtol(optarg, NULL, 10);
|
||||||
if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
|
if (g_server_depth != 8 &&
|
||||||
&& g_server_bpp != 24)
|
g_server_depth != 16 &&
|
||||||
|
g_server_depth != 15 && g_server_depth != 24)
|
||||||
{
|
{
|
||||||
error("invalid server bpp\n");
|
error("Invalid server colour depth.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
23
rdp.c
23
rdp.c
@ -44,7 +44,7 @@ extern BOOL g_polygon_ellipse_orders;
|
|||||||
extern BOOL g_use_rdp5;
|
extern BOOL g_use_rdp5;
|
||||||
extern uint16 g_server_rdp_version;
|
extern uint16 g_server_rdp_version;
|
||||||
extern uint32 g_rdp5_performanceflags;
|
extern uint32 g_rdp5_performanceflags;
|
||||||
extern int g_server_bpp;
|
extern int g_server_depth;
|
||||||
extern int g_width;
|
extern int g_width;
|
||||||
extern int g_height;
|
extern int g_height;
|
||||||
extern BOOL g_bitmap_cache;
|
extern BOOL g_bitmap_cache;
|
||||||
@ -620,7 +620,7 @@ rdp_out_bitmap_caps(STREAM s)
|
|||||||
out_uint16_le(s, RDP_CAPSET_BITMAP);
|
out_uint16_le(s, RDP_CAPSET_BITMAP);
|
||||||
out_uint16_le(s, RDP_CAPLEN_BITMAP);
|
out_uint16_le(s, RDP_CAPLEN_BITMAP);
|
||||||
|
|
||||||
out_uint16_le(s, g_server_bpp); /* Preferred BPP */
|
out_uint16_le(s, g_server_depth); /* Preferred colour depth */
|
||||||
out_uint16_le(s, 1); /* Receive 1 BPP */
|
out_uint16_le(s, 1); /* Receive 1 BPP */
|
||||||
out_uint16_le(s, 1); /* Receive 4 BPP */
|
out_uint16_le(s, 1); /* Receive 4 BPP */
|
||||||
out_uint16_le(s, 1); /* Receive 8 BPP */
|
out_uint16_le(s, 1); /* Receive 8 BPP */
|
||||||
@ -684,7 +684,7 @@ rdp_out_bmpcache_caps(STREAM s)
|
|||||||
out_uint16_le(s, RDP_CAPSET_BMPCACHE);
|
out_uint16_le(s, RDP_CAPSET_BMPCACHE);
|
||||||
out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
|
out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
|
||||||
|
|
||||||
Bpp = (g_server_bpp + 7) / 8;
|
Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
|
||||||
out_uint8s(s, 24); /* unused */
|
out_uint8s(s, 24); /* unused */
|
||||||
out_uint16_le(s, 0x258); /* entries */
|
out_uint16_le(s, 0x258); /* entries */
|
||||||
out_uint16_le(s, 0x100 * Bpp); /* max cell size */
|
out_uint16_le(s, 0x100 * Bpp); /* max cell size */
|
||||||
@ -881,28 +881,29 @@ rdp_process_general_caps(STREAM s)
|
|||||||
static void
|
static void
|
||||||
rdp_process_bitmap_caps(STREAM s)
|
rdp_process_bitmap_caps(STREAM s)
|
||||||
{
|
{
|
||||||
uint16 width, height, bpp;
|
uint16 width, height, depth;
|
||||||
|
|
||||||
in_uint16_le(s, bpp);
|
in_uint16_le(s, depth);
|
||||||
in_uint8s(s, 6);
|
in_uint8s(s, 6);
|
||||||
|
|
||||||
in_uint16_le(s, width);
|
in_uint16_le(s, width);
|
||||||
in_uint16_le(s, height);
|
in_uint16_le(s, height);
|
||||||
|
|
||||||
DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
|
DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The server may limit bpp and change the size of the desktop (for
|
* The server may limit depth and change the size of the desktop (for
|
||||||
* example when shadowing another session).
|
* example when shadowing another session).
|
||||||
*/
|
*/
|
||||||
if (g_server_bpp != bpp)
|
if (g_server_depth != depth)
|
||||||
{
|
{
|
||||||
warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
|
warning("Remote desktop does not support colour depth %d; falling back to %d\n",
|
||||||
g_server_bpp = bpp;
|
g_server_depth, depth);
|
||||||
|
g_server_depth = depth;
|
||||||
}
|
}
|
||||||
if (g_width != width || g_height != height)
|
if (g_width != width || g_height != height)
|
||||||
{
|
{
|
||||||
warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
|
warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
|
||||||
width, height);
|
width, height);
|
||||||
g_width = width;
|
g_width = width;
|
||||||
g_height = height;
|
g_height = height;
|
||||||
|
6
secure.c
6
secure.c
@ -37,7 +37,7 @@ extern BOOL g_encryption;
|
|||||||
extern BOOL g_licence_issued;
|
extern BOOL g_licence_issued;
|
||||||
extern BOOL g_use_rdp5;
|
extern BOOL g_use_rdp5;
|
||||||
extern BOOL g_console_session;
|
extern BOOL g_console_session;
|
||||||
extern int g_server_bpp;
|
extern int g_server_depth;
|
||||||
extern uint16 mcs_userid;
|
extern uint16 mcs_userid;
|
||||||
extern VCHANNEL g_channels[];
|
extern VCHANNEL g_channels[];
|
||||||
extern unsigned int g_num_channels;
|
extern unsigned int g_num_channels;
|
||||||
@ -459,7 +459,7 @@ sec_out_mcs_data(STREAM s)
|
|||||||
out_uint16_le(s, 1);
|
out_uint16_le(s, 1);
|
||||||
|
|
||||||
out_uint32(s, 0);
|
out_uint32(s, 0);
|
||||||
out_uint8(s, g_server_bpp);
|
out_uint8(s, g_server_depth);
|
||||||
out_uint16_le(s, 0x0700);
|
out_uint16_le(s, 0x0700);
|
||||||
out_uint8(s, 0);
|
out_uint8(s, 0);
|
||||||
out_uint32_le(s, 1);
|
out_uint32_le(s, 1);
|
||||||
@ -764,7 +764,7 @@ sec_process_srv_info(STREAM s)
|
|||||||
if (1 == g_server_rdp_version)
|
if (1 == g_server_rdp_version)
|
||||||
{
|
{
|
||||||
g_use_rdp5 = 0;
|
g_use_rdp5 = 0;
|
||||||
g_server_bpp = 8;
|
g_server_depth = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
389
xwin.c
389
xwin.c
@ -38,7 +38,9 @@ extern BOOL g_fullscreen;
|
|||||||
extern BOOL g_grab_keyboard;
|
extern BOOL g_grab_keyboard;
|
||||||
extern BOOL g_hide_decorations;
|
extern BOOL g_hide_decorations;
|
||||||
extern char g_title[];
|
extern char g_title[];
|
||||||
extern int g_server_bpp;
|
/* Color depth of the RDP session.
|
||||||
|
As of RDP 5.1, it may be 8, 15, 16 or 24. */
|
||||||
|
extern int g_server_depth;
|
||||||
extern int g_win_button_size;
|
extern int g_win_button_size;
|
||||||
|
|
||||||
Display *g_display;
|
Display *g_display;
|
||||||
@ -53,7 +55,13 @@ static GC g_gc = NULL;
|
|||||||
static GC g_create_bitmap_gc = NULL;
|
static GC g_create_bitmap_gc = NULL;
|
||||||
static GC g_create_glyph_gc = NULL;
|
static GC g_create_glyph_gc = NULL;
|
||||||
static Visual *g_visual;
|
static Visual *g_visual;
|
||||||
|
/* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual).
|
||||||
|
This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined
|
||||||
|
as far as we're concerned. */
|
||||||
static int g_depth;
|
static int g_depth;
|
||||||
|
/* Bits-per-Pixel of the pixmaps we'll be using to draw on our window.
|
||||||
|
This may be larger than g_depth, in which case some of the bits would
|
||||||
|
be kept solely for alignment (e.g. 32bpp pixmaps on a 24bpp visual). */
|
||||||
static int g_bpp;
|
static int g_bpp;
|
||||||
static XIM g_IM;
|
static XIM g_IM;
|
||||||
static XIC g_IC;
|
static XIC g_IC;
|
||||||
@ -63,7 +71,13 @@ static HCURSOR g_null_cursor = NULL;
|
|||||||
static Atom g_protocol_atom, g_kill_atom;
|
static Atom g_protocol_atom, g_kill_atom;
|
||||||
static BOOL g_focused;
|
static BOOL g_focused;
|
||||||
static BOOL g_mouse_in_wnd;
|
static BOOL g_mouse_in_wnd;
|
||||||
static BOOL g_arch_match = False; /* set to True if RGB XServer and little endian */
|
/* Indicates the visual is has 15, 16 or 24 depth
|
||||||
|
and the same color channel masks as its RDP equivalent. */
|
||||||
|
static BOOL g_compatible_depth;
|
||||||
|
/* Indicates whether RDP's bitmaps and our XImages have the same
|
||||||
|
binary format. If so, we can avoid an expensive translation.
|
||||||
|
If this is True, so is g_compatible_depth. */
|
||||||
|
static BOOL g_no_translate_image = False;
|
||||||
|
|
||||||
/* endianness */
|
/* endianness */
|
||||||
static BOOL g_host_be;
|
static BOOL g_host_be;
|
||||||
@ -150,7 +164,7 @@ extern BOOL g_owncolmap;
|
|||||||
static Colormap g_xcolmap;
|
static Colormap g_xcolmap;
|
||||||
static uint32 *g_colmap = NULL;
|
static uint32 *g_colmap = NULL;
|
||||||
|
|
||||||
#define TRANSLATE(col) ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
|
#define TRANSLATE(col) ( g_server_depth != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
|
||||||
#define SET_FOREGROUND(col) XSetForeground(g_display, g_gc, TRANSLATE(col));
|
#define SET_FOREGROUND(col) XSetForeground(g_display, g_gc, TRANSLATE(col));
|
||||||
#define SET_BACKGROUND(col) XSetBackground(g_display, g_gc, TRANSLATE(col));
|
#define SET_BACKGROUND(col) XSetBackground(g_display, g_gc, TRANSLATE(col));
|
||||||
|
|
||||||
@ -240,7 +254,7 @@ static uint32
|
|||||||
translate_colour(uint32 colour)
|
translate_colour(uint32 colour)
|
||||||
{
|
{
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
switch (g_server_bpp)
|
switch (g_server_depth)
|
||||||
{
|
{
|
||||||
case 15:
|
case 15:
|
||||||
SPLITCOLOUR15(colour, pc);
|
SPLITCOLOUR15(colour, pc);
|
||||||
@ -251,6 +265,12 @@ translate_colour(uint32 colour)
|
|||||||
case 24:
|
case 24:
|
||||||
SPLITCOLOUR24(colour, pc);
|
SPLITCOLOUR24(colour, pc);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
/* Avoid warning */
|
||||||
|
pc.red = 0;
|
||||||
|
pc.green = 0;
|
||||||
|
pc.blue = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return MAKECOLOUR(pc);
|
return MAKECOLOUR(pc);
|
||||||
}
|
}
|
||||||
@ -302,7 +322,7 @@ translate8to16(const uint8 * data, uint8 * out, uint8 * end)
|
|||||||
{
|
{
|
||||||
uint16 value;
|
uint16 value;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT2
|
REPEAT2
|
||||||
@ -336,7 +356,7 @@ translate8to24(const uint8 * data, uint8 * out, uint8 * end)
|
|||||||
{
|
{
|
||||||
uint32 value;
|
uint32 value;
|
||||||
|
|
||||||
if (g_xserver_be)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
while (out < end)
|
while (out < end)
|
||||||
{
|
{
|
||||||
@ -359,7 +379,7 @@ translate8to32(const uint8 * data, uint8 * out, uint8 * end)
|
|||||||
{
|
{
|
||||||
uint32 value;
|
uint32 value;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT4
|
REPEAT4
|
||||||
@ -431,7 +451,7 @@ translate15to24(const uint16 * data, uint8 * out, uint8 * end)
|
|||||||
uint16 pixel;
|
uint16 pixel;
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT3
|
REPEAT3
|
||||||
@ -481,7 +501,7 @@ translate15to32(const uint16 * data, uint8 * out, uint8 * end)
|
|||||||
uint32 value;
|
uint32 value;
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT4
|
REPEAT4
|
||||||
@ -589,7 +609,7 @@ translate16to24(const uint16 * data, uint8 * out, uint8 * end)
|
|||||||
uint16 pixel;
|
uint16 pixel;
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT3
|
REPEAT3
|
||||||
@ -659,7 +679,7 @@ translate16to32(const uint16 * data, uint8 * out, uint8 * end)
|
|||||||
uint32 value;
|
uint32 value;
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
REPEAT4
|
REPEAT4
|
||||||
@ -788,7 +808,7 @@ translate24to32(const uint8 * data, uint8 * out, uint8 * end)
|
|||||||
uint32 value;
|
uint32 value;
|
||||||
PixelColour pc;
|
PixelColour pc;
|
||||||
|
|
||||||
if (g_arch_match)
|
if (g_compatible_depth)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef NEED_ALIGN
|
#ifdef NEED_ALIGN
|
||||||
@ -843,16 +863,19 @@ translate_image(int width, int height, uint8 * data)
|
|||||||
uint8 *out;
|
uint8 *out;
|
||||||
uint8 *end;
|
uint8 *end;
|
||||||
|
|
||||||
/* if server and xserver bpp match, */
|
/*
|
||||||
/* and arch(endian) matches, no need to translate */
|
If RDP depth and X Visual depths match,
|
||||||
/* just return data */
|
and arch(endian) matches, no need to translate:
|
||||||
if (g_arch_match)
|
just return data.
|
||||||
|
Note: select_visual should've already ensured g_no_translate
|
||||||
|
is only set for compatible depths, but the RDP depth might've
|
||||||
|
changed during connection negotiations.
|
||||||
|
*/
|
||||||
|
if (g_no_translate_image)
|
||||||
{
|
{
|
||||||
if (g_depth == 15 && g_server_bpp == 15)
|
if ((g_depth == 15 && g_server_depth == 15) ||
|
||||||
return data;
|
(g_depth == 16 && g_server_depth == 16) ||
|
||||||
if (g_depth == 16 && g_server_bpp == 16)
|
(g_depth == 24 && g_server_depth == 24))
|
||||||
return data;
|
|
||||||
if (g_depth == 24 && g_bpp == 24 && g_server_bpp == 24)
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,7 +883,7 @@ translate_image(int width, int height, uint8 * data)
|
|||||||
out = (uint8 *) xmalloc(size);
|
out = (uint8 *) xmalloc(size);
|
||||||
end = out + size;
|
end = out + size;
|
||||||
|
|
||||||
switch (g_server_bpp)
|
switch (g_server_depth)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
switch (g_bpp)
|
switch (g_bpp)
|
||||||
@ -958,16 +981,212 @@ calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
|
|||||||
*shift_r = 8 - ffs(mask & ~(mask >> 1));
|
*shift_r = 8 - ffs(mask & ~(mask >> 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a mask of a colour channel (e.g. XVisualInfo.red_mask),
|
||||||
|
calculates the bits-per-pixel of this channel (a.k.a. colour weight).
|
||||||
|
*/
|
||||||
|
static unsigned
|
||||||
|
calculate_mask_weight(uint32 mask)
|
||||||
|
{
|
||||||
|
unsigned weight = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
weight += (mask & 1);
|
||||||
|
}
|
||||||
|
while (mask >>= 1);
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
select_visual()
|
||||||
|
{
|
||||||
|
XPixmapFormatValues *pfm;
|
||||||
|
int pixmap_formats_count, visuals_count;
|
||||||
|
XVisualInfo *vmatches = NULL;
|
||||||
|
XVisualInfo template;
|
||||||
|
int i;
|
||||||
|
unsigned red_weight, blue_weight, green_weight;
|
||||||
|
|
||||||
|
red_weight = blue_weight = green_weight = 0;
|
||||||
|
|
||||||
|
pfm = XListPixmapFormats(g_display, &pixmap_formats_count);
|
||||||
|
if (pfm == NULL)
|
||||||
|
{
|
||||||
|
error("Unable to get list of pixmap formats from display.\n");
|
||||||
|
XCloseDisplay(g_display);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search for best TrueColor visual */
|
||||||
|
template.class = TrueColor;
|
||||||
|
vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &visuals_count);
|
||||||
|
g_visual = NULL;
|
||||||
|
g_no_translate_image = False;
|
||||||
|
g_compatible_depth = False;
|
||||||
|
if (vmatches != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < visuals_count; ++i)
|
||||||
|
{
|
||||||
|
XVisualInfo *visual_info = &vmatches[i];
|
||||||
|
|
||||||
|
/* Try to find a no-translation visual that'll
|
||||||
|
allow us to use RDP bitmaps directly as ZPixmaps. */
|
||||||
|
if (!g_xserver_be && (((visual_info->depth == 15) &&
|
||||||
|
/* R5G5B5 */
|
||||||
|
(visual_info->red_mask == 0x7c00) &&
|
||||||
|
(visual_info->green_mask == 0x3e0) &&
|
||||||
|
(visual_info->blue_mask == 0x1f)) ||
|
||||||
|
((visual_info->depth == 16) &&
|
||||||
|
/* R5G6B5 */
|
||||||
|
(visual_info->red_mask == 0xf800) &&
|
||||||
|
(visual_info->green_mask == 0x7e0) &&
|
||||||
|
(visual_info->blue_mask == 0x1f)) ||
|
||||||
|
((visual_info->depth == 24) &&
|
||||||
|
/* R8G8B8 */
|
||||||
|
(visual_info->red_mask == 0xff0000) &&
|
||||||
|
(visual_info->green_mask == 0xff00) &&
|
||||||
|
(visual_info->blue_mask == 0xff))))
|
||||||
|
{
|
||||||
|
g_visual = visual_info->visual;
|
||||||
|
g_depth = visual_info->depth;
|
||||||
|
g_compatible_depth = True;
|
||||||
|
g_no_translate_image = (visual_info->depth == g_server_depth);
|
||||||
|
if (g_no_translate_image)
|
||||||
|
/* We found the best visual */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_compatible_depth = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visual_info->depth > 24)
|
||||||
|
{
|
||||||
|
/* Avoid 32-bit visuals and likes like the plague.
|
||||||
|
They're either untested or proven to work bad
|
||||||
|
(e.g. nvidia's Composite 32-bit visual).
|
||||||
|
Most implementation offer a 24-bit visual anyway. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only care for visuals, for whose BPPs (not depths!)
|
||||||
|
we have a translateXtoY function. */
|
||||||
|
BOOL can_translate_to_bpp = False;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < pixmap_formats_count; ++j)
|
||||||
|
{
|
||||||
|
if (pfm[j].depth == visual_info->depth)
|
||||||
|
{
|
||||||
|
if ((pfm[j].bits_per_pixel == 16) ||
|
||||||
|
(pfm[j].bits_per_pixel == 24) ||
|
||||||
|
(pfm[j].bits_per_pixel == 32))
|
||||||
|
{
|
||||||
|
can_translate_to_bpp = True;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prefer formats which have the most colour depth.
|
||||||
|
We're being truly aristocratic here, minding each
|
||||||
|
weight on its own. */
|
||||||
|
if (can_translate_to_bpp)
|
||||||
|
{
|
||||||
|
unsigned vis_red_weight =
|
||||||
|
calculate_mask_weight(visual_info->red_mask);
|
||||||
|
unsigned vis_green_weight =
|
||||||
|
calculate_mask_weight(visual_info->green_mask);
|
||||||
|
unsigned vis_blue_weight =
|
||||||
|
calculate_mask_weight(visual_info->blue_mask);
|
||||||
|
if ((vis_red_weight >= red_weight)
|
||||||
|
&& (vis_green_weight >= green_weight)
|
||||||
|
&& (vis_blue_weight >= blue_weight))
|
||||||
|
{
|
||||||
|
red_weight = vis_red_weight;
|
||||||
|
green_weight = vis_green_weight;
|
||||||
|
blue_weight = vis_blue_weight;
|
||||||
|
g_visual = visual_info->visual;
|
||||||
|
g_depth = visual_info->depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(vmatches);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_visual != NULL)
|
||||||
|
{
|
||||||
|
g_owncolmap = False;
|
||||||
|
calculate_shifts(g_visual->red_mask, &g_red_shift_r, &g_red_shift_l);
|
||||||
|
calculate_shifts(g_visual->green_mask, &g_green_shift_r, &g_green_shift_l);
|
||||||
|
calculate_shifts(g_visual->blue_mask, &g_blue_shift_r, &g_blue_shift_l);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
template.class = PseudoColor;
|
||||||
|
template.depth = 8;
|
||||||
|
template.colormap_size = 256;
|
||||||
|
vmatches =
|
||||||
|
XGetVisualInfo(g_display,
|
||||||
|
VisualClassMask | VisualDepthMask | VisualColormapSizeMask,
|
||||||
|
&template, &visuals_count);
|
||||||
|
if (vmatches == NULL)
|
||||||
|
{
|
||||||
|
error("No usable TrueColor or PseudoColor visuals on this display.\n");
|
||||||
|
XCloseDisplay(g_display);
|
||||||
|
XFree(pfm);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we use a colourmap, so the default visual should do */
|
||||||
|
g_owncolmap = True;
|
||||||
|
g_visual = vmatches[0].visual;
|
||||||
|
g_depth = vmatches[0].depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bpp = 0;
|
||||||
|
for (i = 0; i < pixmap_formats_count; ++i)
|
||||||
|
{
|
||||||
|
XPixmapFormatValues *pf = &pfm[i];
|
||||||
|
if (pf->depth == g_depth)
|
||||||
|
{
|
||||||
|
g_bpp = pf->bits_per_pixel;
|
||||||
|
|
||||||
|
if (g_no_translate_image)
|
||||||
|
{
|
||||||
|
switch (g_server_depth)
|
||||||
|
{
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
if (g_bpp != 16)
|
||||||
|
g_no_translate_image = False;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
/* Yes, this will force image translation
|
||||||
|
on most modern servers which use 32 bits
|
||||||
|
for R8G8B8. */
|
||||||
|
if (g_bpp != 24)
|
||||||
|
g_no_translate_image = False;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_no_translate_image = False;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pixmap formats list is a depth-to-bpp mapping --
|
||||||
|
there's just a single entry for every depth,
|
||||||
|
so we can safely break here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(pfm);
|
||||||
|
pfm = NULL;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
ui_init(void)
|
ui_init(void)
|
||||||
{
|
{
|
||||||
XVisualInfo vi;
|
int screen_num;
|
||||||
XPixmapFormatValues *pfm;
|
|
||||||
uint16 test;
|
|
||||||
int i, screen_num, nvisuals;
|
|
||||||
XVisualInfo *vmatches = NULL;
|
|
||||||
XVisualInfo template;
|
|
||||||
Bool TrueColorVisual = False;
|
|
||||||
|
|
||||||
g_display = XOpenDisplay(NULL);
|
g_display = XOpenDisplay(NULL);
|
||||||
if (g_display == NULL)
|
if (g_display == NULL)
|
||||||
@ -976,108 +1195,46 @@ ui_init(void)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint16 endianess_test = 1;
|
||||||
|
g_host_be = !(BOOL) (*(uint8 *) (&endianess_test));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
|
||||||
screen_num = DefaultScreen(g_display);
|
screen_num = DefaultScreen(g_display);
|
||||||
g_x_socket = ConnectionNumber(g_display);
|
g_x_socket = ConnectionNumber(g_display);
|
||||||
g_screen = ScreenOfDisplay(g_display, screen_num);
|
g_screen = ScreenOfDisplay(g_display, screen_num);
|
||||||
g_depth = DefaultDepthOfScreen(g_screen);
|
g_depth = DefaultDepthOfScreen(g_screen);
|
||||||
|
|
||||||
/* Search for best TrueColor depth */
|
if (!select_visual())
|
||||||
template.class = TrueColor;
|
|
||||||
vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
|
|
||||||
|
|
||||||
nvisuals--;
|
|
||||||
while (nvisuals >= 0)
|
|
||||||
{
|
|
||||||
if ((vmatches + nvisuals)->depth > g_depth)
|
|
||||||
{
|
|
||||||
g_depth = (vmatches + nvisuals)->depth;
|
|
||||||
}
|
|
||||||
nvisuals--;
|
|
||||||
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 */
|
|
||||||
g_visual = DefaultVisualOfScreen(g_screen);
|
|
||||||
g_depth = DefaultDepthOfScreen(g_screen);
|
|
||||||
|
|
||||||
/* Do not allocate colours on a TrueColor visual */
|
|
||||||
if (g_visual->class == TrueColor)
|
|
||||||
{
|
|
||||||
g_owncolmap = False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* need a truecolour visual */
|
|
||||||
if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
|
|
||||||
{
|
|
||||||
error("The display does not support true colour - high colour support unavailable.\n");
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_visual = vi.visual;
|
|
||||||
g_owncolmap = False;
|
|
||||||
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 everything is little endian */
|
|
||||||
if ((vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) &&
|
|
||||||
!g_xserver_be && !g_host_be)
|
|
||||||
{
|
|
||||||
if (g_depth <= 16 || (g_red_shift_l == 16 && g_green_shift_l == 8 &&
|
|
||||||
g_blue_shift_l == 0))
|
|
||||||
{
|
|
||||||
g_arch_match = True;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_arch_match)
|
|
||||||
{
|
|
||||||
DEBUG(("Architectures match, enabling little endian optimisations.\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pfm = XListPixmapFormats(g_display, &i);
|
|
||||||
if (pfm != NULL)
|
|
||||||
{
|
|
||||||
/* Use maximum bpp for this depth - this is generally
|
|
||||||
desirable, e.g. 24 bits->32 bits. */
|
|
||||||
while (i--)
|
|
||||||
{
|
|
||||||
if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
|
|
||||||
{
|
|
||||||
g_bpp = pfm[i].bits_per_pixel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XFree(pfm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_bpp < 8)
|
|
||||||
{
|
|
||||||
error("Less than 8 bpp not currently supported.\n");
|
|
||||||
XCloseDisplay(g_display);
|
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
|
if (g_no_translate_image)
|
||||||
|
{
|
||||||
|
DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_server_depth > g_bpp)
|
||||||
|
{
|
||||||
|
warning("Remote desktop colour depth %d higher than display colour depth %d.\n",
|
||||||
|
g_server_depth, g_bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(("RDP depth: %d, display depth: %d, display bpp: %d, X server BE: %d, host BE: %d\n",
|
||||||
|
g_server_depth, g_depth, g_bpp, g_xserver_be, g_host_be));
|
||||||
|
|
||||||
if (!g_owncolmap)
|
if (!g_owncolmap)
|
||||||
{
|
{
|
||||||
g_xcolmap =
|
g_xcolmap =
|
||||||
XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
|
XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
|
||||||
AllocNone);
|
AllocNone);
|
||||||
if (g_depth <= 8)
|
if (g_depth <= 8)
|
||||||
warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
|
warning("Display colour depth is %d bit: you may want to use -C for a private colourmap.\n", g_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
|
if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
|
||||||
{
|
{
|
||||||
warning("External BackingStore not available, using internal\n");
|
warning("External BackingStore not available. Using internal.\n");
|
||||||
g_ownbackstore = True;
|
g_ownbackstore = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,7 +1285,7 @@ ui_init(void)
|
|||||||
|
|
||||||
xclip_init();
|
xclip_init();
|
||||||
|
|
||||||
DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
|
DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_depth, g_bpp, g_depth));
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
@ -1689,7 +1846,7 @@ ui_create_bitmap(int width, int height, uint8 * data)
|
|||||||
uint8 *tdata;
|
uint8 *tdata;
|
||||||
int bitmap_pad;
|
int bitmap_pad;
|
||||||
|
|
||||||
if (g_server_bpp == 8)
|
if (g_server_depth == 8)
|
||||||
{
|
{
|
||||||
bitmap_pad = 8;
|
bitmap_pad = 8;
|
||||||
}
|
}
|
||||||
@ -1721,7 +1878,7 @@ ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * dat
|
|||||||
uint8 *tdata;
|
uint8 *tdata;
|
||||||
int bitmap_pad;
|
int bitmap_pad;
|
||||||
|
|
||||||
if (g_server_bpp == 8)
|
if (g_server_depth == 8)
|
||||||
{
|
{
|
||||||
bitmap_pad = 8;
|
bitmap_pad = 8;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user