GUACAMOLE-249: Remove guac_rdp_dvc_list, relying instead on the DVC channel collection within rdpSettings.
This commit is contained in:
parent
eab07b4a61
commit
07f6e6afc2
@ -38,7 +38,7 @@ libguac_client_rdp_la_SOURCES = \
|
|||||||
client.c \
|
client.c \
|
||||||
clipboard.c \
|
clipboard.c \
|
||||||
decompose.c \
|
decompose.c \
|
||||||
dvc.c \
|
disp.c \
|
||||||
error.c \
|
error.c \
|
||||||
input.c \
|
input.c \
|
||||||
keyboard.c \
|
keyboard.c \
|
||||||
@ -46,7 +46,6 @@ libguac_client_rdp_la_SOURCES = \
|
|||||||
rdp.c \
|
rdp.c \
|
||||||
rdp_bitmap.c \
|
rdp_bitmap.c \
|
||||||
rdp_color.c \
|
rdp_color.c \
|
||||||
rdp_disp.c \
|
|
||||||
rdp_fs.c \
|
rdp_fs.c \
|
||||||
rdp_gdi.c \
|
rdp_gdi.c \
|
||||||
rdp_glyph.c \
|
rdp_glyph.c \
|
||||||
@ -107,7 +106,7 @@ noinst_HEADERS = \
|
|||||||
clipboard.h \
|
clipboard.h \
|
||||||
channels.h \
|
channels.h \
|
||||||
decompose.h \
|
decompose.h \
|
||||||
dvc.h \
|
disp.h \
|
||||||
error.h \
|
error.h \
|
||||||
input.h \
|
input.h \
|
||||||
keyboard.h \
|
keyboard.h \
|
||||||
@ -115,7 +114,6 @@ noinst_HEADERS = \
|
|||||||
rdp.h \
|
rdp.h \
|
||||||
rdp_bitmap.h \
|
rdp_bitmap.h \
|
||||||
rdp_color.h \
|
rdp_color.h \
|
||||||
rdp_disp.h \
|
|
||||||
rdp_fs.h \
|
rdp_fs.h \
|
||||||
rdp_gdi.h \
|
rdp_gdi.h \
|
||||||
rdp_glyph.h \
|
rdp_glyph.h \
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "audio_input.h"
|
#include "audio_input.h"
|
||||||
#include "dvc.h"
|
#include "channels.h"
|
||||||
#include "ptr_string.h"
|
#include "ptr_string.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
|
|
||||||
@ -182,14 +182,14 @@ int guac_rdp_audio_end_handler(guac_user* user, guac_stream* stream) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_audio_load_plugin(rdpContext* context, guac_rdp_dvc_list* list) {
|
void guac_rdp_audio_load_plugin(rdpContext* context) {
|
||||||
|
|
||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
char client_ref[GUAC_RDP_PTR_STRING_LENGTH];
|
char client_ref[GUAC_RDP_PTR_STRING_LENGTH];
|
||||||
|
|
||||||
/* Add "AUDIO_INPUT" channel */
|
/* Add "AUDIO_INPUT" channel */
|
||||||
guac_rdp_ptr_to_string(client, client_ref);
|
guac_rdp_ptr_to_string(client, client_ref);
|
||||||
guac_rdp_dvc_list_add(list, "guacai", client_ref, NULL);
|
guac_freerdp_dynamic_channel_collection_add(context->settings, "guacai", client_ref, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#define GUAC_RDP_AUDIO_INPUT_H
|
#define GUAC_RDP_AUDIO_INPUT_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dvc.h"
|
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <guacamole/stream.h>
|
#include <guacamole/stream.h>
|
||||||
@ -296,18 +295,13 @@ guac_user_end_handler guac_rdp_audio_end_handler;
|
|||||||
/**
|
/**
|
||||||
* Adds Guacamole's "guacai" plugin to the list of dynamic virtual channel
|
* Adds Guacamole's "guacai" plugin to the list of dynamic virtual channel
|
||||||
* plugins to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only
|
* plugins to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only
|
||||||
* be loaded once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list
|
* be loaded once the "drdynvc" plugin is loaded. The "guacai" plugin
|
||||||
* passed to this function. The "guacai" plugin ultimately adds support for the
|
* ultimately adds support for the "AUDIO_INPUT" dynamic virtual channel.
|
||||||
* "AUDIO_INPUT" dynamic virtual channel.
|
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* The rdpContext associated with the active RDP session.
|
* The rdpContext associated with the active RDP session.
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* The guac_rdp_dvc_list to which the "guacai" plugin should be added, such
|
|
||||||
* that it may later be loaded by guac_rdp_load_drdynvc().
|
|
||||||
*/
|
*/
|
||||||
void guac_rdp_audio_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
|
void guac_rdp_audio_load_plugin(rdpContext* context);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,22 +24,6 @@
|
|||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
|
|
||||||
void guac_rdp_channel_connected(rdpContext* context,
|
|
||||||
ChannelConnectedEventArgs* e) {
|
|
||||||
|
|
||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
|
||||||
|
|
||||||
guac_client_log(client, GUAC_LOG_DEBUG, "Channel \"%s\" connected.", e->name);
|
|
||||||
|
|
||||||
/* Display update channel */
|
|
||||||
if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) {
|
|
||||||
DispClientContext* disp = (DispClientContext*) e->pInterface;
|
|
||||||
guac_rdp_disp_connect(rdp_client->disp, context, disp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int guac_freerdp_channels_load_plugin(rdpChannels* channels,
|
int guac_freerdp_channels_load_plugin(rdpChannels* channels,
|
||||||
rdpSettings* settings, const char* name, void* data) {
|
rdpSettings* settings, const char* name, void* data) {
|
||||||
|
|
||||||
@ -62,3 +46,36 @@ int guac_freerdp_channels_load_plugin(rdpChannels* channels,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_freerdp_dynamic_channel_collection_add(rdpSettings* settings,
|
||||||
|
const char* name, ...) {
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
ADDIN_ARGV* freerdp_args = malloc(sizeof(ADDIN_ARGV));
|
||||||
|
|
||||||
|
va_start(args, name);
|
||||||
|
|
||||||
|
/* Count number of arguments (excluding terminating NULL) */
|
||||||
|
freerdp_args->argc = 1;
|
||||||
|
while (va_arg(args, char*) != NULL)
|
||||||
|
freerdp_args->argc++;
|
||||||
|
|
||||||
|
/* Reset va_list */
|
||||||
|
va_end(args);
|
||||||
|
va_start(args, name);
|
||||||
|
|
||||||
|
/* Copy argument values into DVC entry */
|
||||||
|
freerdp_args->argv = malloc(sizeof(char*) * freerdp_args->argc);
|
||||||
|
freerdp_args->argv[0] = strdup(name);
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < freerdp_args->argc; i++)
|
||||||
|
freerdp_args->argv[i] = strdup(va_arg(args, char*));
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
/* Register plugin with FreeRDP */
|
||||||
|
settings->SupportDynamicChannels = TRUE;
|
||||||
|
freerdp_dynamic_channel_collection_add(settings, freerdp_args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -25,20 +25,6 @@
|
|||||||
#include <freerdp/channels/channels.h>
|
#include <freerdp/channels/channels.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* Called whenever a channel connects via the PubSub event system within
|
|
||||||
* FreeRDP.
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* The rdpContext associated with the active RDP session.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* Event-specific arguments, mainly the name of the channel, and a
|
|
||||||
* reference to the associated plugin loaded for that channel by FreeRDP.
|
|
||||||
*/
|
|
||||||
void guac_rdp_channel_connected(rdpContext* context,
|
|
||||||
ChannelConnectedEventArgs* e);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the FreeRDP plugin having the given name. This function is a drop-in
|
* Loads the FreeRDP plugin having the given name. This function is a drop-in
|
||||||
* replacement for freerdp_channels_load_plugin() which additionally loads
|
* replacement for freerdp_channels_load_plugin() which additionally loads
|
||||||
@ -47,6 +33,9 @@ void guac_rdp_channel_connected(rdpContext* context,
|
|||||||
* part of FreeRDP can load only plugins which implement the
|
* part of FreeRDP can load only plugins which implement the
|
||||||
* PVIRTUALCHANNELENTRY version of the entry point.
|
* PVIRTUALCHANNELENTRY version of the entry point.
|
||||||
*
|
*
|
||||||
|
* This MUST be called within the PreConnect callback of the freerdp instance
|
||||||
|
* for the referenced plugin to be loaded correctly.
|
||||||
|
*
|
||||||
* @param channels
|
* @param channels
|
||||||
* The rdpChannels structure with which the plugin should be registered
|
* The rdpChannels structure with which the plugin should be registered
|
||||||
* once loaded. This structure should be retrieved directly from the
|
* once loaded. This structure should be retrieved directly from the
|
||||||
@ -76,5 +65,45 @@ void guac_rdp_channel_connected(rdpContext* context,
|
|||||||
int guac_freerdp_channels_load_plugin(rdpChannels* channels,
|
int guac_freerdp_channels_load_plugin(rdpChannels* channels,
|
||||||
rdpSettings* settings, const char* name, void* data);
|
rdpSettings* settings, const char* name, void* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules loading of the FreeRDP dynamic virtual channel plugin having the
|
||||||
|
* given name. This function is essentially a wrapper for
|
||||||
|
* freerdp_dynamic_channel_collection_add() which additionally takes care of
|
||||||
|
* housekeeping tasks which would otherwise need to be performed manually:
|
||||||
|
*
|
||||||
|
* - The ADDIN_ARGV structure used to pass arguments to dynamic virtual
|
||||||
|
* channel plugins is automatically allocated and populated with any given
|
||||||
|
* arguments.
|
||||||
|
* - The SupportDynamicChannels member of the rdpSettings structure is
|
||||||
|
* automatically set to TRUE.
|
||||||
|
*
|
||||||
|
* The "drdynvc" plugin must still eventually be loaded for this function to
|
||||||
|
* have any effect, as it is the "drdynvc" plugin which processes the
|
||||||
|
* collection this function manipulates.
|
||||||
|
*
|
||||||
|
* This MUST be called within the PreConnect callback of the freerdp instance
|
||||||
|
* and the "drdynvc" plugin MUST be loaded at some point after this function is
|
||||||
|
* called for the referenced dynamic channel plugin to be loaded correctly.
|
||||||
|
*
|
||||||
|
* @param settings
|
||||||
|
* The rdpSettings structure associated with the FreeRDP instance, already
|
||||||
|
* populated with any settings applicable to the plugin being loaded.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the plugin to load. If the plugin is not statically built
|
||||||
|
* into FreeRDP, this name will determine the filename of the library to be
|
||||||
|
* loaded dynamically. For a plugin named "NAME", the library called
|
||||||
|
* "libNAME-client" will be loaded from the "freerdp2" subdirectory of the
|
||||||
|
* main directory containing the FreeRDP libraries.
|
||||||
|
*
|
||||||
|
* @param ...
|
||||||
|
* Arbitrary arguments to be passed to the plugin entry point. For most
|
||||||
|
* plugins which are built into FreeRDP, this will be another reference to
|
||||||
|
* the rdpSettings struct or NULL. The source of the relevant plugin must
|
||||||
|
* be consulted to determine the proper value(s) to pass here.
|
||||||
|
*/
|
||||||
|
void guac_freerdp_dynamic_channel_collection_add(rdpSettings* settings,
|
||||||
|
const char* name, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
#include "audio_input.h"
|
#include "audio_input.h"
|
||||||
#include "common/recording.h"
|
#include "common/recording.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "disp.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
#include "rdp_disp.h"
|
|
||||||
#include "rdp_fs.h"
|
#include "rdp_fs.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
|
@ -18,16 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "channels.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "dvc.h"
|
#include "disp.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
#include "rdp_disp.h"
|
|
||||||
#include "rdp_settings.h"
|
#include "rdp_settings.h"
|
||||||
|
|
||||||
#include <freerdp/client/disp.h>
|
#include <freerdp/client/disp.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/timestamp.h>
|
#include <guacamole/timestamp.h>
|
||||||
|
#include <winpr/wtypes.h>
|
||||||
|
|
||||||
guac_rdp_disp* guac_rdp_disp_alloc() {
|
guac_rdp_disp* guac_rdp_disp_alloc() {
|
||||||
|
|
||||||
@ -50,33 +51,42 @@ void guac_rdp_disp_free(guac_rdp_disp* disp) {
|
|||||||
free(disp);
|
free(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_disp_load_plugin(rdpContext* context, guac_rdp_dvc_list* list) {
|
/**
|
||||||
|
* Callback which associates handlers specific to Guacamole with the
|
||||||
context->settings->SupportDisplayControl = TRUE;
|
* DispClientContext instance allocated by FreeRDP to deal with received
|
||||||
|
* Display Update (client-initiated dynamic display resizing) messages.
|
||||||
/* Add "disp" channel */
|
*
|
||||||
guac_rdp_dvc_list_add(list, "disp", NULL);
|
* This function is called whenever a channel connects via the PubSub event
|
||||||
|
* system within FreeRDP, but only has any effect if the connected channel is
|
||||||
}
|
* the Display Update channel. This specific callback is registered with the
|
||||||
|
* PubSub system of the relevant rdpContext when guac_rdp_disp_load_plugin() is
|
||||||
void guac_rdp_disp_connect(guac_rdp_disp* guac_disp, rdpContext* context,
|
* called.
|
||||||
DispClientContext* disp) {
|
*
|
||||||
|
* @param context
|
||||||
|
* The rdpContext associated with the active RDP session.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* Event-specific arguments, mainly the name of the channel, and a
|
||||||
|
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||||
|
*/
|
||||||
|
static void guac_rdp_disp_channel_connected(rdpContext* context,
|
||||||
|
ChannelConnectedEventArgs* e) {
|
||||||
|
|
||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
guac_rdp_settings* settings = rdp_client->settings;
|
guac_rdp_disp* guac_disp = rdp_client->disp;
|
||||||
|
|
||||||
/* Ignore connected channel if not configured to use the display update
|
/* Ignore connection event if it's not for the Display Update channel */
|
||||||
* channel for resize */
|
if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) != 0)
|
||||||
if (settings->resize_method != GUAC_RESIZE_DISPLAY_UPDATE)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Init module with current display size */
|
/* Init module with current display size */
|
||||||
guac_rdp_disp_set_size(rdp_client->disp, rdp_client->settings,
|
guac_rdp_disp_set_size(guac_disp, rdp_client->settings,
|
||||||
context->instance, guac_rdp_get_width(context->instance),
|
context->instance, guac_rdp_get_width(context->instance),
|
||||||
guac_rdp_get_height(context->instance));
|
guac_rdp_get_height(context->instance));
|
||||||
|
|
||||||
/* Store reference to the display update plugin once it's connected */
|
/* Store reference to the display update plugin once it's connected */
|
||||||
|
DispClientContext* disp = (DispClientContext*) e->pInterface;
|
||||||
guac_disp->disp = disp;
|
guac_disp->disp = disp;
|
||||||
|
|
||||||
guac_client_log(client, GUAC_LOG_DEBUG, "Display update channel "
|
guac_client_log(client, GUAC_LOG_DEBUG, "Display update channel "
|
||||||
@ -84,6 +94,17 @@ void guac_rdp_disp_connect(guac_rdp_disp* guac_disp, rdpContext* context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_rdp_disp_load_plugin(rdpContext* context) {
|
||||||
|
|
||||||
|
/* Subscribe to and handle channel connected events */
|
||||||
|
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||||
|
(pChannelConnectedEventHandler) guac_rdp_disp_channel_connected);
|
||||||
|
|
||||||
|
/* Add "disp" channel */
|
||||||
|
guac_freerdp_dynamic_channel_collection_add(context->settings, "disp", NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fits a given dimension within the allowed bounds for Display Update
|
* Fits a given dimension within the allowed bounds for Display Update
|
||||||
* messages, adjusting the other dimension such that aspect ratio is
|
* messages, adjusting the other dimension such that aspect ratio is
|
@ -20,11 +20,12 @@
|
|||||||
#ifndef GUAC_RDP_DISP_H
|
#ifndef GUAC_RDP_DISP_H
|
||||||
#define GUAC_RDP_DISP_H
|
#define GUAC_RDP_DISP_H
|
||||||
|
|
||||||
#include "dvc.h"
|
|
||||||
#include "rdp_settings.h"
|
#include "rdp_settings.h"
|
||||||
|
|
||||||
#include <freerdp/client/disp.h>
|
#include <freerdp/client/disp.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/timestamp.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum value for width or height, in pixels.
|
* The minimum value for width or height, in pixels.
|
||||||
@ -78,55 +79,43 @@ typedef struct guac_rdp_disp {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a new display update module, which will ultimately control the
|
* Allocates a new display update module, which will ultimately control the
|
||||||
* display update channel once conected.
|
* display update channel once connected.
|
||||||
*
|
*
|
||||||
* @return A new display update module.
|
* @return
|
||||||
|
* A newly-allocated display update module.
|
||||||
*/
|
*/
|
||||||
guac_rdp_disp* guac_rdp_disp_alloc();
|
guac_rdp_disp* guac_rdp_disp_alloc();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees the given display update module.
|
* Frees the resources associated with support for the RDP Display Update
|
||||||
|
* channel. Only resources specific to Guacamole are freed. Resources specific
|
||||||
|
* to FreeRDP's handling of the Display Update channel will be freed by
|
||||||
|
* FreeRDP. If no resources are currently allocated for Display Update support,
|
||||||
|
* this function has no effect.
|
||||||
*
|
*
|
||||||
* @param disp The display update module to free.
|
* @param disp
|
||||||
|
* The display update module to free.
|
||||||
*/
|
*/
|
||||||
void guac_rdp_disp_free(guac_rdp_disp* disp);
|
void guac_rdp_disp_free(guac_rdp_disp* disp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds FreeRDP's "disp" plugin to the list of dynamic virtual channel plugins
|
* Adds FreeRDP's "disp" plugin to the list of dynamic virtual channel plugins
|
||||||
* to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only be loaded
|
* to be loaded by FreeRDP's "drdynvc" plugin. The context of the plugin will
|
||||||
* once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list passed to
|
* automatically be assicated with the guac_rdp_disp instance pointed to by the
|
||||||
* this function. The "disp" plugin ultimately adds support for the Display
|
* current guac_rdp_client. The plugin will only be loaded once the "drdynvc"
|
||||||
* Update channel. NOTE: It is still up to external code to detect when the
|
* plugin is loaded. The "disp" plugin ultimately adds support for the Display
|
||||||
* "disp" channel is connected, and update the guac_rdp_disp with a call to
|
* Update channel.
|
||||||
* guac_rdp_disp_connect().
|
*
|
||||||
|
* If failures occur, messages noting the specifics of those failures will be
|
||||||
|
* logged, and the RDP side of Display Update support will not be functional.
|
||||||
|
*
|
||||||
|
* This MUST be called within the PreConnect callback of the freerdp instance
|
||||||
|
* for Display Update support to be loaded.
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* The rdpContext associated with the active RDP session.
|
* The rdpContext associated with the active RDP session.
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* The guac_rdp_dvc_list to which the "disp" plugin should be added, such
|
|
||||||
* that it may later be loaded by guac_rdp_load_drdynvc().
|
|
||||||
*/
|
*/
|
||||||
void guac_rdp_disp_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
|
void guac_rdp_disp_load_plugin(rdpContext* context);
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the given DispClientContext within the given guac_rdp_disp, such that
|
|
||||||
* display updates can be properly sent. Until this is called, changes to the
|
|
||||||
* display size will be deferred.
|
|
||||||
*
|
|
||||||
* @param guac_disp
|
|
||||||
* The display update module to associate with the connected display update
|
|
||||||
* channel.
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* The rdpContext associated with the active RDP session.
|
|
||||||
*
|
|
||||||
* @param disp
|
|
||||||
* The DispClientContext associated by FreeRDP with the connected display
|
|
||||||
* update channel.
|
|
||||||
*/
|
|
||||||
void guac_rdp_disp_connect(guac_rdp_disp* guac_disp, rdpContext* context,
|
|
||||||
DispClientContext* disp);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests a display size update, which may then be sent immediately to the
|
* Requests a display size update, which may then be sent immediately to the
|
||||||
@ -197,6 +186,10 @@ void guac_rdp_disp_reconnect_complete(guac_rdp_disp* disp);
|
|||||||
* Returns whether a full RDP reconnect is required for display update changes
|
* Returns whether a full RDP reconnect is required for display update changes
|
||||||
* to take effect.
|
* to take effect.
|
||||||
*
|
*
|
||||||
|
* @param client
|
||||||
|
* The guac_client associated with the Guacamole side of the RDP
|
||||||
|
* connection.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* Non-zero if a reconnect is needed, zero otherwise.
|
* Non-zero if a reconnect is needed, zero otherwise.
|
||||||
*/
|
*/
|
@ -1,156 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "common/list.h"
|
|
||||||
#include "channels.h"
|
|
||||||
#include "dvc.h"
|
|
||||||
#include "rdp.h"
|
|
||||||
|
|
||||||
#include <freerdp/channels/channels.h>
|
|
||||||
#include <freerdp/freerdp.h>
|
|
||||||
#include <guacamole/client.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
guac_rdp_dvc_list* guac_rdp_dvc_list_alloc() {
|
|
||||||
|
|
||||||
guac_rdp_dvc_list* list = malloc(sizeof(guac_rdp_dvc_list));
|
|
||||||
|
|
||||||
/* Initialize with empty backing list */
|
|
||||||
list->channels = guac_common_list_alloc();
|
|
||||||
list->channel_count = 0;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void guac_rdp_dvc_list_add(guac_rdp_dvc_list* list, const char* name, ...) {
|
|
||||||
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
guac_rdp_dvc* dvc = malloc(sizeof(guac_rdp_dvc));
|
|
||||||
|
|
||||||
va_start(args, name);
|
|
||||||
|
|
||||||
/* Count number of arguments (excluding terminating NULL) */
|
|
||||||
dvc->argc = 1;
|
|
||||||
while (va_arg(args, char*) != NULL)
|
|
||||||
dvc->argc++;
|
|
||||||
|
|
||||||
/* Reset va_list */
|
|
||||||
va_end(args);
|
|
||||||
va_start(args, name);
|
|
||||||
|
|
||||||
/* Copy argument values into DVC entry */
|
|
||||||
dvc->argv = malloc(sizeof(char*) * dvc->argc);
|
|
||||||
dvc->argv[0] = strdup(name);
|
|
||||||
int i;
|
|
||||||
for (i = 1; i < dvc->argc; i++)
|
|
||||||
dvc->argv[i] = strdup(va_arg(args, char*));
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
/* Add entry to DVC list */
|
|
||||||
guac_common_list_add(list->channels, dvc);
|
|
||||||
|
|
||||||
/* Update channel count */
|
|
||||||
list->channel_count++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void guac_rdp_dvc_list_free(guac_rdp_dvc_list* list) {
|
|
||||||
|
|
||||||
/* For each channel */
|
|
||||||
guac_common_list_element* current = list->channels->head;
|
|
||||||
while (current != NULL) {
|
|
||||||
|
|
||||||
/* Free arguments declaration for current channel */
|
|
||||||
guac_rdp_dvc* dvc = (guac_rdp_dvc*) current->data;
|
|
||||||
|
|
||||||
/* Free the underlying arguments list if not delegated to FreeRDP */
|
|
||||||
if (dvc->argv != NULL) {
|
|
||||||
|
|
||||||
/* Free each argument value */
|
|
||||||
for (int i = 0; i < dvc->argc; i++)
|
|
||||||
free(dvc->argv[i]);
|
|
||||||
|
|
||||||
free(dvc->argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dvc);
|
|
||||||
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free underlying list */
|
|
||||||
guac_common_list_free(list->channels);
|
|
||||||
|
|
||||||
/* Free the DVC list itself */
|
|
||||||
free(list);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list) {
|
|
||||||
|
|
||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
|
||||||
rdpChannels* channels = context->channels;
|
|
||||||
|
|
||||||
/* Skip if no channels will be loaded */
|
|
||||||
if (list->channel_count == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* For each channel */
|
|
||||||
guac_common_list_element* current = list->channels->head;
|
|
||||||
while (current != NULL) {
|
|
||||||
|
|
||||||
/* Get channel arguments */
|
|
||||||
guac_rdp_dvc* dvc = (guac_rdp_dvc*) current->data;
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
/* guac_rdp_dvc_list_add() guarantees at one argument */
|
|
||||||
assert(dvc->argc >= 1);
|
|
||||||
|
|
||||||
/* guac_rdp_load_drdynvc() MUST only be invoked once */
|
|
||||||
assert(dvc->argv != NULL);
|
|
||||||
|
|
||||||
/* Log registration of plugin for current channel */
|
|
||||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
|
||||||
"Registering DVC plugin \"%s\"", dvc->argv[0]);
|
|
||||||
|
|
||||||
/* Register plugin with FreeRDP */
|
|
||||||
ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
|
|
||||||
args->argc = dvc->argc;
|
|
||||||
args->argv = dvc->argv;
|
|
||||||
freerdp_dynamic_channel_collection_add(context->settings, args);
|
|
||||||
|
|
||||||
/* Rely on FreeRDP to free argv storage */
|
|
||||||
dvc->argv = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load virtual channel management plugin */
|
|
||||||
return guac_freerdp_channels_load_plugin(channels,
|
|
||||||
context->instance->settings, "drdynvc",
|
|
||||||
context->instance->settings);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GUAC_RDP_DVC_H
|
|
||||||
#define GUAC_RDP_DVC_H
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "common/list.h"
|
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The set of all arguments that should be passed to a given dynamic virtual
|
|
||||||
* channel plugin, including the name of that plugin.
|
|
||||||
*/
|
|
||||||
typedef struct guac_rdp_dvc {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of arguments in the argv array. This MUST be at least 1.
|
|
||||||
*/
|
|
||||||
int argc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The argument values being passed to the dynamic virtual channel plugin.
|
|
||||||
* The first entry in this array is always the name of the plugin. If
|
|
||||||
* guac_rdp_load_drdynvc() has been invoked, and freeing the argument
|
|
||||||
* values is being delegated to FreeRDP, this will be NULL.
|
|
||||||
*/
|
|
||||||
char** argv;
|
|
||||||
|
|
||||||
} guac_rdp_dvc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of dynamic virtual channels which should be provided to the DRDYNVC
|
|
||||||
* plugin once loaded via guac_rdp_load_drdynvc(). This interface exists purely
|
|
||||||
* to bridge incompatibilities between differing versions of FreeRDP and its
|
|
||||||
* DRDYNVC plugin. Any allocated guac_rdp_dvc_list is unlikely to be needed
|
|
||||||
* after the DRDYNVC plugin has been loaded.
|
|
||||||
*/
|
|
||||||
typedef struct guac_rdp_dvc_list {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of all dynamic virtual channels which should be registered with
|
|
||||||
* the DRDYNVC plugin once loaded. Each list element will point to a
|
|
||||||
* guac_rdp_dvc structure which must eventually be freed.
|
|
||||||
*/
|
|
||||||
guac_common_list* channels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of channels within the list.
|
|
||||||
*/
|
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
} guac_rdp_dvc_list;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates a new, empty list of dynamic virtual channels. New channels may
|
|
||||||
* be added via guac_rdp_dvc_list_add(). The loading of those channels'
|
|
||||||
* associated plugins will be deferred until guac_rdp_load_drdynvc() is
|
|
||||||
* invoked.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* A newly-allocated, empty list of dynamic virtual channels.
|
|
||||||
*/
|
|
||||||
guac_rdp_dvc_list* guac_rdp_dvc_list_alloc();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the given dynamic virtual channel plugin name and associated arguments
|
|
||||||
* to the list. The provied arguments list is NOT optional and MUST be
|
|
||||||
* NULL-terminated, even if there are no arguments for the named dynamic
|
|
||||||
* virtual channel plugin. Though FreeRDP requires that the arguments for a
|
|
||||||
* dynamic virtual channel plugin contain the name of the plugin itself as the
|
|
||||||
* first argument, the name must be excluded from the arguments provided here.
|
|
||||||
* This function will automatically take care of adding the plugin name to
|
|
||||||
* the arguments.
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* The guac_rdp_dvc_list to which the given plugin name and arguments
|
|
||||||
* should be added, for later bulk registration via
|
|
||||||
* guac_rdp_load_drdynvc().
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* The name of the dynamic virtual channel plugin that should be given
|
|
||||||
* the provided arguments when guac_rdp_load_drdynvc() is invoked.
|
|
||||||
*
|
|
||||||
* @param ...
|
|
||||||
* The string (char*) arguments which should be passed to the dynamic
|
|
||||||
* virtual channel plugin when it is loaded via guac_rdp_load_drdynvc(),
|
|
||||||
* excluding the plugin name itself.
|
|
||||||
*/
|
|
||||||
void guac_rdp_dvc_list_add(guac_rdp_dvc_list* list, const char* name, ...);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees the given list of dynamic virtual channels. Note that, while each
|
|
||||||
* individual entry within this list will be freed, it is partially up to
|
|
||||||
* FreeRDP to free the storage associated with the arguments passed to the
|
|
||||||
* virtual channels.
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* The list to free.
|
|
||||||
*/
|
|
||||||
void guac_rdp_dvc_list_free(guac_rdp_dvc_list* list);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads FreeRDP's DRDYNVC plugin and registers the dynamic virtual channel
|
|
||||||
* plugins described by the given guac_rdp_dvc_list. This function MUST be
|
|
||||||
* invoked no more than once per RDP connection. Invoking this function
|
|
||||||
* multiple times, even if the guac_rdp_dvc_list is different each time, will
|
|
||||||
* result in undefined behavior.
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* The rdpContext associated with the RDP connection for which the DRDYNVC
|
|
||||||
* plugin should be loaded.
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* A guac_rdp_dvc_list describing the dynamic virtual channel plugins that
|
|
||||||
* should be registered with the DRDYNVC plugin, along with any arguments.
|
|
||||||
*/
|
|
||||||
int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "common/recording.h"
|
#include "common/recording.h"
|
||||||
|
#include "disp.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
#include "rdp_disp.h"
|
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/input.h>
|
#include <freerdp/input.h>
|
||||||
|
@ -26,12 +26,11 @@
|
|||||||
#include "common/cursor.h"
|
#include "common/cursor.h"
|
||||||
#include "common/display.h"
|
#include "common/display.h"
|
||||||
#include "common/recording.h"
|
#include "common/recording.h"
|
||||||
#include "dvc.h"
|
#include "disp.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
#include "rdp_bitmap.h"
|
#include "rdp_bitmap.h"
|
||||||
#include "rdp_disp.h"
|
|
||||||
#include "rdp_fs.h"
|
#include "rdp_fs.h"
|
||||||
#include "rdp_print_job.h"
|
#include "rdp_print_job.h"
|
||||||
#include "rdp_gdi.h"
|
#include "rdp_gdi.h"
|
||||||
@ -90,23 +89,17 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
guac_rdp_settings* settings = rdp_client->settings;
|
guac_rdp_settings* settings = rdp_client->settings;
|
||||||
|
|
||||||
guac_rdp_dvc_list* dvc_list = guac_rdp_dvc_list_alloc();
|
|
||||||
|
|
||||||
/* Init FreeRDP add-in provider */
|
/* Init FreeRDP add-in provider */
|
||||||
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
|
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
|
||||||
|
|
||||||
/* Subscribe to and handle channel connected events */
|
|
||||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
|
||||||
(pChannelConnectedEventHandler) guac_rdp_channel_connected);
|
|
||||||
|
|
||||||
/* Load "disp" plugin for display update */
|
/* Load "disp" plugin for display update */
|
||||||
if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE)
|
if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE)
|
||||||
guac_rdp_disp_load_plugin(instance->context, dvc_list);
|
guac_rdp_disp_load_plugin(context);
|
||||||
|
|
||||||
/* Load "AUDIO_INPUT" plugin for audio input*/
|
/* Load "AUDIO_INPUT" plugin for audio input*/
|
||||||
if (settings->enable_audio_input) {
|
if (settings->enable_audio_input) {
|
||||||
rdp_client->audio_input = guac_rdp_audio_buffer_alloc();
|
rdp_client->audio_input = guac_rdp_audio_buffer_alloc();
|
||||||
guac_rdp_audio_load_plugin(instance->context, dvc_list);
|
guac_rdp_audio_load_plugin(instance->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load "cliprdr" plugin for clipboard support */
|
/* Load "cliprdr" plugin for clipboard support */
|
||||||
@ -175,14 +168,14 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load DRDYNVC plugin if required */
|
/* Load plugin providing Dynamic Virtual Channel support, if required */
|
||||||
if (guac_rdp_load_drdynvc(instance->context, dvc_list))
|
if (instance->settings->SupportDynamicChannels &&
|
||||||
|
guac_freerdp_channels_load_plugin(channels, instance->settings,
|
||||||
|
"drdynvc", instance->settings)) {
|
||||||
guac_client_log(client, GUAC_LOG_WARNING,
|
guac_client_log(client, GUAC_LOG_WARNING,
|
||||||
"Failed to load drdynvc plugin. Display update and audio "
|
"Failed to load drdynvc plugin. Display update and audio "
|
||||||
"input support will be disabled.");
|
"input support will be disabled.");
|
||||||
|
}
|
||||||
/* Dynamic virtual channel list is no longer needed */
|
|
||||||
guac_rdp_dvc_list_free(dvc_list);
|
|
||||||
|
|
||||||
/* Init FreeRDP internal GDI implementation */
|
/* Init FreeRDP internal GDI implementation */
|
||||||
if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
|
if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
#include "common/recording.h"
|
#include "common/recording.h"
|
||||||
#include "common/surface.h"
|
#include "common/surface.h"
|
||||||
|
#include "disp.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "rdp_disp.h"
|
|
||||||
#include "rdp_fs.h"
|
#include "rdp_fs.h"
|
||||||
#include "rdp_print_job.h"
|
#include "rdp_print_job.h"
|
||||||
#include "rdp_settings.h"
|
#include "rdp_settings.h"
|
||||||
|
@ -1192,6 +1192,10 @@ void guac_rdp_push_settings(guac_client* client,
|
|||||||
/* Audio capture */
|
/* Audio capture */
|
||||||
rdp_settings->AudioCapture = guac_settings->enable_audio_input;
|
rdp_settings->AudioCapture = guac_settings->enable_audio_input;
|
||||||
|
|
||||||
|
/* Display Update channel */
|
||||||
|
rdp_settings->SupportDisplayControl =
|
||||||
|
(guac_settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE);
|
||||||
|
|
||||||
/* Timezone redirection */
|
/* Timezone redirection */
|
||||||
if (guac_settings->timezone) {
|
if (guac_settings->timezone) {
|
||||||
if (setenv("TZ", guac_settings->timezone, 1)) {
|
if (setenv("TZ", guac_settings->timezone, 1)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user