summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormetalefty <meta@vmeta.jp>2018-10-31 10:03:51 +0900
committerGitHub <noreply@github.com>2018-10-31 10:03:51 +0900
commit0b3ce652f4ca3209f5b47192ab1f9b07835820a2 (patch)
treee2d0125e18b943c13ef00973aab4736648ce3c95
parent6365905aacc0f39a7280f3c32f6607d3ca1afd5a (diff)
parentbc150c2e56245ec3637d59915600fc65bc3c83a7 (diff)
downloadxrdp-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.h1
-rw-r--r--libxrdp/xrdp_caps.c30
-rw-r--r--libxrdp/xrdp_orders.c152
-rw-r--r--libxrdp/xrdp_rdp.c2
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());