channels/cliprdr: start server-side implementation
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 16 Aug 2013 20:46:47 +0000 (16:46 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 16 Aug 2013 20:46:47 +0000 (16:46 -0400)
18 files changed:
channels/cliprdr/CMakeLists.txt
channels/cliprdr/ChannelOptions.cmake
channels/cliprdr/server/CMakeLists.txt [new file with mode: 0644]
channels/cliprdr/server/cliprdr_main.c [new file with mode: 0644]
channels/cliprdr/server/cliprdr_main.h [new file with mode: 0644]
channels/server/channels.c
client/Windows/wf_interface.c
client/X11/xf_client.c
include/freerdp/channels/wtsvc.h
include/freerdp/client/cliprdr.h
include/freerdp/codec/rfx.h
include/freerdp/server/cliprdr.h [new file with mode: 0644]
libfreerdp/codec/rfx.c
libfreerdp/gdi/gdi.c
server/Mac/mf_peer.c
server/Sample/sfreerdp.c
server/Windows/wf_update.c
server/X11/xf_peer.c

index b5f1cf4..c5cfd72 100644 (file)
@@ -21,3 +21,6 @@ if(WITH_CLIENT_CHANNELS)
        add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
 endif()
 
+if(WITH_SERVER_CHANNELS)
+       add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME})
+endif()
index 9cafcd9..f175f3f 100644 (file)
@@ -1,7 +1,7 @@
 
 set(OPTION_DEFAULT OFF)
 set(OPTION_CLIENT_DEFAULT ON)
-set(OPTION_SERVER_DEFAULT OFF)
+set(OPTION_SERVER_DEFAULT ON)
 
 define_channel_options(NAME "cliprdr" TYPE "static"
        DESCRIPTION "Clipboard Virtual Channel Extension"
diff --git a/channels/cliprdr/server/CMakeLists.txt b/channels/cliprdr/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3e2ef0b
--- /dev/null
@@ -0,0 +1,35 @@
+# FreeRDP: A Remote Desktop Protocol Implementation
+# FreeRDP cmake build script
+#
+# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+#
+# Licensed 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.
+
+define_channel_server("cliprdr")
+
+set(${MODULE_PREFIX}_SRCS
+       cliprdr_main.c
+       cliprdr_main.h)
+
+add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
+
+set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
+
+set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
+       MONOLITHIC ${MONOLITHIC_BUILD}
+       MODULE freerdp
+       MODULES freerdp-utils)
+
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c
new file mode 100644 (file)
index 0000000..7323513
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Clipboard Virtual Channel Extension
+ *
+ * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <winpr/crt.h>
+#include <winpr/stream.h>
+
+#include "cliprdr_main.h"
+
+/**
+ *                                    Initialization Sequence\n
+ *     Client                                                                    Server\n
+ *        |                                                                         |\n
+ *        |<----------------------Server Clipboard Capabilities PDU-----------------|\n
+ *        |<-----------------------------Monitor Ready PDU--------------------------|\n
+ *        |-----------------------Client Clipboard Capabilities PDU---------------->|\n
+ *        |---------------------------Temporary Directory PDU---------------------->|\n
+ *        |-------------------------------Format List PDU-------------------------->|\n
+ *        |<--------------------------Format List Response PDU----------------------|\n
+ *
+ */
+
+static int cliprdr_server_send_capabilities(CliprdrServerContext* context)
+{
+       return 0;
+}
+
+static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context)
+{
+       return 0;
+}
+
+static int cliprdr_server_send_format_list_response(CliprdrServerContext* context)
+{
+       return 0;
+}
+
+static void* cliprdr_server_thread(void* arg)
+{
+       wStream* s;
+       DWORD status;
+       DWORD nCount;
+       void* buffer;
+       HANDLE events[8];
+       HANDLE ChannelEvent;
+       UINT32 BytesReturned;
+       CliprdrServerContext* context;
+
+       context = (CliprdrServerContext*) arg;
+
+       buffer = NULL;
+       BytesReturned = 0;
+       ChannelEvent = NULL;
+
+       s = Stream_New(NULL, 4096);
+
+       if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
+       {
+               if (BytesReturned == sizeof(HANDLE))
+                       CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
+
+               WTSFreeMemory(buffer);
+       }
+
+       nCount = 0;
+       events[nCount++] = ChannelEvent;
+       events[nCount++] = context->priv->StopEvent;
+
+       while (1)
+       {
+               status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+
+               if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
+               {
+                       break;
+               }
+
+               if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
+                               Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE)
+               {
+                       if (BytesReturned == 0)
+                               break;
+
+                       Stream_EnsureRemainingCapacity(s, (int) BytesReturned);
+
+                       if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
+                                       Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE)
+                       {
+                               break;
+                       }
+               }
+       }
+
+       Stream_Free(s, TRUE);
+
+       return NULL;
+}
+
+static int cliprdr_server_start(CliprdrServerContext* context)
+{
+       context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "cliprdr", 0);
+
+       if (!context->priv->ChannelHandle)
+               return -1;
+
+       context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+       context->priv->Thread = CreateThread(NULL, 0,
+                       (LPTHREAD_START_ROUTINE) cliprdr_server_thread, (void*) context, 0, NULL);
+
+       return 0;
+}
+
+static int cliprdr_server_stop(CliprdrServerContext* context)
+{
+       SetEvent(context->priv->StopEvent);
+
+       WaitForSingleObject(context->priv->Thread, INFINITE);
+       CloseHandle(context->priv->Thread);
+
+       return 0;
+}
+
+CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm)
+{
+       CliprdrServerContext* context;
+
+       context = (CliprdrServerContext*) malloc(sizeof(CliprdrServerContext));
+
+       if (context)
+       {
+               ZeroMemory(context, sizeof(CliprdrServerContext));
+
+               context->vcm = vcm;
+
+               context->Start = cliprdr_server_start;
+               context->Stop = cliprdr_server_stop;
+
+               context->SendCapabilities = cliprdr_server_send_capabilities;
+               context->SendMonitorReady = cliprdr_server_send_monitor_ready;
+               context->SendFormatListResponse = cliprdr_server_send_format_list_response;
+
+               context->priv = (CliprdrServerPrivate*) malloc(sizeof(CliprdrServerPrivate));
+
+               if (context->priv)
+               {
+                       ZeroMemory(context->priv, sizeof(CliprdrServerPrivate));
+               }
+       }
+
+       return context;
+}
+
+void cliprdr_server_context_free(CliprdrServerContext* context)
+{
+       if (context)
+       {
+               if (context->priv)
+               {
+                       free(context->priv);
+               }
+
+               free(context);
+       }
+}
diff --git a/channels/cliprdr/server/cliprdr_main.h b/channels/cliprdr/server/cliprdr_main.h
new file mode 100644 (file)
index 0000000..540c333
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Clipboard Virtual Channel Extension
+ *
+ * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed 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 FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H
+#define FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+
+#include <freerdp/server/cliprdr.h>
+
+struct _cliprdr_server_private
+{
+       HANDLE Thread;
+       HANDLE StopEvent;
+       void* ChannelHandle;
+};
+
+#endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H */
index eeae1dc..2bef641 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <freerdp/server/audin.h>
 #include <freerdp/server/rdpsnd.h>
