Merge pull request #1330 from jsorg71/suppress
handle TS_SUPPRESS_OUTPUT_PDU
This commit is contained in:
commit
074cfdee4d
@ -156,6 +156,7 @@ struct xrdp_client_info
|
||||
int no_orders_supported;
|
||||
int use_cache_glyph_v2;
|
||||
int rail_enable;
|
||||
int suppress_output;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -810,7 +810,8 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
||||
out_uint16_le(s, 0); /* Update capability */
|
||||
out_uint16_le(s, 0); /* Remote unshare capability */
|
||||
out_uint16_le(s, 0); /* Compression level */
|
||||
out_uint16_le(s, 0); /* Pad */
|
||||
out_uint8(s, 1); /* refreshRectSupport */
|
||||
out_uint8(s, 1); /* suppressOutputSupport */
|
||||
|
||||
/* Output bitmap capability set */
|
||||
caps_count++;
|
||||
|
@ -1209,21 +1209,91 @@ xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int allowDisplayUpdates;
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
|
||||
if (!s_check_rem(s, 1))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, allowDisplayUpdates);
|
||||
g_writeln("xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
|
||||
"left %d", allowDisplayUpdates, (int) (s->end - s->p));
|
||||
switch (allowDisplayUpdates)
|
||||
{
|
||||
case 0: /* SUPPRESS_DISPLAY_UPDATES */
|
||||
self->client_info.suppress_output = 1;
|
||||
g_writeln("xrdp_rdp_process_suppress: suppress_output %d",
|
||||
self->client_info.suppress_output);
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
self->session->callback(self->session->id, 0x5559, 1,
|
||||
0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 1: /* ALLOW_DISPLAY_UPDATES */
|
||||
self->client_info.suppress_output = 0;
|
||||
if (!s_check_rem(s, 11))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 3); /* pad */
|
||||
in_uint16_le(s, left);
|
||||
in_uint16_le(s, top);
|
||||
in_uint16_le(s, right);
|
||||
in_uint16_le(s, bottom);
|
||||
g_writeln("xrdp_rdp_process_suppress: suppress_output %d "
|
||||
"left %d top %d right %d bottom %d",
|
||||
self->client_info.suppress_output,
|
||||
left, top, right, bottom);
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
self->session->callback(self->session->id, 0x5559, 0,
|
||||
MAKELONG(left, top),
|
||||
MAKELONG(right, bottom), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* RDP_PDU_DATA */
|
||||
int
|
||||
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int data_type;
|
||||
int uncompressedLength;
|
||||
int pduType2;
|
||||
int compressedType;
|
||||
int compressedLength;
|
||||
|
||||
if (!s_check_rem(s, 12))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 6);
|
||||
in_uint8s(s, 2); /* len */
|
||||
in_uint8(s, data_type);
|
||||
in_uint8s(s, 1); /* ctype */
|
||||
in_uint8s(s, 2); /* clen */
|
||||
DEBUG(("xrdp_rdp_process_data code %d", data_type));
|
||||
|
||||
switch (data_type)
|
||||
in_uint16_le(s, uncompressedLength);
|
||||
in_uint8(s, pduType2);
|
||||
in_uint8(s, compressedType);
|
||||
in_uint16_le(s, compressedLength);
|
||||
if (compressedType != 0)
|
||||
{
|
||||
/* don't support compression */
|
||||
return 1;
|
||||
}
|
||||
if (compressedLength > uncompressedLength)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("xrdp_rdp_process_data pduType2 %d", pduType2));
|
||||
switch (pduType2)
|
||||
{
|
||||
case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
|
||||
xrdp_rdp_process_data_pointer(self, s);
|
||||
@ -1240,11 +1310,8 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
case 33: /* 33(0x21) ?? Invalidate an area I think */
|
||||
xrdp_rdp_process_screen_update(self, s);
|
||||
break;
|
||||
case 35: /* 35(0x23) */
|
||||
/* 35 ?? this comes when minimizing a full screen mstsc.exe 2600 */
|
||||
/* I think this is saying the client no longer wants screen */
|
||||
/* updates and it will issue a 33 above to catch up */
|
||||
/* so minimized apps don't take bandwidth */
|
||||
case 35: /* 35(0x23) PDUTYPE2_SUPPRESS_OUTPUT */
|
||||
xrdp_rdp_process_suppress(self, s);
|
||||
break;
|
||||
case 36: /* 36(0x24) ?? disconnect query? */
|
||||
/* when this message comes, send a 37 back so the client */
|
||||
@ -1259,10 +1326,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
xrdp_rdp_process_frame_ack(self, s);
|
||||
break;
|
||||
default:
|
||||
g_writeln("unknown in xrdp_rdp_process_data %d", data_type);
|
||||
g_writeln("unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
|
@ -27,6 +27,12 @@
|
||||
#include "log.h"
|
||||
#include <freerdp/settings.h>
|
||||
|
||||
#if defined(VERSION_STRUCT_RDP_FREERDP)
|
||||
#if VERSION_STRUCT_RDP_FREERDP > 1
|
||||
#define NEUTRINORDP_HAS_SUPPRESS_OUTPUT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XRDP_DEBUG
|
||||
#define LOG_LEVEL 99
|
||||
#else
|
||||
@ -541,6 +547,24 @@ lxrdp_check_wait_objs(struct mod *mod)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
lxrdp_frame_ack(struct mod* mod, int flags, int frame_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
lxrdp_suppress_output(struct mod* mod, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
#if defined(NEUTRINORDP_HAS_SUPPRESS_OUTPUT)
|
||||
mod->inst->SendSuppressOutput(mod->inst, !suppress, left, top, right, bottom);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static void
|
||||
lfreerdp_begin_paint(rdpContext *context)
|
||||
@ -2009,6 +2033,8 @@ mod_init(void)
|
||||
mod->mod_session_change = lxrdp_session_change;
|
||||
mod->mod_get_wait_objs = lxrdp_get_wait_objs;
|
||||
mod->mod_check_wait_objs = lxrdp_check_wait_objs;
|
||||
mod->mod_frame_ack = lxrdp_frame_ack;
|
||||
mod->mod_suppress_output = lxrdp_suppress_output;
|
||||
|
||||
mod->inst = freerdp_new();
|
||||
mod->inst->PreConnect = lfreerdp_pre_connect;
|
||||
|
@ -58,7 +58,7 @@ struct pointer_item
|
||||
int bpp;
|
||||
};
|
||||
|
||||
#define CURRENT_MOD_VER 3
|
||||
#define CURRENT_MOD_VER 4
|
||||
|
||||
struct mod
|
||||
{
|
||||
@ -76,7 +76,10 @@ struct mod
|
||||
int (*mod_get_wait_objs)(struct mod *v, tbus *read_objs, int *rcount,
|
||||
tbus *write_objs, int *wcount, int *timeout);
|
||||
int (*mod_check_wait_objs)(struct mod *v);
|
||||
tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
|
||||
int (*mod_frame_ack)(struct mod* mod, int flags, int frame_id);
|
||||
int (*mod_suppress_output)(struct mod* mod, 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 mod *v);
|
||||
|
50
vnc/vnc.c
50
vnc/vnc.c
@ -379,6 +379,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
||||
error = lib_send_copy(v, s);
|
||||
}
|
||||
else if (msg == 200) /* invalidate */
|
||||
{
|
||||
if (v->suppress_output == 0)
|
||||
{
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
@ -395,6 +397,7 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
||||
s_mark_end(s);
|
||||
error = lib_send_copy(v, s);
|
||||
}
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
return error;
|
||||
@ -741,6 +744,8 @@ lib_framebuffer_update(struct vnc *v)
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
if (v->suppress_output == 0)
|
||||
{
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
@ -753,6 +758,7 @@ lib_framebuffer_update(struct vnc *v)
|
||||
s_mark_end(s);
|
||||
error = lib_send_copy(v, s);
|
||||
}
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
free_stream(pixel_s);
|
||||
@ -916,7 +922,7 @@ lib_mod_process_message(struct vnc *v, struct stream *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
g_sprintf(text, "VNC unknown in lib_mod_signal %d", type);
|
||||
g_sprintf(text, "VNC unknown in lib_mod_process_message %d", type);
|
||||
v->server_msg(v, text, 1);
|
||||
}
|
||||
}
|
||||
@ -1339,6 +1345,8 @@ lib_mod_connect(struct vnc *v)
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
if (v->suppress_output == 0)
|
||||
{
|
||||
/* FramebufferUpdateRequest */
|
||||
init_stream(s, 8192);
|
||||
@ -1352,6 +1360,7 @@ lib_mod_connect(struct vnc *v)
|
||||
s_mark_end(s);
|
||||
error = trans_force_write_s(v->trans, s);
|
||||
}
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
@ -1492,6 +1501,43 @@ lib_mod_check_wait_objs(struct vnc *v)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
int
|
||||
lib_mod_frame_ack(struct vnc* v, int flags, int frame_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
int
|
||||
lib_mod_suppress_output(struct vnc* v, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
int error;
|
||||
struct stream *s;
|
||||
|
||||
error = 0;
|
||||
v->suppress_output = suppress;
|
||||
if (suppress == 0)
|
||||
{
|
||||
/* FramebufferUpdateRequest */
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, 3);
|
||||
out_uint8(s, 0);
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, 0);
|
||||
out_uint16_be(s, v->mod_width);
|
||||
out_uint16_be(s, v->mod_height);
|
||||
s_mark_end(s);
|
||||
error = lib_send_copy(v, s);
|
||||
free_stream(s);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
tintptr EXPORT_CC
|
||||
mod_init(void)
|
||||
@ -1511,6 +1557,8 @@ mod_init(void)
|
||||
v->mod_set_param = lib_mod_set_param;
|
||||
v->mod_get_wait_objs = lib_mod_get_wait_objs;
|
||||
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;
|
||||
return (tintptr) v;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "os_calls.h"
|
||||
#include "defines.h"
|
||||
|
||||
#define CURRENT_MOD_VER 3
|
||||
#define CURRENT_MOD_VER 4
|
||||
|
||||
struct vnc
|
||||
{
|
||||
@ -42,7 +42,10 @@ struct vnc
|
||||
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);
|
||||
tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
|
||||
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);
|
||||
@ -116,4 +119,5 @@ struct vnc
|
||||
struct trans *trans;
|
||||
int got_guid;
|
||||
tui8 guid[16];
|
||||
int suppress_output;
|
||||
};
|
||||
|
@ -371,6 +371,9 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
|
||||
/* xrdp_mm.c */
|
||||
int
|
||||
xrdp_mm_drdynvc_up(struct xrdp_mm* self);
|
||||
int
|
||||
xrdp_mm_suppress_output(struct xrdp_mm* self, int suppress,
|
||||
int left, int top, int right, int bottom);
|
||||
struct xrdp_mm*
|
||||
xrdp_mm_create(struct xrdp_wm* owner);
|
||||
void
|
||||
|
@ -999,6 +999,25 @@ xrdp_mm_drdynvc_up(struct xrdp_mm* self)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
xrdp_mm_suppress_output(struct xrdp_mm* self, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_mm_suppress_output: suppress %d "
|
||||
"left %d top %d right %d bottom %d",
|
||||
suppress, left, top, right, bottom));
|
||||
if (self->mod != NULL)
|
||||
{
|
||||
if (self->mod->mod_suppress_output != NULL)
|
||||
{
|
||||
self->mod->mod_suppress_output(self->mod, suppress,
|
||||
left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* open response from client going to channel server */
|
||||
static int
|
||||
|
@ -48,7 +48,9 @@ struct xrdp_mod
|
||||
tbus* write_objs, int* wcount, int* timeout);
|
||||
int (*mod_check_wait_objs)(struct xrdp_mod* v);
|
||||
int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id);
|
||||
tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod
|
||||
int (*mod_suppress_output)(struct xrdp_mod* 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 xrdp_mod* v);
|
||||
|
@ -1916,6 +1916,11 @@ callback(intptr_t id, int msg, intptr_t param1, intptr_t param2,
|
||||
case 0x5558:
|
||||
xrdp_mm_drdynvc_up(wm->mm);
|
||||
break;
|
||||
case 0x5559:
|
||||
xrdp_mm_suppress_output(wm->mm, param1,
|
||||
LOWORD(param2), HIWORD(param2),
|
||||
LOWORD(param3), HIWORD(param3));
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
40
xup/xup.c
40
xup/xup.c
@ -1143,6 +1143,33 @@ send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
static int
|
||||
send_suppress_output(struct mod *mod, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
int len;
|
||||
struct stream *s;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
s_push_layer(s, iso_hdr, 4);
|
||||
out_uint16_le(s, 108);
|
||||
out_uint32_le(s, suppress);
|
||||
out_uint32_le(s, left);
|
||||
out_uint32_le(s, top);
|
||||
out_uint32_le(s, right);
|
||||
out_uint32_le(s, bottom);
|
||||
s_mark_end(s);
|
||||
len = (int)(s->end - s->data);
|
||||
s_pop_layer(s, iso_hdr);
|
||||
out_uint32_le(s, len);
|
||||
lib_send_copy(mod, s);
|
||||
free_stream(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
static int
|
||||
@ -1556,6 +1583,18 @@ lib_mod_frame_ack(struct mod *amod, int flags, int frame_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* return error */
|
||||
int
|
||||
lib_mod_suppress_output(struct mod *amod, int suppress,
|
||||
int left, int top, int right, int bottom)
|
||||
{
|
||||
LLOGLN(10, ("lib_mod_suppress_output: suppress 0x%8.8x left %d top %d "
|
||||
"right %d bottom %d", suppress, left, top, right, bottom));
|
||||
send_suppress_output(amod, suppress, left, top, right, bottom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
tintptr EXPORT_CC
|
||||
mod_init(void)
|
||||
@ -1575,6 +1614,7 @@ mod_init(void)
|
||||
mod->mod_get_wait_objs = lib_mod_get_wait_objs;
|
||||
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
|
||||
mod->mod_frame_ack = lib_mod_frame_ack;
|
||||
mod->mod_suppress_output = lib_mod_suppress_output;
|
||||
return (tintptr) mod;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "xrdp_client_info.h"
|
||||
#include "xrdp_rail.h"
|
||||
|
||||
#define CURRENT_MOD_VER 3
|
||||
#define CURRENT_MOD_VER 4
|
||||
|
||||
struct mod
|
||||
{
|
||||
@ -45,7 +45,9 @@ struct mod
|
||||
tbus* write_objs, int* wcount, int* timeout);
|
||||
int (*mod_check_wait_objs)(struct mod* v);
|
||||
int (*mod_frame_ack)(struct mod* v, int flags, int frame_id);
|
||||
tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod
|
||||
int (*mod_suppress_output)(struct mod* 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 mod* v);
|
||||
|
Loading…
Reference in New Issue
Block a user