rdp: add virtual channel support
RDP exposes certain features (audio, clipboard, RAIL) through a facility called "virtual channels". Set up the communications framework for using these. Co-authored-by: Steve Pronovost <spronovo@microsoft.com> Co-authored-by: Brenton DeGeer <brdegeer@microsoft.com> Signed-off-by: Hideyuki Nagase <hideyukn@microsoft.com> Signed-off-by: Steve Pronovost <spronovo@microsoft.com> Signed-off-by: Brenton DeGeer <brdegeer@microsoft.com>
This commit is contained in:
parent
3bdc29b934
commit
252771d9aa
|
@ -13,6 +13,11 @@ if not dep_frdp.found()
|
|||
error('RDP-backend requires freerdp >= 2.2.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.')
|
||||
endif
|
||||
|
||||
dep_frdp_server = dependency('freerdp-server2', version: '>= 2.2.0', required: false)
|
||||
if not dep_frdp_server.found()
|
||||
error('RDP-backend requires freerdp-server2 >= 2.2.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.')
|
||||
endif
|
||||
|
||||
dep_wpr = dependency('winpr2', version: '>= 2.2.0', required: false)
|
||||
if not dep_wpr.found()
|
||||
error('RDP-backend requires winpr >= 2.2.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.')
|
||||
|
@ -21,6 +26,7 @@ endif
|
|||
deps_rdp = [
|
||||
dep_libweston_private,
|
||||
dep_frdp,
|
||||
dep_frdp_server,
|
||||
dep_wpr,
|
||||
]
|
||||
srcs_rdp = [
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#define KBD_HEBREW_STANDARD 0x2040D
|
||||
#endif
|
||||
|
||||
extern PWtsApiFunctionTable FreeRDP_InitWtsApi(void);
|
||||
|
||||
static void
|
||||
rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_peer *peer)
|
||||
{
|
||||
|
@ -656,16 +658,20 @@ out_error_stream:
|
|||
static void
|
||||
rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
wl_list_remove(&context->item.link);
|
||||
for (i = 0; i < MAX_FREERDP_FDS; i++) {
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(context->events); i++) {
|
||||
if (context->events[i])
|
||||
wl_event_source_remove(context->events[i]);
|
||||
}
|
||||
|
||||
if (context->vcm)
|
||||
WTSCloseServer(context->vcm);
|
||||
|
||||
rdp_destroy_dispatch_task_event_source(context);
|
||||
|
||||
if (context->item.flags & RDP_PEER_ACTIVATED) {
|
||||
|
@ -686,11 +692,21 @@ static int
|
|||
rdp_client_activity(int fd, uint32_t mask, void *data)
|
||||
{
|
||||
freerdp_peer* client = (freerdp_peer *)data;
|
||||
RdpPeerContext *peerCtx = (RdpPeerContext *)client->context;
|
||||
|
||||
if (!client->CheckFileDescriptor(client)) {
|
||||
weston_log("unable to checkDescriptor for %p\n", client);
|
||||
goto out_clean;
|
||||
}
|
||||
|
||||
if (peerCtx && peerCtx->vcm)
|
||||
{
|
||||
if (!WTSVirtualChannelManagerCheckFileDescriptor(peerCtx->vcm)) {
|
||||
weston_log("failed to check FreeRDP WTS VC file descriptor for %p\n", client);
|
||||
goto out_clean;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_clean:
|
||||
|
@ -1394,7 +1410,7 @@ static int
|
|||
rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
||||
{
|
||||
int rcount = 0;
|
||||
void *rfds[MAX_FREERDP_FDS];
|
||||
void *rfds[MAX_FREERDP_FDS + 1]; /* +1 for WTSVirtualChannelManagerGetFileDescriptor. */
|
||||
int i, fd;
|
||||
struct wl_event_loop *loop;
|
||||
rdpSettings *settings;
|
||||
|
@ -1455,6 +1471,15 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
|||
goto error_initialize;
|
||||
}
|
||||
|
||||
PWtsApiFunctionTable fn = FreeRDP_InitWtsApi();
|
||||
WTSRegisterWtsApiFunctionTable(fn);
|
||||
peerCtx->vcm = WTSOpenServerA((LPSTR)peerCtx);
|
||||
if (peerCtx->vcm) {
|
||||
WTSVirtualChannelManagerGetFileDescriptor(peerCtx->vcm, rfds, &rcount);
|
||||
} else {
|
||||
weston_log("WTSOpenServer is failed! continue without virtual channel.\n");
|
||||
}
|
||||
|
||||
loop = wl_display_get_event_loop(b->compositor->wl_display);
|
||||
for (i = 0; i < rcount; i++) {
|
||||
fd = (int)(long)(rfds[i]);
|
||||
|
@ -1462,16 +1487,28 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
|||
peerCtx->events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
|
||||
rdp_client_activity, client);
|
||||
}
|
||||
for ( ; i < MAX_FREERDP_FDS; i++)
|
||||
for ( ; i < (int)ARRAY_LENGTH(peerCtx->events); i++)
|
||||
peerCtx->events[i] = 0;
|
||||
|
||||
wl_list_insert(&b->output->peers, &peerCtx->item.link);
|
||||
|
||||
if (!rdp_initialize_dispatch_task_event_source(peerCtx))
|
||||
goto error_initialize;
|
||||
goto error_dispatch_initialize;
|
||||
|
||||
return 0;
|
||||
|
||||
error_dispatch_initialize:
|
||||
for (i = 0; i < (int)ARRAY_LENGTH(peerCtx->events); i++) {
|
||||
if (peerCtx->events[i]) {
|
||||
wl_event_source_remove(peerCtx->events[i]);
|
||||
peerCtx->events[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (peerCtx->vcm) {
|
||||
WTSCloseServer(peerCtx->vcm);
|
||||
peerCtx->vcm = NULL;
|
||||
}
|
||||
|
||||
error_initialize:
|
||||
client->Close(client);
|
||||
return -1;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
#include <freerdp/channels/wtsvc.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/backend-rdp.h>
|
||||
|
@ -118,7 +119,7 @@ struct rdp_peer_context {
|
|||
rdpContext _p;
|
||||
|
||||
struct rdp_backend *rdpBackend;
|
||||
struct wl_event_source *events[MAX_FREERDP_FDS];
|
||||
struct wl_event_source *events[MAX_FREERDP_FDS + 1]; /* +1 for WTSVirtualChannelManagerGetFileDescriptor */
|
||||
RFX_CONTEXT *rfx_context;
|
||||
wStream *encode_stream;
|
||||
RFX_RECT *rfx_rects;
|
||||
|
@ -133,6 +134,8 @@ struct rdp_peer_context {
|
|||
int horizontalAccumWheelRotationPrecise;
|
||||
int horizontalAccumWheelRotationDiscrete;
|
||||
|
||||
HANDLE vcm;
|
||||
|
||||
/* list of outstanding event_source sent from FreeRDP thread to display loop.*/
|
||||
int loop_task_event_source_fd;
|
||||
struct wl_event_source *loop_task_event_source;
|
||||
|
|
Loading…
Reference in New Issue