summaryrefslogtreecommitdiffstats
path: root/xrdp
diff options
context:
space:
mode:
authorjsorg71 <jsorg71>2005-01-12 00:48:11 +0000
committerjsorg71 <jsorg71>2005-01-12 00:48:11 +0000
commit1d03bafb9e8ff4cef59b041235a986d6e4ae2fce (patch)
treef7ad121305b66baf59612fdd54753f29324d25e3 /xrdp
parentff5f2d59b10ca11bc9f5382f94323325dd0045ed (diff)
downloadxrdp-proprietary-1d03bafb9e8ff4cef59b041235a986d6e4ae2fce.tar.gz
xrdp-proprietary-1d03bafb9e8ff4cef59b041235a986d6e4ae2fce.zip
added bitmap cache
Diffstat (limited to 'xrdp')
-rw-r--r--xrdp/xrdp.h18
-rw-r--r--xrdp/xrdp.ini9
-rw-r--r--xrdp/xrdp_bitmap.c237
-rw-r--r--xrdp/xrdp_bitmap_compress.c9
-rw-r--r--xrdp/xrdp_cache.c96
-rw-r--r--xrdp/xrdp_login_wnd.c6
-rw-r--r--xrdp/xrdp_orders.c569
-rw-r--r--xrdp/xrdp_painter.c138
-rw-r--r--xrdp/xrdp_rdp.c48
-rw-r--r--xrdp/xrdp_types.h20
-rw-r--r--xrdp/xrdp_wm.c16
11 files changed, 967 insertions, 199 deletions
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index d594298a..573c990f 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -81,6 +81,7 @@ struct xrdp_orders* xrdp_orders_create(struct xrdp_process* owner);
void xrdp_orders_delete(struct xrdp_orders* self);
int xrdp_orders_init(struct xrdp_orders* self);
int xrdp_orders_send(struct xrdp_orders* self);
+int xrdp_orders_force_send(struct xrdp_orders* self);
int xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
int color, struct xrdp_rect* rect);
int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
@@ -116,6 +117,9 @@ int xrdp_orders_send_palette(struct xrdp_orders* self, int* palette,
int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
struct xrdp_bitmap* bitmap,
int cache_id, int cache_idx);
+int xrdp_orders_send_bitmap(struct xrdp_orders* self,
+ struct xrdp_bitmap* bitmap,
+ int cache_id, int cache_idx);
int xrdp_orders_send_font(struct xrdp_orders* self,
struct xrdp_font_item* font_item,
int font_index, int char_index);
@@ -182,9 +186,16 @@ int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused);
int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette);
int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y);
int xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel);
-int xrdp_bitmap_copy_box(struct xrdp_bitmap* self, struct xrdp_bitmap* dest,
+int xrdp_bitmap_copy_box(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* dest,
int x, int y, int cx, int cy);
-int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b);
+int xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* dest,
+ int x, int y, int cx, int cy);
+int xrdp_bitmap_compare(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* b);
+int xrdp_bitmap_compare_with_crc(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* b);
int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect);
int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg,
int param1, int param2);
@@ -253,4 +264,5 @@ int xrdp_file_read_section(int fd, char* section, struct xrdp_list* names,
/* xrdp_bitmap_compress.c */
int xrdp_bitmap_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
- int start_line, struct stream* temp);
+ int start_line, struct stream* temp,
+ int e);
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index db1562fb..4f0493ac 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -18,3 +18,12 @@ ip=127.0.0.1
port=5903
username=n/a
password=master
+
+[vnc3]
+name=playback
+lib=../vnc/libvnc.so
+auth=local
+ip=127.0.0.1
+port=5910
+username=n/a
+password=tucker
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index af1924e3..2f0a5346 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -25,6 +25,59 @@
#include "xrdp.h"
+int g_crc_seed = 0xffffffff;
+int g_crc_table[256] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+#define CRC_START(in_crc) in_crc = g_crc_seed
+#define CRC_PASS(in_pixel, in_crc) \
+in_crc = g_crc_table[(in_crc ^ (in_pixel)) & 0xff] ^ (in_crc >> 8)
+#define CRC_END(in_crc) in_crc = (in_crc ^ g_crc_seed)
+
/*****************************************************************************/
struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp,
int type)
@@ -337,74 +390,240 @@ int xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel)
}
/*****************************************************************************/
-/* copy part of self at x, y to 0, o in dest */
+/* copy part of self at x, y to 0, 0 in dest */
/* returns error */
-int xrdp_bitmap_copy_box(struct xrdp_bitmap* self, struct xrdp_bitmap* dest,
+int xrdp_bitmap_copy_box(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* dest,
int x, int y, int cx, int cy)
{
int i;
int j;
int destx;
int desty;
+ int pixel;
+
+ if (self == 0)
+ {
+ return 1;
+ }
+ if (dest == 0)
+ {
+ return 1;
+ }
+ if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE)
+ {
+ return 1;
+ }
+ if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE)
+ {
+ return 1;
+ }
+ if (self->bpp != dest->bpp)
+ {
+ return 1;
+ }
+ destx = 0;
+ desty = 0;
+ if (!check_bounds(self, &x, &y, &cx, &cy))
+ {
+ return 1;
+ }
+ if (!check_bounds(dest, &destx, &desty, &cx, &cy))
+ {
+ return 1;
+ }
+ if (self->bpp == 24)
+ {
+ for (i = 0; i < cy; i++)
+ {
+ for (j = 0; j < cx; j++)
+ {
+ pixel = GETPIXEL32(self->data, j + x, i + y, self->width);
+ SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
+ }
+ else if (self->bpp == 15 || self->bpp == 16)
+ {
+ for (i = 0; i < cy; i++)
+ {
+ for (j = 0; j < cx; j++)
+ {
+ pixel = GETPIXEL16(self->data, j + x, i + y, self->width);
+ SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
+ }
+ else if (self->bpp == 8)
+ {
+ for (i = 0; i < cy; i++)
+ {
+ for (j = 0; j < cx; j++)
+ {
+ pixel = GETPIXEL8(self->data, j + x, i + y, self->width);
+ SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
+ }
+ else
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* copy part of self at x, y to 0, 0 in dest */
+/* returns error */
+int xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* dest,
+ int x, int y, int cx, int cy)
+{
+ int i;
+ int j;
+ int destx;
+ int desty;
+ int pixel;
if (self == 0)
+ {
return 1;
+ }
if (dest == 0)
+ {
return 1;
+ }
if (self->type != WND_TYPE_BITMAP && self->type != WND_TYPE_IMAGE)
+ {
return 1;
+ }
if (dest->type != WND_TYPE_BITMAP && dest->type != WND_TYPE_IMAGE)
+ {
return 1;
+ }
if (self->bpp != dest->bpp)
+ {
return 1;
+ }
destx = 0;
desty = 0;
if (!check_bounds(self, &x, &y, &cx, &cy))
+ {
return 1;
+ }
if (!check_bounds(dest, &destx, &desty, &cx, &cy))
+ {
return 1;
+ }
+ CRC_START(dest->crc);
if (self->bpp == 24)
{
for (i = 0; i < cy; i++)
+ {
for (j = 0; j < cx; j++)
- SETPIXEL32(dest->data, j + destx, i + desty, dest->width,
- GETPIXEL32(self->data, j + x, i + y, self->width));
+ {
+ pixel = GETPIXEL32(self->data, j + x, i + y, self->width);
+ CRC_PASS(pixel, dest->crc);
+ CRC_PASS(pixel >> 8, dest->crc);
+ CRC_PASS(pixel >> 16, dest->crc);
+ SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
}
else if (self->bpp == 15 || self->bpp == 16)
{
for (i = 0; i < cy; i++)
+ {
for (j = 0; j < cx; j++)
- SETPIXEL16(dest->data, j + destx, i + desty, dest->width,
- GETPIXEL16(self->data, j + x, i + y, self->width));
+ {
+ pixel = GETPIXEL16(self->data, j + x, i + y, self->width);
+ CRC_PASS(pixel, dest->crc);
+ CRC_PASS(pixel >> 8, dest->crc);
+ SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
}
else if (self->bpp == 8)
{
for (i = 0; i < cy; i++)
+ {
for (j = 0; j < cx; j++)
- SETPIXEL8(dest->data, j + destx, i + desty, dest->width,
- GETPIXEL8(self->data, j + x, i + y, self->width));
+ {
+ pixel = GETPIXEL8(self->data, j + x, i + y, self->width);
+ CRC_PASS(pixel, dest->crc);
+ SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel);
+ }
+ }
}
else
+ {
return 1;
+ }
+ CRC_END(dest->crc);
return 0;
}
/*****************************************************************************/
/* returns true if they are the same, else returns false */
-int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b)
+int xrdp_bitmap_compare(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* b)
{
if (self == 0)
+ {
return 0;
+ }
if (b == 0)
+ {
return 0;
+ }
if (self->bpp != b->bpp)
+ {
return 0;
+ }
if (self->width != b->width)
+ {
return 0;
+ }
if (self->height != b->height)
+ {
return 0;
+ }
if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns true if they are the same, else returns false */
+int xrdp_bitmap_compare_with_crc(struct xrdp_bitmap* self,
+ struct xrdp_bitmap* b)
+{
+ if (self == 0)
+ {
+ return 0;
+ }
+ if (b == 0)
+ {
+ return 0;
+ }
+ if (self->bpp != b->bpp)
+ {
+ return 0;
+ }
+ if (self->width != b->width)
+ {
+ return 0;
+ }
+ if (self->height != b->height)
+ {
+ return 0;
+ }
+ if (self->crc == b->crc)
+ {
return 1;
+ }
return 0;
}
diff --git a/xrdp/xrdp_bitmap_compress.c b/xrdp/xrdp_bitmap_compress.c
index be170a25..f17eb1d4 100644
--- a/xrdp/xrdp_bitmap_compress.c
+++ b/xrdp/xrdp_bitmap_compress.c
@@ -434,14 +434,14 @@
/*****************************************************************************/
int xrdp_bitmap_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
- int start_line, struct stream* temp_s)
+ int start_line, struct stream* temp_s,
+ int e)
{
char* line;
char* last_line;
char fom_mask[8192];
int lines_sent;
int pixel;
- int e;
int count;
int color_count;
int last_pixel;
@@ -462,11 +462,6 @@ int xrdp_bitmap_compress(char* in_data, int width, int height,
int temp; /* used in macros */
init_stream(temp_s, 0);
- e = width % 4;
- if (e != 0)
- {
- e = 4 - e;
- }
fom_mask_len = 0;
last_line = 0;
lines_sent = 0;
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index 97472e0b..55ffaf42 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -62,19 +62,60 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
int oldest;
int cache_id;
int cache_idx;
- struct xrdp_bitmap* b;
+ int bmp_size;
+ int e;
+ int Bpp;
+ e = bitmap->width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
+ Bpp = (bitmap->bpp + 7) / 8;
+ bmp_size = (bitmap->width + e) * bitmap->height * Bpp;
self->bitmap_stamp++;
/* look for match */
- for (i = 0; i < 3; i++)
+ if (bmp_size < self->cache1_size)
{
- for (j = 0; j < 600; j++)
- //for (j = 0; (i == 0 && j < 600) || (i == 1 && j < 300); j++)
+ i = 0;
+ for (j = 0; j < self->cache1_entries; j++)
+ {
+ if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap))
+ {
+ self->bitmap_items[i][j].stamp = self->bitmap_stamp;
+ DEBUG(("found bitmap at %d %d\n\r", i, j));
+ //g_printf("found bitmap at %d %d\n\r", i, j);
+ xrdp_bitmap_delete(bitmap);
+ return MAKELONG(i, j);
+ }
+ }
+ }
+ else if (bmp_size < self->cache2_size)
+ {
+ i = 1;
+ for (j = 0; j < self->cache2_entries; j++)
+ {
+ if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap))
+ {
+ self->bitmap_items[i][j].stamp = self->bitmap_stamp;
+ DEBUG(("found bitmap at %d %d\n\r", i, j));
+ //g_printf("found bitmap at %d %d\n\r", i, j);
+ xrdp_bitmap_delete(bitmap);
+ return MAKELONG(i, j);
+ }
+ }
+ }
+ else if (bmp_size < self->cache3_size)
+ {
+ i = 2;
+ for (j = 0; j < self->cache3_entries; j++)
{
- if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
+ if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap))
{
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
DEBUG(("found bitmap at %d %d\n\r", i, j));
+ //g_printf("found bitmap at %d %d\n\r", i, j);
+ xrdp_bitmap_delete(bitmap);
return MAKELONG(i, j);
}
}
@@ -83,10 +124,36 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
cache_id = 0;
cache_idx = 0;
oldest = 0x7fffffff;
- for (i = 0; i < 3; i++)
+ if (bmp_size < self->cache1_size)
{
- for (j = 0; j < 600; j++)
- //for (j = 0; (i == 0 && j < 600) || (i == 1 && j < 300); j++)
+ i = 0;
+ for (j = 0; j < self->cache1_entries; j++)
+ {
+ if (self->bitmap_items[i][j].stamp < oldest)
+ {
+ oldest = self->bitmap_items[i][j].stamp;
+ cache_id = i;
+ cache_idx = j;
+ }
+ }
+ }
+ else if (bmp_size < self->cache2_size)
+ {
+ i = 1;
+ for (j = 0; j < self->cache2_entries; j++)
+ {
+ if (self->bitmap_items[i][j].stamp < oldest)
+ {
+ oldest = self->bitmap_items[i][j].stamp;
+ cache_id = i;
+ cache_idx = j;
+ }
+ }
+ }
+ else if (bmp_size < self->cache3_size)
+ {
+ i = 2;
+ for (j = 0; j < self->cache3_entries; j++)
{
if (self->bitmap_items[i][j].stamp < oldest)
{
@@ -99,11 +166,16 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
DEBUG(("adding bitmap at %d %d\n\r", cache_id, cache_idx));
/* set, send bitmap and return */
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
- b = xrdp_bitmap_create(bitmap->width, bitmap->height, bitmap->bpp, 0);
- xrdp_bitmap_copy_box(bitmap, b, 0, 0, bitmap->width, bitmap->height);
- self->bitmap_items[cache_id][cache_idx].bitmap = b;
+ self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
- xrdp_orders_send_raw_bitmap(self->orders, b, cache_id, cache_idx);
+ if (self->use_bitmap_comp)
+ {
+ xrdp_orders_send_bitmap(self->orders, bitmap, cache_id, cache_idx);
+ }
+ else
+ {
+ xrdp_orders_send_raw_bitmap(self->orders, bitmap, cache_id, cache_idx);
+ }
return MAKELONG(cache_id, cache_idx);
}
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index 48ad2138..59480195 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -132,9 +132,9 @@ int server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy,
wm = (struct xrdp_wm*)mod->wm;
b = xrdp_bitmap_create_with_data(cx, cy, wm->screen->bpp, data);
- xrdp_wm_send_bitmap(wm, b, x, y, cx, cy);
- /*xrdp_painter_draw_bitmap((struct xrdp_painter*)mod->painter,
- wm->screen, b, x, y, cx, cy);*/
+ //xrdp_wm_send_bitmap(wm, b, x, y, cx, cy);
+ xrdp_painter_draw_bitmap((struct xrdp_painter*)mod->painter,
+ wm->screen, b, x, y, cx, cy);
xrdp_bitmap_delete(b);
return 0;
}
diff --git a/xrdp/xrdp_orders.c b/xrdp/xrdp_orders.c
index d49ce630..aeb10bb2 100644
--- a/xrdp/xrdp_orders.c
+++ b/xrdp/xrdp_orders.c
@@ -52,7 +52,9 @@ int xrdp_orders_init(struct xrdp_orders* self)
self->order_count = 0;
/* is this big enough */
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
+ {
return 1;
+ }
out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
@@ -79,7 +81,9 @@ int xrdp_orders_send(struct xrdp_orders* self)
self->order_count_ptr[1] = self->order_count >> 8;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
+ {
rv = 1;
+ }
}
}
return rv;
@@ -96,7 +100,9 @@ int xrdp_orders_force_send(struct xrdp_orders* self)
self->order_count_ptr[1] = self->order_count >> 8;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
+ {
return 1;
+ }
}
self->order_count = 0;
self->order_level = 0;
@@ -114,13 +120,19 @@ int xrdp_orders_check(struct xrdp_orders* self, int max_size)
if (self->order_level < 1)
{
if (max_size > 8000)
+ {
return 1;
+ }
else
+ {
return 0;
+ }
}
size = self->out_s->p - self->order_count_ptr;
if (size < 0 || size > 8192)
+ {
return 1;
+ }
if (size + max_size + 100 > 8000)
{
xrdp_orders_force_send(self);
@@ -136,10 +148,16 @@ int xrdp_orders_last_bounds(struct xrdp_orders* self,
struct xrdp_rect* rect)
{
if (rect == 0)
+ {
return 0;
- if (rect->left == self->clip_left && rect->top == self->clip_top &&
- rect->right == self->clip_right && rect->bottom == self->clip_bottom)
+ }
+ if (rect->left == self->clip_left &&
+ rect->top == self->clip_top &&
+ rect->right == self->clip_right &&
+ rect->bottom == self->clip_bottom)
+ {
return 1;
+ }
return 0;
}
@@ -151,8 +169,12 @@ int xrdp_orders_send_delta(struct xrdp_orders* self, int* vals, int count)
int i;
for (i = 0; i < count; i += 2)
+ {
if (g_abs(vals[i] - vals[i + 1]) >= 128)
+ {
return 0;
+ }
+ }
return 1;
}
@@ -167,52 +189,92 @@ int xrdp_orders_out_bounds(struct xrdp_orders* self, struct xrdp_rect* rect)
bounds_flags_ptr = self->out_s->p;
out_uint8s(self->out_s, 1);
/* left */
- if (rect->left == self->clip_left) ;
+ if (rect->left == self->clip_left)
+ {
+ }
else if (g_abs(rect->left - self->clip_left) < 128)
+ {
bounds_flags |= 0x10;
+ }
else
+ {
bounds_flags |= 0x01;
+ }
/* top */
- if (rect->top == self->clip_top) ;
+ if (rect->top == self->clip_top)
+ {
+ }
else if (g_abs(rect->top - self->clip_top) < 128)
+ {
bounds_flags |= 0x20;
+ }
else
+ {
bounds_flags |= 0x02;
+ }
/* right */
- if (rect->right == self->clip_right) ;
+ if (rect->right == self->clip_right)
+ {
+ }
else if (g_abs(rect->right - self->clip_right) < 128)
+ {
bounds_flags |= 0x40;
+ }
else
+ {
bounds_flags |= 0x04;
+ }
/* bottom */
- if (rect->bottom == self->clip_bottom) ;
+ if (rect->bottom == self->clip_bottom)
+ {
+ }
else if (g_abs(rect->bottom - self->clip_bottom) < 128)
+ {
bounds_flags |= 0x80;
+ }
else
+ {
bounds_flags |= 0x08;
+ }
/* left */
if (bounds_flags & 0x01)
- out_uint16_le(self->out_s, rect->left)
+ {
+ out_uint16_le(self->out_s, rect->left);
+ }
else if (bounds_flags & 0x10)
- out_uint8(self->out_s, rect->left - self->clip_left)
+ {
+ out_uint8(self->out_s, rect->left - self->clip_left);
+ }
self->clip_left = rect->left;
/* top */
if (bounds_flags & 0x02)
- out_uint16_le(self->out_s, rect->top)
+ {
+ out_uint16_le(self->out_s, rect->top);
+ }
else if (bounds_flags & 0x20)
- out_uint8(self->out_s, rect->top - self->clip_top)
+ {
+ out_uint8(self->out_s, rect->top - self->clip_top);
+ }
self->clip_top = rect->top;
/* right */
if (bounds_flags & 0x04)
- out_uint16_le(self->out_s, rect->right)
+ {
+ out_uint16_le(self->out_s, rect->right);
+ }
else if (bounds_flags & 0x40)
- out_uint8(self->out_s, rect->right - self->clip_right)
+ {
+ out_uint8(self->out_s, rect->right - self->clip_right);
+ }
self->clip_right = rect->right;
/* bottom */
if (bounds_flags & 0x08)
- out_uint16_le(self->out_s, rect->bottom)
+ {
+ out_uint16_le(self->out_s, rect->bottom);
+ }
else if (bounds_flags & 0x80)
- out_uint8(self->out_s, rect->bottom - self->clip_bottom)
+ {
+ out_uint8(self->out_s, rect->bottom - self->clip_bottom);
+ }
self->clip_bottom = rect->bottom;
/* set flags */
*bounds_flags_ptr = bounds_flags;
@@ -235,63 +297,93 @@ int xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_RECT)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_RECT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = x; vals[1] = self->rect_x;
- vals[2] = y; vals[3] = self->rect_y;
- vals[4] = cx; vals[5] = self->rect_cx;
- vals[6] = cy; vals[7] = self->rect_cy;
+ vals[0] = x;
+ vals[1] = self->rect_x;
+ vals[2] = y;
+ vals[3] = self->rect_y;
+ vals[4] = cx;
+ vals[5] = self->rect_cx;
+ vals[6] = cy;
+ vals[7] = self->rect_cy;
if (xrdp_orders_send_delta(self, vals, 8))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags)
if (order_flags & RDP_ORDER_CHANGE)
- out_uint8(self->out_s, self->last_order)
+ {
+ out_uint8(self->out_s, self->last_order);
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (x != self->rect_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, x - self->rect_x)
+ {
+ out_uint8(self->out_s, x - self->rect_x);
+ }
else
- out_uint16_le(self->out_s, x)
+ {
+ out_uint16_le(self->out_s, x);
+ }
self->rect_x = x;
}
if (y != self->rect_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, y - self->rect_y)
+ {
+ out_uint8(self->out_s, y - self->rect_y);
+ }
else
- out_uint16_le(self->out_s, y)
+ {
+ out_uint16_le(self->out_s, y);
+ }
self->rect_y = y;
}
if (cx != self->rect_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cx - self->rect_cx)
+ {
+ out_uint8(self->out_s, cx - self->rect_cx);
+ }
else
- out_uint16_le(self->out_s, cx)
+ {
+ out_uint16_le(self->out_s, cx);
+ }
self->rect_cx = cx;
}
if (cy != self->rect_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cy - self->rect_cy)
+ {
+ out_uint8(self->out_s, cy - self->rect_cy);
+ }
else
- out_uint16_le(self->out_s, cy)
+ {
+ out_uint16_le(self->out_s, cy);
+ }
self->rect_cy = cy;
}
if ((color & 0xff) != (self->rect_color & 0xff))
@@ -333,65 +425,97 @@ int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_SCREENBLT)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_SCREENBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = x; vals[1] = self->scr_blt_x;
- vals[2] = y; vals[3] = self->scr_blt_y;
- vals[4] = cx; vals[5] = self->scr_blt_cx;
- vals[6] = cy; vals[7] = self->scr_blt_cy;
- vals[8] = srcx; vals[9] = self->scr_blt_srcx;
- vals[10] = srcy; vals[11] = self->scr_blt_srcy;
+ vals[0] = x;
+ vals[1] = self->scr_blt_x;
+ vals[2] = y;
+ vals[3] = self->scr_blt_y;
+ vals[4] = cx;
+ vals[5] = self->scr_blt_cx;
+ vals[6] = cy;
+ vals[7] = self->scr_blt_cy;
+ vals[8] = srcx;
+ vals[9] = self->scr_blt_srcx;
+ vals[10] = srcy;
+ vals[11] = self->scr_blt_srcy;
if (xrdp_orders_send_delta(self, vals, 12))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
- out_uint8(self->out_s, self->last_order)
+ {
+ out_uint8(self->out_s, self->last_order);
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (x != self->scr_blt_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, x - self->scr_blt_x)
+ {
+ out_uint8(self->out_s, x - self->scr_blt_x);
+ }
else
- out_uint16_le(self->out_s, x)
+ {
+ out_uint16_le(self->out_s, x);
+ }
self->scr_blt_x = x;
}
if (y != self->scr_blt_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, y - self->scr_blt_y)
+ {
+ out_uint8(self->out_s, y - self->scr_blt_y);
+ }
else
- out_uint16_le(self->out_s, y)
+ {
+ out_uint16_le(self->out_s, y);
+ }
self->scr_blt_y = y;
}
if (cx != self->scr_blt_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cx - self->scr_blt_cx)
+ {
+ out_uint8(self->out_s, cx - self->scr_blt_cx);
+ }
else
- out_uint16_le(self->out_s, cx)
+ {
+ out_uint16_le(self->out_s, cx);
+ }
self->scr_blt_cx = cx;
}
if (cy != self->scr_blt_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cy - self->scr_blt_cy)
+ {
+ out_uint8(self->out_s, cy - self->scr_blt_cy);
+ }
else
- out_uint16_le(self->out_s, cy)
+ {
+ out_uint16_le(self->out_s, cy);
+ }
self->scr_blt_cy = cy;
}
if (rop != self->scr_blt_rop)
@@ -404,18 +528,26 @@ int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
{
present |= 0x20;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, srcx - self->scr_blt_srcx)
+ {
+ out_uint8(self->out_s, srcx - self->scr_blt_srcx);
+ }
else
- out_uint16_le(self->out_s, srcx)
+ {
+ out_uint16_le(self->out_s, srcx);
+ }
self->scr_blt_srcx = srcx;
}
if (srcy != self->scr_blt_srcy)
{
present |= 0x40;
if (order_flags & RDP_ORDER_DELTA)
+ {
out_uint8(self->out_s, srcy - self->scr_blt_srcy)
+ }
else
+ {
out_uint16_le(self->out_s, srcy)
+ }
self->scr_blt_srcy = srcy;
}
present_ptr[0] = present;
@@ -441,64 +573,94 @@ int xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_PATBLT)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_PATBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = x; vals[1] = self->pat_blt_x;
- vals[2] = y; vals[3] = self->pat_blt_y;
- vals[4] = cx; vals[5] = self->pat_blt_cx;
- vals[6] = cy; vals[7] = self->pat_blt_cy;
+ vals[0] = x;
+ vals[1] = self->pat_blt_x;
+ vals[2] = y;
+ vals[3] = self->pat_blt_y;
+ vals[4] = cx;
+ vals[5] = self->pat_blt_cx;
+ vals[6] = cy;
+ vals[7] = self->pat_blt_cy;
if (xrdp_orders_send_delta(self, vals, 8))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
- out_uint8(self->out_s, self->last_order)
+ {
+ out_uint8(self->out_s, self->last_order);
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */
out_uint8s(self->out_s, 2) /* this can be smaller, */
/* see RDP_ORDER_SMALL and RDP_ORDER_TINY */
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (x != self->pat_blt_x)
{
present |= 0x0001;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, x - self->pat_blt_x)
+ {
+ out_uint8(self->out_s, x - self->pat_blt_x);
+ }
else
- out_uint16_le(self->out_s, x)
+ {
+ out_uint16_le(self->out_s, x);
+ }
self->pat_blt_x = x;
}
if (y != self->pat_blt_y)
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, y - self->pat_blt_y)
+ {
+ out_uint8(self->out_s, y - self->pat_blt_y);
+ }
else
- out_uint16_le(self->out_s, y)
+ {
+ out_uint16_le(self->out_s, y);
+ }
self->pat_blt_y = y;
}
if (cx != self->pat_blt_cx)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cx - self->pat_blt_cx)
+ {
+ out_uint8(self->out_s, cx - self->pat_blt_cx);
+ }
else
- out_uint16_le(self->out_s, cx)
+ {
+ out_uint16_le(self->out_s, cx);
+ }
self->pat_blt_cx = cx;
}
if (cy != self->pat_blt_cy)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cy - self->pat_blt_cy)
+ {
+ out_uint8(self->out_s, cy - self->pat_blt_cy);
+ }
else
- out_uint16_le(self->out_s, cy)
+ {
+ out_uint16_le(self->out_s, cy);
+ }
self->pat_blt_cy = cy;
}
if (rop != self->pat_blt_rop)
@@ -581,63 +743,93 @@ int xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_DESTBLT)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_DESTBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = x; vals[1] = self->dest_blt_x;
- vals[2] = y; vals[3] = self->dest_blt_y;
- vals[4] = cx; vals[5] = self->dest_blt_cx;
- vals[6] = cy; vals[7] = self->dest_blt_cy;
+ vals[0] = x;
+ vals[1] = self->dest_blt_x;
+ vals[2] = y;
+ vals[3] = self->dest_blt_y;
+ vals[4] = cx;
+ vals[5] = self->dest_blt_cx;
+ vals[6] = cy;
+ vals[7] = self->dest_blt_cy;
if (xrdp_orders_send_delta(self, vals, 8))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
+ {
out_uint8(self->out_s, self->last_order)
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (x != self->dest_blt_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, x - self->dest_blt_x)
+ {
+ out_uint8(self->out_s, x - self->dest_blt_x);
+ }
else
- out_uint16_le(self->out_s, x)
+ {
+ out_uint16_le(self->out_s, x);
+ }
self->dest_blt_x = x;
}
if (y != self->dest_blt_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, y - self->dest_blt_y)
+ {
+ out_uint8(self->out_s, y - self->dest_blt_y);
+ }
else
- out_uint16_le(self->out_s, y)
+ {
+ out_uint16_le(self->out_s, y);
+ }
self->dest_blt_y = y;
}
if (cx != self->dest_blt_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cx - self->dest_blt_cx)
+ {
+ out_uint8(self->out_s, cx - self->dest_blt_cx);
+ }
else
- out_uint16_le(self->out_s, cx)
+ {
+ out_uint16_le(self->out_s, cx);
+ }
self->dest_blt_cx = cx;
}
if (cy != self->dest_blt_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cy - self->dest_blt_cy)
+ {
+ out_uint8(self->out_s, cy - self->dest_blt_cy);
+ }
else
- out_uint16_le(self->out_s, cy)
+ {
+ out_uint16_le(self->out_s, cy);
+ }
self->dest_blt_cy = cy;
}
if (rop != self->dest_blt_rop)
@@ -670,29 +862,43 @@ int xrdp_orders_line(struct xrdp_orders* self, int mix_mode,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_LINE)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_LINE;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = startx; vals[1] = self->line_startx;
- vals[2] = starty; vals[3] = self->line_starty;
- vals[4] = endx; vals[5] = self->line_endx;
- vals[6] = endy; vals[7] = self->line_endy;
+ vals[0] = startx;
+ vals[1] = self->line_startx;
+ vals[2] = starty;
+ vals[3] = self->line_starty;
+ vals[4] = endx;
+ vals[5] = self->line_endx;
+ vals[6] = endy;
+ vals[7] = self->line_endy;
if (xrdp_orders_send_delta(self, vals, 8))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
- out_uint8(self->out_s, self->last_order)
+ {
+ out_uint8(self->out_s, self->last_order);
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer */
out_uint8s(self->out_s, 2)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (mix_mode != self->line_mix_mode)
{
present |= 0x0001;
@@ -703,36 +909,52 @@ int xrdp_orders_line(struct xrdp_orders* self, int mix_mode,
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, startx - self->line_startx)
+ {
+ out_uint8(self->out_s, startx - self->line_startx);
+ }
else
- out_uint16_le(self->out_s, startx)
+ {
+ out_uint16_le(self->out_s, startx);
+ }
self->line_startx = startx;
}
if (starty != self->line_starty)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, starty - self->line_starty)
+ {
+ out_uint8(self->out_s, starty - self->line_starty);
+ }
else
- out_uint16_le(self->out_s, starty)
+ {
+ out_uint16_le(self->out_s, starty);
+ }
self->line_starty = starty;
}
if (endx != self->line_endx)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, endx - self->line_endx)
+ {
+ out_uint8(self->out_s, endx - self->line_endx);
+ }
else
- out_uint16_le(self->out_s, endx)
+ {
+ out_uint16_le(self->out_s, endx);
+ }
self->line_endx = endx;
}
if (endy != self->line_endy)
{
present |= 0x0010;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, endy - self->line_endy)
+ {
+ out_uint8(self->out_s, endy - self->line_endy);
+ }
else
- out_uint16_le(self->out_s, endy)
+ {
+ out_uint16_le(self->out_s, endy);
+ }
self->line_endy = endy;
}
if (bg_color != self->line_bg_color)
@@ -797,32 +1019,48 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_MEMBLT)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_MEMBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
- vals[0] = x; vals[1] = self->mem_blt_x;
- vals[2] = y; vals[3] = self->mem_blt_y;
- vals[4] = cx; vals[5] = self->mem_blt_cx;
- vals[6] = cy; vals[7] = self->mem_blt_cy;
- vals[8] = srcx; vals[9] = self->mem_blt_srcx;
- vals[10] = srcy; vals[11] = self->mem_blt_srcy;
+ vals[0] = x;
+ vals[1] = self->mem_blt_x;
+ vals[2] = y;
+ vals[3] = self->mem_blt_y;
+ vals[4] = cx;
+ vals[5] = self->mem_blt_cx;
+ vals[6] = cy;
+ vals[7] = self->mem_blt_cy;
+ vals[8] = srcx;
+ vals[9] = self->mem_blt_srcx;
+ vals[10] = srcy;
+ vals[11] = self->mem_blt_srcy;
if (xrdp_orders_send_delta(self, vals, 12))
+ {
order_flags |= RDP_ORDER_DELTA;
+ }
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
+ {
out_uint8(self->out_s, self->last_order)
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */
out_uint8s(self->out_s, 2) /* this can be smaller, */
/* see RDP_ORDER_SMALL and RDP_ORDER_TINY */
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
+ }
if (cache_id != self->mem_blt_cache_id ||
color_table != self->mem_blt_color_table)
{
@@ -836,36 +1074,52 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, x - self->mem_blt_x)
+ {
+ out_uint8(self->out_s, x - self->mem_blt_x);
+ }
else
- out_uint16_le(self->out_s, x)
+ {
+ out_uint16_le(self->out_s, x);
+ }
self->mem_blt_x = x;
}
if (y != self->mem_blt_y)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, y - self->mem_blt_y)
+ {
+ out_uint8(self->out_s, y - self->mem_blt_y);
+ }
else
- out_uint16_le(self->out_s, y)
+ {
+ out_uint16_le(self->out_s, y);
+ }
self->mem_blt_y = y;
}
if (cx != self->mem_blt_cx)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cx - self->mem_blt_cx)
+ {
+ out_uint8(self->out_s, cx - self->mem_blt_cx);
+ }
else
- out_uint16_le(self->out_s, cx)
+ {
+ out_uint16_le(self->out_s, cx);
+ }
self->mem_blt_cx = cx;
}
if (cy != self->mem_blt_cy)
{
present |= 0x0010;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, cy - self->mem_blt_cy)
+ {
+ out_uint8(self->out_s, cy - self->mem_blt_cy);
+ }
else
- out_uint16_le(self->out_s, cy)
+ {
+ out_uint16_le(self->out_s, cy);
+ }
self->mem_blt_cy = cy;
}
if (rop != self->mem_blt_rop)
@@ -878,18 +1132,26 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
{
present |= 0x0040;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, srcx - self->mem_blt_srcx)
+ {
+ out_uint8(self->out_s, srcx - self->mem_blt_srcx);
+ }
else
- out_uint16_le(self->out_s, srcx)
+ {
+ out_uint16_le(self->out_s, srcx);
+ }
self->mem_blt_srcx = srcx;
}
if (srcy != self->mem_blt_srcy)
{
present |= 0x0080;
if (order_flags & RDP_ORDER_DELTA)
- out_uint8(self->out_s, srcy - self->mem_blt_srcy)
+ {
+ out_uint8(self->out_s, srcy - self->mem_blt_srcy);
+ }
else
- out_uint16_le(self->out_s, srcy)
+ {
+ out_uint16_le(self->out_s, srcy);
+ }
self->mem_blt_srcy = srcy;
}
if (cache_idx != self->mem_blt_cache_idx)
@@ -923,25 +1185,32 @@ int xrdp_orders_text(struct xrdp_orders* self,
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_TEXT2)
+ {
order_flags |= RDP_ORDER_CHANGE;
+ }
self->last_order = RDP_ORDER_TEXT2;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
+ {
order_flags |= RDP_ORDER_LASTBOUNDS;
+ }
}
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
- out_uint8(self->out_s, self->last_order)
+ {
+ out_uint8(self->out_s, self->last_order);
+ }
present = 0;
present_ptr = self->out_s->p; /* hold 3 byte present pointer, todo */
out_uint8s(self->out_s, 3) /* this can be smaller, */
/* see RDP_ORDER_SMALL and RDP_ORDER_TINY */
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
xrdp_orders_out_bounds(self, rect);
-
+ }
if (font != self->text_font)
{
present |= 0x000001;
@@ -1095,9 +1364,15 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
int i;
int j;
int pixel;
+ int e;
+ e = bitmap->width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
Bpp = (bitmap->bpp + 7) / 8;
- bufsize = bitmap->width * bitmap->height * Bpp;
+ bufsize = (bitmap->width + e) * bitmap->height * Bpp;
xrdp_orders_check(self, bufsize + 16);
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
@@ -1108,7 +1383,7 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */
out_uint8(self->out_s, cache_id);
out_uint8s(self->out_s, 1); /* pad */
- out_uint8(self->out_s, bitmap->width);
+ out_uint8(self->out_s, bitmap->width + e);
out_uint8(self->out_s, bitmap->height);
out_uint8(self->out_s, bitmap->bpp);
out_uint16_le(self->out_s, bufsize);
@@ -1130,9 +1405,95 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
out_uint8(self->out_s, pixel >> 8);
}
else if (Bpp == 1)
+ {
out_uint8(self->out_s, pixel);
+ }
}
+ for (j = 0; j < e; j++)
+ {
+ out_uint8s(self->out_s, Bpp);
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+/* max size width * height * Bpp + 16 */
+int xrdp_orders_send_bitmap(struct xrdp_orders* self,
+ struct xrdp_bitmap* bitmap,
+ int cache_id, int cache_idx)
+{
+ int order_flags;
+ int len;
+ int bufsize;
+ int Bpp;
+ int i;
+ int lines_sending;
+ int e;
+ struct stream* s;
+ struct stream* temp_s;
+ char* p;
+
+ if (bitmap->width > 64)
+ {
+ g_printf("error, width > 64\n\r");
+ return 1;
}
+ if (bitmap->height > 64)
+ {
+ g_printf("error, height > 64\n\r");
+ return 1;
+ }
+ e = bitmap->width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
+ make_stream(s);
+ init_stream(s, 8192);
+ make_stream(temp_s);
+ init_stream(temp_s, 8192);
+ p = s->p;
+ i = bitmap->height;
+ lines_sending = xrdp_bitmap_compress(bitmap->data, bitmap->width,
+ bitmap->height,
+ s, bitmap->bpp,
+ 8192,
+ i - 1, temp_s, e);
+ if (lines_sending != bitmap->height)
+ {
+ free_stream(s);
+ free_stream(temp_s);
+ g_printf("error lines_sending != bitmap->height\n\r");
+ return 1;
+ }
+ bufsize = s->p - p;
+ //g_printf("bufsize %d\n", bufsize);
+ Bpp = (bitmap->bpp + 7) / 8;
+ xrdp_orders_check(self, bufsize + 16);
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
+ out_uint8(self->out_s, order_flags);
+ len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */
+ out_uint16_le(self->out_s, len);
+ out_uint16_le(self->out_s, 8); /* flags */
+ out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */
+ out_uint8(self->out_s, cache_id);
+ out_uint8s(self->out_s, 1); /* pad */
+ out_uint8(self->out_s, bitmap->width + e);
+ out_uint8(self->out_s, bitmap->height);
+ out_uint8(self->out_s, bitmap->bpp);
+ out_uint16_le(self->out_s, bufsize + 8);
+ out_uint16_le(self->out_s, cache_idx);
+ out_uint8s(self->out_s, 2); /* pad */
+ out_uint16_le(self->out_s, bufsize);
+ out_uint16_le(self->out_s, (bitmap->width + e) * Bpp); /* line size */
+ out_uint16_le(self->out_s, (bitmap->width + e) *
+ Bpp * bitmap->height); /* final size */
+ out_uint8a(self->out_s, s->data, bufsize);
+ free_stream(s);
+ free_stream(temp_s);
return 0;
}
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c
index 1edceba6..dff1cab5 100644
--- a/xrdp/xrdp_painter.c
+++ b/xrdp/xrdp_painter.c
@@ -220,7 +220,8 @@ int xrdp_painter_fill_rect2(struct xrdp_painter* self,
return 0;
}
-#define SS 16
+#define SSW 64
+#define SSH 63
/*****************************************************************************/
int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
@@ -251,7 +252,9 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
/* todo data */
if (bitmap->type == WND_TYPE_BITMAP)
+ {
return 0;
+ }
region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region,
self->clip_children);
@@ -262,78 +265,103 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
y = y + b->top;
b = b->parent;
}
- palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette);
- j = 0;
- while (j < to_draw->height)
+ if (self->wm->use_bitmap_cache)
{
- i = 0;
- while (i < to_draw->width)
+ palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette);
+ j = 0;
+ while (j < to_draw->height)
{
- x1 = x + i;
- y1 = y + j;
- w = MIN(SS, to_draw->width - i);
- h = MIN(SS, to_draw->height - j);
- b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0);
- xrdp_bitmap_copy_box(to_draw, b, i, j, w, h);
- bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b);
- cache_id = HIWORD(bitmap_id);
- cache_idx = LOWORD(bitmap_id);
- k = 0;
- while (xrdp_region_get_rect(region, k, &rect) == 0)
+ i = 0;
+ while (i < to_draw->width)
{
- if (!ISRECTEMPTY(rect))
+ x1 = x + i;
+ y1 = y + j;
+ w = MIN(SSW, to_draw->width - i);
+ h = MIN(SSH, to_draw->height - j);
+ b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0);
+ xrdp_bitmap_copy_box_with_crc(to_draw, b, i, j, w, h);
+ bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b);
+ cache_id = HIWORD(bitmap_id);
+ cache_idx = LOWORD(bitmap_id);
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
{
- MAKERECT(rect1, x1, y1, w, h);
- if (rect_intersect(&rect, &rect1, &rect2))
+ if (!ISRECTEMPTY(rect))
{
- ok = 1;
- if (self->use_clip)
- {
- rect = self->clip;
- RECTOFFSET(rect, x, y);
- if (!rect_intersect(&rect2, &rect, &rect1))
- ok = 0;
- }
- else
- rect1 = rect2;
- if (ok)
+ MAKERECT(rect1, x1, y1, w, h);
+ if (rect_intersect(&rect, &rect1, &rect2))
{
- rect1.right--;
- rect1.bottom--;
- /* check these so ms client don't crash */
- if (x1 + w >= self->wm->screen->width)
- w = self->wm->screen->width - x1;
- if (y1 + h >= self->wm->screen->height)
- h = self->wm->screen->height - y1;
- if (w > 0 && h > 0 && x1 + w > 0 && y1 + h > 0)
+ ok = 1;
+ if (self->use_clip)
+ {
+ rect = self->clip;
+ RECTOFFSET(rect, x, y);
+ if (!rect_intersect(&rect2, &rect, &rect1))
+ ok = 0;
+ }
+ else
+ {
+ rect1 = rect2;
+ }
+ if (ok)
{
- srcx = 0;
- srcy = 0;
- if (x1 < 0)
+ rect1.right--;
+ rect1.bottom--;
+ /* check these so ms client don't crash */
+ if (x1 + w >= self->wm->screen->width)
+ {
+ w = self->wm->screen->width - x1;
+ }
+ if (y1 + h >= self->wm->screen->height)
{
- w = w + x1;
- srcx = srcx - x1;
- x1 = 0;
+ h = self->wm->screen->height - y1;
}
- if (y1 < 0)
+ if (w > 0 && h > 0 && x1 + w > 0 && y1 + h > 0)
{
- h = h + y1;
- srcy = srcy - y1;
- y1 = 0;
+ srcx = 0;
+ srcy = 0;
+ if (x1 < 0)
+ {
+ w = w + x1;
+ srcx = srcx - x1;
+ x1 = 0;
+ }
+ if (y1 < 0)
+ {
+ h = h + y1;
+ srcy = srcy - y1;
+ y1 = 0;
+ }
+ xrdp_orders_mem_blt(self->orders, cache_id, palette_id,
+ x1, y1, w, h, self->rop, srcx, srcy,
+ cache_idx, &rect1);
}
- xrdp_orders_mem_blt(self->orders, cache_id, palette_id,
- x1, y1, w, h, self->rop, srcx, srcy,
- cache_idx, &rect1);
}
}
}
+ k++;
}
- k++;
+ i += SSW;
}
+ j += SSH;
+ }
+ }
+ else /* no bitmap cache */
+ {
+ xrdp_orders_force_send(self->orders);
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
+ {
+ x1 = rect.left;
+ y1 = rect.top;
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+ b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0);
+ xrdp_bitmap_copy_box(to_draw, b, x1 - x, y1 - y, w, h);
+ xrdp_wm_send_bitmap(self->wm, b, x1, y1, w, h);
xrdp_bitmap_delete(b);
- i += SS;
+ k++;
}
- j += SS;
}
xrdp_region_delete(region);
return 0;
diff --git a/xrdp/xrdp_rdp.c b/xrdp/xrdp_rdp.c
index 622b4be0..a6592a56 100644
--- a/xrdp/xrdp_rdp.c
+++ b/xrdp/xrdp_rdp.c
@@ -359,8 +359,56 @@ int xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
}
/*****************************************************************************/
+int xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s,
+ int len)
+{
+ //g_hexdump(s->p, len);
+ in_uint8s(s, 24);
+ in_uint16_le(s, self->cache1_entries);
+ in_uint16_le(s, self->cache1_size);
+ in_uint16_le(s, self->cache2_entries);
+ in_uint16_le(s, self->cache2_size);
+ in_uint16_le(s, self->cache3_entries);
+ in_uint16_le(s, self->cache3_size);
+ //g_printf("%d %d %d %d %d %d\n", self->cache1_entries, self->cache1_size,
+ // self->cache2_entries, self->cache2_size,
+ // self->cache3_entries, self->cache3_size);
+ return 0;
+}
+
+/*****************************************************************************/
int xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s)
{
+ int cap_len;
+ int source_len;
+ int num_caps;
+ int index;
+ int type;
+ int len;
+ char* p;
+
+ in_uint8s(s, 4); /* rdp_shareid */
+ in_uint8s(s, 2); /* userid */
+ in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */
+ in_uint16_le(s, cap_len);
+ in_uint8s(s, source_len);
+ in_uint16_le(s, num_caps);
+ in_uint8s(s, 2); /* pad */
+ for (index = 0; index < num_caps; index++)
+ {
+ p = s->p;
+ in_uint16_le(s, type);
+ in_uint16_le(s, len);
+ //g_printf("%d %d\n", type, len);
+ switch (type)
+ {
+ case RDP_CAPSET_BMPCACHE:
+ xrdp_process_capset_bmpcache(self, s, len);
+ break;
+ }
+ s->p = p + len;
+ }
+ //g_hexdump(s->p, s->end - s->p);
return 0;
}
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index b4bd26c9..fedbbbd6 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -180,6 +180,12 @@ struct xrdp_rdp
int width;
int height;
int up_and_running;
+ int cache1_entries;
+ int cache1_size;
+ int cache2_entries;
+ int cache2_size;
+ int cache3_entries;
+ int cache3_size;
};
/* orders */
@@ -309,6 +315,13 @@ struct xrdp_cache
struct xrdp_bitmap_item bitmap_items[3][600];
int char_stamp;
struct xrdp_char_item char_items[12][256];
+ int use_bitmap_comp;
+ int cache1_entries;
+ int cache1_size;
+ int cache2_entries;
+ int cache2_size;
+ int cache3_entries;
+ int cache3_size;
};
/* the window manager */
@@ -364,9 +377,10 @@ struct xrdp_wm
int (*mod_exit)(int);
struct xrdp_mod* mod;
/* */
- int use_comp;
+ int use_bitmap_comp;
+ int use_bitmap_cache;
/* */
- int op1;
+ int op1; /* use smaller bitmap header, todo */
};
/* rdp process */
@@ -461,6 +475,8 @@ struct xrdp_bitmap
/* for popup */
struct xrdp_bitmap* popped_from;
int item_height;
+ /* crc */
+ int crc;
};
/* font */
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 6b69fee7..ff3b9ac3 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -35,10 +35,18 @@ struct xrdp_wm* xrdp_wm_create(struct xrdp_process* owner)
self->pro_layer = owner;
self->orders = owner->orders;
self->painter = xrdp_painter_create(self);
+ self->use_bitmap_comp = 1;
+ self->use_bitmap_cache = 1;
+ self->op1 = 0;
self->rdp_layer = owner->rdp_layer;
self->cache = xrdp_cache_create(self, self->orders);
- self->use_comp = 1;
- self->op1 = 0;
+ self->cache->use_bitmap_comp = self->use_bitmap_comp;
+ self->cache->cache1_entries = owner->rdp_layer->cache1_entries;
+ self->cache->cache1_size = owner->rdp_layer->cache1_size;
+ self->cache->cache2_entries = owner->rdp_layer->cache2_entries;
+ self->cache->cache2_size = owner->rdp_layer->cache2_size;
+ self->cache->cache3_entries = owner->rdp_layer->cache3_entries;
+ self->cache->cache3_size = owner->rdp_layer->cache3_size;
return self;
}
@@ -123,7 +131,7 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
line_size = bitmap->width * Bpp;
make_stream(s);
init_stream(s, 8192);
- if (self->use_comp)
+ if (self->use_bitmap_comp)
{
make_stream(temp_s);
init_stream(temp_s, 65536);
@@ -153,7 +161,7 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
bitmap->height,
s, bitmap->bpp,
4096 - total_bufsize,
- i - 1, temp_s);
+ i - 1, temp_s, e);
if (lines_sending == 0)
break;
num_updates++;