From 6d7e315b0c0a1e56e135614f1e2e96fa19870975 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 18 Mar 2014 00:07:11 -0700 Subject: [PATCH] work on surface command --- libxrdp/libxrdp.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ libxrdp/libxrdp.h | 2 ++ libxrdp/libxrdpinc.h | 7 +++++ libxrdp/xrdp_rdp.c | 12 ++++++++ xrdp/xrdp_encoder.c | 17 ++++++++--- xrdp/xrdp_mm.c | 12 ++++++-- xrdp/xrdp_types.h | 3 +- 7 files changed, 115 insertions(+), 7 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 24443429..0d8e030e 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -1309,3 +1309,72 @@ libxrdp_codec_jpeg_compress(struct xrdp_session *session, width, height, stride, x, y, cx, cy, quality, out_data, io_len); } + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_fastpath_send_surface(struct xrdp_session *session, + char* data_pad, int pad_bytes, + int data_bytes, + int destLeft, int destTop, + int destRight, int destBottom, int bpp, + int codecID, int width, int height) +{ + struct stream ls; + struct stream *s; + struct xrdp_rdp *rdp; + int rv; + int sec_bytes; + int rdp_bytes; + int max_bytes; + int cmd_bytes; + + LLOGLN(10, ("libxrdp_fastpath_init:")); + if ((session->client_info->use_fast_path & 1) == 0) + { + return 1; + } + max_bytes = session->client_info->max_fastpath_frag_bytes; + if (max_bytes < 32 * 1024) + { + max_bytes = 32 * 1024; + } + rdp = (struct xrdp_rdp *) (session->rdp); + rdp_bytes = xrdp_rdp_get_fastpath_bytes(rdp); + sec_bytes = xrdp_sec_get_fastpath_bytes(rdp->sec_layer); + cmd_bytes = 10 + 12; + if (data_bytes + rdp_bytes + sec_bytes + cmd_bytes > max_bytes) + { + return 1; + } + if (sec_bytes + rdp_bytes + cmd_bytes > pad_bytes) + { + return 1; + } + g_memset(&ls, 0, sizeof(ls)); + s = &ls; + s->data = (data_pad + pad_bytes) - (rdp_bytes + sec_bytes + cmd_bytes); + s->sec_hdr = s->data; + s->rdp_hdr = s->sec_hdr + sec_bytes; + s->end = data_pad + pad_bytes + data_bytes; + s->p = s->data + (rdp_bytes + sec_bytes); + /* TS_SURFCMD_SET_SURF_BITS */ + out_uint16_le(s, 0x0001); /* CMDTYPE_SET_SURFACE_BITS */ + out_uint16_le(s, destLeft); + out_uint16_le(s, destTop); + out_uint16_le(s, destRight); + out_uint16_le(s, destBottom); + /* TS_ BITMAP_DATA_EX */ + out_uint8(s, bpp); + out_uint8(s, 0); + out_uint8(s, 0); + out_uint8(s, codecID); + out_uint16_le(s, width); + out_uint16_le(s, height); + out_uint32_le(s, data_bytes); + /* 4 = FASTPATH_UPDATETYPE_SURFCMDS */ + if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0) + { + return 1; + } + return 0; +} diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 1ddf345c..b909dd72 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -376,6 +376,8 @@ xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s); int APP_CC xrdp_rdp_init_data(struct xrdp_rdp* self, struct stream* s); int APP_CC +xrdp_rdp_get_fastpath_bytes(struct xrdp_rdp *self); +int APP_CC xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s); int APP_CC xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code); diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 8e41e7fe..8617f605 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -235,5 +235,12 @@ libxrdp_codec_jpeg_compress(struct xrdp_session *session, int stride, int x, int y, int cx, int cy, int quality, char *out_data, int *io_len); +int DEFAULT_CC +libxrdp_fastpath_send_surface(struct xrdp_session *session, + char* data_pad, int pad_bytes, + int data_bytes, + int destLeft, int dst_Top, + int destRight, int destBottom, int bpp, + int codecID, int width, int height); #endif diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 76834591..e6a2f622 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -507,6 +507,18 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s, return 0; } +/*****************************************************************************/ +/* returns the fastpath rdp byte count */ +int APP_CC +xrdp_rdp_get_fastpath_bytes(struct xrdp_rdp *self) +{ + if (self->client_info.rdp_compression) + { + return 4; + } + return 3; +} + /*****************************************************************************/ int APP_CC xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s) diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index 40c921f1..02b371ec 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -162,7 +162,7 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc) LLOGLN(0, ("process_enc: error")); return 1; } - out_data = (char *) g_malloc(out_data_bytes, 0); + out_data = (char *) g_malloc(out_data_bytes + 256, 0); if (out_data == 0) { LLOGLN(0, ("process_enc: error")); @@ -172,11 +172,20 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc) enc->width, enc->height, enc->width * 4, x, y, cx, cy, quality, - out_data, &out_data_bytes); + out_data + 256, &out_data_bytes); + if (error < 0) + { + LLOGLN(0, ("process_enc: jpeg error %d bytes %d", + error, out_data_bytes)); + g_free(out_data); + return 1; + } LLOGLN(10, ("jpeg error %d bytes %d", error, out_data_bytes)); - enc_done = g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1); + enc_done = (XRDP_ENC_DATA_DONE *) + g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1); enc_done->comp_bytes = out_data_bytes; - enc_done->comp_data = out_data; + enc_done->pad_bytes = 256; + enc_done->comp_pad_data = out_data; enc_done->enc = enc; enc_done->last = index == (enc->num_crects - 1); enc_done->index = index; diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index daa82c80..10b7234d 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1980,9 +1980,17 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) g_snprintf(text, 255, "/tmp/jj0x%8.8x.jpg", jj); jj++; ii = g_file_open(text); - g_file_write(ii, enc_done->comp_data, enc_done->comp_bytes); + g_file_write(ii, enc_done->comp_pad_data + enc_done->pad_bytes, enc_done->comp_bytes); g_file_close(ii); } + + libxrdp_fastpath_send_surface(self->wm->session, + enc_done->comp_pad_data, + enc_done->pad_bytes, + enc_done->comp_bytes, + 0, 0, 0, 0, 32, 99, 0, 0); + + /* free enc_done */ if (enc_done->last) { @@ -1991,7 +1999,7 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) g_free(enc_done->enc->crects); g_free(enc_done->enc); } - g_free(enc_done->comp_data); + g_free(enc_done->comp_pad_data); g_free(enc_done); tc_mutex_lock(self->mutex); enc_done = (XRDP_ENC_DATA_DONE*) diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 3ac1b752..c50daf79 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -629,7 +629,8 @@ typedef struct xrdp_enc_data XRDP_ENC_DATA; struct xrdp_enc_data_done { int comp_bytes; - char *comp_data; + int pad_bytes; + char *comp_pad_data; struct xrdp_enc_data *enc; int last; /* true is this is last message for enc */ int index; /* depends on codec */