channels/rdpgfx: implement basic negotiation
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 22 Oct 2013 03:33:25 +0000 (23:33 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 22 Oct 2013 03:33:25 +0000 (23:33 -0400)
channels/rdpgfx/client/rdpgfx_common.c
channels/rdpgfx/client/rdpgfx_common.h
channels/rdpgfx/client/rdpgfx_main.c
client/common/cmdline.c
include/freerdp/settings.h
libfreerdp/core/gcc.c
libfreerdp/core/nego.c
libfreerdp/core/nego.h

index bd0a76f..c2ea76d 100644 (file)
 
 #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;
+}
index 20fd722..df80c2a 100644 (file)
 #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 */
 
index 889da5f..8c6d52b 100644 (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);
        }
 
index b9f56a7..735a647 100644 (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);
index 406a318..7092753 100644 (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
index 316f4f9..ee039a9 100644 (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 */
 
index 2e97d05..13afb11 100644 (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,
index e8f429f..7d3e08b 100644 (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)