Merge pull request #1343 from matt335672/extended-vnc

Add resizeable backend VNC support
This commit is contained in:
matt335672 2020-06-04 15:36:00 +01:00 committed by GitHub
commit f37d1ba46e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1213 additions and 210 deletions

View File

@ -148,12 +148,12 @@ This works only with xorgxrdp session. Moreover, xorgxrdp must be v0.2.9 or late
.TP .TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR \fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
Session allocation policy. By default, a new session is created Session allocation policy. Used to decide when to allocate a
for the combination <User,BitPerPixel> when using Xrdp, and new session. Set to one of the following values:
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
This behavior can be changed by setting session policy to:
.br .br
.br
\fBDefault\fR - session per <User,BitPerPixel>
.br .br
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize> \fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
.br .br
@ -168,7 +168,8 @@ This behavior can be changed by setting session policy to:
.br .br
Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well. off. \fBDisplaySize\fR refers to the initial geometry of a connection,
as actual display sizes can change dynamically.
.br .br
.SH "SECURITY" .SH "SECURITY"

View File

@ -302,6 +302,14 @@ Specifies color depth of the backend X server. The default is the color
depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
\fI24\fR bpp. \fI24\fR bpp.
.TP
\fBdisabled_encodings_mask\fR=\fI<number>\fR
Set this bitmask to a non-zero value to prevent \fBxrdp\fR(8) requesting
some features from the Xvnc server. You should only need to set this
to a non-zero value to work around bugs in your Xvnc server. The bit
values supported for a particular release of \fBxrdp\fR(8) are documented in
\fBxrdp.ini\fR.
.TP .TP
\fBcode\fR=\fI<number>\fR|\fI0\fR \fBcode\fR=\fI<number>\fR|\fI0\fR
Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is

View File

