channels/rdpgfx: implement basic negotiation

This commit is contained in:
Marc-André Moreau
2013-10-21 23:33:25 -04:00
parent fb752b3aae
commit 3951a6e1c3
8 changed files with 127 additions and 2 deletions

View File

@@ -26,4 +26,76 @@
#include "rdpgfx_common.h"
int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16)
{
Stream_Read_UINT16(s, point16->x); /* x (2 bytes) */
Stream_Read_UINT16(s, point16->y); /* y (2 bytes) */
return 0;
}
int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16)
{
Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
return 0;
}
int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16)
{
Stream_Read_UINT16(s, rect16->left); /* left (2 bytes) */
Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
return 0;
}
int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16)
{
Stream_Write_UINT16(s, rect16->left); /* left (2 bytes) */
Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
return 0;
}
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32)
{
Stream_Read_UINT8(s, color32->B); /* B (1 byte) */
Stream_Read_UINT8(s, color32->G); /* G (1 byte) */
Stream_Read_UINT8(s, color32->R); /* R (1 byte) */
Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
return 0;
}
int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32)
{
Stream_Write_UINT8(s, color32->B); /* B (1 byte) */
Stream_Write_UINT8(s, color32->G); /* G (1 byte) */
Stream_Write_UINT8(s, color32->R); /* R (1 byte) */
Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
return 0;
}
int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header)
{
Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Read_UINT16(s, header->pduLength); /* pduLength (4 bytes) */
return 0;
}
int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header)
{
Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Write_UINT16(s, header->pduLength); /* pduLength (4 bytes) */
return 0;
}

View File

@@ -23,7 +23,16 @@
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/channels/rdpgfx.h>
int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16);
int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16);
int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16);
int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16);
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32);
int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header);
int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header);
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H */

View File

@@ -27,6 +27,7 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/wlog.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
@@ -80,6 +81,8 @@ static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
int status = 0;
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
fprintf(stderr, "RdpGfxOnDataReceived\n");
s = Stream_New(pBuffer, cbSize);
status = rdpgfx_recv_pdu(callback, s);
@@ -117,6 +120,8 @@ static int rdpgfx_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
*ppCallback = (IWTSVirtualChannelCallback*) callback;
fprintf(stderr, "RdpGfxOnNewChannelConnection\n");
return 0;
}
@@ -137,6 +142,8 @@ static int rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
rdpgfx->listener->pInterface = rdpgfx->iface.pInterface;
fprintf(stderr, "RdpGfxInitialize\n");
return status;
}
@@ -191,6 +198,8 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
rdpgfx->iface.pInterface = (void*) context;
fprintf(stderr, "RdpGfxDVCPluginEntry\n");
error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpgfx", (IWTSPlugin*) rdpgfx);
}

View File

@@ -102,6 +102,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Themes" },
{ "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Wallpaper" },
{ "gdi", COMMAND_LINE_VALUE_REQUIRED, "<sw|hw>", NULL, NULL, -1, NULL, "GDI rendering" },
{ "gfx", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "RDP8 graphics pipeline (experimental)" },
{ "rfx", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "RemoteFX" },
{ "rfx-mode", COMMAND_LINE_VALUE_REQUIRED, "<image|video>", NULL, NULL, -1, NULL, "RemoteFX mode" },
{ "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Frame acknowledgement" },
@@ -1466,6 +1467,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
else if (strcmp(arg->Value, "hw") == 0)
settings->SoftwareGdi = FALSE;
}
CommandLineSwitchCase(arg, "gfx")
{
settings->SupportGraphicsPipeline = TRUE;
}
CommandLineSwitchCase(arg, "rfx")
{
settings->RemoteFxCodec = TRUE;
@@ -1819,6 +1824,17 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
freerdp_client_load_static_channel_addin(channels, settings, "rail", settings);
}
if (settings->SupportGraphicsPipeline)
{
char* p[1];
int count;
count = 1;
p[0] = "rdpgfx";
freerdp_client_add_dynamic_channel(settings, count, p);
}
if (settings->DynamicChannelCount)
{
freerdp_client_load_static_channel_addin(channels, settings, "drdynvc", settings);

View File

@@ -94,6 +94,7 @@
#define RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT 0x0080
#define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100
#define RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE 0x0200
#define RNS_UD_CS_SUPPORT_HEARTBEAT_PDU 0x0400
/* Early Capability Flags (Server to Client) */
#define RNS_UD_SC_EDGE_ACTIONS_SUPPORTED 0x00000001

View File

@@ -727,6 +727,15 @@ void gcc_write_client_core_data(wStream* s, rdpSettings* settings)
earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION;
}
if (settings->NetworkAutoDetect)
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT;
if (settings->SupportGraphicsPipeline)
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL;
if (settings->SupportDynamicTimeZone)
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE;
Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */
Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */

View File

@@ -833,6 +833,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
int bm, em;
BOOL status;
wStream* s;
BYTE flags;
rdpSettings* settings;
status = TRUE;
@@ -846,17 +847,24 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
if (nego->selected_protocol > PROTOCOL_RDP)
{
flags = EXTENDED_CLIENT_DATA_SUPPORTED;
if (settings->SupportGraphicsPipeline)
flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;
/* RDP_NEG_DATA must be present for TLS and NLA */
Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
Stream_Write_UINT8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
Stream_Write_UINT8(s, flags); /* flags */
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */
length += 8;
}
else if (!settings->RdpSecurity)
{
flags = 0;
Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
Stream_Write_UINT8(s, 0); /* flags */
Stream_Write_UINT8(s, flags); /* flags */
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
/*
* TODO: Check for other possibilities,

View File

@@ -76,6 +76,7 @@ enum RDP_NEG_MSG
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
#define RDP_NEGRSP_RESERVED 0x04
#define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08
#define PRECONNECTION_PDU_V1_SIZE 16
#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE + 2)