From 1d03bafb9e8ff4cef59b041235a986d6e4ae2fce Mon Sep 17 00:00:00 2001 From: jsorg71 Date: Wed, 12 Jan 2005 00:48:11 +0000 Subject: [PATCH] added bitmap cache --- common/os_calls.c | 6 +- common/os_calls.h | 4 +- vnc/vnc.c | 12 +- xrdp/xrdp.h | 18 +- xrdp/xrdp.ini | 9 + xrdp/xrdp_bitmap.c | 237 ++++++++++++++- xrdp/xrdp_bitmap_compress.c | 9 +- xrdp/xrdp_cache.c | 96 +++++- xrdp/xrdp_login_wnd.c | 6 +- xrdp/xrdp_orders.c | 569 +++++++++++++++++++++++++++++------- xrdp/xrdp_painter.c | 138 +++++---- xrdp/xrdp_rdp.c | 48 +++ xrdp/xrdp_types.h | 20 +- xrdp/xrdp_wm.c | 16 +- 14 files changed, 978 insertions(+), 210 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index c05c740d..9d786f16 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -14,7 +14,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004 + Copyright (C) Jay Sorg 2004-2005 generic operating system calls @@ -57,7 +57,7 @@ static pthread_mutex_t g_term_mutex = PTHREAD_MUTEX_INITIALIZER; static int g_term = 0; #ifdef MEMLEAK -#include "xrdp.h" +#include "/home/j/cvs/xrdp/xrdp/xrdp.h" #endif #ifdef MEMLEAK @@ -181,7 +181,7 @@ void g_free1(void* ptr) } /*****************************************************************************/ -void g_printf(char* format, ...) +void g_printf(const char* format, ...) { va_list ap; diff --git a/common/os_calls.h b/common/os_calls.h index d4faae71..7766563d 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -14,7 +14,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004 + Copyright (C) Jay Sorg 2004-2005 generic operating system calls @@ -23,7 +23,7 @@ int g_init_system(void); int g_exit_system(void); void g_printf(char *format, ...); -void g_sprintf(char* dest, ...); +void g_sprintf(char* dest, char* format, ...); void g_hexdump(char* p, int len); void* g_malloc(int size, int zero); void* g_malloc1(int size, int zero); diff --git a/vnc/vnc.c b/vnc/vnc.c index d036b278..a8514c7b 100644 --- a/vnc/vnc.c +++ b/vnc/vnc.c @@ -22,9 +22,9 @@ #include "vnc.h" -const char* vnc_start_command = +char* vnc_start_command = "su %s -c \"sh ../vnc/startvnc.sh :%d %d %d %d\""; -const char* vnc_stop_command = +char* vnc_stop_command = ""; /******************************************************************************/ @@ -270,6 +270,8 @@ int lib_framebuffer_update(struct vnc* v) } in_uint8s(s, 1); in_uint16_be(s, num_recs); + + v->server_begin_update(v); for (i = 0; i < num_recs; i++) { init_stream(s, 8192); @@ -292,9 +294,7 @@ int lib_framebuffer_update(struct vnc* v) free_stream(s); return 1; } - v->server_begin_update(v); v->server_paint_rect(v, x, y, cx, cy, data); - v->server_end_update(v); g_free(data); } else if (encoding == 1) /* copy rect */ @@ -307,9 +307,7 @@ int lib_framebuffer_update(struct vnc* v) } in_uint16_be(s, srcx); in_uint16_be(s, srcy); - v->server_begin_update(v); v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); - v->server_end_update(v); } else if (encoding == 0xffffff11) /* cursor */ { @@ -342,6 +340,8 @@ int lib_framebuffer_update(struct vnc* v) v->server_set_cursor(v, x, y, cursor_data, cursor_mask); } } + v->server_end_update(v); + /* FrambufferUpdateRequest */ init_stream(s, 8192); out_uint8(s, 3); 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 @@ -358,9 +358,57 @@ int xrdp_rdp_send_demand_active(struct xrdp_rdp* self) return 0; } +/*****************************************************************************/ +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++;