summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/xrdp_client_info.h2
-rw-r--r--common/xrdp_constants.h4
-rw-r--r--libxrdp/xrdp_orders.c83
-rw-r--r--libxrdp/xrdp_rdp.c36
-rw-r--r--xrdp/xrdp_cache.c42
5 files changed, 140 insertions, 27 deletions
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index e1879cef..d7c20783 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -40,7 +40,7 @@ struct xrdp_client_info
int cache3_entries;
int cache3_size;
int bitmap_cache_persist_enable; /* 0 or 2 */
- int bitmap_cache_version; /* 0 = original version, 2 = v2, 3 = v3 */
+ int bitmap_cache_version; /* ored 1 = original version, 2 = v2, 4 = v3 */
/* pointer info */
int pointer_cache_entries;
/* other */
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index 7d31326e..1aa18eb5 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -516,6 +516,10 @@
#define XR_CODEC_GUID_REMOTEFX \
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
+/* CODEC_GUID_JPEG 0x430C9EED1BAF4CE6869ACB8B37B66237*/
+#define XR_CODEC_GUID_JPEG \
+ "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
+
#define RDP_CAPSET_SURFCMDS 0x1c
#define RDP_CAPLEN_SURFCMDS 0x0c
#define RDP_CAPSET_BMPCODECS 0x1d
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 77fdbf23..35666492 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -1946,6 +1946,26 @@ height(%d)", lines_sending, height);
return 0;
}
+#if defined(XRDP_FREERDP1)
+/*****************************************************************************/
+/* secondary drawing order (bitmap v3) using remotefx compression */
+static int APP_CC
+xrdp_orders_send_in_rfx(struct xrdp_orders* self,
+ int width, int height, int bpp,
+ int hints)
+{
+ if (bpp != 24)
+ {
+ return 0;
+ }
+ if (self->rdp_layer->client_info.rfx_codec_id == 0)
+ {
+ return 0;
+ }
+ return 1;
+}
+#endif
+
/*****************************************************************************/
/* secondary drawing order (bitmap v3) using remotefx compression */
int APP_CC
@@ -1953,6 +1973,69 @@ xrdp_orders_send_bitmap3(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
int cache_id, int cache_idx, int hints)
{
+#if defined(XRDP_FREERDP1)
+ int bufsize;
+ int Bpp;
+ int order_flags;
+ int len;
+ int i;
+ STREAM* fr_s; /* FreeRDP stream */
+ struct stream* xr_s; /* xrdp stream */
+ RFX_CONTEXT* context = (RFX_CONTEXT*)(self->rdp_layer->rfx_enc);
+ RFX_RECT rect;
+
+ if (width > 64)
+ {
+ g_writeln("error, width > 64");
+ return 1;
+ }
+ if (height > 64)
+ {
+ g_writeln("error, height > 64");
+ return 1;
+ }
+ if (!xrdp_orders_send_in_rfx(self, width, height, bpp, hints))
+ {
+ return 2;
+ }
+ make_stream(xr_s);
+ init_stream(xr_s, 16384);
+ fr_s = stream_new(0);
+ stream_attach(fr_s, xr_s->data, 16384);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ rfx_compose_message(context, fr_s, &rect, 1, data, width, height, width * 4);
+ bufsize = stream_get_length(fr_s);
+ Bpp = (bpp + 7) / 8;
+ xrdp_orders_check(self, bufsize + 30);
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
+ out_uint8(self->out_s, order_flags);
+ len = (bufsize + 22) - 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_BMPCACHE3); /* type */
+ /* cache index */
+ out_uint16_le(self->out_s, cache_idx);
+ /* persistant cache key 1/2 */
+ out_uint32_le(self->out_s, 0);
+ out_uint32_le(self->out_s, 0);
+ /* bitmap data */
+ out_uint8(self->out_s, bpp);
+ out_uint8(self->out_s, 0); /* reserved */
+ out_uint8(self->out_s, 0); /* reserved */
+ out_uint8(self->out_s, self->rdp_layer->client_info.rfx_codec_id);
+ out_uint16_le(self->out_s, width);
+ out_uint16_le(self->out_s, height);
+ out_uint32_le(self->out_s, bufsize);
+ out_uint8a(self->out_s, fr_s->data, bufsize);
+ stream_detach(fr_s);
+ stream_free(fr_s);
+ free_stream(xr_s);
+#endif
return 0;
}
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index f25108f0..1c381274 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -684,18 +684,25 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
/* Output bmpcodecs capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_BMPCODECS);
- out_uint16_le(s, 302); /* cap len */
- out_uint8(s, 2); /* bitmapCodecCount */
+ out_uint16_le(s, 5 + 22 + 275 + 20); /* cap len */
+ out_uint8(s, 3); /* bitmapCodecCount */
+ /* nscodec */
out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16);
out_uint8(s, 1); /* codec id */
out_uint16_le(s, 3);
out_uint8(s, 0x01); /* fAllowDynamicFidelity */
out_uint8(s, 0x01); /* fAllowSubsampling */
out_uint8(s, 0x03); /* colorLossLevel */
+ /* remotefx */
out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16);
out_uint8(s, 0); /* codec id */
out_uint16_le(s, 256);
out_uint8s(s, 256);
+ /* jpeg */
+ out_uint8a(s, XR_CODEC_GUID_JPEG, 16);
+ out_uint8(s, 2); /* codec id */
+ out_uint16_le(s, 1); /* ext length */
+ out_uint8(s, 75);
/* Output color cache capability set */
caps_count++;
@@ -818,10 +825,7 @@ xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s,
{
g_writeln("RDP_CAPSET_BMPCACHE3");
DEBUG(("RDP_CAPSET_BMPCACHE3"));
- if (self->client_info.bitmap_cache_version < 3)
- {
- self->client_info.bitmap_cache_version = 3;
- }
+ self->client_info.bitmap_cache_version |= 4;
}
in_uint8s(s, 4); /* Pad */
@@ -839,6 +843,7 @@ static int APP_CC
xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s,
int len)
{
+ self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24);
in_uint16_le(s, self->client_info.cache1_entries);
in_uint16_le(s, self->client_info.cache1_size);
@@ -864,10 +869,7 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
int Bpp = 0;
int i = 0;
- if (self->client_info.bitmap_cache_version < 2)
- {
- self->client_info.bitmap_cache_version = 2;
- }
+ self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */
#if defined(XRDP_JPEG)
@@ -1036,8 +1038,22 @@ xrdp_process_capset_codecs(struct xrdp_rdp* self, struct stream* s, int len)
g_memcpy(self->client_info.rfx_prop, s->p, i1);
self->client_info.rfx_prop_len = i1;
}
+ else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
+ {
+ g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d",
+ codec_id, codec_properties_length);
+ self->client_info.jpeg_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.jpeg_prop, s->p, i1);
+ self->client_info.jpeg_prop_len = i1;
+ }
+ else
+ {
+ g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id);
+ }
s->p = next_guid;
}
+ return 0;
}
/*****************************************************************************/
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index 9c708313..17316633 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -261,36 +261,46 @@ xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap,
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
- if (self->bitmap_cache_version == 0) /* orginal version */
+ if (self->use_bitmap_comp)
{
- if (self->use_bitmap_comp)
+ if (self->bitmap_cache_version & 4)
{
- libxrdp_orders_send_bitmap(self->session, bitmap->width,
- bitmap->height, bitmap->bpp,
- bitmap->data, cache_id, cache_idx);
- }
- else
- {
- libxrdp_orders_send_raw_bitmap(self->session, bitmap->width,
- bitmap->height, bitmap->bpp,
- bitmap->data, cache_id, cache_idx);
+ if (libxrdp_orders_send_bitmap3(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx,
+ hints) == 0)
+ {
+ return MAKELONG(cache_idx, cache_id);
+ }
}
- }
- else
- {
- if (self->use_bitmap_comp)
+ if (self->bitmap_cache_version & 2)
{
libxrdp_orders_send_bitmap2(self->session, bitmap->width,
bitmap->height, bitmap->bpp,
bitmap->data, cache_id, cache_idx,
hints);
}
- else
+ else if (self->bitmap_cache_version & 1)
+ {
+ libxrdp_orders_send_bitmap(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx);
+ }
+ }
+ else
+ {
+ if (self->bitmap_cache_version & 2)
{
libxrdp_orders_send_raw_bitmap2(self->session, bitmap->width,
bitmap->height, bitmap->bpp,
bitmap->data, cache_id, cache_idx);
}
+ else if (self->bitmap_cache_version & 1)
+ {
+ libxrdp_orders_send_raw_bitmap(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx);
+ }
}
return MAKELONG(cache_idx, cache_id);
}