16bit
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@308 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
b417d5ed8a
commit
4b26f4fc6b
221
bitmap.c
221
bitmap.c
@ -21,6 +21,7 @@
|
||||
#include "rdesktop.h"
|
||||
|
||||
#define CVAL(p) (*(p++))
|
||||
#define CVAL16(p) (*(((uint16*)p)++))
|
||||
|
||||
#define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
|
||||
|
||||
@ -43,7 +44,7 @@
|
||||
}
|
||||
|
||||
BOOL
|
||||
bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size)
|
||||
bitmap_decompress8(unsigned char *output, int width, int height, unsigned char *input, int size)
|
||||
{
|
||||
unsigned char *end = input + size;
|
||||
unsigned char *prevline = NULL, *line = NULL;
|
||||
@ -246,3 +247,221 @@ bitmap_decompress(unsigned char *output, int width, int height, unsigned char *i
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL
|
||||
bitmap_decompress16(unsigned char *output, int width, int height, unsigned char *input, int size)
|
||||
{
|
||||
unsigned char *end = input + size;
|
||||
uint16 *prevline = NULL, *line = NULL;
|
||||
int opcode, count, offset, isfillormix, x = width;
|
||||
int lastopcode = -1, insertmix = False, bicolour = False;
|
||||
uint8 code;
|
||||
uint16 colour1 = 0, colour2 = 0;
|
||||
uint8 mixmask, mask = 0;
|
||||
uint16 mix = 0xffff;
|
||||
int fom_mask = 0;
|
||||
|
||||
while (input < end)
|
||||
{
|
||||
fom_mask = 0;
|
||||
code = CVAL(input);
|
||||
opcode = code >> 4;
|
||||
|
||||
/* Handle different opcode forms */
|
||||
switch (opcode)
|
||||
{
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
opcode -= 6;
|
||||
count = code & 0xf;
|
||||
offset = 16;
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
opcode = code & 0xf;
|
||||
if (opcode < 9)
|
||||
{
|
||||
count = CVAL(input);
|
||||
count |= CVAL(input) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit
|
||||
}
|
||||
offset = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
opcode >>= 1;
|
||||
count = code & 0x1f;
|
||||
offset = 32;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle strange cases for counts */
|
||||
if (offset != 0)
|
||||
{
|
||||
isfillormix = ((opcode == 2) || (opcode == 7));
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
if (isfillormix)
|
||||
count = CVAL(input) + 1;
|
||||
else
|
||||
count = CVAL(input) + offset;
|
||||
}
|
||||
else if (isfillormix)
|
||||
{
|
||||
count <<= 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read preliminary data */
|
||||
switch (opcode)
|
||||
{
|
||||
case 0: /* Fill */
|
||||
if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
|
||||
insertmix = True;
|
||||
break;
|
||||
case 8: /* Bicolour */
|
||||
colour1 = CVAL16(input);
|
||||
case 3: /* Colour */
|
||||
colour2 = CVAL16(input);
|
||||
break;
|
||||
case 6: /* SetMix/Mix */
|
||||
case 7: /* SetMix/FillOrMix */
|
||||
mix = CVAL16(input);
|
||||
opcode -= 5;
|
||||
break;
|
||||
case 9: /* FillOrMix_1 */
|
||||
mask = 0x03;
|
||||
opcode = 0x02;
|
||||
fom_mask = 3;
|
||||
break;
|
||||
case 0x0a: /* FillOrMix_2 */
|
||||
mask = 0x05;
|
||||
opcode = 0x02;
|
||||
fom_mask = 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
lastopcode = opcode;
|
||||
mixmask = 0;
|
||||
|
||||
/* Output body */
|
||||
while (count > 0)
|
||||
{
|
||||
if (x >= width)
|
||||
{
|
||||
if (height <= 0)
|
||||
return False;
|
||||
|
||||
x = 0;
|
||||
height--;
|
||||
|
||||
prevline = line;
|
||||
line = (uint16*)output + height * width;
|
||||
}
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0: /* Fill */
|
||||
if (insertmix)
|
||||
{
|
||||
if (prevline == NULL)
|
||||
line[x] = mix;
|
||||
else
|
||||
line[x] = prevline[x] ^ mix;
|
||||
|
||||
insertmix = False;
|
||||
count--;
|
||||
x++;
|
||||
}
|
||||
|
||||
if (prevline == NULL)
|
||||
{
|
||||
REPEAT(line[x] = 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
REPEAT(line[x] = prevline[x]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* Mix */
|
||||
if (prevline == NULL)
|
||||
{
|
||||
REPEAT(line[x] = mix);
|
||||
}
|
||||
else
|
||||
{
|
||||
REPEAT(line[x] = prevline[x] ^ mix);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Fill or Mix */
|
||||
if (prevline == NULL)
|
||||
{
|
||||
REPEAT(MASK_UPDATE();
|
||||
if (mask & mixmask) line[x] = mix;
|
||||
else
|
||||
line[x] = 0;);
|
||||
}
|
||||
else
|
||||
{
|
||||
REPEAT(MASK_UPDATE();
|
||||
if (mask & mixmask)
|
||||
line[x] = prevline[x] ^ mix;
|
||||
else
|
||||
line[x] = prevline[x];);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* Colour */
|
||||
REPEAT(line[x] = colour2);
|
||||
break;
|
||||
|
||||
case 4: /* Copy */
|
||||
REPEAT(line[x] = CVAL16(input));
|
||||
break;
|
||||
|
||||
case 8: /* Bicolour */
|
||||
REPEAT(if (bicolour)
|
||||
{
|
||||
line[x] = colour2; bicolour = False;}
|
||||
else
|
||||
{
|
||||
line[x] = colour1; bicolour = True; count++;}
|
||||
);
|
||||
break;
|
||||
|
||||
case 0xd: /* White */
|
||||
REPEAT(line[x] = 0xffff);
|
||||
break;
|
||||
|
||||
case 0xe: /* Black */
|
||||
REPEAT(line[x] = 0x00);
|
||||
break;
|
||||
|
||||
default:
|
||||
unimpl("bitmap opcode 0x%x\n", opcode);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL
|
||||
bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int bpp)
|
||||
{
|
||||
if (bpp == 8)
|
||||
return bitmap_decompress8(output, width, height, input, size);
|
||||
else if (bpp == 16)
|
||||
return bitmap_decompress16(output, width, height, input, size);
|
||||
else
|
||||
return False;
|
||||
}
|
||||
|
35
orders.c
35
orders.c
@ -71,10 +71,15 @@ rdp_in_coord(STREAM s, uint16 * coord, BOOL delta)
|
||||
|
||||
/* Read a colour entry */
|
||||
static void
|
||||
rdp_in_colour(STREAM s, uint8 * colour)
|
||||
rdp_in_colour(STREAM s, uint32 * colour)
|
||||
{
|
||||
in_uint8(s, *colour);
|
||||
s->p += 2;
|
||||
uint32 i;
|
||||
in_uint8(s, i);
|
||||
*colour = i;
|
||||
in_uint8(s, i);
|
||||
*colour |= i << 8;
|
||||
in_uint8(s, i);
|
||||
*colour |= i << 16;
|
||||
}
|
||||
|
||||
/* Parse bounds information */
|
||||
@ -279,6 +284,7 @@ process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
|
||||
static void
|
||||
process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
|
||||
{
|
||||
uint32 i;
|
||||
if (present & 0x01)
|
||||
rdp_in_coord(s, &os->x, delta);
|
||||
|
||||
@ -292,7 +298,22 @@ process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
|
||||
rdp_in_coord(s, &os->cy, delta);
|
||||
|
||||
if (present & 0x10)
|
||||
in_uint8(s, os->colour);
|
||||
{
|
||||
in_uint8(s, i);
|
||||
os->colour = (os->colour & 0xffffff00) | i;
|
||||
}
|
||||
|
||||
if (present & 0x20)
|
||||
{
|
||||
in_uint8(s, i);
|
||||
os->colour = (os->colour & 0xffff00ff) | (i << 8);
|
||||
}
|
||||
|
||||
if (present & 0x40)
|
||||
{
|
||||
in_uint8(s, i);
|
||||
os->colour = (os->colour & 0xff00ffff) | (i << 16);
|
||||
}
|
||||
|
||||
DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
|
||||
|
||||
@ -632,6 +653,8 @@ process_raw_bmpcache(STREAM s)
|
||||
in_uint16_le(s, bufsize);
|
||||
in_uint16_le(s, cache_idx);
|
||||
in_uint8p(s, data, bufsize);
|
||||
if (bpp != 8) /* todo */
|
||||
return;
|
||||
|
||||
DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
|
||||
inverted = xmalloc(width * height);
|
||||
@ -665,12 +688,14 @@ process_bmpcache(STREAM s)
|
||||
in_uint16_le(s, size);
|
||||
in_uint8s(s, 4); /* row_size, final_size */
|
||||
in_uint8p(s, data, size);
|
||||
if (bpp != 8) /* todo */
|
||||
return;
|
||||
|
||||
DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
|
||||
|
||||
bmpdata = xmalloc(width * height);
|
||||
|
||||
if (bitmap_decompress(bmpdata, width, height, data, size))
|
||||
if (bitmap_decompress(bmpdata, width, height, data, size, bpp))
|
||||
{
|
||||
bitmap = ui_create_bitmap(width, height, bmpdata);
|
||||
cache_put_bitmap(cache_id, cache_idx, bitmap);
|
||||
|
18
orders.h
18
orders.h
@ -67,8 +67,8 @@ typedef struct _PATBLT_ORDER
|
||||
uint16 cx;
|
||||
uint16 cy;
|
||||
uint8 opcode;
|
||||
uint8 bgcolour;
|
||||
uint8 fgcolour;
|
||||
uint32 bgcolour;
|
||||
uint32 fgcolour;
|
||||
BRUSH brush;
|
||||
|
||||
}
|
||||
@ -94,7 +94,7 @@ typedef struct _LINE_ORDER
|
||||
uint16 starty;
|
||||
uint16 endx;
|
||||
uint16 endy;
|
||||
uint8 bgcolour;
|
||||
uint32 bgcolour;
|
||||
uint8 opcode;
|
||||
PEN pen;
|
||||
|
||||
@ -107,7 +107,7 @@ typedef struct _RECT_ORDER
|
||||
uint16 y;
|
||||
uint16 cx;
|
||||
uint16 cy;
|
||||
uint8 colour;
|
||||
uint32 colour;
|
||||
|
||||
}
|
||||
RECT_ORDER;
|
||||
@ -135,8 +135,8 @@ typedef struct _TRIBLT_ORDER
|
||||
uint8 opcode;
|
||||
uint16 srcx;
|
||||
uint16 srcy;
|
||||
uint8 bgcolour;
|
||||
uint8 fgcolour;
|
||||
uint32 bgcolour;
|
||||
uint32 fgcolour;
|
||||
BRUSH brush;
|
||||
uint16 cache_idx;
|
||||
uint16 unknown;
|
||||
@ -167,7 +167,7 @@ typedef struct _POLYLINE_ORDER
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
uint8 opcode;
|
||||
uint8 fgcolour;
|
||||
uint32 fgcolour;
|
||||
uint8 lines;
|
||||
uint8 datasize;
|
||||
uint8 data[MAX_DATA];
|
||||
@ -183,8 +183,8 @@ typedef struct _TEXT2_ORDER
|
||||
uint8 flags;
|
||||
uint8 mixmode;
|
||||
uint8 unknown;
|
||||
uint8 fgcolour;
|
||||
uint8 bgcolour;
|
||||
uint32 fgcolour;
|
||||
uint32 bgcolour;
|
||||
uint16 clipleft;
|
||||
uint16 cliptop;
|
||||
uint16 clipright;
|
||||
|
2
proto.h
2
proto.h
@ -1,6 +1,6 @@
|
||||
/* bitmap.c */
|
||||
BOOL bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input,
|
||||
int size);
|
||||
int size, int bpp);
|
||||
/* cache.c */
|
||||
HBITMAP cache_get_bitmap(uint8 cache_id, uint16 cache_idx);
|
||||
void cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap);
|
||||
|
13
rdesktop.c
13
rdesktop.c
@ -49,6 +49,7 @@ int width = 800; /* If width or height are reset to zero, the geometry will
|
||||
be fetched from _NET_WORKAREA */
|
||||
int height = 600;
|
||||
int tcp_port_rdp = TCP_PORT_RDP;
|
||||
int server_bpp = 8;
|
||||
BOOL bitmap_compression = True;
|
||||
BOOL sendmotion = True;
|
||||
BOOL orders = True;
|
||||
@ -84,6 +85,7 @@ usage(char *program)
|
||||
fprintf(stderr, " -K: keep window manager key bindings\n");
|
||||
fprintf(stderr, " -T: window title\n");
|
||||
fprintf(stderr, " -D: hide window manager decorations\n");
|
||||
fprintf(stderr, " -a: server bpp\n");
|
||||
}
|
||||
|
||||
static BOOL
|
||||
@ -144,7 +146,7 @@ main(int argc, char *argv[])
|
||||
domain[0] = password[0] = shell[0] = directory[0] = 0;
|
||||
strcpy(keymapname, "en-us");
|
||||
|
||||
while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemCKT:Dh?")) != -1)
|
||||
while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:a:fbemCKT:Dh?")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -239,6 +241,15 @@ main(int argc, char *argv[])
|
||||
hide_decorations = True;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
server_bpp = strtol(optarg, NULL, 10);
|
||||
if (server_bpp != 8 && server_bpp != 16)
|
||||
{
|
||||
error("invalid server bpp\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
|
10
rdp.c
10
rdp.c
@ -579,10 +579,10 @@ process_bitmap_updates(STREAM s)
|
||||
if (!compress)
|
||||
{
|
||||
int y;
|
||||
bmpdata = xmalloc(width * height);
|
||||
bmpdata = xmalloc(width * height * (bpp / 8));
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
in_uint8a(s, &bmpdata[(height - y - 1) * width], width);
|
||||
in_uint8a(s, &bmpdata[(height - y - 1) * (width * (bpp / 8))], width * (bpp / 8));
|
||||
}
|
||||
ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
|
||||
xfree(bmpdata);
|
||||
@ -593,13 +593,11 @@ process_bitmap_updates(STREAM s)
|
||||
in_uint16_le(s, size);
|
||||
in_uint8s(s, 4); /* line_size, final_size */
|
||||
in_uint8p(s, data, size);
|
||||
|
||||
bmpdata = xmalloc(width * height);
|
||||
if (bitmap_decompress(bmpdata, width, height, data, size))
|
||||
bmpdata = xmalloc(width * height * (bpp / 8));
|
||||
if (bitmap_decompress(bmpdata, width, height, data, size, bpp))
|
||||
{
|
||||
ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
|
||||
}
|
||||
|
||||
xfree(bmpdata);
|
||||
}
|
||||
}
|
||||
|
10
secure.c
10
secure.c
@ -38,6 +38,7 @@ extern int height;
|
||||
extern int keylayout;
|
||||
extern BOOL encryption;
|
||||
extern BOOL licence_issued;
|
||||
extern int server_bpp;
|
||||
|
||||
static int rc4_key_len;
|
||||
static RC4_KEY rc4_decrypt_key;
|
||||
@ -425,7 +426,14 @@ sec_out_mcs_data(STREAM s)
|
||||
out_uint32_le(s, 12);
|
||||
out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
|
||||
|
||||
out_uint16_le(s, 0xca01);
|
||||
if (server_bpp == 16)
|
||||
{
|
||||
out_uint16_le(s, 0xca03); /* 16 bit */
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint16_le(s, 0xca01); /* 8 bit */
|
||||
}
|
||||
out_uint16(s, 0);
|
||||
|
||||
/* Client encryption settings */
|
||||
|
2
types.h
2
types.h
@ -68,7 +68,7 @@ typedef struct _PEN
|
||||
{
|
||||
uint8 style;
|
||||
uint8 width;
|
||||
uint8 colour;
|
||||
uint32 colour;
|
||||
|
||||
}
|
||||
PEN;
|
||||
|
21
xwin.c
21
xwin.c
@ -31,6 +31,7 @@ extern BOOL fullscreen;
|
||||
extern BOOL grab_keyboard;
|
||||
extern BOOL hide_decorations;
|
||||
extern char title[];
|
||||
extern int server_bpp;
|
||||
BOOL enable_compose = False;
|
||||
BOOL focused;
|
||||
BOOL mouse_in_wnd;
|
||||
@ -88,7 +89,7 @@ BOOL owncolmap = False;
|
||||
static Colormap xcolmap;
|
||||
static uint32 *colmap;
|
||||
|
||||
#define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
|
||||
#define TRANSLATE(col) ( server_bpp != 8 ? col : owncolmap ? col : translate_colour(colmap[col]) )
|
||||
#define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
|
||||
#define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
|
||||
|
||||
@ -749,6 +750,24 @@ ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * dat
|
||||
XImage *image;
|
||||
uint8 *tdata;
|
||||
|
||||
if (server_bpp == 16)
|
||||
{
|
||||
image = XCreateImage(display, visual, depth, ZPixmap, 0,
|
||||
(char *) data, width, height, 16, 0);
|
||||
|
||||
if (ownbackstore)
|
||||
{
|
||||
XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
|
||||
XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
|
||||
}
|
||||
|
||||
XFree(image);
|
||||
return;
|
||||
}
|
||||
tdata = (owncolmap ? data : translate_image(width, height, data));
|
||||
image = XCreateImage(display, visual, depth, ZPixmap, 0,
|
||||
(char *) tdata, width, height, 8, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user