Skip to content

Commit

Permalink
Resolution switching without reconnecting.
Browse files Browse the repository at this point in the history
- Based on https://github.com/jsorg71/xrdp/tree/dynamic_monitor
- Tested with xorgxrdp
- Tested with vnc
- Only works with single monitor.
- Update documentation to clarify the difference between MSTSC and
Microsoft Remote Desktop.
- Does not include compatibility with /gfx at this time, which is still
in testing.
- Updates to include ms-rdpedisp.h header for the 2.2.2 specification of
the protocol.
- Adds new dynamic_monitor_layout struct that shares the number of
monitors with xrdp_client_info.h

Depends on neutrinolabs/xorgxrdp#183
  • Loading branch information
Nexarian committed Mar 15, 2021
1 parent feb8ef3 commit 88c4453
Show file tree
Hide file tree
Showing 12 changed files with 422 additions and 65 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
## Overview

**xrdp** provides a graphical login to remote machines using Microsoft
Remote Desktop Protocol (RDP). xrdp accepts connections from a variety of
RDP clients: FreeRDP, rdesktop, KRDC, NeutrinoRDP and Microsoft Remote Desktop
Client (for Windows, Mac OS, iOS and Android).
Remote Desktop Protocol (RDP). xrdp accepts connections from a variety of RDP clients:
- FreeRDP
- rdesktop
- KRDC
- NeutrinoRDP
- Windows MSTSC (Microsoft Terminal Services Client)
- Microsoft Remote Desktop (which is distinct from MSTSC)

Many of these work on some or all of Windows, Mac OS, iOS, and/or Android.

RDP transport is encrypted using TLS by default.

