diff options
author | daixj <daixj@shterm.com> | 2018-10-25 10:34:00 +0800 |
---|---|---|
committer | daixj <daixj@shterm.com> | 2018-10-25 10:34:00 +0800 |
commit | b3a188920087bbc0293ee4e61bf8eb8e03a1c752 (patch) | |
tree | 3975d0f73e48d16ac279a2ed1684025a4ab34444 | |
parent | c2ade7a1f7318527bd8cb5aedc4ed127c5546c94 (diff) | |
download | xrdp-proprietary-b3a188920087bbc0293ee4e61bf8eb8e03a1c752.tar.gz xrdp-proprietary-b3a188920087bbc0293ee4e61bf8eb8e03a1c752.zip |
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 | 6 | ||||
-rw-r--r-- | xrdp/xrdp.ini.in | 2 |
5 files changed, 185 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..46810c18 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) + { + 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 (self->client_info.use_cache_glyph_v2 && (glyph_support_level != 3)) + { + self->client_info.use_cache_glyph_v2 = 0; + } + 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..928c1610 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -269,12 +269,16 @@ 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()); } } + else if (g_strcasecmp(item, "use_cache_glyph_v2") == 0) + { + client_info->use_cache_glyph_v2 = g_text2bool(value); + } } diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index c73e271c..0b24012d 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -53,6 +53,8 @@ use_fastpath=both #require_credentials=true ; You can set the PAM error text in a gateway setup (MAX 256 chars) #pamerrortxt=change your password according to policy at http://url +; Cache Glyph Revison 2. default: false +use_cache_glyph_v2=true ; ; colors used by windows in RGB format |