GUACAMOLE-1231: Merge support for restoring minimized RAIL windows.
This commit is contained in:
commit
4cd10b3bd9
@ -26,27 +26,15 @@
|
||||
#include <freerdp/event.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/window.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/mem.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/wtsapi.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef FREERDP_RAIL_CALLBACKS_REQUIRE_CONST
|
||||
/**
|
||||
* FreeRDP 2.0.0-rc4 and newer requires the final argument for all RAIL
|
||||
* callbacks to be const.
|
||||
*/
|
||||
#define RAIL_CONST const
|
||||
#else
|
||||
/**
|
||||
* FreeRDP 2.0.0-rc3 and older requires the final argument for all RAIL
|
||||
* callbacks to NOT be const.
|
||||
*/
|
||||
#define RAIL_CONST
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Completes initialization of the RemoteApp session, responding to the server
|
||||
* handshake, sending client status and system parameters, and executing the
|
||||
@ -86,6 +74,7 @@ static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
|
||||
};
|
||||
|
||||
/* Send client handshake response */
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "Sending RAIL handshake.");
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
status = rail->ClientHandshake(rail, &handshake);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
@ -94,10 +83,13 @@ static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
|
||||
return status;
|
||||
|
||||
RAIL_CLIENT_STATUS_ORDER client_status = {
|
||||
.flags = 0x00
|
||||
.flags =
|
||||
TS_RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE
|
||||
| TS_RAIL_CLIENTSTATUS_APPBAR_REMOTING_SUPPORTED
|
||||
};
|
||||
|
||||
/* Send client status */
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "Sending RAIL client status.");
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
status = rail->ClientInformation(rail, &client_status);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
@ -135,8 +127,7 @@ static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
|
||||
},
|
||||
|
||||
.params =
|
||||
SPI_MASK_SET_DRAG_FULL_WINDOWS
|
||||
| SPI_MASK_SET_HIGH_CONTRAST
|
||||
SPI_MASK_SET_HIGH_CONTRAST
|
||||
| SPI_MASK_SET_KEYBOARD_CUES
|
||||
| SPI_MASK_SET_KEYBOARD_PREF
|
||||
| SPI_MASK_SET_MOUSE_BUTTON_SWAP
|
||||
@ -145,6 +136,7 @@ static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
|
||||
};
|
||||
|
||||
/* Send client system parameters */
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "Sending RAIL client system parameters.");
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
status = rail->ClientSystemParam(rail, &sysparam);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
@ -160,6 +152,7 @@ static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
|
||||
};
|
||||
|
||||
/* Execute desired RemoteApp command */
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "Executing remote application.");
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
status = rail->ClientExecute(rail, &exec);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
@ -220,6 +213,8 @@ static UINT guac_rdp_rail_execute_result(RailClientContext* context,
|
||||
*/
|
||||
static UINT guac_rdp_rail_handshake(RailClientContext* rail,
|
||||
RAIL_CONST RAIL_HANDSHAKE_ORDER* handshake) {
|
||||
guac_client* client = (guac_client*) rail->custom;
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "RAIL handshake callback.");
|
||||
return guac_rdp_rail_complete_handshake(rail);
|
||||
}
|
||||
|
||||
@ -244,9 +239,63 @@ static UINT guac_rdp_rail_handshake(RailClientContext* rail,
|
||||
*/
|
||||
static UINT guac_rdp_rail_handshake_ex(RailClientContext* rail,
|
||||
RAIL_CONST RAIL_HANDSHAKE_EX_ORDER* handshake_ex) {
|
||||
guac_client* client = (guac_client*) rail->custom;
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "RAIL handshake ex callback.");
|
||||
return guac_rdp_rail_complete_handshake(rail);
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback function that is executed when an update for a RAIL window is
|
||||
* received from the RDP server.
|
||||
*
|
||||
* @param context
|
||||
* A pointer to the rdpContext structure used by FreeRDP to handle the
|
||||
* window update.
|
||||
*
|
||||
* @param orderInfo
|
||||
* A pointer to the data structure that contains information about what
|
||||
* window was updated what updates were performed.
|
||||
*
|
||||
* @param windowState
|
||||
* A pointer to the data structure that contains details of the updates
|
||||
* to the window, as indicated by flags in the orderInfo field.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the client-side processing of the updates as successful; otherwise
|
||||
* FALSE. This implementation always returns TRUE.
|
||||
*/
|
||||
static BOOL guac_rdp_rail_window_update(rdpContext* context,
|
||||
RAIL_CONST WINDOW_ORDER_INFO* orderInfo,
|
||||
RAIL_CONST WINDOW_STATE_ORDER* windowState) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "RAIL window update callback: %d", orderInfo->fieldFlags);
|
||||
|
||||
UINT32 fieldFlags = orderInfo->fieldFlags;
|
||||
|
||||
/* If the flag for window visibilty is set, check visibility. */
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW) {
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "RAIL window visibility change: %d", windowState->showState);
|
||||
|
||||
/* State is either hidden or minimized - send restore command. */
|
||||
if (windowState->showState == GUAC_RDP_RAIL_WINDOW_STATE_HIDDEN
|
||||
|| windowState->showState == GUAC_RDP_RAIL_WINDOW_STATE_MINIMIZED) {
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "RAIL window minimized, sending restore command.");
|
||||
|
||||
RAIL_SYSCOMMAND_ORDER syscommand;
|
||||
syscommand.windowId = orderInfo->windowId;
|
||||
syscommand.command = SC_RESTORE;
|
||||
rdp_client->rail_interface->ClientSystemCommand(rdp_client->rail_interface, &syscommand);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback which associates handlers specific to Guacamole with the
|
||||
* RailClientContext instance allocated by FreeRDP to deal with received
|
||||
@ -269,6 +318,7 @@ static void guac_rdp_rail_channel_connected(rdpContext* context,
|
||||
ChannelConnectedEventArgs* args) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
/* Ignore connection event if it's not for the RAIL channel */
|
||||
if (strcmp(args->name, RAIL_SVC_CHANNEL_NAME) != 0)
|
||||
@ -277,6 +327,7 @@ static void guac_rdp_rail_channel_connected(rdpContext* context,
|
||||
/* The structure pointed to by pInterface is guaranteed to be a
|
||||
* RailClientContext if the channel is RAIL */
|
||||
RailClientContext* rail = (RailClientContext*) args->pInterface;
|
||||
rdp_client->rail_interface = rail;
|
||||
|
||||
/* Init FreeRDP RAIL context, ensuring the guac_client can be accessed from
|
||||
* within any RAIL-specific callbacks */
|
||||
@ -284,6 +335,7 @@ static void guac_rdp_rail_channel_connected(rdpContext* context,
|
||||
rail->ServerExecuteResult = guac_rdp_rail_execute_result;
|
||||
rail->ServerHandshake = guac_rdp_rail_handshake;
|
||||
rail->ServerHandshakeEx = guac_rdp_rail_handshake_ex;
|
||||
context->update->window->WindowUpdate = guac_rdp_rail_window_update;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "RAIL (RemoteApp) channel "
|
||||
"connected.");
|
||||
@ -312,4 +364,3 @@ void guac_rdp_rail_load_plugin(rdpContext* context) {
|
||||
"registered. Awaiting channel connection.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,34 @@
|
||||
#ifndef GUAC_RDP_CHANNELS_RAIL_H
|
||||
#define GUAC_RDP_CHANNELS_RAIL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/window.h>
|
||||
|
||||
#ifdef FREERDP_RAIL_CALLBACKS_REQUIRE_CONST
|
||||
/**
|
||||
* FreeRDP 2.0.0-rc4 and newer requires the final arguments for RAIL
|
||||
* callbacks to be const.
|
||||
*/
|
||||
#define RAIL_CONST const
|
||||
#else
|
||||
/**
|
||||
* FreeRDP 2.0.0-rc3 and older requires the final arguments for RAIL
|
||||
* callbacks to NOT be const.
|
||||
*/
|
||||
#define RAIL_CONST
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The RAIL window state that indicates a hidden window.
|
||||
*/
|
||||
#define GUAC_RDP_RAIL_WINDOW_STATE_HIDDEN 0x00
|
||||
|
||||
/**
|
||||
* The RAIL window state that indicates a visible but minimized window.
|
||||
*/
|
||||
#define GUAC_RDP_RAIL_WINDOW_STATE_MINIMIZED 0x02
|
||||
|
||||
/**
|
||||
* Initializes RemoteApp support for RDP and handling of the RAIL channel. If
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "channels/cliprdr.h"
|
||||
#include "channels/disp.h"
|
||||
#include "channels/pipe-svc.h"
|
||||
#include "channels/rail.h"
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
|
||||
#include <freerdp/codec/color.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/rail.h>
|
||||
#include <guacamole/audio.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/rwlock.h>
|
||||
@ -197,6 +198,12 @@ typedef struct guac_rdp_client {
|
||||
*/
|
||||
pthread_mutex_t message_lock;
|
||||
|
||||
/**
|
||||
* A pointer to the RAIL interface provided by the RDP client when rail is
|
||||
* in use.
|
||||
*/
|
||||
RailClientContext* rail_interface;
|
||||
|
||||
} guac_rdp_client;
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user