@ -1044,29 +1044,36 @@ libxrdp_orders_send_font(struct xrdp_session *session,
} }
/*****************************************************************************/ /*****************************************************************************/
/* Note : if this is called on a multimon setup, the client is resized
* to a single monitor */
int EXPORT_CC int EXPORT_CC
libxrdp_reset(struct xrdp_session *session, libxrdp_reset(struct xrdp_session *session,
int width, int height, int bpp) int width, int height, int bpp)
{ {
if (session->client_info != 0) if (session->client_info != 0)
{ {
struct xrdp_client_info *client_info = session->client_info;
/* older client can't resize */ /* older client can't resize */
if (session->client_info->build <= 419) if (client_info->build <= 419)
{ {
return 0; return 0;
} }
/* if same, don't need to do anything */ /* if same (and only one monitor on client) don't need to do anything */
if (session->client_info->width == width && if (client_info->width == width &&
session->client_info->height == height && client_info->height == height &&
session->client_info->bpp == bpp) client_info->bpp == bpp &&
(client_info->monitorCount == 0 || client_info->multimon == 0))
{ {
return 0; return 0;
} }
session->client_info->width = width; client_info->width = width;
session->client_info->height = height; client_info->height = height;
session->client_info->bpp = bpp; client_info->bpp = bpp;
client_info->monitorCount = 0;
client_info->multimon = 0;
} }
else else
{ {

View File

@ -105,9 +105,6 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
{ {
case SCP_SESSION_TYPE_XVNC: /* 0 */ case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
/* Xvnc cannot resize */
policy = (enum SESMAN_CFG_SESS_POLICY)
(policy | SESMAN_CFG_SESS_POLICY_D);
break; break;
case SCP_SESSION_TYPE_XRDP: /* 1 */ case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ type = SESMAN_SESSION_TYPE_XRDP; /* 1 */

View File

@ -31,6 +31,10 @@
#include "sesman.h" #include "sesman.h"
#include "tcp.h" #include "tcp.h"
#if !defined(PACKAGE_VERSION)
#define PACKAGE_VERSION "???"
#endif
struct config_sesman g_cfg; /* config.h */ struct config_sesman g_cfg; /* config.h */
/******************************************************************************/ /******************************************************************************/
@ -61,9 +65,9 @@ main(int argc, char **argv)
if (argc == 1) if (argc == 1)
{ {
g_printf("xrdp session starter v0.1\n"); g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
g_printf("\nusage:\n"); g_printf("\nusage:\n");
g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_cod>\n"); g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_code>\n");
g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n"); g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n");
} }
else if (argc == 8) else if (argc == 8)

1145
vnc/vnc.c

File diff suppressed because it is too large Load Diff

211
vnc/vnc.h
View File

@ -26,98 +26,129 @@
#define CURRENT_MOD_VER 4 #define CURRENT_MOD_VER 4
/* Screen used for ExtendedDesktopSize / Set DesktopSize */
struct vnc_screen
{
int id;
int x;
int y;
int width;
int height;
int flags;
};
struct vnc_screen_layout
{
int total_width;
int total_height;
unsigned int count;
/* For comparison, screens are sorted in increasing order of ID */
struct vnc_screen *s;
};
/**
* Keep track of resize status at start of connection
*/
enum vnc_resize_status
{
VRS_WAITING_FOR_FIRST_UPDATE,
VRS_WAITING_FOR_RESIZE_CONFIRM,
VRS_DONE
};
struct vnc struct vnc
{ {
int size; /* size of this struct */ int size; /* size of this struct */
int version; /* internal version */ int version; /* internal version */
/* client functions */ /* client functions */
int (*mod_start)(struct vnc* v, int w, int h, int bpp); int (*mod_start)(struct vnc *v, int w, int h, int bpp);
int (*mod_connect)(struct vnc* v); int (*mod_connect)(struct vnc *v);
int (*mod_event)(struct vnc* v, int msg, long param1, long param2, int (*mod_event)(struct vnc *v, int msg, long param1, long param2,
long param3, long param4); long param3, long param4);
int (*mod_signal)(struct vnc* v); int (*mod_signal)(struct vnc *v);
int (*mod_end)(struct vnc* v); int (*mod_end)(struct vnc *v);
int (*mod_set_param)(struct vnc *v, const char *name, const char *value); int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
int (*mod_session_change)(struct vnc* v, int, int); int (*mod_session_change)(struct vnc *v, int, int);
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount, int (*mod_get_wait_objs)(struct vnc *v, tbus *read_objs, int *rcount,
tbus* write_objs, int* wcount, int* timeout); tbus *write_objs, int *wcount, int *timeout);
int (*mod_check_wait_objs)(struct vnc* v); int (*mod_check_wait_objs)(struct vnc *v);
int (*mod_frame_ack)(struct vnc* v, int flags, int frame_id); int (*mod_frame_ack)(struct vnc *v, int flags, int frame_id);
int (*mod_suppress_output)(struct vnc* v, int suppress, int (*mod_suppress_output)(struct vnc *v, int suppress,
int left, int top, int right, int bottom); int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct vnc* v); int (*server_begin_update)(struct vnc *v);
int (*server_end_update)(struct vnc* v); int (*server_end_update)(struct vnc *v);
int (*server_fill_rect)(struct vnc* v, int x, int y, int cx, int cy); int (*server_fill_rect)(struct vnc *v, int x, int y, int cx, int cy);
int (*server_screen_blt)(struct vnc* v, int x, int y, int cx, int cy, int (*server_screen_blt)(struct vnc *v, int x, int y, int cx, int cy,
int srcx, int srcy); int srcx, int srcy);
int (*server_paint_rect)(struct vnc* v, int x, int y, int cx, int cy, int (*server_paint_rect)(struct vnc *v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy); char *data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask); int (*server_set_cursor)(struct vnc *v, int x, int y, char *data, char *mask);
int (*server_palette)(struct vnc* v, int* palette); int (*server_palette)(struct vnc *v, int *palette);
int (*server_msg)(struct vnc* v, const char *msg, int code); int (*server_msg)(struct vnc *v, const char *msg, int code);
int (*server_is_term)(struct vnc* v); int (*server_is_term)(struct vnc *v);
int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy); int (*server_set_clip)(struct vnc *v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct vnc* v); int (*server_reset_clip)(struct vnc *v);
int (*server_set_fgcolor)(struct vnc* v, int fgcolor); int (*server_set_fgcolor)(struct vnc *v, int fgcolor);
int (*server_set_bgcolor)(struct vnc* v, int bgcolor); int (*server_set_bgcolor)(struct vnc *v, int bgcolor);
int (*server_set_opcode)(struct vnc* v, int opcode); int (*server_set_opcode)(struct vnc *v, int opcode);
int (*server_set_mixmode)(struct vnc* v, int mixmode); int (*server_set_mixmode)(struct vnc *v, int mixmode);
int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin, int (*server_set_brush)(struct vnc *v, int x_origin, int y_origin,
int style, char* pattern); int style, char *pattern);
int (*server_set_pen)(struct vnc* v, int style, int (*server_set_pen)(struct vnc *v, int style,
int width); int width);
int (*server_draw_line)(struct vnc* v, int x1, int y1, int x2, int y2); int (*server_draw_line)(struct vnc *v, int x1, int y1, int x2, int y2);
int (*server_add_char)(struct vnc* v, int font, int character, int (*server_add_char)(struct vnc *v, int font, int character,
int offset, int baseline, int offset, int baseline,
int width, int height, char* data); int width, int height, char *data);
int (*server_draw_text)(struct vnc* v, int font, int (*server_draw_text)(struct vnc *v, int font,
int flags, int mixmode, int clip_left, int clip_top, int flags, int mixmode, int clip_left, int clip_top,
int clip_right, int clip_bottom, int clip_right, int clip_bottom,
int box_left, int box_top, int box_left, int box_top,
int box_right, int box_bottom, int box_right, int box_bottom,
int x, int y, char* data, int data_len); int x, int y, char *data, int data_len);
int (*server_reset)(struct vnc* v, int width, int height, int bpp); int (*server_reset)(struct vnc *v, int width, int height, int bpp);
int (*server_query_channel)(struct vnc* v, int index, int (*server_query_channel)(struct vnc *v, int index,
char* channel_name, char *channel_name,
int* channel_flags); int *channel_flags);
int (*server_get_channel_id)(struct vnc* v, const char *name); int (*server_get_channel_id)(struct vnc *v, const char *name);
int (*server_send_to_channel)(struct vnc* v, int channel_id, int (*server_send_to_channel)(struct vnc *v, int channel_id,
char* data, int data_len, char *data, int data_len,
int total_data_len, int flags); int total_data_len, int flags);
int (*server_bell_trigger)(struct vnc* v); int (*server_bell_trigger)(struct vnc *v);
tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */
tintptr wm; tintptr wm;
tintptr painter; tintptr painter;
tintptr si; tintptr si;
/* mod data */ /* mod data */
int server_width; int server_width;
int server_height; int server_height;
int server_bpp; int server_bpp;
int mod_width; char mod_name[256];
int mod_height; int mod_mouse_state;
int mod_bpp; int palette[256];
char mod_name[256]; int vnc_desktop;
int mod_mouse_state; char username[256];
int palette[256]; char password[256];
int vnc_desktop; char ip[256];
char username[256]; char port[256];
char password[256]; int sck_closed;
char ip[256]; int shift_state; /* 0 up, 1 down */
char port[256]; int keylayout;
int sck_closed; int clip_chanid;
int shift_state; /* 0 up, 1 down */ struct stream *clip_data_s;
int keylayout; int delay_ms;
int clip_chanid; struct trans *trans;
struct stream *clip_data_s; int got_guid;
int delay_ms; tui8 guid[16];
struct trans *trans; int suppress_output;
int got_guid; unsigned int enabled_encodings_mask;
tui8 guid[16]; /* Resizeable support */
int suppress_output; struct vnc_screen_layout client_layout;
enum vnc_resize_status initial_resize_status;
}; };

View File

@ -196,6 +196,10 @@ ip=127.0.0.1
port=-1 port=-1
#xserverbpp=24 #xserverbpp=24
#delay_ms=2000 #delay_ms=2000
; Disable requested encodings to support buggy VNC servers
; (1 = ExtendedDesktopSize)
#disabled_encodings_mask=0
[vnc-any] [vnc-any]
name=vnc-any name=vnc-any

View File

@ -3261,6 +3261,9 @@ server_draw_text(struct xrdp_mod *mod, int font,
} }
/*****************************************************************************/ /*****************************************************************************/
/* Note : if this is called on a multimon setup, the client is resized
* to a single monitor */
int int
server_reset(struct xrdp_mod *mod, int width, int height, int bpp) server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
{ {
@ -3279,10 +3282,11 @@ server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
return 0; return 0;
} }
/* if same, don't need to do anything */ /* if same (and only one monitor on client) don't need to do anything */
if (wm->client_info->width == width && if (wm->client_info->width == width &&
wm->client_info->height == height && wm->client_info->height == height &&
wm->client_info->bpp == bpp) wm->client_info->bpp == bpp &&
(wm->client_info->monitorCount == 0 || wm->client_info->multimon == 0))
{ {
return 0; return 0;
} }