diff options
author | metalefty <meta@vmeta.jp> | 2018-10-31 10:03:51 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-31 10:03:51 +0900 |
commit | 0b3ce652f4ca3209f5b47192ab1f9b07835820a2 (patch) | |
tree | e2d0125e18b943c13ef00973aab4736648ce3c95 | |
parent | 6365905aacc0f39a7280f3c32f6607d3ca1afd5a (diff) | |
parent | bc150c2e56245ec3637d59915600fc65bc3c83a7 (diff) | |
download | xrdp-proprietary-0b3ce652f4ca3209f5b47192ab1f9b07835820a2.tar.gz xrdp-proprietary-0b3ce652f4ca3209f5b47192ab1f9b07835820a2.zip |
Merge pull request #1235 from daixj-shterm/devel-mac
Support Cache Glyph Revison 2, issue #367
-rw-r--r-- | common/xrdp_client_info.h | 1 | ||||
-rw-r--r-- | libxrdp/xrdp_caps.c | 30 | ||||
-rw-r--r-- | libxrdp/xrdp_orders.c | 152 | ||||
-rw-r--r-- | libxrdp/xrdp_rdp.c | 2 |
4 files changed, 179 insertions, 6 deletions
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index e8e91da4..b57b1949 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -154,6 +154,7 @@ struct xrdp_client_info int client_os_minor; int no_orders_supported; + int use_cache_glyph_v2; }; #endif diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c index dddf6d23..ff9b4484 100644 --- a/libxrdp/xrdp_caps.c +++ b/libxrdp/xrdp_caps.c @@ -361,6 +361,33 @@ xrdp_caps_process_brushcache(struct xrdp_rdp *self, struct stream *s, } /*****************************************************************************/ +static int +xrdp_caps_process_glyphcache(struct xrdp_rdp *self, struct stream *s, + int len) +{ + int glyph_support_level; + + if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */ + { + g_writeln("xrdp_caps_process_glyphcache: error"); + return 1; + } + + in_uint8s(s, 40); /* glyph cache */ + in_uint8s(s, 4); /* frag cache */ + in_uint16_le(s, glyph_support_level); + in_uint8s(s, 2); /* pad */ + + if (glyph_support_level == GLYPH_SUPPORT_ENCODE) + { + self->client_info.use_cache_glyph_v2 = 1; + } + g_writeln("xrdp_caps_process_glyphcache: support level %d ", + glyph_support_level); + return 0; +} + +/*****************************************************************************/ int xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) @@ -657,7 +684,8 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s) xrdp_caps_process_brushcache(self, s, len); break; case RDP_CAPSET_GLYPHCACHE: - DEBUG(("--0x11")); + DEBUG(("RDP_CAPSET_GLYPHCACHE")); + xrdp_caps_process_glyphcache(self, s, len); break; case RDP_CAPSET_OFFSCREENCACHE: DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index 52d043c9..5790a675 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -2444,10 +2444,10 @@ xrdp_orders_send_bitmap(struct xrdp_orders *self, /* returns error */ /* max size datasize + 18*/ /* todo, only sends one for now */ -int -xrdp_orders_send_font(struct xrdp_orders *self, - struct xrdp_font_char *font_char, - int font_index, int char_index) +static int +xrdp_orders_cache_glyph(struct xrdp_orders *self, + struct xrdp_font_char *font_char, + int font_index, int char_index) { int order_flags = 0; int datasize = 0; @@ -2488,6 +2488,150 @@ xrdp_orders_send_font(struct xrdp_orders *self, /*****************************************************************************/ /* returns error */ +static int write_2byte_signed(struct stream * s, int value) +{ + unsigned char byte; + int negative = 0; + + if (value < 0) + { + negative = 1; + value *= -1; + } + + if (value > 0x3FFF) + { + return 1; + } + + if (value >= 0x3F) + { + byte = ((value & 0x3F00) >> 8); + + if (negative) + { + byte |= 0x40; + } + + out_uint8(s, byte | 0x80); + byte = (value & 0xFF); + out_uint8(s, byte); + } + else + { + byte = (value & 0x3F); + + if (negative) + { + byte |= 0x40; + } + + out_uint8(s, byte); + } + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int write_2byte_unsigned(struct stream * s, unsigned int value) +{ + unsigned char byte; + + if (value > 0x7FFF) + { + return 1; + } + + if (value >= 0x7F) + { + byte = ((value & 0x7F00) >> 8); + out_uint8(s, byte | 0x80); + byte = (value & 0xFF); + out_uint8(s, byte); + } + else + { + byte = (value & 0x7F); + out_uint8(s, byte); + } + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +/* max size datasize + 15*/ +/* todo, only sends one for now */ +static int +xrdp_orders_cache_glyph_v2(struct xrdp_orders *self, + struct xrdp_font_char *font_char, + int font_index, int char_index) +{ + int order_flags = 0; + int datasize = 0; + int len = 0; + int extra_flags; + char *len_ptr; + + if (font_char->bpp == 8) /* alpha font */ + { + datasize = ((font_char->width + 3) & ~3) * font_char->height; + } + else + { + datasize = FONT_DATASIZE(font_char); + } + + /* cacheId, flags(GLYPH_ORDER_REV2), cGlyphs */ + extra_flags = (font_index & 0x000F) | (0x2 << 4) | (1 << 8); + + if (xrdp_orders_check(self, datasize + 15) != 0) + { + return 1; + } + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len_ptr = self->out_s->p; + out_uint16_le(self->out_s, 0); /* set later */ + out_uint16_le(self->out_s, extra_flags); + out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ + + out_uint8(self->out_s, char_index); + if (write_2byte_signed(self->out_s, font_char->offset) || + write_2byte_signed(self->out_s, font_char->baseline) || + write_2byte_unsigned(self->out_s, font_char->width) || + write_2byte_unsigned(self->out_s, font_char->height)) + { + return 1; + } + + out_uint8a(self->out_s, font_char->data, datasize); + len = (self->out_s->p - len_ptr) + 1 - 13; + len_ptr[0] = len & 0xFF; + len_ptr[1] = (len >> 8) & 0xFF; + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int +xrdp_orders_send_font(struct xrdp_orders *self, + struct xrdp_font_char *font_char, + int font_index, int char_index) +{ + if (self->rdp_layer->client_info.use_cache_glyph_v2) + { + return xrdp_orders_cache_glyph_v2(self, font_char, font_index, char_index); + } + + return xrdp_orders_cache_glyph(self, font_char, font_index, char_index); +} + +/*****************************************************************************/ +/* returns error */ /* max size width * height * Bpp + 14 */ int xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 494d23e8..ff099da9 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -269,7 +269,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info) g_strncpy(client_info->key_file, value, 1023); } - if (!g_file_readable(client_info->key_file)) + if (!g_file_readable(client_info->key_file)) { log_message(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s", client_info->key_file, g_get_strerror()); |