File xrdp-fate319683-allow-vnc-resizing.patch of Package xrdp
commit bb1eae0bdb6ad8e58b88d5ba3a7bc639f70d9e8a (HEAD -> master)
Author: Felix Zhang <fezhang@suse.com>
Date: Thu May 11 12:19:13 2017 +0800
Add ExtendedDesktopSize support for xrdp's Xvnc client.
This enables resolution change for sessions.
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index e60aaa9..c77d28c 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -47,7 +47,7 @@ DisconnectedTimeLimit=0
## Policy - session allocation policy
# Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
-# Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
+# Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel>
# "UBD" session per <User,BitPerPixel,DisplaySize>
# "UBI" session per <User,BitPerPixel,IPAddr>
# "UBC" session per <User,BitPerPixel,Connection>
diff --git a/sesman/session.c b/sesman/session.c
index 4ea48d3..e603930 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -105,7 +105,6 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
- policy |= SESMAN_CFG_SESS_POLICY_D; /* Xvnc cannot resize */
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
@@ -136,9 +135,9 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
tmp->item->client_ip);
#endif
- if (type == SESMAN_SESSION_TYPE_XRDP)
+ if (type == SESMAN_SESSION_TYPE_XRDP || type == SESMAN_SESSION_TYPE_XVNC)
{
- /* only name and bpp need to match for X11rdp, it can resize */
+ /* only name and bpp need to match for X11rdp and Xvnc, it can resize */
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
(!(policy & SESMAN_CFG_SESS_POLICY_D) ||
(tmp->item->width == width && tmp->item->height == height)) &&
diff --git a/vnc/vnc.c b/vnc/vnc.c
index 5558c71..1025605 100644
--- a/vnc/vnc.c
+++ b/vnc/vnc.c
@@ -359,7 +359,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
/* FrambufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
- out_uint8(s, 0);
+ out_uint8(s, v->incremental);
+ v->incremental = 1;
x = (param1 >> 16) & 0xffff;
out_uint16_be(s, x);
y = param1 & 0xffff;
@@ -707,7 +708,24 @@ lib_framebuffer_update(struct vnc *v)
{
v->mod_width = cx;
v->mod_height = cy;
- error = v->server_reset(v, cx, cy, v->mod_bpp);
+ }
+ else if (encoding == 0xfffffecc) /* extended desktop resize */
+ {
+ init_stream(s, 8192);
+ error = lib_recv(v, s->data, 4);
+ if (error == 0)
+ {
+ in_uint8(s, k); /* number of screens */
+ in_uint8s(s, 3);
+ error = lib_recv(v, s->data, k * 16);
+ if (error == 0)
+ {
+ in_uint8s(s, k * 16); /* skip screen list */
+ /* note new dimensions for later */
+ v->server_width = cx;
+ v->server_height = cy;
+ }
+ }
}
else
{
@@ -724,13 +742,22 @@ lib_framebuffer_update(struct vnc *v)
}
g_free(data);
+ if (v->mod_width != v->server_width || v->mod_height != v->server_height)
+ {
+ /* perform actual resize outside the update */
+ v->mod_width = v->server_width;
+ v->mod_height = v->server_height;
+ error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp);
+ v->incremental = 0;
+ }
if (error == 0)
{
/* FrambufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
- out_uint8(s, 1);
+ out_uint8(s, v->incremental);
+ v->incremental = 1;
out_uint16_be(s, 0);
out_uint16_be(s, 0);
out_uint16_be(s, v->mod_width);
@@ -1244,13 +1271,14 @@ lib_mod_connect(struct vnc *v)
init_stream(s, 8192);
out_uint8(s, 2);
out_uint8(s, 0);
- out_uint16_be(s, 4);
+ out_uint16_be(s, 5);
out_uint32_be(s, 0); /* raw */
out_uint32_be(s, 1); /* copy rect */
out_uint32_be(s, 0xffffff11); /* cursor */
out_uint32_be(s, 0xffffff21); /* desktop size */
+ out_uint32_be(s, 0xfffffecc); /* extended desktop resize */
v->server_msg(v, "VNC sending encodings", 0);
- error = lib_send(v, s->data, 4 + 4 * 4);
+ error = lib_send(v, s->data, 4 + 5 * 4);
}
if (error == 0)
@@ -1263,7 +1291,8 @@ lib_mod_connect(struct vnc *v)
/* FrambufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
- out_uint8(s, 0);
+ out_uint8(s, v->incremental);
+ v->incremental = 1;
out_uint16_be(s, 0);
out_uint16_be(s, 0);
out_uint16_be(s, v->mod_width);
diff --git a/vnc/vnc.h b/vnc/vnc.h
index 6d265be..69e899b 100644
--- a/vnc/vnc.h
+++ b/vnc/vnc.h
@@ -116,4 +116,5 @@ struct vnc
int clip_data_size;
tbus sck_obj;
int delay_ms;
+ int incremental;
};