Compare commits
4 Commits
devel
...
extended-v
Author | SHA1 | Date | |
---|---|---|---|
|
8945b49e61 | ||
|
7d305b0085 | ||
|
3293370faf | ||
|
79c8ed8579 |
@ -63,6 +63,10 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
|
||||
s->type = SCP_SESSION_TYPE_XVNC;
|
||||
break;
|
||||
|
||||
case SCP_SESSION_TYPE_RESIZABLE_XVNC:
|
||||
s->type = SCP_SESSION_TYPE_RESIZABLE_XVNC;
|
||||
break;
|
||||
|
||||
case SCP_SESSION_TYPE_XRDP:
|
||||
s->type = SCP_SESSION_TYPE_XRDP;
|
||||
break;
|
||||
|
@ -38,15 +38,16 @@
|
||||
#define SCP_RESOURCE_SHARING_REQUEST_YES 0x01
|
||||
#define SCP_RESOURCE_SHARING_REQUEST_NO 0x00
|
||||
|
||||
#define SCP_SESSION_TYPE_XVNC 0x00
|
||||
#define SCP_SESSION_TYPE_XRDP 0x01
|
||||
#define SCP_SESSION_TYPE_MANAGE 0x02
|
||||
#define SCP_SESSION_TYPE_XORG 0x03
|
||||
#define SCP_SESSION_TYPE_XVNC 0x00
|
||||
#define SCP_SESSION_TYPE_XRDP 0x01
|
||||
#define SCP_SESSION_TYPE_MANAGE 0x02
|
||||
#define SCP_SESSION_TYPE_XORG 0x03
|
||||
|
||||
/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway
|
||||
* XRDP sends this command to let sesman verify if the user is allowed
|
||||
* to use the gateway */
|
||||
#define SCP_GW_AUTHENTICATION 0x04
|
||||
#define SCP_GW_AUTHENTICATION 0x04
|
||||
#define SCP_SESSION_TYPE_RESIZABLE_XVNC 0x05
|
||||
|
||||
#define SCP_ADDRESS_TYPE_IPV4 0x00
|
||||
#define SCP_ADDRESS_TYPE_IPV6 0x01
|
||||
|
@ -56,6 +56,10 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
{
|
||||
out_uint16_be(c->out_s, 0);
|
||||
}
|
||||
else if (s->type == SCP_SESSION_TYPE_RESIZABLE_XVNC)
|
||||
{
|
||||
out_uint16_be(c->out_s, 1);
|
||||
}
|
||||
else if (s->type == SCP_SESSION_TYPE_XRDP)
|
||||
{
|
||||
out_uint16_be(c->out_s, 10);
|
||||
@ -199,7 +203,7 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
|
||||
|
||||
in_uint16_be(c->in_s, code);
|
||||
|
||||
if (code == 0 || code == 10 || code == 20)
|
||||
if (code == 0 || code == 1 || code == 10 || code == 20)
|
||||
{
|
||||
session = scp_session_create();
|
||||
|
||||
@ -215,6 +219,10 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
|
||||
}
|
||||
else if (code == 1)
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_RESIZABLE_XVNC);
|
||||
}
|
||||
else if (code == 10)
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
|
||||
|
@ -120,7 +120,8 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
"username %s", s->username);
|
||||
}
|
||||
|
||||
if (SCP_SESSION_TYPE_XVNC == s->type)
|
||||
if (SCP_SESSION_TYPE_XVNC == s->type ||
|
||||
SCP_SESSION_TYPE_RESIZABLE_XVNC == s->type)
|
||||
{
|
||||
log_message( LOG_LEVEL_INFO, "starting Xvnc session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
|
||||
|
@ -124,7 +124,8 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
|
||||
}
|
||||
|
||||
if (SCP_SESSION_TYPE_XVNC == s->type)
|
||||
if (SCP_SESSION_TYPE_XVNC == s->type ||
|
||||
SCP_SESSION_TYPE_RESIZABLE_XVNC == s->type)
|
||||
{
|
||||
log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
|
||||
|
@ -105,10 +105,13 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
|
||||
{
|
||||
case SCP_SESSION_TYPE_XVNC: /* 0 */
|
||||
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
|
||||
/* Xvnc cannot resize */
|
||||
/* standard Xvnc can never resize */
|
||||
policy = (enum SESMAN_CFG_SESS_POLICY)
|
||||
(policy | SESMAN_CFG_SESS_POLICY_D);
|
||||
break;
|
||||
case SCP_SESSION_TYPE_RESIZABLE_XVNC:
|
||||
type = SESMAN_SESSION_TYPE_XVNC;
|
||||
break;
|
||||
case SCP_SESSION_TYPE_XRDP: /* 1 */
|
||||
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
|
||||
break;
|
||||
|
@ -31,6 +31,10 @@
|
||||
#include "sesman.h"
|
||||
#include "tcp.h"
|
||||
|
||||
#if !defined(PACKAGE_VERSION)
|
||||
#define PACKAGE_VERSION "???"
|
||||
#endif
|
||||
|
||||
struct config_sesman g_cfg; /* config.h */
|
||||
|
||||
/******************************************************************************/
|
||||
@ -61,10 +65,14 @@ main(int argc, char **argv)
|
||||
|
||||
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("sesrun <server> <username> <password> <width> <height> <bpp> <session_cod>\n");
|
||||
g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n");
|
||||
g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_code>\n");
|
||||
g_printf("session code:-\n");
|
||||
g_printf(" - 0 for fixed Xvnc\n");
|
||||
g_printf(" - 1 for resizeable Xvnc\n");
|
||||
g_printf(" - 10 for X11RDP\n");
|
||||
g_printf(" - 20 for Xorg\n");
|
||||
}
|
||||
else if (argc == 8)
|
||||
{
|
||||
|
514
vnc/vnc.c
514
vnc/vnc.c
@ -16,6 +16,14 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
* libvnc
|
||||
*
|
||||
* The message definitions used in this source file can be found mostly
|
||||
* in RFC6143 - "The Remote Framebuffer Protocol".
|
||||
*
|
||||
* The ExtendedDesktopSize encoding is reserved in RFC6143, but not
|
||||
* documented there. It is documented by the RFB protocol community
|
||||
* wiki currently held at https://github.com/rfbproto/rfbroto. This is
|
||||
* referred to below as the "RFB community wiki"
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@ -26,21 +34,29 @@
|
||||
#include "log.h"
|
||||
#include "trans.h"
|
||||
#include "ssl_calls.h"
|
||||
#include "xrdp_client_info.h"
|
||||
|
||||
#define LLOG_LEVEL 1
|
||||
#define LLOGLN(_level, _args) \
|
||||
do \
|
||||
{ \
|
||||
if (_level < LLOG_LEVEL) \
|
||||
do \
|
||||
{ \
|
||||
g_write("xrdp:vnc [%10.10u]: ", g_time3()); \
|
||||
g_writeln _args ; \
|
||||
if (_level < LLOG_LEVEL) \
|
||||
{ \
|
||||
g_write("xrdp:vnc [%10.10u]: ", g_time3()); \
|
||||
g_writeln _args ; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
while (0)
|
||||
|
||||
#define AS_LOG_MESSAGE log_message
|
||||
|
||||
/* Encodings and pseudo-encodings from RFC6143 */
|
||||
#define ENC_RAW 0
|
||||
#define ENC_COPY_RECT 1
|
||||
#define ENC_CURSOR (unsigned int)-239
|
||||
#define ENC_DESKTOP_SIZE (unsigned int)-223
|
||||
#define ENC_EXTENDED_DESKTOP_SIZE (unsigned int)-308
|
||||
|
||||
static int
|
||||
lib_mod_process_message(struct vnc *v, struct stream *s);
|
||||
|
||||
@ -256,6 +272,356 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static void
|
||||
log_debug_screen_layout(const char *source,
|
||||
const struct vnc_screen_layout *layout)
|
||||
{
|
||||
unsigned int i;
|
||||
char text[256];
|
||||
size_t pos;
|
||||
int res;
|
||||
|
||||
pos = 0;
|
||||
res = g_snprintf(text, sizeof(text) - pos,
|
||||
"Layout from %s (#screens=%d) :",
|
||||
source, layout->count);
|
||||
|
||||
i = 0;
|
||||
while (res > 0 && (size_t)res < sizeof(text) - pos && i < layout->count)
|
||||
{
|
||||
pos += res;
|
||||
res = g_snprintf(&text[pos], sizeof(text) - pos,
|
||||
" %d:(%dx%d+%d+%d)",
|
||||
layout->s[i].id,
|
||||
layout->s[i].width, layout->s[i].height,
|
||||
layout->s[i].x, layout->s[i].y);
|
||||
++i;
|
||||
}
|
||||
log_message(LOG_LEVEL_DEBUG, "%s", text);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Compares two vnc_screen structures, returning a value which can
|
||||
* also be used for sorting on id
|
||||
*/
|
||||
static int cmp_vnc_screen(const struct vnc_screen *a,
|
||||
const struct vnc_screen *b)
|
||||
{
|
||||
int result = 0;
|
||||
if (a->id != b->id)
|
||||
{
|
||||
result = a->id - b->id;
|
||||
}
|
||||
else if (a->x != b->x)
|
||||
{
|
||||
result = a->x - b->x;
|
||||
}
|
||||
else if (a->y != b->y)
|
||||
{
|
||||
result = a->y - b->y;
|
||||
}
|
||||
else if (a->width != b->width)
|
||||
{
|
||||
result = a->width - b->width;
|
||||
}
|
||||
else if (a->height != b->height)
|
||||
{
|
||||
result = a->height - b->height;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Compares two vnc_screen_layout structures
|
||||
*
|
||||
* Result can only be used for equality testing
|
||||
*/
|
||||
static int cmp_vnc_screen_layout(const struct vnc_screen_layout *a,
|
||||
const struct vnc_screen_layout *b)
|
||||
{
|
||||
unsigned int i;
|
||||
int result = b->count - a->count;
|
||||
|
||||
for (i = 0 ; result == 0 && i < a->count ; ++i)
|
||||
{
|
||||
result = cmp_vnc_screen(&a->s[i], &b->s[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Reads an extended desktop size rectangle from the VNC server
|
||||
*
|
||||
* Returned structure is in increasing ID order, rather than order on-the-wire
|
||||
*
|
||||
* On a successful return, layout->s has been allocated, and must be
|
||||
* freed after use.
|
||||
*/
|
||||
static int
|
||||
read_extended_desktop_size_rect(struct vnc *v,
|
||||
struct vnc_screen_layout *layout)
|
||||
{
|
||||
struct stream *s;
|
||||
int error;
|
||||
unsigned int i;
|
||||
|
||||
layout->count = 0;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
/* Read in the current screen config */
|
||||
error = trans_force_read_s(v->trans, s, 4);
|
||||
if (error == 0)
|
||||
{
|
||||
/* Get the number of screens */
|
||||
in_uint8(s, layout->count);
|
||||
in_uint8s(s, 3);
|
||||
|
||||
error = trans_force_read_s(v->trans, s, 16 * layout->count);
|
||||
if (error == 0)
|
||||
{
|
||||
layout->s = g_new(struct vnc_screen, layout->count);
|
||||
if (layout->s == NULL)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
"VNC : Can't alloc for %d screens", layout->count);
|
||||
layout->count = 0;
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0 ; i < layout->count ; ++i)
|
||||
{
|
||||
in_uint32_be(s, layout->s[i].id);
|
||||
in_uint16_be(s, layout->s[i].x);
|
||||
in_uint16_be(s, layout->s[i].y);
|
||||
in_uint16_be(s, layout->s[i].width);
|
||||
in_uint16_be(s, layout->s[i].height);
|
||||
in_uint32_be(s, layout->s[i].flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* sort monitors in increasing ID order */
|
||||
qsort(layout->s, layout->count, sizeof(layout->s[0]),
|
||||
(int (*)(const void *, const void *))cmp_vnc_screen);
|
||||
}
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Check to see if a SetDesktopSize message should be sent, based on the
|
||||
* current Xvnc geometry and screen layout
|
||||
*/
|
||||
static int
|
||||
set_desktop_size_is_needed(struct vnc *v, int vnc_width, int vnc_height,
|
||||
const struct vnc_screen_layout *vnc_layout)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (v->mod_width != vnc_width || v->mod_height != vnc_height)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG, "VNC SetDesktopSize needed "
|
||||
"for size change from (%d,%d) to (%d,%d)",
|
||||
vnc_width, vnc_height, v->mod_width, v->mod_height);
|
||||
result = 1;
|
||||
}
|
||||
else if (cmp_vnc_screen_layout(vnc_layout, &v->screen_layout) != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG, "VNC SetDesktopSize needed "
|
||||
"for changed screen layouts");
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG, "VNC SetDesktopSize not needed");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Send a SetDesktopSize message based on the initial RDP parameters
|
||||
*/
|
||||
static int
|
||||
send_set_desktop_size_msg(struct vnc *v)
|
||||
{
|
||||
unsigned int i;
|
||||
struct stream *s;
|
||||
int error;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 251);
|
||||
out_uint8(s, 0);
|
||||
out_uint16_be(s, v->mod_width);
|
||||
out_uint16_be(s, v->mod_height);
|
||||
|
||||
out_uint8(s, v->screen_layout.count);
|
||||
out_uint8(s, 0);
|
||||
for (i = 0 ; i < v->screen_layout.count ; ++i)
|
||||
{
|
||||
out_uint32_be(s, v->screen_layout.s[i].id);
|
||||
out_uint16_be(s, v->screen_layout.s[i].x);
|
||||
out_uint16_be(s, v->screen_layout.s[i].y);
|
||||
out_uint16_be(s, v->screen_layout.s[i].width);
|
||||
out_uint16_be(s, v->screen_layout.s[i].height);
|
||||
out_uint32_be(s, v->screen_layout.s[i].flags);
|
||||
}
|
||||
s_mark_end(s);
|
||||
log_message(LOG_LEVEL_DEBUG, "VNC Sending SetDesktopSize");
|
||||
error = lib_send_copy(v, s);
|
||||
free_stream(s);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Check to resize the attached client
|
||||
*
|
||||
* The resizing of multi-screen layouts isn't supported. If
|
||||
* we end up in this situation we currently throw an error, resulting in
|
||||
* a disconnect.
|
||||
*/
|
||||
static int
|
||||
check_to_resize_client(struct vnc *v, int width, int height,
|
||||
const struct vnc_screen_layout *layout)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (width != v->mod_width || height != v->mod_height ||
|
||||
cmp_vnc_screen_layout(&v->screen_layout, layout) != 0)
|
||||
{
|
||||
/*
|
||||
* we don't have the capability to cope with a rearrangement
|
||||
* of a multi-screen layout.
|
||||
*/
|
||||
if (layout->count != 1 || v->screen_layout.count != 1)
|
||||
{
|
||||
char text[256];
|
||||
g_sprintf(text, "VNC Resize to %d screen(s) from %d screen(s) "
|
||||
"not implemented",
|
||||
v->screen_layout.count, layout->count);
|
||||
v->server_msg(v, text, 0);
|
||||
|
||||
/* Dump some useful info, in case we get here when we don't
|
||||
* need to */
|
||||
log_debug_screen_layout("OldLayout", layout);
|
||||
log_debug_screen_layout("NewLayout", layout);
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
v->mod_width = width;
|
||||
v->mod_height = height;
|
||||
v->screen_layout.s[0] = layout->s[0];
|
||||
error = v->server_reset(v, width, height, v->mod_bpp);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Process an ExtendedDesktopSize message
|
||||
*/
|
||||
static int
|
||||
process_extended_desktop_size(struct vnc *v, int x, int y, int cx, int cy,
|
||||
const struct vnc_screen_layout *layout)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (x)
|
||||
{
|
||||
default:
|
||||
/* Spec says to treat unknown values as a zero */
|
||||
if (x != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
"VNC got ExtendedDesktopSize rectangle type %d", x);
|
||||
}
|
||||
|
||||
if (v->first_framebuffer_update)
|
||||
{
|
||||
/*
|
||||
* This is a response to our first framebuffer update
|
||||
* request. At this point, we want to impose our will
|
||||
* on the client. After that, the server may request
|
||||
* size changes of its own.
|
||||
*/
|
||||
log_message(LOG_LEVEL_DEBUG,
|
||||
"VNC got first ExtendedDesktopSize rectangle "
|
||||
"x=%d, y=%d, cx=%d, cy=%d", x, y, cx, cy);
|
||||
log_debug_screen_layout("Xvnc", layout);
|
||||
|
||||
/*
|
||||
* If we've only got one screen, and the other side has
|
||||
* only got one screen, we will preserve their screen
|
||||
* ID and any flags. This may prevent us sending
|
||||
* an unwanted SetDesktopSize message if the screen
|
||||
* dimensions are a match. We can't do this with more than
|
||||
* one screen, as we have no way to map different IDs
|
||||
*/
|
||||
if (layout->count == 1 && v->screen_layout.count == 1)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG, "VNC "
|
||||
"setting screen id to %d from server",
|
||||
layout->s[0].id);
|
||||
|
||||
v->screen_layout.s[0].id = layout->s[0].id;
|
||||
v->screen_layout.s[0].flags = layout->s[0].flags;
|
||||
}
|
||||
if (set_desktop_size_is_needed(v, cx, cy, layout))
|
||||
{
|
||||
error = send_set_desktop_size_msg(v);
|
||||
v->set_desktop_size_in_progress = 1;
|
||||
}
|
||||
}
|
||||
else if (v->set_desktop_size_in_progress)
|
||||
{
|
||||
/* Ignore this, until the X server has responded */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could be a response to another framebuffer update request,
|
||||
* or a server-side change (i.e. with xrandr)
|
||||
*/
|
||||
error = check_to_resize_client(v, cx, cy, layout);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* Response to a SetDesktopSize message from us */
|
||||
v->set_desktop_size_in_progress = 0;
|
||||
if (y == 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG,
|
||||
"VNC SetDesktopSize was successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
"VNC SetDesktopSize failed and returned %d", y);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
* Another client has resized or re-arranged the screen
|
||||
*/
|
||||
error = check_to_resize_client(v, cx, cy, layout);
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
||||
long param3, long param4)
|
||||
@ -385,7 +751,7 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 3);
|
||||
out_uint8(s, 0);
|
||||
out_uint8(s, 0); /* incremental == 0 : Full contents */
|
||||
x = (param1 >> 16) & 0xffff;
|
||||
out_uint16_be(s, x);
|
||||
y = param1 & 0xffff;
|
||||
@ -615,6 +981,8 @@ lib_framebuffer_update(struct vnc *v)
|
||||
int need_size;
|
||||
struct stream *s;
|
||||
struct stream *pixel_s;
|
||||
int extended_desktop_size_msg_received = 0;
|
||||
struct vnc_screen_layout layout = { 0 };
|
||||
|
||||
num_recs = 0;
|
||||
Bpp = (v->mod_bpp + 7) / 8;
|
||||
@ -655,7 +1023,7 @@ lib_framebuffer_update(struct vnc *v)
|
||||
in_uint16_be(s, cy);
|
||||
in_uint32_be(s, encoding);
|
||||
|
||||
if (encoding == 0) /* raw */
|
||||
if (encoding == ENC_RAW)
|
||||
{
|
||||
need_size = cx * cy * Bpp;
|
||||
init_stream(pixel_s, need_size);
|
||||
@ -666,7 +1034,7 @@ lib_framebuffer_update(struct vnc *v)
|
||||
error = v->server_paint_rect(v, x, y, cx, cy, pixel_s->data, cx, cy, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (encoding == 1) /* copy rect */
|
||||
else if (encoding == ENC_COPY_RECT)
|
||||
{
|
||||
init_stream(s, 8192);
|
||||
error = trans_force_read_s(v->trans, s, 4);
|
||||
@ -678,7 +1046,7 @@ lib_framebuffer_update(struct vnc *v)
|
||||
error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy);
|
||||
}
|
||||
}
|
||||
else if (encoding == 0xffffff11) /* cursor */
|
||||
else if (encoding == ENC_CURSOR)
|
||||
{
|
||||
g_memset(cursor_data, 0, 32 * (32 * 3));
|
||||
g_memset(cursor_mask, 0, 32 * (32 / 8));
|
||||
@ -723,12 +1091,24 @@ lib_framebuffer_update(struct vnc *v)
|
||||
error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask);
|
||||
}
|
||||
}
|
||||
else if (encoding == 0xffffff21) /* desktop size */
|
||||
else if (encoding == ENC_DESKTOP_SIZE)
|
||||
{
|
||||
/* Only received for non-resizeable desktops */
|
||||
v->mod_width = cx;
|
||||
v->mod_height = cy;
|
||||
error = v->server_reset(v, cx, cy, v->mod_bpp);
|
||||
}
|
||||
else if (encoding == ENC_EXTENDED_DESKTOP_SIZE)
|
||||
{
|
||||
extended_desktop_size_msg_received = 1;
|
||||
error = read_extended_desktop_size_rect(v, &layout);
|
||||
if (error == 0)
|
||||
{
|
||||
error = process_extended_desktop_size(v, x, y, cx, cy,
|
||||
&layout);
|
||||
g_free(layout.s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x",
|
||||
@ -743,6 +1123,20 @@ lib_framebuffer_update(struct vnc *v)
|
||||
error = v->server_end_update(v);
|
||||
}
|
||||
|
||||
if (v->first_framebuffer_update)
|
||||
{
|
||||
v->first_framebuffer_update = 0;
|
||||
if (v->resizeable_mode && !extended_desktop_size_msg_received)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "Resizeable mode requested, "
|
||||
"but X server does not support it");
|
||||
if (error == 0)
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
if (v->suppress_output == 0)
|
||||
@ -750,7 +1144,7 @@ lib_framebuffer_update(struct vnc *v)
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 3);
|
||||
out_uint8(s, 1);
|
||||
out_uint8(s, 1); /* incremental == 1 : Changes only */
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, v->mod_width);
|
||||
@ -1026,7 +1420,7 @@ lib_mod_connect(struct vnc *v)
|
||||
default:
|
||||
v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 "
|
||||
"bpp rdp connections", 0);
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_strcmp(v->ip, "") == 0)
|
||||
@ -1055,7 +1449,7 @@ lib_mod_connect(struct vnc *v)
|
||||
v->server_msg(v, text, 0);
|
||||
g_sleep(v->delay_ms);
|
||||
}
|
||||
|
||||
|
||||
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
|
||||
v->server_msg(v, text, 0);
|
||||
|
||||
@ -1188,8 +1582,14 @@ lib_mod_connect(struct vnc *v)
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
in_uint16_be(s, v->mod_width);
|
||||
in_uint16_be(s, v->mod_height);
|
||||
/* In resizeable mode, we're not interested at this stage how
|
||||
* big the X server is, as we're going to go for the size set
|
||||
* by the "client_info" param */
|
||||
if (!v->resizeable_mode)
|
||||
{
|
||||
in_uint16_be(s, v->mod_width);
|
||||
in_uint16_be(s, v->mod_height);
|
||||
}
|
||||
init_stream(pixel_format, 8192);
|
||||
v->server_msg(v, "VNC receiving pixel format", 0);
|
||||
error = trans_force_read_s(v->trans, pixel_format, 16);
|
||||
@ -1329,11 +1729,20 @@ lib_mod_connect(struct vnc *v)
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 2);
|
||||
out_uint8(s, 0);
|
||||
out_uint16_be(s, 4);
|
||||
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_uint16_be(s, 4); /* Number of encodings following */
|
||||
out_uint32_be(s, ENC_RAW);
|
||||
out_uint32_be(s, ENC_COPY_RECT);
|
||||
out_uint32_be(s, ENC_CURSOR);
|
||||
if (v->resizeable_mode)
|
||||
{
|
||||
v->server_msg(v, "VNC with ExtendedDesktopSize pseudo-encoding", 0);
|
||||
out_uint32_be(s, ENC_EXTENDED_DESKTOP_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
v->server_msg(v, "VNC with DesktopSize pseudo-encoding", 0);
|
||||
out_uint32_be(s, ENC_DESKTOP_SIZE);
|
||||
}
|
||||
v->server_msg(v, "VNC sending encodings", 0);
|
||||
s_mark_end(s);
|
||||
error = trans_force_write_s(v->trans, s);
|
||||
@ -1344,6 +1753,7 @@ lib_mod_connect(struct vnc *v)
|
||||
error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp);
|
||||
}
|
||||
|
||||
v->first_framebuffer_update = 1;
|
||||
if (error == 0)
|
||||
{
|
||||
if (v->suppress_output == 0)
|
||||
@ -1351,7 +1761,7 @@ lib_mod_connect(struct vnc *v)
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 3);
|
||||
out_uint8(s, 0);
|
||||
out_uint8(s, 0); /* incremental == 0 : Full contents */
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, v->mod_width);
|
||||
@ -1459,6 +1869,57 @@ lib_mod_set_param(struct vnc *v, const char *name, const char *value)
|
||||
v->got_guid = 1;
|
||||
g_memcpy(v->guid, value, 16);
|
||||
}
|
||||
else if (g_strcasecmp(name, "code") == 0)
|
||||
{
|
||||
v->resizeable_mode = (g_atoi(value) == 1);
|
||||
}
|
||||
else if (g_strcasecmp(name, "client_info") == 0)
|
||||
{
|
||||
const struct xrdp_client_info *client_info =
|
||||
(const struct xrdp_client_info *) value;
|
||||
|
||||
g_free(v->screen_layout.s);
|
||||
|
||||
/* The RDP client (width,height) is requested for the X server
|
||||
* later on if we're in resizeable mode. If we're not, these
|
||||
* settings will be overwritten later by the ServerInit
|
||||
* message from the X server */
|
||||
v->mod_width = client_info->width;
|
||||
v->mod_height = client_info->height;
|
||||
|
||||
/* Save info needed for resizeable support */
|
||||
if (!client_info->multimon || client_info->monitorCount < 1)
|
||||
{
|
||||
v->screen_layout.count = 1;
|
||||
v->screen_layout.s = g_new(struct vnc_screen, 1);
|
||||
v->screen_layout.s[0].id = 0;
|
||||
v->screen_layout.s[0].x = 0;
|
||||
v->screen_layout.s[0].y = 0;
|
||||
v->screen_layout.s[0].width = client_info->width;
|
||||
v->screen_layout.s[0].height = client_info->height;
|
||||
v->screen_layout.s[0].flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
v->screen_layout.count = client_info->monitorCount;
|
||||
v->screen_layout.s = g_new(struct vnc_screen,
|
||||
v->screen_layout.count);
|
||||
for (i = 0 ; i < client_info->monitorCount ; ++i)
|
||||
{
|
||||
v->screen_layout.s[i].id = i;
|
||||
v->screen_layout.s[i].x = client_info->minfo[i].left;
|
||||
v->screen_layout.s[i].y = client_info->minfo[i].top;
|
||||
v->screen_layout.s[i].width = client_info->minfo[i].right -
|
||||
client_info->minfo[i].left + 1;
|
||||
v->screen_layout.s[i].height = client_info->minfo[i].bottom -
|
||||
client_info->minfo[i].top + 1;
|
||||
v->screen_layout.s[i].flags = 0;
|
||||
}
|
||||
}
|
||||
log_debug_screen_layout("client_info", &v->screen_layout);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1504,7 +1965,7 @@ lib_mod_check_wait_objs(struct vnc *v)
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
int
|
||||
lib_mod_frame_ack(struct vnc* v, int flags, int frame_id)
|
||||
lib_mod_frame_ack(struct vnc *v, int flags, int frame_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -1512,7 +1973,7 @@ lib_mod_frame_ack(struct vnc* v, int flags, int frame_id)
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
int
|
||||
lib_mod_suppress_output(struct vnc* v, int suppress,
|
||||
lib_mod_suppress_output(struct vnc *v, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
int error;
|
||||
@ -1526,7 +1987,7 @@ lib_mod_suppress_output(struct vnc* v, int suppress,
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 3);
|
||||
out_uint8(s, 0);
|
||||
out_uint8(s, 0); /* incremental == 0 : Full contents */
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, v->mod_width);
|
||||
@ -1575,5 +2036,6 @@ mod_exit(tintptr handle)
|
||||
}
|
||||
trans_delete(v->trans);
|
||||
g_free(v);
|
||||
g_free(v->screen_layout.s);
|
||||
return 0;
|
||||
}
|
||||
|
203
vnc/vnc.h
203
vnc/vnc.h
@ -26,98 +26,121 @@
|
||||
|
||||
#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
|
||||
{
|
||||
unsigned int count;
|
||||
/* For comparison, screens are sorted in increasing order of ID */
|
||||
struct vnc_screen *s;
|
||||
};
|
||||
|
||||
struct vnc
|
||||
{
|
||||
int size; /* size of this struct */
|
||||
int version; /* internal version */
|
||||
/* client functions */
|
||||
int (*mod_start)(struct vnc* v, int w, int h, int bpp);
|
||||
int (*mod_connect)(struct vnc* v);
|
||||
int (*mod_event)(struct vnc* v, int msg, long param1, long param2,
|
||||
long param3, long param4);
|
||||
int (*mod_signal)(struct vnc* v);
|
||||
int (*mod_end)(struct vnc* v);
|
||||
int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
|
||||
int (*mod_session_change)(struct vnc* v, int, int);
|
||||
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
|
||||
tbus* write_objs, int* wcount, int* timeout);
|
||||
int (*mod_check_wait_objs)(struct vnc* v);
|
||||
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 size; /* size of this struct */
|
||||
int version; /* internal version */
|
||||
/* client functions */
|
||||
int (*mod_start)(struct vnc *v, int w, int h, int bpp);
|
||||
int (*mod_connect)(struct vnc *v);
|
||||
int (*mod_event)(struct vnc *v, int msg, long param1, long param2,
|
||||
long param3, long param4);
|
||||
int (*mod_signal)(struct vnc *v);
|
||||
int (*mod_end)(struct vnc *v);
|
||||
int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
|
||||
int (*mod_session_change)(struct vnc *v, int, int);
|
||||
int (*mod_get_wait_objs)(struct vnc *v, tbus *read_objs, int *rcount,
|
||||
tbus *write_objs, int *wcount, int *timeout);
|
||||
int (*mod_check_wait_objs)(struct vnc *v);
|
||||
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
|
||||
functions above */
|
||||
/* server functions */
|
||||
int (*server_begin_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_screen_blt)(struct vnc* v, int x, int y, int cx, int cy,
|
||||
int srcx, int srcy);
|
||||
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);
|
||||
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_msg)(struct vnc* v, const char *msg, int code);
|
||||
int (*server_is_term)(struct vnc* v);
|
||||
int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy);
|
||||
int (*server_reset_clip)(struct vnc* v);
|
||||
int (*server_set_fgcolor)(struct vnc* v, int fgcolor);
|
||||
int (*server_set_bgcolor)(struct vnc* v, int bgcolor);
|
||||
int (*server_set_opcode)(struct vnc* v, int opcode);
|
||||
int (*server_set_mixmode)(struct vnc* v, int mixmode);
|
||||
int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin,
|
||||
int style, char* pattern);
|
||||
int (*server_set_pen)(struct vnc* v, int style,
|
||||
int width);
|
||||
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 offset, int baseline,
|
||||
int width, int height, char* data);
|
||||
int (*server_draw_text)(struct vnc* v, int font,
|
||||
int flags, int mixmode, int clip_left, int clip_top,
|
||||
int clip_right, int clip_bottom,
|
||||
int box_left, int box_top,
|
||||
int box_right, int box_bottom,
|
||||
int x, int y, char* data, int data_len);
|
||||
int (*server_reset)(struct vnc* v, int width, int height, int bpp);
|
||||
int (*server_query_channel)(struct vnc* v, int index,
|
||||
char* channel_name,
|
||||
int* channel_flags);
|
||||
int (*server_get_channel_id)(struct vnc* v, const char *name);
|
||||
int (*server_send_to_channel)(struct vnc* v, int channel_id,
|
||||
char* data, int data_len,
|
||||
int total_data_len, int flags);
|
||||
int (*server_bell_trigger)(struct vnc* v);
|
||||
tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
|
||||
/* server functions */
|
||||
int (*server_begin_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_screen_blt)(struct vnc *v, int x, int y, int cx, int cy,
|
||||
int srcx, int srcy);
|
||||
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);
|
||||
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_msg)(struct vnc *v, const char *msg, int code);
|
||||
int (*server_is_term)(struct vnc *v);
|
||||
int (*server_set_clip)(struct vnc *v, int x, int y, int cx, int cy);
|
||||
int (*server_reset_clip)(struct vnc *v);
|
||||
int (*server_set_fgcolor)(struct vnc *v, int fgcolor);
|
||||
int (*server_set_bgcolor)(struct vnc *v, int bgcolor);
|
||||
int (*server_set_opcode)(struct vnc *v, int opcode);
|
||||
int (*server_set_mixmode)(struct vnc *v, int mixmode);
|
||||
int (*server_set_brush)(struct vnc *v, int x_origin, int y_origin,
|
||||
int style, char *pattern);
|
||||
int (*server_set_pen)(struct vnc *v, int style,
|
||||
int width);
|
||||
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 offset, int baseline,
|
||||
int width, int height, char *data);
|
||||
int (*server_draw_text)(struct vnc *v, int font,
|
||||
int flags, int mixmode, int clip_left, int clip_top,
|
||||
int clip_right, int clip_bottom,
|
||||
int box_left, int box_top,
|
||||
int box_right, int box_bottom,
|
||||
int x, int y, char *data, int data_len);
|
||||
int (*server_reset)(struct vnc *v, int width, int height, int bpp);
|
||||
int (*server_query_channel)(struct vnc *v, int index,
|
||||
char *channel_name,
|
||||
int *channel_flags);
|
||||
int (*server_get_channel_id)(struct vnc *v, const char *name);
|
||||
int (*server_send_to_channel)(struct vnc *v, int channel_id,
|
||||
char *data, int data_len,
|
||||
int total_data_len, int flags);
|
||||
int (*server_bell_trigger)(struct vnc *v);
|
||||
tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
|
||||
functions above */
|
||||
/* common */
|
||||
tintptr handle; /* pointer to self as long */
|
||||
tintptr wm;
|
||||
tintptr painter;
|
||||
tintptr si;
|
||||
/* mod data */
|
||||
int server_width;
|
||||
int server_height;
|
||||
int server_bpp;
|
||||
int mod_width;
|
||||
int mod_height;
|
||||
int mod_bpp;
|
||||
char mod_name[256];
|
||||
int mod_mouse_state;
|
||||
int palette[256];
|
||||
int vnc_desktop;
|
||||
char username[256];
|
||||
char password[256];
|
||||
char ip[256];
|
||||
char port[256];
|
||||
int sck_closed;
|
||||
int shift_state; /* 0 up, 1 down */
|
||||
int keylayout;
|
||||
int clip_chanid;
|
||||
struct stream *clip_data_s;
|
||||
int delay_ms;
|
||||
struct trans *trans;
|
||||
int got_guid;
|
||||
tui8 guid[16];
|
||||
int suppress_output;
|
||||
/* common */
|
||||
tintptr handle; /* pointer to self as long */
|
||||
tintptr wm;
|
||||
tintptr painter;
|
||||
tintptr si;
|
||||
/* mod data */
|
||||
int server_width;
|
||||
int server_height;
|
||||
int server_bpp;
|
||||
int mod_width;
|
||||
int mod_height;
|
||||
int mod_bpp;
|
||||
char mod_name[256];
|
||||
int mod_mouse_state;
|
||||
int palette[256];
|
||||
int vnc_desktop;
|
||||
char username[256];
|
||||
char password[256];
|
||||
char ip[256];
|
||||
char port[256];
|
||||
int sck_closed;
|
||||
int shift_state; /* 0 up, 1 down */
|
||||
int keylayout;
|
||||
int clip_chanid;
|
||||
struct stream *clip_data_s;
|
||||
int delay_ms;
|
||||
struct trans *trans;
|
||||
int got_guid;
|
||||
tui8 guid[16];
|
||||
int suppress_output;
|
||||
/* Resizeable support */
|
||||
int resizeable_mode; /* true for resizeable mode, false for traditional */
|
||||
struct vnc_screen_layout screen_layout;
|
||||
int first_framebuffer_update; /* Identifies the first framebuffer_update */
|
||||
int set_desktop_size_in_progress; /* Waiting for SetDesktopSize response */
|
||||
};
|
||||
|
@ -171,6 +171,12 @@ ip=127.0.0.1
|
||||
port=-1
|
||||
#xserverbpp=24
|
||||
#delay_ms=2000
|
||||
; If your Xvnc server supports the ExtendedDesktopSize encoding, you can
|
||||
; uncomment the following line for resizeable session support. This includes
|
||||
; support for multiple monitors.
|
||||
; Unlike traditional VNC sessions, you can connect to (and resize) active
|
||||
; VNC sessions on the same machine which have different sizes.
|
||||
#code=1
|
||||
|
||||
[vnc-any]
|
||||
name=vnc-any
|
||||
|
@ -197,7 +197,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
|
||||
}
|
||||
else if (g_strcasecmp(name, "code") == 0)
|
||||
{
|
||||
/* this code is either 0 for Xvnc, 10 for X11rdp or 20 for Xorg */
|
||||
/* this code is either 0/1 for Xvnc, 10 for X11rdp or 20 for Xorg */
|
||||
self->code = g_atoi(value);
|
||||
}
|
||||
else if (g_strcasecmp(name, "xserverbpp") == 0)
|
||||
@ -215,7 +215,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
|
||||
|
||||
s = trans_get_out_s(self->sesman_trans, 8192);
|
||||
s_push_layer(s, channel_hdr, 8);
|
||||
/* this code is either 0 for Xvnc, 10 for X11rdp or 20 for Xorg */
|
||||
/* this code is either 0/1 for Xvnc, 10 for X11rdp or 20 for Xorg */
|
||||
out_uint16_be(s, self->code);
|
||||
index = g_strlen(username);
|
||||
out_uint16_be(s, index);
|
||||
@ -515,7 +515,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
|
||||
{
|
||||
if (self->display > 0)
|
||||
{
|
||||
if (self->code == 0) /* Xvnc */
|
||||
if (self->code == 0 || self->code == 1) /* Xvnc */
|
||||
{
|
||||
g_snprintf(text, 255, "%d", 5900 + self->display);
|
||||
}
|
||||
@ -1903,7 +1903,7 @@ cleanup_states(struct xrdp_mm *self)
|
||||
self-> sesman_trans_up = 0; /* true once connected to sesman */
|
||||
self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
|
||||
self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
|
||||
self-> code = 0; /* 0 Xvnc session, 10 X11rdp session, 20 Xorg session */
|
||||
self-> code = 0; /* 0/1 Xvnc session, 10 X11rdp session, 20 Xorg session */
|
||||
self-> sesman_controlled = 0; /* true if this is a sesman session */
|
||||
self-> chan_trans = NULL; /* connection to chansrv */
|
||||
self-> chan_trans_up = 0; /* true once connected to chansrv */
|
||||
|
@ -290,7 +290,7 @@ struct xrdp_mm
|
||||
int (*mod_exit)(struct xrdp_mod*);
|
||||
struct xrdp_mod* mod; /* module interface */
|
||||
int display; /* 10 for :10.0, 11 for :11.0, etc */
|
||||
int code; /* 0=Xvnc session, 10=X11rdp session, 20=xorg driver mode */
|
||||
int code; /* 0/1=Xvnc session, 10=X11rdp session, 20=xorg driver mode */
|
||||
int sesman_controlled; /* true if this is a sesman session */
|
||||
struct trans* chan_trans; /* connection to chansrv */
|
||||
int chan_trans_up; /* true once connected to chansrv */
|
||||
|
Loading…
Reference in New Issue
Block a user