brush cache for > 2 color brushes
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1482 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
b64678c9ee
commit
c3dc159869
29
cache.c
29
cache.c
@ -432,30 +432,41 @@ cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor)
|
||||
}
|
||||
|
||||
/* BRUSH CACHE */
|
||||
static BRUSHDATA g_brushcache[64];
|
||||
/* index 0 is 2 colour brush, index 1 is muti colour brush */
|
||||
static BRUSHDATA g_brushcache[2][64];
|
||||
|
||||
/* Retrieve brush from cache */
|
||||
BRUSHDATA *
|
||||
cache_get_brush_data(uint16 cache_idx)
|
||||
cache_get_brush_data(uint8 colour_code, uint8 idx)
|
||||
{
|
||||
if (cache_idx < NUM_ELEMENTS(g_brushcache))
|
||||
colour_code = colour_code == 1 ? 0 : 1;
|
||||
if (idx < NUM_ELEMENTS(g_brushcache[0]))
|
||||
{
|
||||
return &g_brushcache[cache_idx];
|
||||
return &g_brushcache[colour_code][idx];
|
||||
}
|
||||
error("get brush %d\n", cache_idx);
|
||||
error("get brush %d %d\n", colour_code, idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Store brush in cache */
|
||||
/* this function takes over the data pointer in struct, eg, caller gives it up */
|
||||
void
|
||||
cache_put_brush_data(uint16 cache_idx, BRUSHDATA * brush_data)
|
||||
cache_put_brush_data(uint8 colour_code, uint8 idx, BRUSHDATA * brush_data)
|
||||
{
|
||||
if (cache_idx < NUM_ELEMENTS(g_brushcache))
|
||||
BRUSHDATA * bd;
|
||||
|
||||
colour_code = colour_code == 1 ? 0 : 1;
|
||||
if (idx < NUM_ELEMENTS(g_brushcache[0]))
|
||||
{
|
||||
memcpy(&g_brushcache[cache_idx], brush_data, sizeof(BRUSHDATA));
|
||||
bd = &g_brushcache[colour_code][idx];
|
||||
if (bd->data != 0)
|
||||
{
|
||||
xfree(bd->data);
|
||||
}
|
||||
memcpy(bd, brush_data, sizeof(BRUSHDATA));
|
||||
}
|
||||
else
|
||||
{
|
||||
error("put brush %d\n", cache_idx);
|
||||
error("put brush %d %d\n", colour_code, idx);
|
||||
}
|
||||
}
|
||||
|
110
orders.c
110
orders.c
@ -152,30 +152,24 @@ static void
|
||||
setup_brush(BRUSH * out_brush, BRUSH * in_brush)
|
||||
{
|
||||
BRUSHDATA *brush_data;
|
||||
uint16 cache_idx;
|
||||
uint8 brush_bpp;
|
||||
uint8 cache_idx;
|
||||
uint8 colour_code;
|
||||
|
||||
memcpy(out_brush, in_brush, sizeof(BRUSH));
|
||||
if (out_brush->style & 0x80)
|
||||
{
|
||||
brush_bpp = out_brush->style & 0x0f;
|
||||
if (brush_bpp == 1) /* 1 bpp */
|
||||
{
|
||||
colour_code = out_brush->style & 0x0f;
|
||||
cache_idx = out_brush->pattern[0];
|
||||
brush_data = cache_get_brush_data(cache_idx);
|
||||
if (brush_data == NULL)
|
||||
brush_data = cache_get_brush_data(colour_code, cache_idx);
|
||||
if ((brush_data == NULL) || (brush_data->data == NULL))
|
||||
{
|
||||
error("error getting brush data, style %x\n", out_brush->style);
|
||||
out_brush->bd = NULL;
|
||||
memset(out_brush->pattern, 0, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(out_brush->pattern, brush_data->pattern,
|
||||
sizeof(out_brush->pattern));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("bad brush bpp %d\n", brush_bpp);
|
||||
out_brush->bd = brush_data;
|
||||
}
|
||||
out_brush->style = 3;
|
||||
}
|
||||
@ -1154,31 +1148,105 @@ process_fontcache(STREAM s)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_compressed_8x8_brush_data(uint8 * in, uint8 * out, int Bpp)
|
||||
{
|
||||
int x, y, pal_index, in_index, shift, do2, i;
|
||||
uint8 * pal;
|
||||
|
||||
in_index = 0;
|
||||
pal = in + 16;
|
||||
/* read it bottom up */
|
||||
for (y = 7; y >= 0; y--)
|
||||
{
|
||||
/* 2 bytes per row */
|
||||
x = 0;
|
||||
for (do2 = 0; do2 < 2; do2++)
|
||||
{
|
||||
/* 4 pixels per byte */
|
||||
shift = 6;
|
||||
while (shift >= 0)
|
||||
{
|
||||
pal_index = (in[in_index] >> shift) & 3;
|
||||
/* size of palette entries depends on Bpp */
|
||||
for (i = 0; i < Bpp; i++)
|
||||
{
|
||||
out[(y * 8 + x) * Bpp + i] = pal[pal_index * Bpp + i];
|
||||
}
|
||||
x++;
|
||||
shift -= 2;
|
||||
}
|
||||
in_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process a brush cache order */
|
||||
static void
|
||||
process_brushcache(STREAM s, uint16 flags)
|
||||
{
|
||||
BRUSHDATA brush_data;
|
||||
uint8 cache_idx, depth, width, height, size;
|
||||
uint8 cache_idx, colour_code, width, height, size, type;
|
||||
uint8 * comp_brush;
|
||||
int index;
|
||||
int Bpp;
|
||||
|
||||
in_uint8(s, cache_idx);
|
||||
in_uint8(s, depth);
|
||||
in_uint8(s, colour_code);
|
||||
in_uint8(s, width);
|
||||
in_uint8(s, height);
|
||||
in_uint8s(s, 1); /* type, 0x80 = cached */
|
||||
in_uint8(s, type); /* type, 0x8x = cached */
|
||||
in_uint8(s, size);
|
||||
|
||||
DEBUG(("BRUSHCACHE(idx=%d,dp=%d,wd=%d,ht=%d,sz=%d)\n", cache_idx, depth,
|
||||
width, height, size));
|
||||
|
||||
if ((depth == 1) && (width == 8) && (height == 8) && (size == 8))
|
||||
if ((width == 8) && (height == 8))
|
||||
{
|
||||
in_uint8a(s, brush_data.pattern, sizeof(brush_data.pattern));
|
||||
cache_put_brush_data(cache_idx, &brush_data);
|
||||
if (colour_code == 1)
|
||||
{
|
||||
brush_data.colour_code = 1;
|
||||
brush_data.data_size = 8;
|
||||
brush_data.data = xmalloc(8);
|
||||
if (size == 8)
|
||||
{
|
||||
/* read it bottom up */
|
||||
for (index = 7; index >= 0; index--)
|
||||
{
|
||||
in_uint8(s, brush_data.data[index]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warning("ignoring incompatible brush type. display may be incorrect\n");
|
||||
warning("incompatible brush, colour_code %d size %d\n", colour_code, size);
|
||||
}
|
||||
cache_put_brush_data(1, cache_idx, &brush_data);
|
||||
}
|
||||
else if ((colour_code >= 3) && (colour_code <= 6))
|
||||
{
|
||||
Bpp = colour_code - 2;
|
||||
brush_data.colour_code = colour_code;
|
||||
brush_data.data_size = 8 * 8 * Bpp;
|
||||
brush_data.data = xmalloc(8 * 8 * Bpp);
|
||||
if (size == 16 + 4 * Bpp)
|
||||
{
|
||||
in_uint8p(s, comp_brush, 16 + 4 * Bpp);
|
||||
process_compressed_8x8_brush_data(comp_brush, brush_data.data, Bpp);
|
||||
}
|
||||
else
|
||||
{
|
||||
in_uint8a(s, brush_data.data, 8 * 8 * Bpp);
|
||||
}
|
||||
cache_put_brush_data(colour_code, cache_idx, &brush_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
warning("incompatible brush, colour_code %d size %d\n", colour_code, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warning("incompatible brush, width height %d %d\n", width, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
4
proto.h
4
proto.h
@ -44,8 +44,8 @@ void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_pe
|
||||
uint8 * data);
|
||||
RD_HCURSOR cache_get_cursor(uint16 cache_idx);
|
||||
void cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor);
|
||||
BRUSHDATA *cache_get_brush_data(uint16 cache_idx);
|
||||
void cache_put_brush_data(uint16 cache_idx, BRUSHDATA * brush_data);
|
||||
BRUSHDATA *cache_get_brush_data(uint8 colour_code, uint8 idx);
|
||||
void cache_put_brush_data(uint8 colour_code, uint8 idx, BRUSHDATA * brush_data);
|
||||
/* channels.c */
|
||||
VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
|
||||
STREAM channel_init(VCHANNEL * channel, uint32 length);
|
||||
|
4
rdp.c
4
rdp.c
@ -858,6 +858,7 @@ rdp_send_confirm_active(void)
|
||||
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
|
||||
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
|
||||
RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
|
||||
RDP_CAPLEN_BRUSHCACHE +
|
||||
0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
|
||||
4 /* w2k fix, why? */ ;
|
||||
|
||||
@ -885,10 +886,7 @@ rdp_send_confirm_active(void)
|
||||
rdp_out_control_caps(s);
|
||||
rdp_out_pointer_caps(s);
|
||||
rdp_out_share_caps(s);
|
||||
#if 0
|
||||
/* Temporarily disabled due to bug 2167833. When re-enabling, add RDP_CAPLEN_BRUSHCACHE to caplen. */
|
||||
rdp_out_brushcache_caps(s);
|
||||
#endif
|
||||
|
||||
rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
|
||||
rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
|
||||
|
6
types.h
6
types.h
@ -82,7 +82,9 @@ PEN;
|
||||
/* this is whats in the brush cache */
|
||||
typedef struct _BRUSHDATA
|
||||
{
|
||||
uint8 pattern[8];
|
||||
uint32 colour_code;
|
||||
uint32 data_size;
|
||||
uint8 * data;
|
||||
}
|
||||
BRUSHDATA;
|
||||
|
||||
@ -92,7 +94,7 @@ typedef struct _BRUSH
|
||||
uint8 yorigin;
|
||||
uint8 style;
|
||||
uint8 pattern[8];
|
||||
|
||||
BRUSHDATA * bd;
|
||||
}
|
||||
BRUSH;
|
||||
|
||||
|
81
xwin.c
81
xwin.c
@ -3070,6 +3070,8 @@ ui_patblt(uint8 opcode,
|
||||
break;
|
||||
|
||||
case 3: /* Pattern */
|
||||
if (brush->bd == 0) /* rdp4 brush */
|
||||
{
|
||||
for (i = 0; i != 8; i++)
|
||||
ipattern[7 - i] = brush->pattern[i];
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
|
||||
@ -3082,6 +3084,31 @@ ui_patblt(uint8 opcode,
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
else if (brush->bd->colour_code > 1) /* > 1 bpp */
|
||||
{
|
||||
fill = (Pixmap) ui_create_bitmap(8, 8, brush->bd->data);
|
||||
XSetFillStyle(g_display, g_gc, FillTiled);
|
||||
XSetTile(g_display, g_gc, fill);
|
||||
XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
|
||||
FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_bitmap((RD_HBITMAP) fill);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, brush->bd->data);
|
||||
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_BACKSTORE(x, y, cx, cy);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3244,6 +3271,8 @@ ui_polygon(uint8 opcode,
|
||||
break;
|
||||
|
||||
case 3: /* Pattern */
|
||||
if (brush->bd == 0) /* rdp4 brush */
|
||||
{
|
||||
for (i = 0; i != 8; i++)
|
||||
ipattern[7 - i] = brush->pattern[i];
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
|
||||
@ -3256,6 +3285,31 @@ ui_polygon(uint8 opcode,
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
else if (brush->bd->colour_code > 1) /* > 1 bpp */
|
||||
{
|
||||
fill = (Pixmap) ui_create_bitmap(8, 8, brush->bd->data);
|
||||
XSetFillStyle(g_display, g_gc, FillTiled);
|
||||
XSetTile(g_display, g_gc, fill);
|
||||
XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
|
||||
FILL_POLYGON((XPoint *) point, npoints);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_bitmap((RD_HBITMAP) fill);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, brush->bd->data);
|
||||
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_POLYGON((XPoint *) point, npoints);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3322,6 +3376,8 @@ ui_ellipse(uint8 opcode,
|
||||
break;
|
||||
|
||||
case 3: /* Pattern */
|
||||
if (brush->bd == 0) /* rdp4 brush */
|
||||
{
|
||||
for (i = 0; i != 8; i++)
|
||||
ipattern[7 - i] = brush->pattern[i];
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
|
||||
@ -3334,6 +3390,31 @@ ui_ellipse(uint8 opcode,
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
else if (brush->bd->colour_code > 1) /* > 1 bpp */
|
||||
{
|
||||
fill = (Pixmap) ui_create_bitmap(8, 8, brush->bd->data);
|
||||
XSetFillStyle(g_display, g_gc, FillTiled);
|
||||
XSetTile(g_display, g_gc, fill);
|
||||
XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
|
||||
DRAW_ELLIPSE(x, y, cx, cy, fillmode);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_bitmap((RD_HBITMAP) fill);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = (Pixmap) ui_create_glyph(8, 8, brush->bd->data);
|
||||
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);
|
||||
DRAW_ELLIPSE(x, y, cx, cy, fillmode);
|
||||
XSetFillStyle(g_display, g_gc, FillSolid);
|
||||
XSetTSOrigin(g_display, g_gc, 0, 0);
|
||||
ui_destroy_glyph((RD_HGLYPH) fill);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user