+#include <freerdp/server/cliprdr.h>
 
 void freerdp_channels_dummy()
 {
@@ -50,6 +51,9 @@ void freerdp_channels_dummy()
 
        rdpsnd_server_context_new(NULL);
        rdpsnd_server_context_free(NULL);
+
+       cliprdr_server_context_new(NULL);
+       cliprdr_server_context_free(NULL);
 }
 
 /**
@@ -420,7 +424,7 @@ WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client)
 
        vcm = (WTSVirtualChannelManager*) malloc(sizeof(WTSVirtualChannelManager));
 
-       if (vcm != NULL)
+       if (vcm)
        {
                ZeroMemory(vcm, sizeof(WTSVirtualChannelManager));
 
@@ -659,6 +663,7 @@ BOOL WTSVirtualChannelQuery(
        BOOL result = FALSE;
        rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
        ZeroMemory(fds, sizeof(fds));
+
        switch (WtsVirtualClass)
        {
                case WTSVirtualFileHandle:
@@ -677,6 +682,13 @@ BOOL WTSVirtualChannelQuery(
                        result = TRUE;
                        break;
 
+               case WTSVirtualEventHandle:
+                       *ppBuffer = malloc(sizeof(HANDLE));
+                       CopyMemory(*ppBuffer, &(channel->receive_event), sizeof(HANDLE));
+                       *pBytesReturned = sizeof(void*);
+                       result = TRUE;
+                       break;
+
                case WTSVirtualChannelReady:
                        if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
                        {
index 9ae2de7..d3c76aa 100644 (file)
@@ -371,7 +371,7 @@ BOOL wf_post_connect(freerdp* instance)
                if (settings->RemoteFxCodec)
                {
                        wfc->tile = wf_image_new(wfc, 64, 64, 32, NULL);
-                       wfc->rfx_context = rfx_context_new();
+                       wfc->rfx_context = rfx_context_new(FALSE);
                }
 
                if (settings->NSCodec)
index 5ad3f4f..273df06 100644 (file)
@@ -893,7 +893,7 @@ BOOL xf_post_connect(freerdp* instance)
 
                if (instance->settings->RemoteFxCodec)
                {
-                       rfx_context = (void*) rfx_context_new();
+                       rfx_context = (void*) rfx_context_new(FALSE);
                        xfc->rfx_context = rfx_context;
                }
 
index 227c75f..1b59d8e 100644 (file)
@@ -43,6 +43,7 @@ typedef enum _WTS_VIRTUAL_CLASS
 {
        WTSVirtualClientData,
        WTSVirtualFileHandle,
+       WTSVirtualEventHandle,
        WTSVirtualChannelReady
 } WTS_VIRTUAL_CLASS;
 
index ea0d1cf..a0455dc 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef FREERDP_CHANNEL_CLIENT_CLIPRDR_H
 #define FREERDP_CHANNEL_CLIENT_CLIPRDR_H
 
+#include <freerdp/types.h>
+
 /**
  * Client Interface
  */