Expand All @@ -24,7 +30,7 @@ RDP transport is encrypted using TLS by default.
* Connect to a Linux desktop using RDP from anywhere (requires
[xorgxrdp](https://github.com/neutrinolabs/xorgxrdp) Xorg module)
* Reconnect to an existing session
* Session resizing
* Session resizing on connect and while an existing session is active.
* RDP/VNC proxy (connect to another RDP/VNC server via xrdp)

### Access to Remote Resources
Expand Down
1 change: 1 addition & 0 deletions common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include_HEADERS = \
ms-rdpegdi.h \
ms-rdpele.h \
ms-rdperp.h \
ms-rdpedisp.h \
ms-smb2.h \
xrdp_client_info.h \
xrdp_constants.h \
Expand Down
29 changes: 29 additions & 0 deletions common/ms-rdpedisp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* MS-RDPEDISP : Definitions from [MS-RDPEDISP]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* References to MS-RDPEDISP are currently correct for v20201030 of that
* document
*/

#if !defined(MS_RDPEDISP_H)
#define MS_RDPEDISP_H

/* Display Control Messages: Display Virtual Channel Extension (2.2.2) */
#define DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
#define DISPLAYCONTROL_PDU_TYPE_CAPS 0x00000005

#endif /* MS_RDPEDISP_H */
6 changes: 4 additions & 2 deletions common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#if !defined(XRDP_CLIENT_INFO_H)
#define XRDP_CLIENT_INFO_H

#define XRDP_MAXIMUM_MONITORS 16

struct monitor_info
{
int left;
Expand Down Expand Up @@ -120,8 +122,8 @@ struct xrdp_client_info
int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */
int multimon; /* 0 = deny , 1 = allow */
int monitorCount; /* number of monitors detected (max = 16) */
struct monitor_info minfo[16]; /* client monitor data */
struct monitor_info minfo_wm[16]; /* client monitor data, non-negative values */
struct monitor_info minfo[XRDP_MAXIMUM_MONITORS]; /* client monitor data */
struct monitor_info minfo_wm[XRDP_MAXIMUM_MONITORS]; /* client monitor data, non-negative values */

int keyboard_type;
int keyboard_subtype;
Expand Down
7 changes: 6 additions & 1 deletion libxrdp/xrdp_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,12 @@ xrdp_channel_drdynvc_start(struct xrdp_channel *self)
struct mcs_channel_item *ci;
struct mcs_channel_item *dci;


LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_channel_drdynvc_start: drdynvc_channel_id %d", self->drdynvc_channel_id);
if (self->drdynvc_channel_id != -1)
{
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_channel_drdynvc_start: already started");
return 0;
}
dci = NULL;
count = self->mcs_layer->channel_list->count;
for (index = 0; index < count; index++)
Expand Down
45 changes: 38 additions & 7 deletions vnc/vnc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ send_update_request_for_resize_status(struct vnc *v)
make_stream(s);
init_stream(s, 8192);

switch (v->initial_resize_status)
switch (v->resize_status)
{
case VRS_WAITING_FOR_FIRST_UPDATE:
/*
Expand Down Expand Up @@ -1364,14 +1364,14 @@ lib_framebuffer_first_update(struct vnc *v)
{
LOG(LOG_LEVEL_DEBUG, "Server layout is the same "
"as the client layout");
v->initial_resize_status = VRS_DONE;
v->resize_status = VRS_DONE;
}
else
{
LOG(LOG_LEVEL_DEBUG, "Server layout differs from "
"the client layout. Changing server layout");
error = send_set_desktop_size(v, &v->client_layout);
v->initial_resize_status = VRS_WAITING_FOR_RESIZE_CONFIRM;
v->resize_status = VRS_WAITING_FOR_RESIZE_CONFIRM;
}
}
else
Expand All @@ -1382,7 +1382,7 @@ lib_framebuffer_first_update(struct vnc *v)
LOG(LOG_LEVEL_DEBUG, "Resizing client to server %dx%d",
v->server_width, v->server_height);
error = resize_client(v, 0, v->server_width, v->server_height);
v->initial_resize_status = VRS_DONE;
v->resize_status = VRS_DONE;
}

g_free(layout.s);
Expand Down Expand Up @@ -1437,7 +1437,7 @@ lib_framebuffer_waiting_for_resize_confirm(struct vnc *v)
v->server_width, v->server_height);
error = resize_client(v, 0, v->server_width, v->server_height);
}
v->initial_resize_status = VRS_DONE;
v->resize_status = VRS_DONE;
}

g_free(layout.s);
Expand Down Expand Up @@ -1777,7 +1777,7 @@ lib_mod_process_message(struct vnc *v, struct stream *s)
{
if (type == S2C_FRAMEBUFFER_UPDATE)
{
switch (v->initial_resize_status)
switch (v->resize_status)
{
case VRS_WAITING_FOR_FIRST_UPDATE:
error = lib_framebuffer_first_update(v);
Expand Down Expand Up @@ -2237,7 +2237,7 @@ lib_mod_connect(struct vnc *v)

if (error == 0)
{
v->initial_resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
v->resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
error = send_update_request_for_resize_status(v);
}

Expand Down Expand Up @@ -2465,6 +2465,34 @@ lib_mod_suppress_output(struct vnc *v, int suppress,
return error;
}

/******************************************************************************/
/* return error */
int
lib_mod_server_version_message(struct vnc *v)
{
return 0;
}

/******************************************************************************/
/* return error */
int
lib_mod_server_monitor_resize(struct vnc *v, int width, int height, int bpp)
{
int error = 0;
set_single_screen_layout(&v->client_layout, width, height);
v->resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
error = send_update_request_for_resize_status(v);
return error;
}

/******************************************************************************/
/* return error */
int
lib_mod_server_monitor_full_invalidate(struct vnc *v, int param1, int param2)
{
return 0;
}

/******************************************************************************/
tintptr EXPORT_CC
mod_init(void)
Expand All @@ -2486,6 +2514,9 @@ mod_init(void)
v->mod_check_wait_objs = lib_mod_check_wait_objs;
v->mod_frame_ack = lib_mod_frame_ack;
v->mod_suppress_output = lib_mod_suppress_output;
v->mod_server_monitor_resize = lib_mod_server_monitor_resize;
v->mod_server_monitor_full_invalidate = lib_mod_server_monitor_full_invalidate;
v->mod_server_version_message = lib_mod_server_version_message;

/* Member variables */
v->enabled_encodings_mask = -1;
Expand Down
9 changes: 7 additions & 2 deletions vnc/vnc.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ struct vnc
int (*mod_frame_ack)(struct vnc *v, int flags, int frame_id);
int (*mod_suppress_output)(struct vnc *v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
int (*mod_server_monitor_resize)(struct vnc *v,
int width, int height, int bpp);
int (*mod_server_monitor_full_invalidate)(struct vnc *v,
int width, int height);
int (*mod_server_version_message)(struct vnc *v);
tintptr mod_dumby[100 - 14]; /* align, 100 minus the number of mod
functions above */
/* server functions */
int (*server_begin_update)(struct vnc *v);
Expand Down Expand Up @@ -152,5 +157,5 @@ struct vnc
unsigned int enabled_encodings_mask;
/* Resizeable support */
struct vnc_screen_layout client_layout;
enum vnc_resize_status initial_resize_status;
enum vnc_resize_status resize_status;
};
15 changes: 15 additions & 0 deletions xrdp/xrdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,21 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
int e);

/* xrdp_mm.c */

struct dynamic_monitor_layout
{
int flags;
int left;
int top;
int width;
int height;
int physical_width;
int physical_height;
int orientation;
int desktop_scale_factor;
int device_scale_factor;
};

int
xrdp_mm_drdynvc_up(struct xrdp_mm *self);
int
Expand Down
Loading

0 comments on commit 88c4453

Please sign in to comment.