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:
committed by
Derek Foreman
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\'.')
|
error('RDP-backend requires freerdp >= 2.2.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.')
|
||||||
endif
|
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)
|
dep_wpr = dependency('winpr2', version: '>= 2.2.0', required: false)
|
||||||
if not dep_wpr.found()
|
if not dep_wpr.found()
|
||||||
error('RDP-backend requires winpr >= 2.2.0 which was not found. Or, you can use \'-Dbackend-rdp=false\'.')
|
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 = [
|
deps_rdp = [
|
||||||
dep_libweston_private,
|
dep_libweston_private,
|
||||||
dep_frdp,
|
dep_frdp,
|
||||||
|
dep_frdp_server,
|
||||||
dep_wpr,
|
dep_wpr,
|
||||||
]
|
]
|
||||||
srcs_rdp = [
|
srcs_rdp = [
|
||||||
|
|||||||
@@ -51,6 +51,8 @@
|
|||||||
#define KBD_HEBREW_STANDARD 0x2040D
|
#define KBD_HEBREW_STANDARD 0x2040D
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern PWtsApiFunctionTable FreeRDP_InitWtsApi(void);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_peer *peer)
|
rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_peer *peer)
|
||||||
{
|
{
|
||||||
@@ -656,16 +658,20 @@ out_error_stream:
|
|||||||
static void
|
static void
|
||||||
rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
|
rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wl_list_remove(&context->item.link);
|
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])
|
if (context->events[i])
|
||||||
wl_event_source_remove(context->events[i]);
|
wl_event_source_remove(context->events[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->vcm)
|
||||||
|
WTSCloseServer(context->vcm);
|
||||||
|
|
||||||
rdp_destroy_dispatch_task_event_source(context);
|
rdp_destroy_dispatch_task_event_source(context);
|
||||||
|
|
||||||
if (context->item.flags & RDP_PEER_ACTIVATED) {
|
if (context->item.flags & RDP_PEER_ACTIVATED) {
|
||||||
@@ -686,11 +692,21 @@ static int
|
|||||||
rdp_client_activity(int fd, uint32_t mask, void *data)
|
rdp_client_activity(int fd, uint32_t mask, void *data)
|
||||||
{
|
{
|
||||||
freerdp_peer* client = (freerdp_peer *)data;
|
freerdp_peer* client = (freerdp_peer *)data;
|
||||||
|
RdpPeerContext *peerCtx = (RdpPeerContext *)client->context;
|
||||||
|
|
||||||
if (!client->CheckFileDescriptor(client)) {
|
if (!client->CheckFileDescriptor(client)) {
|
||||||
weston_log("unable to checkDescriptor for %p\n", client);
|
weston_log("unable to checkDescriptor for %p\n", client);
|
||||||
goto out_clean;
|
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;
|
return 0;
|
||||||
|
|
||||||
out_clean:
|
out_clean:
|
||||||
@@ -1394,7 +1410,7 @@ static int
|
|||||||
rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
||||||
{
|
{
|
||||||
int rcount = 0;
|
int rcount = 0;
|
||||||
void *rfds[MAX_FREERDP_FDS];
|
void *rfds[MAX_FREERDP_FDS + 1]; /* +1 for WTSVirtualChannelManagerGetFileDescriptor. */
|
||||||
int i, fd;
|
int i, fd;
|
||||||
struct wl_event_loop *loop;
|
struct wl_event_loop *loop;
|
||||||
rdpSettings *settings;
|
rdpSettings *settings;
|
||||||
@@ -1455,6 +1471,15 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
|
|||||||
goto error_initialize;
|
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);
|
loop = wl_display_get_event_loop(b->compositor->wl_display);
|
||||||
for (i = 0; i < rcount; i++) {
|
for (i = 0; i < rcount; i++) {
|
||||||
fd = (int)(long)(rfds[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,
|
peerCtx->events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
|
||||||
rdp_client_activity, client);
|
rdp_client_activity, client);
|
||||||
}
|
}
|
||||||
for ( ; i < MAX_FREERDP_FDS; i++)
|
for ( ; i < (int)ARRAY_LENGTH(peerCtx->events); i++)
|
||||||
peerCtx->events[i] = 0;
|
peerCtx->events[i] = 0;
|
||||||
|
|
||||||
wl_list_insert(&b->output->peers, &peerCtx->item.link);
|
wl_list_insert(&b->output->peers, &peerCtx->item.link);
|
||||||
|
|
||||||
if (!rdp_initialize_dispatch_task_event_source(peerCtx))
|
if (!rdp_initialize_dispatch_task_event_source(peerCtx))
|
||||||
goto error_initialize;
|
goto error_dispatch_initialize;
|
||||||
|
|
||||||
return 0;
|
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:
|
error_initialize:
|
||||||
client->Close(client);
|
client->Close(client);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <freerdp/codec/rfx.h>
|
#include <freerdp/codec/rfx.h>
|
||||||
#include <freerdp/codec/nsc.h>
|
#include <freerdp/codec/nsc.h>
|
||||||
#include <freerdp/locale/keyboard.h>
|
#include <freerdp/locale/keyboard.h>
|
||||||
|
#include <freerdp/channels/wtsvc.h>
|
||||||
|
|
||||||
#include <libweston/libweston.h>
|
#include <libweston/libweston.h>
|
||||||
#include <libweston/backend-rdp.h>
|
#include <libweston/backend-rdp.h>
|
||||||
@@ -118,7 +119,7 @@ struct rdp_peer_context {
|
|||||||
rdpContext _p;
|
rdpContext _p;
|
||||||
|
|
||||||
struct rdp_backend *rdpBackend;
|
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;
|
RFX_CONTEXT *rfx_context;
|
||||||
wStream *encode_stream;
|
wStream *encode_stream;
|
||||||
RFX_RECT *rfx_rects;
|
RFX_RECT *rfx_rects;
|
||||||
@@ -133,6 +134,8 @@ struct rdp_peer_context {
|
|||||||
int horizontalAccumWheelRotationPrecise;
|
int horizontalAccumWheelRotationPrecise;
|
||||||
int horizontalAccumWheelRotationDiscrete;
|
int horizontalAccumWheelRotationDiscrete;
|
||||||
|
|
||||||
|
HANDLE vcm;
|
||||||
|
|
||||||
/* list of outstanding event_source sent from FreeRDP thread to display loop.*/
|
/* list of outstanding event_source sent from FreeRDP thread to display loop.*/
|
||||||
int loop_task_event_source_fd;
|
int loop_task_event_source_fd;
|
||||||
struct wl_event_source *loop_task_event_source;
|
struct wl_event_source *loop_task_event_source;
|
||||||
|
|||||||
Reference in New Issue
Block a user