index 254cadf..d8fa52c 100644 (file)
@@ -55,7 +55,6 @@ struct _RFX_TILE
        int height;
        BYTE* data;
        int scanline;
-
        BYTE quantIdxY;
        BYTE quantIdxCb;
        BYTE quantIdxCr;
@@ -117,6 +116,7 @@ struct _RFX_CONTEXT
 {
        RFX_STATE state;
 
+       BOOL encoder;
        UINT16 flags;
        UINT16 properties;
        UINT16 width;
@@ -152,7 +152,7 @@ struct _RFX_CONTEXT
 };
 typedef struct _RFX_CONTEXT RFX_CONTEXT;
 
-FREERDP_API RFX_CONTEXT* rfx_context_new(void);
+FREERDP_API RFX_CONTEXT* rfx_context_new(BOOL encoder);
 FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
 FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format);
 FREERDP_API void rfx_context_reset(RFX_CONTEXT* context);
diff --git a/include/freerdp/server/cliprdr.h b/include/freerdp/server/cliprdr.h
new file mode 100644 (file)
index 0000000..01e612b
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Clipboard Virtual Channel Server Interface
+ *
+ * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed 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 FREERDP_CHANNEL_SERVER_CLIPRDR_H
+#define FREERDP_CHANNEL_SERVER_CLIPRDR_H
+
+#include <freerdp/api.h>
+#include <freerdp/types.h>
+#include <freerdp/channels/wtsvc.h>
+#include <freerdp/client/cliprdr.h>
+
+/**
+ * Server Interface
+ */
+
+typedef struct _cliprdr_server_context CliprdrServerContext;
+typedef struct _cliprdr_server_private CliprdrServerPrivate;
+
+typedef int (*psCliprdrStart)(CliprdrServerContext* context);
+typedef int (*psCliprdrStop)(CliprdrServerContext* context);
+
+typedef int (*psCliprdrSendCapabilities)(CliprdrServerContext* context);
+typedef int (*psCliprdrSendMonitorReady)(CliprdrServerContext* context);
+typedef int (*psCliprdrSendFormatListResponse)(CliprdrServerContext* context);
+
+struct _cliprdr_server_context
+{
+       WTSVirtualChannelManager* vcm;
+
+       psCliprdrStart Start;
+       psCliprdrStop Stop;
+
+       psCliprdrSendCapabilities SendCapabilities;
+       psCliprdrSendMonitorReady SendMonitorReady;
+       psCliprdrSendFormatListResponse SendFormatListResponse;
+
+       CliprdrServerPrivate* priv;
+};
+
+FREERDP_API CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm);
+FREERDP_API void cliprdr_server_context_free(CliprdrServerContext* context);
+
+#endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_H */
index 5d6bbe7..d6e6547 100644 (file)
@@ -153,7 +153,7 @@ void rfx_tile_init(RFX_TILE* tile)
        }
 }
 
-RFX_TILE* rfx_tile_new()
+RFX_TILE* rfx_decoder_tile_new()
 {
        RFX_TILE* tile = NULL;
 
@@ -169,7 +169,7 @@ RFX_TILE* rfx_tile_new()
        return tile;
 }
 
-void rfx_tile_free(RFX_TILE* tile)
+void rfx_decoder_tile_free(RFX_TILE* tile)
 {
        if (tile)
        {
@@ -178,7 +178,29 @@ void rfx_tile_free(RFX_TILE* tile)
        }
 }
 
