summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
authorjsorg71 <jsorg71>2006-03-17 01:10:24 +0000
committerjsorg71 <jsorg71>2006-03-17 01:10:24 +0000
commitb91f25deef43cce2d528e2e121dab32941735dea (patch)
tree0c178b06bfe37acf36675456971d67625e419781 /libxrdp
parentb475ff2c83299fee8baed228f13a337d25a0fa1f (diff)
downloadxrdp-proprietary-b91f25deef43cce2d528e2e121dab32941735dea.tar.gz
xrdp-proprietary-b91f25deef43cce2d528e2e121dab32941735dea.zip
bitmap cache v2
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/libxrdp.c22
-rw-r--r--libxrdp/libxrdp.h8
-rw-r--r--libxrdp/libxrdpinc.h13
-rw-r--r--libxrdp/xrdp_orders.c166
-rw-r--r--libxrdp/xrdp_rdp.c41
5 files changed, 248 insertions, 2 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 0d69ab01..8a02c7f7 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -578,3 +578,25 @@ libxrdp_reset(struct xrdp_session* session,
libxrdp_process_data(session);
return 0;
}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx)
+{
+ return xrdp_orders_send_raw_bitmap2((struct xrdp_orders*)session->orders,
+ width, height, bpp, data,
+ cache_id, cache_idx);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_orders_send_bitmap2(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx)
+{
+ return xrdp_orders_send_bitmap2((struct xrdp_orders*)session->orders,
+ width, height, bpp, data,
+ cache_id, cache_idx);
+}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 9164b187..b5afde0a 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -339,6 +339,14 @@ int APP_CC
xrdp_orders_send_font(struct xrdp_orders* self,
struct xrdp_font_char* font_char,
int font_index, int char_index);
+int APP_CC
+xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx);
+int APP_CC
+xrdp_orders_send_bitmap2(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx);
/* xrdp_bitmap_compress.c */
int APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index c84ba64d..cc8f77be 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -28,13 +28,18 @@ struct xrdp_client_info
int bpp;
int width;
int height;
+ /* bitmap cache info */
int cache1_entries;
int cache1_size;
int cache2_entries;
int cache2_size;
int cache3_entries;
int cache3_size;
+ int bitmap_cache_persist_enable; /* 0 or 2 */
+ int bitmap_cache_version; /* 0 = original version, 2 = v2 */
+ /* pointer info */
int pointer_cache_entries;
+ /* other */
int use_bitmap_comp;
int use_bitmap_cache;
int op1; /* use smaller bitmap header, non cache */
@@ -181,5 +186,13 @@ libxrdp_orders_send_font(struct xrdp_session* session,
int DEFAULT_CC
libxrdp_reset(struct xrdp_session* session,
int width, int height, int bpp);
+int DEFAULT_CC
+libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx);
+int DEFAULT_CC
+libxrdp_orders_send_bitmap2(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx);
#endif
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 7795089e..9585ebcf 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -1476,6 +1476,16 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
int pixel;
int e;
+ if (width > 64)
+ {
+ g_printf("error, width > 64\r\n");
+ return 1;
+ }
+ if (height > 64)
+ {
+ g_printf("error, height > 64\r\n");
+ return 1;
+ }
e = width % 4;
if (e != 0)
{
@@ -1651,3 +1661,159 @@ xrdp_orders_send_font(struct xrdp_orders* self,
out_uint8a(self->out_s, font_char->data, datasize);
return 0;
}
+
+/*****************************************************************************/
+/* returns error */
+/* max size width * height * Bpp + 14 */
+int APP_CC
+xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx)
+{
+ int order_flags;
+ int len;
+ int bufsize;
+ int Bpp;
+ int i;
+ int j;
+ int pixel;
+ int e;
+
+ if (width > 64)
+ {
+ g_printf("error, width > 64\r\n");
+ return 1;
+ }
+ if (height > 64)
+ {
+ g_printf("error, height > 64\r\n");
+ return 1;
+ }
+ e = width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
+ Bpp = (bpp + 7) / 8;
+ bufsize = (width + e) * height * Bpp;
+ xrdp_orders_check(self, bufsize + 14);
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
+ out_uint8(self->out_s, order_flags);
+ len = (bufsize + 6) - 7; /* length after type minus 7 */
+ out_uint16_le(self->out_s, len);
+ i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7);
+ out_uint16_le(self->out_s, i); /* flags */
+ out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE2); /* type */
+ out_uint8(self->out_s, width + e);
+ out_uint8(self->out_s, height);
+ out_uint16_be(self->out_s, bufsize | 0x4000);
+ i = ((cache_idx >> 8) & 0xff) | 0x80;
+ out_uint8(self->out_s, i);
+ i = cache_idx & 0xff;
+ out_uint8(self->out_s, i);
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
+ {
+ if (Bpp == 3)
+ {
+ pixel = GETPIXEL32(data, j, i, width);
+ out_uint8(self->out_s, pixel >> 16);
+ out_uint8(self->out_s, pixel >> 8);
+ out_uint8(self->out_s, pixel);
+ }
+ else if (Bpp == 2)
+ {
+ pixel = GETPIXEL16(data, j, i, width);
+ out_uint8(self->out_s, pixel);
+ out_uint8(self->out_s, pixel >> 8);
+ }
+ else if (Bpp == 1)
+ {
+ pixel = GETPIXEL8(data, j, i, width);
+ 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 + 14 */
+int APP_CC
+xrdp_orders_send_bitmap2(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ 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 (width > 64)
+ {
+ g_printf("error, width > 64\r\n");
+ return 1;
+ }
+ if (height > 64)
+ {
+ g_printf("error, height > 64\r\n");
+ return 1;
+ }
+ e = width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
+ make_stream(s);
+ init_stream(s, 16384);
+ make_stream(temp_s);
+ init_stream(temp_s, 16384);
+ p = s->p;
+ i = height;
+ lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ i - 1, temp_s, e);
+ if (lines_sending != height)
+ {
+ free_stream(s);
+ free_stream(temp_s);
+ g_printf("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \
+height(%d)\r\n", lines_sending, height);
+ return 1;
+ }
+ bufsize = s->p - p;
+ Bpp = (bpp + 7) / 8;
+ xrdp_orders_check(self, bufsize + 14);
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
+ out_uint8(self->out_s, order_flags);
+ len = (bufsize + 6) - 7; /* length after type minus 7 */
+ out_uint16_le(self->out_s, len);
+ i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7);
+ i = i | 0x400;
+ out_uint16_le(self->out_s, i); /* flags */
+ out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */
+ out_uint8(self->out_s, width + e);
+ out_uint8(self->out_s, height);
+ out_uint16_be(self->out_s, bufsize | 0x4000);
+ i = ((cache_idx >> 8) & 0xff) | 0x80;
+ out_uint8(self->out_s, i);
+ i = cache_idx & 0xff;
+ out_uint8(self->out_s, i);
+ out_uint8a(self->out_s, s->data, bufsize);
+ free_stream(s);
+ free_stream(temp_s);
+ return 0;
+}
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 7d9d376f..ed69c17e 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -107,7 +107,7 @@ xrdp_rdp_create(struct xrdp_session* session, int sck)
self->sec_layer = xrdp_sec_create(self, sck);
/* read ini settings */
xrdp_rdp_read_config(&self->client_info);
- /* deafult 8 bit color bitmap cache entries and size */
+ /* default 8 bit v1 color bitmap cache entries and size */
self->client_info.cache1_entries = 600;
self->client_info.cache1_size = 256;
self->client_info.cache2_entries = 300;
@@ -352,7 +352,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
out_uint16_le(s, 0x200); /* Protocol version */
out_uint16_le(s, 0); /* pad */
out_uint16_le(s, 0); /* Compression types */
- out_uint16_le(s, 0); /* pad use 0x40d for rdp packets */
+ out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */
out_uint16_le(s, 0); /* Update capability */
out_uint16_le(s, 0); /* Remote unshare capability */
out_uint16_le(s, 0); /* Compression level */
@@ -512,6 +512,42 @@ xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s,
}
/*****************************************************************************/
+/* get the bitmap cache size */
+static int APP_CC
+xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
+ int len)
+{
+ int Bpp;
+ int i;
+
+ self->client_info.bitmap_cache_version = 2;
+ Bpp = (self->client_info.bpp + 7) / 8;
+ in_uint16_le(s, i);
+ self->client_info.bitmap_cache_persist_enable = i;
+ in_uint8s(s, 2); /* number of caches in set, 3 */
+ in_uint32_le(s, i);
+ i = MIN(i, 2000);
+ self->client_info.cache1_entries = i;
+ self->client_info.cache1_size = 256 * Bpp;
+ in_uint32_le(s, i);
+ i = MIN(i, 2000);
+ self->client_info.cache2_entries = i;
+ self->client_info.cache2_size = 1024 * Bpp;
+ in_uint32_le(s, i);
+ i = i & 0x7fffffff;
+ i = MIN(i, 2000);
+ self->client_info.cache3_entries = i;
+ self->client_info.cache3_size = 4096 * Bpp;
+ DEBUG(("cache1 entries %d size %d\r\n", self->client_info.cache1_entries,
+ self->client_info.cache1_size));
+ DEBUG(("cache2 entries %d size %d\r\n", self->client_info.cache2_entries,
+ self->client_info.cache2_size));
+ DEBUG(("cache3 entries %d size %d\r\n", self->client_info.cache3_entries,
+ self->client_info.cache3_size));
+ return 0;
+}
+
+/*****************************************************************************/
/* get the number of client cursor cache */
static int APP_CC
xrdp_process_capset_pointercache(struct xrdp_rdp* self, struct stream* s,
@@ -604,6 +640,7 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s)
break;
case RDP_CAPSET_BMPCACHE2: /* 19 */
DEBUG(("RDP_CAPSET_BMPCACHE2\r\n"));
+ xrdp_process_capset_bmpcache2(self, s, len);
break;
case 20: /* 20 */
DEBUG(("--20\r\n"));