-RFX_CONTEXT* rfx_context_new(void)
+RFX_TILE* rfx_encoder_tile_new()
+{
+       RFX_TILE* tile = NULL;
+
+       tile = (RFX_TILE*) malloc(sizeof(RFX_TILE));
+
+       if (tile)
+       {
+               ZeroMemory(tile, sizeof(RFX_TILE));
+       }
+
+       return tile;
+}
+
+void rfx_encoder_tile_free(RFX_TILE* tile)
+{
+       if (tile)
+       {
+               free(tile);
+       }
+}
+
+RFX_CONTEXT* rfx_context_new(BOOL encoder)
 {
        HKEY hKey;
        LONG status;
@@ -191,13 +213,24 @@ RFX_CONTEXT* rfx_context_new(void)
        context = (RFX_CONTEXT*) malloc(sizeof(RFX_CONTEXT));
        ZeroMemory(context, sizeof(RFX_CONTEXT));
 
+       context->encoder = encoder;
+
        context->priv = (RFX_CONTEXT_PRIV*) malloc(sizeof(RFX_CONTEXT_PRIV));
        ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV));
 
        context->priv->TilePool = ObjectPool_New(TRUE);
-       ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_tile_new;
        ObjectPool_Object(context->priv->TilePool)->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init;
-       ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_tile_free;
+
+       if (context->encoder)
+       {
+               ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new;
+               ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free;
+       }
+       else
+       {
+               ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new;
+               ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free;
+       }
 
        /*
         * align buffers to 16 byte boundary (needed for SSE/NEON instructions)
@@ -1065,7 +1098,8 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
        if (!context->numQuant)
        {
                context->numQuant = 1;
-               context->quants = (UINT32*) rfx_default_quantization_values;
+               context->quants = (UINT32*) malloc(sizeof(rfx_default_quantization_values));
+               CopyMemory(context->quants, &rfx_default_quantization_values, sizeof(rfx_default_quantization_values));
                context->quantIdxY = 0;
                context->quantIdxCb = 0;
                context->quantIdxCr = 0;
@@ -1225,9 +1259,6 @@ RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, in
        RFX_MESSAGE* message;
        RFX_MESSAGE* messages;
 
-       printf("rfx_encode_messages: numRects: %d maxDataSize: %d x: %d y: %d w: %d/%d h: %d/%d\n", numRects, maxDataSize,
-                       rects[0].x, rects[0].y, rects[0].width, width, rects[0].height, height);
-
        message = rfx_encode_message(context, rects, numRects, data, width, height, scanline);
        messages = rfx_split_message(context, message, numMessages, maxDataSize);
        rfx_message_free(context, message);
index 95443ab..566a12d 100644 (file)
@@ -1042,7 +1042,7 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer)
 
        gdi_register_graphics(instance->context->graphics);
 
-       gdi->rfx_context = rfx_context_new();
+       gdi->rfx_context = rfx_context_new(FALSE);
        gdi->nsc_context = nsc_context_new();
 
        return 0;
index 074ece0..0d059cf 100644 (file)
@@ -175,7 +175,7 @@ void mf_peer_rfx_update(freerdp_peer* client)
 int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)\r
 {\r
        context->info = mf_info_get_instance();\r
-       context->rfx_context = rfx_context_new();\r
+       context->rfx_context = rfx_context_new(TRUE);\r
        context->rfx_context->mode = RLGR3;\r
        context->rfx_context->width = client->settings->DesktopWidth;\r
        context->rfx_context->height = client->settings->DesktopHeight;\r
index e988a2e..a889861 100644 (file)
@@ -49,7 +49,7 @@ static BOOL test_dump_rfx_realtime = TRUE;
 
 void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
 {
-       context->rfx_context = rfx_context_new();
+       context->rfx_context = rfx_context_new(TRUE);
        context->rfx_context->mode = RLGR3;
        context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH;
        context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT;
index e6daf5c..0332316 100644 (file)
@@ -198,7 +198,7 @@ void wf_update_encoder_reset(wfInfo* wfi)
                }
                else
                {
-                       wfi->rfx_context = rfx_context_new();
+                       wfi->rfx_context = rfx_context_new(TRUE);
                        wfi->rfx_context->mode = RLGR3;
                        wfi->rfx_context->width = wfi->servscreen_width;
                        wfi->rfx_context->height = wfi->servscreen_height;
index 7b08eff..fe92598 100644 (file)
@@ -295,7 +295,7 @@ xfInfo* xf_info_init()
 void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context)
 {
        context->info = xf_info_init();
-       context->rfx_context = rfx_context_new();
+       context->rfx_context = rfx_context_new(TRUE);
        context->rfx_context->mode = RLGR3;
        context->rfx_context->width = context->info->width;
        context->rfx_context->height = context->info->height;