From 475a44f0e2f0e78108c08bae990228858db3dce9 Mon Sep 17 00:00:00 2001 From: Daniel Bungert Date: Tue, 11 Jun 2013 16:49:27 -0400 Subject: [PATCH 01/74] Free incompletely initialized dvcs. If dynamic channels are not completely initialized, the server will reuse those channel numbers for new channels. This causes interesting problems when the server asks for a channel by number, as we can end up with multiple channels with the same number. Log example of the problem: DBG_DVC drdynvc_process_receive (341): Cmd=0x1 DBG_DVC drdynvc_process_create_request (249): ChannelId=0 ChannelName=PNPDR DBG_DVC drdynvc_process_create_request (265): no listener DBG_DVC drdynvc_process_receive (341): Cmd=0x1 DBG_DVC drdynvc_process_create_request (249): ChannelId=0 ChannelName=TSMF DBG_DVC tsmf_on_new_channel_connection (378): DBG_DVC dvcman_create_channel (415): listener TSMF created new channel 0 DBG_DVC drdynvc_process_create_request (260): channel created DBG_DVC drdynvc_process_receive (341): Cmd=0x3 DBG_DVC drdynvc_process_data (311): ChannelId=0 Warning dvcman_receive_channel_data (517): ChannelId 0 not ready! In this log, we received data intended for TSMF, but the channel lookup found the incompletely initialized PNPDR. --- channels/drdynvc/client/dvcman.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index ac897a669..954247d02 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -376,16 +376,13 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel { DEBUG_WARN("channel rejected by plugin"); - channel->status = 1; - ArrayList_Add(dvcman->channels, channel); + free(channel); return 1; } } } - channel->status = 1; - ArrayList_Add(dvcman->channels, channel); - + free(channel); return 1; } From 6422eb57d8b82bef5f788d10560d238ad9cfc189 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 13 Jun 2013 13:39:49 +0800 Subject: [PATCH 02/74] libfreerdp-core/surface: remove reduncdant frame ack - was done in client. --- libfreerdp/core/surface.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index 3de41339f..7d0fb229a 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -58,15 +58,6 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3 return 0; } -static void update_send_frame_acknowledge(rdpRdp* rdp, UINT32 frameId) -{ - wStream* s; - - s = rdp_data_pdu_init(rdp); - Stream_Write_UINT32(s, frameId); - rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id); -} - static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT32 *length) { SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker; @@ -79,13 +70,6 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT3 IFCALL(update->SurfaceFrameMarker, update->context, marker); - if (update->context->rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE] && - (update->context->rdp->settings->FrameAcknowledge > 0) && - (marker->frameAction == SURFACECMD_FRAMEACTION_END)) - { - update_send_frame_acknowledge(update->context->rdp, marker->frameId); - } - *length = 6; return 0; From 9dbc240f681842993cb5fb33f2bf50fa64b6bd84 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 13 Jun 2013 16:56:06 +0800 Subject: [PATCH 03/74] libfreerdp-core/server: fix stream memory leaks. --- libfreerdp/core/update.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 9984791d2..4781349a5 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -638,6 +638,7 @@ static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_ update_write_refresh_rect(s, count, areas); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id); + Stream_Release(s); } } @@ -666,6 +667,7 @@ static void update_send_suppress_output(rdpContext* context, BYTE allow, RECTANG update_write_suppress_output(s, allow, area); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id); + Stream_Release(s); } } @@ -678,6 +680,7 @@ static void update_send_surface_command(rdpContext* context, wStream* s) Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s)); Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s)); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update); + Stream_Release(update); } static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) @@ -690,6 +693,7 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* update_write_surfcmd_surface_bits_header(s, surface_bits_command); Stream_Write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); + Stream_Release(s); } static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) @@ -700,6 +704,7 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_ s = fastpath_update_pdu_init(rdp->fastpath); update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); + Stream_Release(s); } static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId) @@ -712,6 +717,7 @@ static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId) s = rdp_data_pdu_init(rdp); Stream_Write_UINT32(s, frameId); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id); + Stream_Release(s); } } @@ -723,6 +729,7 @@ static void update_send_synchronize(rdpContext* context) s = fastpath_update_pdu_init(rdp->fastpath); Stream_Zero(s, 2); /* pad2Octets (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s); + Stream_Release(s); } static void update_send_desktop_resize(rdpContext* context) @@ -1221,6 +1228,7 @@ static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDAT updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT; fastpath_send_update_pdu(rdp->fastpath, updateCode, s); + Stream_Release(s); } static void update_write_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color) @@ -1252,6 +1260,7 @@ static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* s = fastpath_update_pdu_init(rdp->fastpath); update_write_pointer_color(s, pointer_color); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s); + Stream_Release(s); } static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new) @@ -1263,6 +1272,7 @@ static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* poi Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ update_write_pointer_color(s, &pointer_new->colorPtrAttr); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s); + Stream_Release(s); } static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached) @@ -1273,6 +1283,7 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT s = fastpath_update_pdu_init(rdp->fastpath); Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s); + Stream_Release(s); } BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s) From ce17a827c495bf59e96b1ac48b651652bbbffd26 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 27 May 2013 15:28:08 +0200 Subject: [PATCH 04/74] Added play-rfx command line option. PCAP dumps can now be played with /play-rfx:path_to_file again. --- client/common/cmdline.c | 6 ++++++ libfreerdp/core/freerdp.c | 15 +++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 77353ff81..12ab61ab0 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -134,6 +134,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "wm-class", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "set the WM_CLASS hint for the window instance" }, { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" }, { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" }, + { "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Replay rfx pcap file" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -1596,6 +1597,11 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin { settings->WmClass = _strdup(arg->Value); } + CommandLineSwitchCase(arg, "play-rfx") + { + settings->PlayRemoteFxFile = _strdup(arg->Value); + settings->PlayRemoteFx = TRUE; + } CommandLineSwitchDefault(arg) { diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index b28437ea5..15d259ac3 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -127,28 +127,31 @@ BOOL freerdp_connect(freerdp* instance) update = instance->update; s = StreamPool_Take(rdp->transport->ReceivePool, 0); - instance->update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); + update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); - if (update->pcap_rfx) + if (!update->pcap_rfx) + return FALSE; + else update->play_rfx = TRUE; - - while (update->play_rfx && pcap_has_next_record(update->pcap_rfx)) + + while (pcap_has_next_record(update->pcap_rfx)) { + pcap_get_next_record_header(update->pcap_rfx, &record); Stream_EnsureCapacity(s, record.length); record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); + Stream_SetLength(s,record.length); Stream_SetPosition(s, 0); update->BeginPaint(update->context); - update_recv_surfcmds(update, Stream_Capacity(s), s); + update_recv_surfcmds(update, Stream_Length(s) , s); update->EndPaint(update->context); } Stream_Release(s); - return TRUE; } } From 8748cfc57f94da0309db7452541895ddc0ada3dc Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 27 May 2013 15:35:25 +0200 Subject: [PATCH 05/74] Added auth-only parameter to new command line syntax auth-only only authenticates. This can be used for credential testing. Username and password are required for auth-only --- client/common/cmdline.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 12ab61ab0..72be77a82 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -135,6 +135,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" }, { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" }, { "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Replay rfx pcap file" }, + { "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -1602,6 +1603,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->PlayRemoteFxFile = _strdup(arg->Value); settings->PlayRemoteFx = TRUE; } + CommandLineSwitchCase(arg, "auth-only") + { + settings->AuthenticationOnly = arg->Value ? TRUE : FALSE; + } CommandLineSwitchDefault(arg) { From 0fd6439123395584abbac74dd1088082a606e0d0 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 13 Jun 2013 14:53:09 +0200 Subject: [PATCH 06/74] server/sample: fix build Needs now also to be linked against winpr-error --- channels/server/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/server/CMakeLists.txt b/channels/server/CMakeLists.txt index b86cd6df4..aa15ce965 100644 --- a/channels/server/CMakeLists.txt +++ b/channels/server/CMakeLists.txt @@ -40,7 +40,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-crt winpr-synch winpr-interlocked) + MODULES winpr-crt winpr-synch winpr-interlocked winpr-error) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) From c96cbb7f746e5ff61b8a571a6f344f7849ed7a8e Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 13 Jun 2013 15:46:31 +0200 Subject: [PATCH 07/74] server/x11: build fix when xfixes is disabled --- server/X11/xf_cursor.c | 2 ++ server/X11/xf_update.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/server/X11/xf_cursor.c b/server/X11/xf_cursor.c index ebd523f29..00e4abb3c 100644 --- a/server/X11/xf_cursor.c +++ b/server/X11/xf_cursor.c @@ -38,6 +38,7 @@ int xf_cursor_init(xfInfo* xfi) { +#ifdef WITH_XFIXES int event; int error; @@ -50,6 +51,7 @@ int xf_cursor_init(xfInfo* xfi) xfi->xfixes_notify_event = event + XFixesCursorNotify; XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask); +#endif return 0; } diff --git a/server/X11/xf_update.c b/server/X11/xf_update.c index 33dd426b3..3ef239c8c 100644 --- a/server/X11/xf_update.c +++ b/server/X11/xf_update.c @@ -80,12 +80,14 @@ void* xf_update_thread(void* param) ResetEvent(xfp->updateSentEvent); } } +#ifdef WITH_XFIXES else if (xevent.type == xfi->xfixes_notify_event) { XFixesCursorImage* ci = XFixesGetCursorImage(xfi->display); XFree(ci); } +#endif } end = GetTickCount(); From 0c2f6d59dd1c1703516215281cd5d1c478d18de7 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 13 Jun 2013 16:38:31 +0200 Subject: [PATCH 08/74] core: update play-rfx to work with async-updates --- libfreerdp/core/freerdp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 15d259ac3..51e0158ef 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -126,7 +126,6 @@ BOOL freerdp_connect(freerdp* instance) update = instance->update; - s = StreamPool_Take(rdp->transport->ReceivePool, 0); update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); if (!update->pcap_rfx) @@ -139,7 +138,7 @@ BOOL freerdp_connect(freerdp* instance) pcap_get_next_record_header(update->pcap_rfx, &record); - Stream_EnsureCapacity(s, record.length); + s = StreamPool_Take(rdp->transport->ReceivePool, record.length); record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); @@ -149,9 +148,9 @@ BOOL freerdp_connect(freerdp* instance) update->BeginPaint(update->context); update_recv_surfcmds(update, Stream_Length(s) , s); update->EndPaint(update->context); + Stream_Release(s); } - Stream_Release(s); return TRUE; } } From 72c6ecdd3b3e442559bf3d75a0675d3cf3066874 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 13 Jun 2013 20:24:17 +0200 Subject: [PATCH 09/74] core: Don't sent persistent key list if deact/react Client persistent key list should not be sent if deactivation- reactivation sequence is in progress. See [MS-RDPBCGR] 2.2.1.17 for details. fixes #1229 --- libfreerdp/core/activation.c | 8 ++++++++ libfreerdp/core/connection.c | 11 +++++++++-- libfreerdp/core/rdp.h | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libfreerdp/core/activation.c b/libfreerdp/core/activation.c index 58d80ed82..c64c654dd 100644 --- a/libfreerdp/core/activation.c +++ b/libfreerdp/core/activation.c @@ -279,6 +279,14 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s) { UINT16 lengthSourceDescriptor; + if (rdp->state == CONNECTION_STATE_ACTIVE) + { + rdp->deactivation_reactivation = TRUE; + } + else + { + rdp->deactivation_reactivation = FALSE; + } /* * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain * the following fields. diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 2ce41eb11..553a27df5 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -587,8 +587,15 @@ BOOL rdp_client_connect_finalize(rdpRdp* rdp) return FALSE; if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL)) return FALSE; - if (!rdp_send_client_persistent_key_list_pdu(rdp)) - return FALSE; + /** + * [MS-RDPBCGR] 2.2.1.17 + * Client persistent key list must be sent if a bitmap is + * stored in persistent bitmap cache or the server has advertised support for bitmap + * host cache and a deactivation reactivation sequence is *not* in progress. + */ + if (!rdp->deactivation_reactivation && rdp->settings->BitmapCachePersistEnabled) + if (!rdp_send_client_persistent_key_list_pdu(rdp)) + return FALSE; if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST)) return FALSE; diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index a0f2c9530..fc730261e 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -157,6 +157,7 @@ struct rdp_rdp UINT32 finalize_sc_pdus; BOOL disconnect; BOOL resendFocus; + BOOL deactivation_reactivation; }; BOOL rdp_read_security_header(wStream* s, UINT16* flags); From b194ddc2113d280daa76a69fcef07777a9c993c5 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 14 Jun 2013 12:16:04 +0800 Subject: [PATCH 10/74] libfreerdp-codec/rfx: dwSize must be initialized. --- libfreerdp/codec/rfx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index afd9e5ecc..610654a0d 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -196,6 +196,8 @@ RFX_CONTEXT* rfx_context_new(void) if (status == ERROR_SUCCESS) { + dwSize = sizeof(dwValue); + if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->UseThreads = dwValue ? 1 : 0; From 96d5910a752e6021a96bfdfbb156a1807dcba99a Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 14 Jun 2013 13:21:29 +0800 Subject: [PATCH 11/74] libfreerdp-utils: fix profiler on Windows. --- libfreerdp/utils/profiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/utils/profiler.c b/libfreerdp/utils/profiler.c index f12a25cc9..3d8fae62d 100644 --- a/libfreerdp/utils/profiler.c +++ b/libfreerdp/utils/profiler.c @@ -70,7 +70,7 @@ void profiler_print(PROFILER* profiler) double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; - fprintf(stderr, "| %-30.30s| %'10lu | %'9f | %'9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); + fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); } void profiler_print_footer() From 9373787fb15f94c1e501a72e3a50ab8601ad9709 Mon Sep 17 00:00:00 2001 From: Christian Plattner Date: Fri, 14 Jun 2013 15:41:06 +0200 Subject: [PATCH 12/74] winpr: check added if handle is NULL --- winpr/libwinpr/handle/handle.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index 5011e826d..ad4556f95 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -47,6 +47,9 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj { WINPR_HANDLE* wHandle; + if (handle == NULL) + return FALSE; + wHandle = (WINPR_HANDLE*) handle; *pType = wHandle->Type; From c89be21c71010c28bf993bf4f33f4cfd15998b7a Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 17 Jun 2013 11:13:14 +0200 Subject: [PATCH 13/74] build: use uppercase XRENDER_FOUND FIND_PACKAGE_HANDLE_STANDARD_ARGS sets _FOUND --- cmake/FindXrender.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/FindXrender.cmake b/cmake/FindXrender.cmake index 5264604df..461217578 100644 --- a/cmake/FindXrender.cmake +++ b/cmake/FindXrender.cmake @@ -26,18 +26,18 @@ # limitations under the License. #============================================================================= -find_path(Xrender_INCLUDE_DIR NAMES X11/extensions/Xrender.h +find_path(XRENDER_INCLUDE_DIR NAMES X11/extensions/Xrender.h DOC "The Xrender include directory") -find_library(Xrender_LIBRARY NAMES Xrender +find_library(XRENDER_LIBRARY NAMES Xrender DOC "The Xrender library") include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG Xrender_LIBRARY Xrender_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR) -if(Xrender_FOUND) - set(XRENDER_LIBRARIES ${Xrender_LIBRARY}) - set(XRENDER_INCLUDE_DIRS ${Xrender_INCLUDE_DIR}) +if(XRENDER_FOUND) + set(XRENDER_LIBRARIES ${XRENDER_LIBRARY}) + set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR}) endif() mark_as_advanced(XRENDER_INCLUDE_DIRS XRENDER_LIBRARIES) From bcef9317552a78f0e247513beaac8b28a6cf3970 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 17 Jun 2013 11:14:25 +0200 Subject: [PATCH 14/74] build: changed X11_FEATURE_TYPE to optional on osX If X11_FEATURE_TYPE is disables on mac xfreerdp can't be build properly. Setting it to optional allows to enable X11 builds with -DWITH_X11 --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca6e154b0..5d7f01312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,8 +318,9 @@ if(APPLE) set(DIRECTFB_FEATURE_TYPE "DISABLED") set(FFMPEG_FEATURE_TYPE "OPTIONAL") set(GSTREAMER_FEATURE_TYPE "OPTIONAL") - set(X11_FEATURE_TYPE "DISABLED") + set(X11_FEATURE_TYPE "OPTIONAL") if(IOS) + set(X11_FEATURE_TYPE "DISABLED") set(ALSA_FEATURE_TYPE "DISABLED") set(PULSE_FEATURE_TYPE "DISABLED") set(CUPS_FEATURE_TYPE "DISABLED") From 13466349bc80060db78e0c4ad00415a8a7008151 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Jun 2013 21:19:01 +0200 Subject: [PATCH 15/74] 1) Add support for Wildcard Certificates 2) For Gateway connections compare against gateway host name instead of target host --- include/freerdp/crypto/tls.h | 1 + libfreerdp/crypto/tls.c | 65 +++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index c396679b3..7e9aca995 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -61,6 +61,7 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length); FREERDP_API int tls_wait_read(rdpTls* tls); FREERDP_API int tls_wait_write(rdpTls* tls); +FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname); FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname); FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file); FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 78b9b637e..705346224 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -100,6 +100,7 @@ BOOL tls_connect(rdpTls* tls) CryptoCert cert; long options = 0; int connection_status; + char *hostname; tls->ctx = SSL_CTX_new(TLSv1_client_method()); @@ -183,7 +184,12 @@ BOOL tls_connect(rdpTls* tls) return FALSE; } - if (!tls_verify_certificate(tls, cert, tls->settings->ServerHostname)) + if (tls->settings->GatewayUsageMethod) + hostname = tls->settings->GatewayHostname; + else + hostname = tls->settings->ServerHostname; + + if (!tls_verify_certificate(tls, cert, hostname)) { fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n"); tls_disconnect(tls); @@ -513,6 +519,50 @@ BOOL tls_print_error(char* func, SSL* connection, int value) } } +BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname) +{ + if (strlen(hostname) == pattern_length) + { + if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0) + return TRUE; + } + + /* ccpp: Check for wildcard certificates */ + if (memchr(pattern, '*', pattern_length) != NULL) + { + /* The wildcard matches one subdomain level (all except a dot) */ + + int pattern_position = 0; + int hostname_position = 0; + + for(; hostname[hostname_position] && pattern_position < pattern_length; pattern_position++, hostname_position++) + { + if( pattern[pattern_position] == '*' ) { + while( hostname[hostname_position] != '.' && hostname[hostname_position] != '\0' ) + hostname_position++; + + pattern_position++; + } + + if (hostname[hostname_position] != pattern[pattern_position] ) + { + return FALSE; + } + } + } + + if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.') + { + char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ]; + if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 ) + { + return TRUE; + } + } + + return FALSE; +} + BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) { int match; @@ -549,11 +599,8 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) if (common_name != NULL) { - if (strlen(hostname) == common_name_length) - { - if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0) - hostname_match = TRUE; - } + if (tls_match_hostname(common_name, common_name_length, hostname)) + hostname_match = TRUE; } /* compare against alternative names */ @@ -562,10 +609,10 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) { for (index = 0; index < alt_names_count; index++) { - if (strlen(hostname) == alt_names_lengths[index]) + if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname)) { - if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0) - hostname_match = TRUE; + hostname_match = TRUE; + break; } } } From cd548da226f1b87a2cd3c92e0f6d1223aaae71aa Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Jun 2013 21:26:35 +0200 Subject: [PATCH 16/74] Using the more efficient code for comparing host names --- libfreerdp/crypto/tls.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 705346224..46cf7ad79 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -527,30 +527,6 @@ BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname) return TRUE; } - /* ccpp: Check for wildcard certificates */ - if (memchr(pattern, '*', pattern_length) != NULL) - { - /* The wildcard matches one subdomain level (all except a dot) */ - - int pattern_position = 0; - int hostname_position = 0; - - for(; hostname[hostname_position] && pattern_position < pattern_length; pattern_position++, hostname_position++) - { - if( pattern[pattern_position] == '*' ) { - while( hostname[hostname_position] != '.' && hostname[hostname_position] != '\0' ) - hostname_position++; - - pattern_position++; - } - - if (hostname[hostname_position] != pattern[pattern_position] ) - { - return FALSE; - } - } - } - if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.') { char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ]; From 44f6f169533d4e6c748744d525f3833cb0596d6c Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Jun 2013 21:49:29 +0200 Subject: [PATCH 17/74] Fixed a possible buffer overflow issue --- libfreerdp/crypto/tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 46cf7ad79..a15be3ea4 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -527,7 +527,7 @@ BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname) return TRUE; } - if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.') + if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.' && strlen(hostname) >= pattern_length) { char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ]; if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 ) From 89f69aa9ba89600c5f0954a2dad6b1dfe693bcc8 Mon Sep 17 00:00:00 2001 From: Mike Gilbert Date: Mon, 17 Jun 2013 20:44:00 -0400 Subject: [PATCH 18/74] libfreerdp-gdi/test: Fix segfault in gdi_convert_postfix_to_infix. --- libfreerdp/gdi/test/TestGdiRop3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/gdi/test/TestGdiRop3.c b/libfreerdp/gdi/test/TestGdiRop3.c index 5dec672a7..f33d68feb 100644 --- a/libfreerdp/gdi/test/TestGdiRop3.c +++ b/libfreerdp/gdi/test/TestGdiRop3.c @@ -175,7 +175,7 @@ char* gdi_convert_postfix_to_infix(char* postfix) dl = al + bl + cl + 3; - d = malloc(cl + 1); + d = malloc(dl + 1); sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a); Stack_Push(stack, d); From edc34d4d0299c537c6264f89d475289141e75294 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 18 Jun 2013 12:29:30 +0200 Subject: [PATCH 19/74] directfb: print "unmaintained" build warning directfb client is currently unmaintained --- CMakeLists.txt | 5 +++++ docs/README.directfb | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 docs/README.directfb diff --git a/CMakeLists.txt b/CMakeLists.txt index ca6e154b0..8261c5428 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,6 +342,11 @@ endif() find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION}) find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION}) +if (${WITH_DIRECTFB}) + message(WARNING " +DIRECTFB is orphaned and not maintained see docs/README.directfb for details +") +endif() find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION}) find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION}) diff --git a/docs/README.directfb b/docs/README.directfb new file mode 100644 index 000000000..db72c0e85 --- /dev/null +++ b/docs/README.directfb @@ -0,0 +1,3 @@ +The dfreerdp FreeRDP client is currently orphaned and unmaintained so please don't expect it to build and work without problems. + +If you are interested to update and maintain the dfreerdp client please let us know. From 86ca8f9523ae1529a6e1c95ff08cad40a60dea5e Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 18 Jun 2013 14:33:07 +0200 Subject: [PATCH 20/74] codec: yCbCrToRGB did not get profiled anymore --- libfreerdp/codec/rfx_decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index 960096f1d..051a44b20 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -218,8 +218,10 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in, Stream_Seek(data_in, cr_size); } + PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb); prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16), pSrcDst, 64 * sizeof(INT16), &roi_64x64); + PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb); PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb); rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2], From bacc27229908298afd60d058d9d8a714755f3ab3 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 18 Jun 2013 15:39:13 +0200 Subject: [PATCH 21/74] xfreerdp-server: removed binary --- server/X11/cli/xfreerdp-server | Bin 10847 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 server/X11/cli/xfreerdp-server diff --git a/server/X11/cli/xfreerdp-server b/server/X11/cli/xfreerdp-server deleted file mode 100755 index 9e837526bcf2d214862ecced6059b2a82ddf5e02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10847 zcmeHNdvIITnLoOcZ8>%v=K&2#0CjOnV6bGT#<-yYIetW@N&<-kX(3$8(zUH1ORjWf zJ1pI%lfqODVNJ`hY};Yd>CU#(*D&oqvMfVG(;<{8GwEZy?1r7m!iKdW3}MMK-nQWV zednA{y1J5f(w*sl{Sw{pe82B;9{1ey^7-sQbkOj41d}0d5hOj;7?zNFLcUyz8tV~_ zA}rd(hebV*I{d;?LtLepFY3_D{o2k8?!&LgP(Y6nmI>w?6fBr?35ipFB?{}L;=gKE zB6A@E5+FY+>)GW}1Rs$J=5x9nPiW45B$D5v_FL3`%mv$P&h?|Z(QjDe!$ueq$zfum zUp`BmY>93^XD6huu7|HVEOF*HNJ$9h>~{zJsGOHdT+ZD(zgq1Q(B)^&?;(^*j&^s2 zQi=9dGM%4opY7>x@9qlbGQrKV-mNGI*>2ytR~CuFQ2Ey4M`d1vAN2v!Zw(*FUiS9V z*EXIT{>Ba0e*F4t2Y0+hx)%J%uK~Zg)49@sp3=B?vL-)VXI)B84@dFiz$-}vR*Ez8%u`XpRx z($}F`RYhx{GSzUqhW$rs*uPlA{(9g6{M__+0IKEtpEdAXfCun%)3zGrc?5>l;;#oD za0h|>sT%k&;Q+P`cj#+H5?mFSxQ$`qq8$rcILQcoAyN3iY0_gleT8ukSvWG zBsVuUp302IQf5A#OegIcN~yXlmb3>m**(ehc*@!}dcca?0*x}0Oi#(C=s;6!x9ox0 zq}`WESi`EMu!vJbb)%Umt($2wmP`xNO2q6K6r;JE!U3fdA~cbiv_i3&*nL)LJZY;` zJd;4qp+Qt(cmM4n)h3~Rot;}Q#T;4dHoGKqSt%MKWnv57(JmAa1u*kDD}fSI!MVt) zUh!PslZsl$QuoJG1G2kxBL!w#JCW{Nm)p2J9Y zy8~aw#^C!Lc#{K<96s-#KLa3g_$U68CB@Q>|5YClOB*lZx#H?DQY251!NS=k(8f1N zrlwdpE#+59rY2Z8A?1H1nX10cLOwGP+(7b_ zlz%`nRdrzma_3t^g`eLWDZCmv{2v!?A09e&f<~Iispn{bikvz{wR9Mv&$ zq;4ewL>@e08%w8UWygXmuKqmY2~O+JbCyDK!TlB&{QuuM?xi@Z&cuq$O&qsd#K_323lWpX|Uljdc)&7UJ{!d*% zi2TaE@SOiM6mT+kN_QyBMd%ivMGkN~HQz+w(Y^BoA|OF)9X>Z8tukK4sh^%KweVb|kZOB5T1d2= zjT~*CF#;lbbmIgu;PcUf-F6{bc%TiD?`gx^Io}h#?p$x-{h`8pk>}p`4i)}+e$V^J z|G~HH4V`DGeWHcmL<{fr7vAn&TJuWe@JUbPV{hi)h#a}64X--Y)*3yMXj>aaDiA$l zw{40Zd7!NWZ@mYNdkC*YynAwNPWB7k?L8O+JnOwTZ-S0GX*06x2S1M5q`>b%Gdv7_ z9{g{>Y28NTxqr9t%(i;gH#hj_@HMmnqqX{p-z_a20~al=gDq=sThTP*KO}Blck}fh zZTk~~$%f+hBfgxgds|u`GWwR+8;>E9ij#o;1?UUl;*N*w9;!E6!iO9F+<3%$)MxB# zp^t&eLFMW|xt!wdZ4Ci9V#52fu98?rcb4^;ZwN~q z-B!xn&KI=&eXUpCfB0u{AM48MBYOYet@)tlcWOSS`LyN_Y5ut8f33MItk~Yywt1cx=wD9)oWER$Gt^x7p)8LLfd;*L+MH4@dAGAxEE6_li_cmAiV! ze40j^Xll9z5K5<$cn7`}Kv8sJLuldp%Z0aPOViC#Xjl#5;}}-_LC>wt3ct2_Xf=fl z*FV0knchibUD3n97r(5lOcZ`9rZ`Jw^8B`CIiB)liz;*}i~Q1_AQVp}FKHX07W&C_ zJe5yaAt_ywUwKxcU{DC&9R}m{#%JtaXcU&)cfRq31=;VKK*r-)cJHSIi9u>0kWGN+avd; zA~C}oF;O&#PsFlR7*%+Y$mD7N`TMtQ$Whf;c04X}$@?v;ugFbgvUZ@DA(iO&4=)gN zT8yPKFD}2M9T5F@?b=Pt5JhNjNrsrAE+omPIj~kvKT*V{TRF`K4&kxXyYM`g{=P;zwIW(_BB!~xh z2bQlvg64kqA2z~}O6R-*DU}}Fbr|VH!s%}tVX3lpz&0tB9&Z1BsNTa`f%AXD2uou= zx4uV8rS+1#Pws>sV{ozji$)j{&bM{IDa~npMRjNYwPXak6F(Y&IDcM`$sH|lUVkAe z$=!bU0;RPN`}2C|`_w3)F2#!LJ+@^=3b|Nt6pcd zHY&GcW!`l5s)+ex5S{*fKKhjQ@8^bb`Dsyn#pTcEpBJf9fpi!p;OQ>^F<_K`@yxk7 z3<*Sy1#;W7%=}xhA%89=|6RnV{coTk4q`us=sex&-=XvG(EfkLhMM#HXZQpX^p4~t z49@!-{`-mB-Yx$OKD3u&f8PJh>kX9K-YrxAqVlspos1A&xJ3VdgDv$v_UH9K|9y)a zmis5?&;93h_&W3FbHhcd6o~DWRFWBg6AGulXdO|eIs+{!3{UoBei4|{pZ~5fqW!s? z9Dw~;{*8{w^{3-3qABg@ws-fRCD>B_9pvO7_NVd5Nn}gJoYohdRvPs@qw{yib=%TL zz>QIaCi-I-i1+JCsGW5_D@4&CG0{7r_+1>sr9Y-t+BUPf$AxZH& zT=-)ecb~g{8@R{O&isAw6E+}O$b=6UbX5==e-{E+taRoPUCR3 zc0jgO<9A5=wPM26-_&?t*>4B6J%{VTPz`<}(OfLAN$ zPqe-Jp2e>uURkksYvA>mZ>z<>tOhPZ`COL%vL70c$3wXFWOjGyD^NJ73E?Okhk5#c zg*KkGlfjIL$5JWBoeu#xXXnSpaPnuGxApBdqeFX!aTBC;;ls2i%{X28$O*pb;ec?R zAYgl@cq65nFuWDCP z^sNk+m*ehC Date: Tue, 18 Jun 2013 18:43:59 +0200 Subject: [PATCH 22/74] winpr: offset support in _aligned_offset_malloc Added support to handle offset parameter in _aligned_offset_ functions. fixes #1299 --- winpr/libwinpr/crt/alignment.c | 79 +++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/winpr/libwinpr/crt/alignment.c b/winpr/libwinpr/crt/alignment.c index 765b3d484..ddad782f5 100644 --- a/winpr/libwinpr/crt/alignment.c +++ b/winpr/libwinpr/crt/alignment.c @@ -35,32 +35,20 @@ #include #endif +struct _aligned_meminfo { + UINT32 size; + void *base_addr; +}; + + void* _aligned_malloc(size_t size, size_t alignment) { - void* memptr; - - /* alignment must be a power of 2 */ - - if (alignment % 2 == 1) - return NULL; - -#ifdef ANDROID - memptr = memalign(alignment, size); -#else - if (posix_memalign(&memptr, alignment, size) != 0) - return NULL; -#endif - - return memptr; + return _aligned_offset_malloc(size, alignment, 0); } void* _aligned_realloc(void* memblock, size_t size, size_t alignment) { - void* memptr = NULL; - - memptr = realloc(memblock, size); - - return memptr; + return _aligned_offset_realloc(memblock, size, alignment, 0); } void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment) @@ -70,36 +58,59 @@ void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignmen void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset) { - void* memptr; + void* memptr, *tmpptr; + struct _aligned_meminfo *ameminfo; /* alignment must be a power of 2 */ - if (alignment % 2 == 1) return NULL; /* offset must be less than size */ - if (offset >= size) return NULL; /* minimum alignment is pointer size */ - if (alignment < sizeof(void*)) alignment = sizeof(void*); -#ifdef ANDROID - memptr = memalign(alignment, size); -#else - if (posix_memalign(&memptr, alignment, size) != 0) + /* malloc size + alignment to make sure we can align afterwards */ + tmpptr = malloc(size + alignment + sizeof(struct _aligned_meminfo)); + if (!tmpptr) return NULL; -#endif + + + memptr = (void *)((((size_t)((PBYTE)tmpptr + alignment + offset + sizeof(struct _aligned_meminfo)) & ~(alignment - 1)) - offset)); + + ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo)))); + ameminfo->base_addr = tmpptr; + ameminfo->size = size; return memptr; } void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset) { - return NULL; + struct _aligned_meminfo *ameminfo; + void *newmem; + + if (!memblock) + return _aligned_offset_malloc(size, alignment, offset); + + if (size == 0) + { + _aligned_free(memblock); + return NULL; + } + /* The following is not very performant but a simple and working solution */ + newmem = _aligned_offset_malloc(size, alignment, offset); + + if (!newmem) + return NULL; + + ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo)))); + memcpy(newmem, memblock, ameminfo->size); + _aligned_free(memblock); + return newmem; } void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset) @@ -114,7 +125,13 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset) void _aligned_free(void* memblock) { - free(memblock); + struct _aligned_meminfo *ameminfo; + if (!memblock) + return; + + ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo)))); + + free(ameminfo->base_addr); } #endif From c95b5c49a6a14c5cdf26d0acc6a4944b1ab43fee Mon Sep 17 00:00:00 2001 From: Daniel Bungert Date: Wed, 19 Jun 2013 12:33:46 -0400 Subject: [PATCH 23/74] Assorted tsmf and gstreamer fixes: * tsmf audio volume fixes * The first audio volume message is received before everything is initialized. Cache this data until we're ready. * Handle the cases of gstreamer unitialized/partially ready/ fully ready. * Default to 50% as a fallback if the above fails. * Improved detection of the primary monitor. * Fix an unexpected shutdown when the server asks us to resize the media overlay to (width=0,height=0). * Permit multiple presentations - required for repeat of audio files and also is seen in some video cases. * Several leak fixes. * Fix logging related compile warnings and other usage of PRIu64. --- .../tsmf/client/gstreamer/tsmf_gstreamer.c | 42 +++++++++++-------- channels/tsmf/client/tsmf_ifman.c | 11 +++-- channels/tsmf/client/tsmf_media.c | 13 ++++++ 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c index 9e2c1674d..9ead22b81 100644 --- a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c +++ b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c @@ -669,7 +669,6 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder * decoder, TS_AM_MEDIA_TYPE * return FALSE; } - return TRUE; } @@ -1133,12 +1132,12 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) { - DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)", + DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")", start_time, end_time, duration, mdecoder->last_sample_end_time); } else { - DEBUG_DVC("tsmf_gstreamer_decodeEX_AUDIO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)", + DEBUG_DVC("tsmf_gstreamer_decodeEx_AUDIO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")", start_time, end_time, duration, mdecoder->last_sample_end_time); } @@ -1176,7 +1175,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U */ if (start_time > (mdecoder->last_sample_end_time + 10000000) || (end_time + 10000000) < mdecoder->last_sample_end_time) { - DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%llu] > last_sample_end_time=[%llu]", start_time, mdecoder->last_sample_end_time); + DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_end_time=[%"PRIu64"]", start_time, mdecoder->last_sample_end_time); DEBUG_DVC("tsmf_gstreamer_decodeEx: Stream seek detected - flushing element."); tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL); gst_object_unref(mdecoder->pipe); @@ -1205,7 +1204,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U if (fout) { - fprintf(fout, "%"PRIu64"\n", (long unsigned int) start_time); + fprintf(fout, "%"PRIu64"\n", start_time); fclose(fout); } @@ -1231,7 +1230,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U if (fin) { UINT64 AStartTime = 0; - fscanf(fin, "%"PRIu64, (long unsigned int*) &AStartTime); + fscanf(fin, "%"PRIu64, &AStartTime); fclose(fin); if (start_time > AStartTime) { @@ -1265,7 +1264,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U if (fin) { UINT64 VStartTime = 0; - fscanf(fin, "%"PRIu64, (long unsigned int*) &VStartTime); + fscanf(fin, "%"PRIu64, &VStartTime); fclose(fin); if (start_time > VStartTime) { @@ -1283,7 +1282,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U pthread_mutex_unlock(&mdecoder->gst_mutex); DEBUG_WARN("tsmf_gstreamer_decodeEx: gst_buffer_try_new_and_alloc(%d) failed.", data_size); return FALSE; - } + } gst_buffer_set_caps(gst_buf, mdecoder->gst_caps); memcpy(GST_BUFFER_MALLOCDATA(gst_buf), data, data_size); GST_BUFFER_TIMESTAMP(gst_buf) = tsmf_gstreamer_timestamp_ms_to_gst(start_time); @@ -1325,20 +1324,21 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder * decoder, UINT32 newVolum if (mdecoder->shutdown) return; - if (!mdecoder->aVolume) + if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) return; - if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) + mdecoder->gstMuted = (BOOL) muted; + DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted); + mdecoder->gstVolume = (double) newVolume / (double) 10000; + DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume); + + if (!mdecoder->aVolume) return; if (!G_IS_OBJECT(mdecoder->aVolume)) return; - mdecoder->gstMuted = (BOOL) muted; - DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted); g_object_set(mdecoder->aVolume, "mute", mdecoder->gstMuted, NULL); - mdecoder->gstVolume = (double) newVolume / (double) 10000; - DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume); g_object_set(mdecoder->aVolume, "volume", mdecoder->gstVolume, NULL); } @@ -1482,7 +1482,7 @@ static UINT64 tsmf_gstreamer_get_running_time(ITSMFDecoder * decoder) GstFormat fmt = GST_FORMAT_TIME; gint64 pos = 0; gst_element_query_position (mdecoder->outsink, &fmt, &pos); - DEBUG_DVC("tsmf_gstreamer_current_pos=[%llu]", pos); + DEBUG_DVC("tsmf_gstreamer_current_pos=[%"PRIu64"]", pos); return pos/100; } @@ -1524,13 +1524,14 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new { if (info->noutput > 0) { - if (info->outputs[0] == primary_output) + if (info->outputs[0] == primary_output || i == 0) { mdecoder->xOffset = info->x; mdecoder->yOffset = info->y; } DEBUG_DVC("output %d ID: %lu (x,y): (%d,%d) (w,h): (%d,%d) primary: %d", i, info->outputs[0], info->x, info->y, info->width, info->height, (info->outputs[0] == primary_output)); } + XRRFreeCrtcInfo(info); } } } @@ -1545,7 +1546,12 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new if(mdecoder->subwin) { XMoveWindow(mdecoder->disp, mdecoder->subwin, anewX, anewY); - XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight); + if(newWidth > 0 && newHeight > 0) { + XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight); + } else { + XResizeWindow(mdecoder->disp, mdecoder->subwin, 1, 1); + } + XSync(mdecoder->disp, FALSE); XShapeCombineRectangles (mdecoder->disp, mdecoder->subwin, ShapeBounding, 0, 0,(XRectangle*) rectangles, numRectangles, ShapeSet, Unsorted); XSync(mdecoder->disp, FALSE); @@ -1599,7 +1605,7 @@ ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void) decoder->xOffset = 0; decoder->yOffset = 0; decoder->offsetObtained = FALSE; - decoder->gstVolume = 1.0; + decoder->gstVolume = 0.5; decoder->gstMuted = FALSE; decoder->state = GST_STATE_VOID_PENDING; /* No real state yet */ pthread_mutex_init(&decoder->gst_mutex, NULL); diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 59059dbba..03229adb5 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -127,8 +127,6 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman) return 0; } -static TSMF_PRESENTATION* pexisted = 0; - int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman) { int status = 0; @@ -136,15 +134,16 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman) DEBUG_DVC(""); - if (pexisted) + presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (presentation) { + DEBUG_DVC("Presentation already exists"); ifman->output_pending = FALSE; return 0; } presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback); - pexisted = presentation; if (presentation == NULL) status = 1; @@ -283,8 +282,8 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) if (presentation) tsmf_presentation_free(presentation); - - pexisted = 0; + else + DEBUG_WARN("unknown presentation id"); Stream_EnsureRemainingCapacity(ifman->output, 4); Stream_Write_UINT32(ifman->output, 0); /* Result */ diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index d1449237e..f31175150 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -84,6 +84,9 @@ struct _TSMF_PRESENTATION UINT64 audio_start_time; UINT64 audio_end_time; + UINT32 volume; + UINT32 muted; + HANDLE mutex; HANDLE thread; @@ -282,6 +285,9 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal memcpy(presentation->presentation_id, guid, GUID_SIZE); presentation->channel_callback = pChannelCallback; + presentation->volume = 5000; /* 50% */ + presentation->muted = 0; + presentation->mutex = CreateMutex(NULL, FALSE, NULL); presentation->stream_list = list_new(); @@ -786,6 +792,9 @@ void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 ne LIST_ITEM* item; TSMF_STREAM* stream; + presentation->volume = newVolume; + presentation->muted = muted; + for (item = presentation->stream_list->head; item; item = item->next) { stream = (TSMF_STREAM*) item->data; @@ -964,7 +973,10 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id) stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL); stream->sample_list = Queue_New(TRUE, -1, -1); + stream->sample_list->object.fnObjectFree = free; + stream->sample_ack_list = Queue_New(TRUE, -1, -1); + stream->sample_ack_list->object.fnObjectFree = free; WaitForSingleObject(presentation->mutex, INFINITE); list_enqueue(presentation->stream_list, stream); @@ -1026,6 +1038,7 @@ void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s) stream->width = mediatype.Width; stream->height = mediatype.Height; stream->decoder = tsmf_load_decoder(name, &mediatype); + tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted); } void tsmf_stream_end(TSMF_STREAM* stream) From b0d69caee89c6bfce216a0233895683bdd15d02f Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 19 Jun 2013 19:07:31 +0200 Subject: [PATCH 24/74] winpr/alignment: use size_t instead of UINT32 --- winpr/libwinpr/crt/alignment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/crt/alignment.c b/winpr/libwinpr/crt/alignment.c index ddad782f5..1ee3d3850 100644 --- a/winpr/libwinpr/crt/alignment.c +++ b/winpr/libwinpr/crt/alignment.c @@ -36,7 +36,7 @@ #endif struct _aligned_meminfo { - UINT32 size; + size_t size; void *base_addr; }; From 6551815991d3e49ce15352f6149ebf0de1560a95 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 20 Jun 2013 12:10:01 +0800 Subject: [PATCH 25/74] libfreerdp-codec/rfx: fix a memory leak. --- libfreerdp/codec/rfx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 610654a0d..a8fbea20c 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -741,7 +741,10 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (context->priv->UseThreads) { for (i = 0; i < message->num_tiles; i++) + { WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); + CloseThreadpoolWork(work_objects[i]); + } free(work_objects); free(params); From 237c9e1975c7394eb88a5c402d5056a2c6e1d21e Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 20 Jun 2013 14:13:57 +0800 Subject: [PATCH 26/74] libfreerdp-common: add some null pointer checks. --- libfreerdp/common/settings.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 6bda2092e..944e83ef7 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1185,7 +1185,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + if (settings->instance) + { + IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + } return -1; } @@ -1821,7 +1824,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + if (settings->instance) + { + IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + } return 0; } @@ -1857,7 +1863,10 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + if (settings->instance) + { + IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + } return 0; } @@ -2189,7 +2198,10 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + if (settings->instance) + { + IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + } return 0; } From 3065523405dfef10aefc8817cb8e887abf9aaf90 Mon Sep 17 00:00:00 2001 From: byteboon Date: Thu, 20 Jun 2013 11:29:18 -0700 Subject: [PATCH 27/74] fixed incorrect size calculation --- libfreerdp/gdi/graphics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index dcc3c46e7..3bd5f2801 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -107,7 +107,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, rdpGdi* gdi; BOOL status; - size = width * height * (bpp + 7) / 8; + size = width * height * ((bpp + 7) / 8); if (bitmap->data == NULL) bitmap->data = (BYTE*) malloc(size); From 018ed7e09bc01a1f8894dd62c67b6532632dcd8d Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Fri, 21 Jun 2013 16:46:46 +0200 Subject: [PATCH 28/74] server/sample: fix for issue #1312 (mstsc protocol error) --- server/Sample/sfreerdp.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 637e634ba..afd83f4f8 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -41,6 +41,10 @@ #include "sfreerdp.h" +#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 0 +#define SAMPLE_SERVER_DEFAULT_WIDTH 1024 +#define SAMPLE_SERVER_DEFAULT_HEIGHT 768 + static char* test_pcap_file = NULL; static BOOL test_dump_rfx_realtime = TRUE; @@ -48,8 +52,8 @@ void test_peer_context_new(freerdp_peer* client, testPeerContext* context) { context->rfx_context = rfx_context_new(); context->rfx_context->mode = RLGR3; - context->rfx_context->width = client->settings->DesktopWidth; - context->rfx_context->height = client->settings->DesktopHeight; + context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH; + context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT; rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8); context->nsc_context = nsc_context_new(); @@ -473,6 +477,17 @@ BOOL tf_peer_post_connect(freerdp_peer* client) printf("Client requested desktop: %dx%dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth); +#if (SAMPLE_SERVER_USE_CLIENT_RESOLUTION == 1) + context->rfx_context->width = client->settings->DesktopWidth; + context->rfx_context->height = client->settings->DesktopHeight; + printf("Using resolution requested by client.\n"); +#else + client->settings->DesktopWidth = context->rfx_context->width; + client->settings->DesktopHeight = context->rfx_context->height; + printf("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight); + client->update->DesktopResize(client->update->context); +#endif + /* A real server should tag the peer as activated here and start sending updates in main loop. */ test_peer_load_icon(client); @@ -667,6 +682,8 @@ static void* test_peer_mainloop(void* arg) client->update->RefreshRect = tf_peer_refresh_rect; client->update->SuppressOutput = tf_peer_suppress_output; + client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */ + client->Initialize(client); context = (testPeerContext*) client->context; From 729814fabd2016aeb558457cfc53bffb95c3fef5 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Mon, 24 Jun 2013 18:02:21 +0200 Subject: [PATCH 29/74] sample server: support build on win32 --- server/CMakeLists.txt | 8 ++++---- server/Sample/sfreerdp.c | 42 +++++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 265706ba5..fed64d78c 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -19,11 +19,11 @@ add_subdirectory(common) -if(NOT WIN32) - if(WITH_SAMPLE) - add_subdirectory(Sample) - endif() +if(WITH_SAMPLE) + add_subdirectory(Sample) +endif() +if(NOT WIN32) if(WITH_X11) add_subdirectory(X11) endif() diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index afd83f4f8..952b7218f 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -26,14 +26,13 @@ #include #include #include -#include #include -#include #include #include #include +#include #include #include "sf_audin.h" @@ -41,7 +40,7 @@ #include "sfreerdp.h" -#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 0 +#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 1 #define SAMPLE_SERVER_DEFAULT_WIDTH 1024 #define SAMPLE_SERVER_DEFAULT_HEIGHT 768 @@ -569,9 +568,11 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) } else { - client->settings->DesktopWidth = 640; - client->settings->DesktopHeight = 480; + client->settings->DesktopWidth = SAMPLE_SERVER_DEFAULT_WIDTH; + client->settings->DesktopHeight = SAMPLE_SERVER_DEFAULT_HEIGHT; } + context->rfx_context->width = client->settings->DesktopWidth; + context->rfx_context->height = client->settings->DesktopHeight; update->DesktopResize(update->context); context->activated = FALSE; } @@ -698,7 +699,11 @@ static void* test_peer_mainloop(void* arg) printf("Failed to get FreeRDP file descriptor\n"); break; } + +#ifndef _WIN32 + /* winsock's select() only works with sockets ! */ WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount); +#endif max_fds = 0; FD_ZERO(&rfds_set); @@ -718,15 +723,27 @@ static void* test_peer_mainloop(void* arg) if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) { +#ifdef _WIN32 + /* error codes set by windows sockets are not made available through errno ! */ + int wsa_error = WSAGetLastError(); + if (!((wsa_error == WSAEWOULDBLOCK) || + (wsa_error == WSAEINPROGRESS) || + (wsa_error == WSAEINTR))) + { + printf("select failed (WSAGetLastError: %d)\n", wsa_error); + break; + } +#else /* these are not really errors */ if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - printf("select failed\n"); + printf("select failed (errno: %d)\n", errno); break; } +#endif } if (client->CheckFileDescriptor(client) != TRUE) @@ -747,10 +764,10 @@ static void* test_peer_mainloop(void* arg) static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { - pthread_t th; - - pthread_create(&th, 0, test_peer_mainloop, client); - pthread_detach(th); + HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL); + if (hThread != NULL) { + CloseHandle(hThread); + } } static void test_server_mainloop(freerdp_listener* instance) @@ -817,9 +834,6 @@ int main(int argc, char* argv[]) { freerdp_listener* instance; - /* Ignore SIGPIPE, otherwise an SSL_write failure could crash your server */ - signal(SIGPIPE, SIG_IGN); - instance = freerdp_listener_new(); instance->PeerAccepted = test_peer_accepted; @@ -831,12 +845,14 @@ int main(int argc, char* argv[]) test_dump_rfx_realtime = FALSE; /* Open the server socket and start listening. */ + freerdp_wsa_startup(); if (instance->Open(instance, NULL, 3389) && instance->OpenLocal(instance, "/tmp/tfreerdp-server.0")) { /* Entering the server main loop. In a real server the listener can be run in its own thread. */ test_server_mainloop(instance); } + freerdp_wsa_cleanup(); freerdp_listener_free(instance); From 786df03bb6a51647401a5a91c0f5af7e46dcbb5a Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 25 Jun 2013 16:33:40 +0200 Subject: [PATCH 30/74] libwinpr-synch: fix broken USleep (on WIN32) Also reduce CPU usage by reducing the max busy-looping time to 1ms --- winpr/libwinpr/synch/sleep.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/winpr/libwinpr/synch/sleep.c b/winpr/libwinpr/synch/sleep.c index 9eee1ef8d..096e24323 100644 --- a/winpr/libwinpr/synch/sleep.c +++ b/winpr/libwinpr/synch/sleep.c @@ -52,17 +52,23 @@ VOID USleep(DWORD dwMicroseconds) #ifndef _WIN32 usleep(dwMicroseconds); #else - UINT64 t1; - UINT64 t2; - UINT64 freq; + static LARGE_INTEGER freq = { 0, 0 }; + LARGE_INTEGER t1 = { 0, 0 }; + LARGE_INTEGER t2 = { 0, 0 }; - QueryPerformanceCounter((LARGE_INTEGER*) &t1); - QueryPerformanceCounter((LARGE_INTEGER*) &freq); + QueryPerformanceCounter(&t1); - do - { - QueryPerformanceCounter((LARGE_INTEGER*) &t2); + if (freq.QuadPart == 0) { + QueryPerformanceFrequency(&freq); } - while ((t2 - t1) < dwMicroseconds); + + // in order to save cpu cyles we use Sleep() for the large share ... + if (dwMicroseconds >= 1000) { + Sleep(dwMicroseconds/1000); + } + // ... and busy loop until all the requested micro seconds have passed + do { + QueryPerformanceCounter(&t2); + } while (((t2.QuadPart - t1.QuadPart)*1000000)/freq.QuadPart < dwMicroseconds); #endif } From 9df9c7d28a26e93deb59eddea597b2fff23fc9ce Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 25 Jun 2013 17:11:36 +0200 Subject: [PATCH 31/74] libfreerdp-utils/pcap: open pcap in binary mode Use 'b' in fopen's mode string to force binary (untranslated) mode when reading or writing the pcap file. This is required on WIN32 and maybe on other non POSIX conforming systems. This fixes the mstsc internal error disconnect followed by a crash of the sample server when latter is used to serve a pcap file on WIN32. --- libfreerdp/utils/pcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/utils/pcap.c b/libfreerdp/utils/pcap.c index 4f7f77952..52d912bf3 100644 --- a/libfreerdp/utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -158,7 +158,7 @@ rdpPcap* pcap_open(char* name, BOOL write) { rdpPcap* pcap; - FILE* pcap_fp = fopen(name, write ? "w+" : "r"); + FILE* pcap_fp = fopen(name, write ? "w+b" : "rb"); if (pcap_fp == NULL) { From 44034305d30b41482463ea1c0e376f1ec1d9c6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Tue, 25 Jun 2013 16:05:37 -0400 Subject: [PATCH 32/74] Fixed output path for MacFreeRDP framework deployment. MRDPView: replaced awakeFromNib with viewDidLoad --- client/Mac/CMakeLists.txt | 22 +++++++++++----------- client/Mac/MRDPView.m | 2 +- client/Mac/cli/AppDelegate.h | 4 ++-- client/Mac/cli/AppDelegate.m | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt index 78dfca32b..8b7ae739f 100755 --- a/client/Mac/CMakeLists.txt +++ b/client/Mac/CMakeLists.txt @@ -106,15 +106,15 @@ if (${BUILD_SHARED_LIBS}) add_custom_command(TARGET ${MODULE_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy "$" - "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$" + "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$" COMMENT "Copying ${LIB} to output directory" COMMAND install_name_tool -change "$" - "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" - "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}" + "@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$" + "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}" COMMENT Setting install name for ${LIB} COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$" - "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" - "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}") + "@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$" + "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}") endforeach() # Call install_name_tool to reassign the library install names in dependent libraries @@ -123,8 +123,8 @@ if (${BUILD_SHARED_LIBS}) # message("adding post-build dependency: ${LIB}") add_custom_command(TARGET ${MODULE_NAME} POST_BUILD COMMAND install_name_tool -change "$" - "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$" - "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$" + "@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$" + "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$" COMMENT Setting install name for ${LIB} in module ${DEST}) endforeach() endforeach() @@ -145,7 +145,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") # Make sure the 'Resources' Directory is correctly created before we build add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources) + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources) # Compile the .xib files using the 'ibtool' program with the destination being the app package foreach(xib ${${MODULE_NAME}_XIBS}) @@ -153,7 +153,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") add_custom_command (TARGET ${MODULE_NAME} POST_BUILD COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text - --compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib} + --compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources/${XIB_WE}.nib ${xib} COMMENT "Compiling ${xib}") endforeach() endif() @@ -162,13 +162,13 @@ endif() foreach(HEADER ${${MODULE_NAME}_HEADERS}) # message("adding post-build dependency: ${LIB}") add_custom_command(TARGET ${MODULE_NAME} POST_BUILD - COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/ + COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/ COMMENT Copying public header files to ${MODULE_NAME}) endforeach() # Copy the FreeRDP header files into the framework add_custom_command(TARGET ${MODULE_NAME} POST_BUILD - COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/freerdp + COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/freerdp COMMENT Copying FreeRDP header files to ${MODULE_NAME}) add_subdirectory(cli) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index fe516b543..5b951c4d3 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -201,7 +201,7 @@ struct rgba_data //TODO - Expose this code as a public method, because awakeFromNib // won't be called if the view is created dynamically -- (void) awakeFromNib +- (void) viewDidLoad { // store our window dimensions width = [self frame].size.width; diff --git a/client/Mac/cli/AppDelegate.h b/client/Mac/cli/AppDelegate.h index fe2671351..07cdd9732 100644 --- a/client/Mac/cli/AppDelegate.h +++ b/client/Mac/cli/AppDelegate.h @@ -7,8 +7,8 @@ // #import -#import -#import +#import +#import @interface AppDelegate : NSObject { diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m index 1eb3d13c1..d92222651 100644 --- a/client/Mac/cli/AppDelegate.m +++ b/client/Mac/cli/AppDelegate.m @@ -7,8 +7,8 @@ // #import "AppDelegate.h" -#import "MacFreeRDP-library/mfreerdp.h" -#import "MacFreeRDP-library/mf_client.h" +#import "MacFreeRDP/mfreerdp.h" +#import "MacFreeRDP/mf_client.h" @implementation AppDelegate From 03f2b7ea51ea900298da7f999e6f385dc5cad3bf Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 26 Jun 2013 14:35:49 +0200 Subject: [PATCH 33/74] client/x11: fixed incorrect size calculation xf_Bitmap_Decompress used the same calculation like gdi_Bitmap_Decompress see #1310 --- client/X11/xf_graphics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index da609790a..68ce1595b 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -134,7 +134,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, xfi = ((xfContext*) context)->xfi; - size = width * height * (bpp + 7) / 8; + size = width * height * ((bpp + 7) / 8); if (bitmap->data == NULL) bitmap->data = (BYTE*) malloc(size); From 77f8ca315eaf57e275ff0771924c575df37b07aa Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Wed, 26 Jun 2013 06:50:10 -0700 Subject: [PATCH 34/74] Android: various bug fixes to prevent NullPointerExceptions --- .../freerdpcore/presentation/SessionActivity.java | 9 ++++++++- .../freerdp/freerdpcore/utils/ClipboardManagerProxy.java | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java index 055b48b73..defaf9247 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java @@ -248,6 +248,9 @@ public class SessionActivity extends Activity { Log.v(TAG, "OnConnectionFailure"); + // remove pending move events + uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT); + if(progressDialog != null) { progressDialog.dismiss(); @@ -264,7 +267,10 @@ public class SessionActivity extends Activity private void OnDisconnected(Context context) { Log.v(TAG, "OnDisconnected"); - + + // remove pending move events + uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT); + if(progressDialog != null) { progressDialog.dismiss(); @@ -434,6 +440,7 @@ public class SessionActivity extends Activity keyboardMapper = new KeyboardMapper(); keyboardMapper.init(this); + keyboardMapper.reset(this); modifiersKeyboard = new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard); specialkeysKeyboard = new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java index 83f6ca562..06b800a80 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/ClipboardManagerProxy.java @@ -65,7 +65,9 @@ public abstract class ClipboardManagerProxy { String data = null; if (clip != null && clip.getItemCount() > 0) { - data = clip.getItemAt(0).getText().toString(); + CharSequence cs = clip.getItemAt(0).getText(); + if (cs != null) + data = cs.toString(); } if (mListener != null) { mListener.onClipboardChanged(data); From ed4a25d1ae4f056931da399fe403109daae6fc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Wed, 26 Jun 2013 13:45:12 -0400 Subject: [PATCH 35/74] WaykClient (Mac): integrated MRDPView (allocated at runtime) --- client/Mac/MRDPView.h | 2 ++ client/Mac/MRDPView.m | 50 +++++++++++++++++++++++------------------- client/Mac/mf_client.m | 15 +++++++++++++ client/Mac/mfreerdp.h | 1 + 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h index 2cc67c2d4..cd4d06b03 100755 --- a/client/Mac/MRDPView.h +++ b/client/Mac/MRDPView.h @@ -78,6 +78,8 @@ int kdlmeta; int kdrmeta; int kdcapslock; + + BOOL initialized; @public NSPasteboard* pasteboard_rd; /* for reading from clipboard */ diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 5b951c4d3..d4020679f 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -129,11 +129,12 @@ struct rgba_data rdpSettings* settings; EmbedWindowEventArgs e; + [self initializeView]; + context = rdp_context; mfc = (mfContext*) rdp_context; instance = context->instance; settings = context->settings; - mfc->view = self; EventArgsInit(&e, "mfreerdp"); e.embed = TRUE; @@ -185,7 +186,7 @@ struct rgba_data - (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; + self = [super initWithFrame:frame]; if (self) { @@ -203,22 +204,32 @@ struct rgba_data // won't be called if the view is created dynamically - (void) viewDidLoad { - // store our window dimensions - width = [self frame].size.width; - height = [self frame].size.height; - titleBarHeight = 22; - - [[self window] becomeFirstResponder]; - [[self window] setAcceptsMouseMovedEvents:YES]; - - cursors = [[NSMutableArray alloc] initWithCapacity:10]; + [self initializeView]; +} - // setup a mouse tracking area - NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil]; - - [self addTrackingArea:trackingArea]; - - mouseInClientArea = YES; +- (void) initializeView +{ + if (!initialized) + { + // store our window dimensions + width = [self frame].size.width; + height = [self frame].size.height; + titleBarHeight = 22; + + [[self window] becomeFirstResponder]; + [[self window] setAcceptsMouseMovedEvents:YES]; + + cursors = [[NSMutableArray alloc] initWithCapacity:10]; + + // setup a mouse tracking area + NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil]; + + [self addTrackingArea:trackingArea]; + + mouseInClientArea = YES; + + initialized = YES; + } } /** ********************************************************************* @@ -619,11 +630,6 @@ struct rgba_data if (run_loop_src_channels != 0) CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_channels, kCFRunLoopDefaultMode); - - freerdp_client_stop(self->context); - - freerdp_client_context_free(self->context); - } /** ********************************************************************* diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m index 20aa3ce01..7913a4ee9 100755 --- a/client/Mac/mf_client.m +++ b/client/Mac/mf_client.m @@ -25,6 +25,7 @@ #include #include #include +#import "MRDPView.h" /** * Client Interface @@ -46,6 +47,13 @@ int mfreerdp_client_start(rdpContext* context) MRDPView* view; mfContext* mfc = (mfContext*) context; + if (mfc->view == NULL) + { + // view not specified beforehand. Create view dynamically + mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, 300, 300)]; + mfc->view_ownership = TRUE; + } + view = (MRDPView*) mfc->view; [view rdpStart:context]; @@ -74,6 +82,13 @@ int mfreerdp_client_stop(rdpContext* context) mfc->disconnect = TRUE; } + if (mfc->view_ownership) + { + MRDPView* view = (MRDPView*) view; + [view releaseResources]; + [view release]; + } + return 0; } diff --git a/client/Mac/mfreerdp.h b/client/Mac/mfreerdp.h index 02b0272e2..ff3bd6176 100644 --- a/client/Mac/mfreerdp.h +++ b/client/Mac/mfreerdp.h @@ -28,6 +28,7 @@ struct mf_context DEFINE_RDP_CLIENT_COMMON(); void* view; + BOOL view_ownership; // TRUE indicates that the window was created and should be freed by the API. int width; int height; From 77f5994e1c6d364ba3938ceafbc291edd455a678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Jun 2013 18:12:01 -0400 Subject: [PATCH 36/74] winpr: add _WINRT platform detection macro --- winpr/include/winpr/platform.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/winpr/include/winpr/platform.h b/winpr/include/winpr/platform.h index 63d1328b1..f178b0c95 100644 --- a/winpr/include/winpr/platform.h +++ b/winpr/include/winpr/platform.h @@ -128,6 +128,22 @@ /* Windows (_WIN32) */ +/* WinRT (_WINRT) */ + +#if defined(WINAPI_FAMILY) +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#ifndef _WINRT +#define _WINRT 1 +#endif +#endif +#endif + +#if defined(__cplusplus_winrt) +#ifndef _WINRT +#define _WINRT 1 +#endif +#endif + /* Linux (__linux__) */ #if defined(linux) || defined(__linux) From aa4ce5ee4b4a7310b5bac9c216cd25538770a8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Jun 2013 18:49:01 -0400 Subject: [PATCH 37/74] freerdp: add more settings for window panning and scaling --- include/freerdp/settings.h | 18 ++++++- libfreerdp/common/settings.c | 98 ++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index eb3541cf2..b6f34e6f7 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -609,6 +609,9 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_WmClass 1549 #define FreeRDP_EmbeddedWindow 1550 #define FreeRDP_SmartSizing 1551 +#define FreeRDP_XPan 1552 +#define FreeRDP_YPan 1553 +#define FreeRDP_ScalingFactor 1554 #define FreeRDP_SoftwareGdi 1601 #define FreeRDP_LocalConnection 1602 #define FreeRDP_AuthenticationOnly 1603 @@ -677,6 +680,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_UnicodeInput 2629 #define FreeRDP_FastPathInput 2630 #define FreeRDP_MultiTouchInput 2631 +#define FreeRDP_MultiTouchGestures 2632 #define FreeRDP_BrushSupportLevel 2688 #define FreeRDP_GlyphSupportLevel 2752 #define FreeRDP_GlyphCache 2753 @@ -976,7 +980,10 @@ struct rdp_settings ALIGN64 char* WmClass; /* 1549 */ ALIGN64 BOOL EmbeddedWindow; /* 1550 */ ALIGN64 BOOL SmartSizing; /* 1551 */ - UINT64 padding1600[1600 - 1552]; /* 1552 */ + ALIGN64 int XPan; /* 1552 */ + ALIGN64 int YPan; /* 1553 */ + ALIGN64 double ScalingFactor; /* 1554 */ + UINT64 padding1600[1600 - 1555]; /* 1555 */ /* Miscellaneous */ ALIGN64 BOOL SoftwareGdi; /* 1601 */ @@ -1101,7 +1108,8 @@ struct rdp_settings ALIGN64 BOOL UnicodeInput; /* 2629 */ ALIGN64 BOOL FastPathInput; /* 2630 */ ALIGN64 BOOL MultiTouchInput; /* 2631 */ - UINT64 padding2688[2688 - 2632]; /* 2632 */ + ALIGN64 BOOL MultiTouchGestures; /* 2632 */ + UINT64 padding2688[2688 - 2633]; /* 2633 */ /* Brush Capabilities */ ALIGN64 UINT32 BrushSupportLevel; /* 2688 */ @@ -1310,6 +1318,9 @@ FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings); FREERDP_API BOOL freerdp_get_param_bool(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param); +FREERDP_API int freerdp_get_param_int(rdpSettings* settings, int id); +FREERDP_API int freerdp_set_param_int(rdpSettings* settings, int id, int param); + FREERDP_API UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param); @@ -1319,6 +1330,9 @@ FREERDP_API int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 p FREERDP_API char* freerdp_get_param_string(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, char* param); +FREERDP_API double freerdp_get_param_double(rdpSettings* settings, int id); +FREERDP_API int freerdp_set_param_double(rdpSettings* settings, int id, double param); + #ifdef __cplusplus } #endif diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index c85f2a120..e99066b15 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -658,6 +658,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->MultiTouchInput; break; + case FreeRDP_MultiTouchGestures: + return settings->MultiTouchGestures; + break; + case FreeRDP_SoundBeepsEnabled: return settings->SoundBeepsEnabled; break; @@ -1109,6 +1113,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->MultiTouchInput = param; break; + case FreeRDP_MultiTouchGestures: + settings->MultiTouchGestures = param; + break; + case FreeRDP_SoundBeepsEnabled: settings->SoundBeepsEnabled = param; break; @@ -1204,6 +1212,55 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) return -1; } +int freerdp_get_param_int(rdpSettings* settings, int id) +{ + switch (id) + { + case FreeRDP_XPan: + return settings->XPan; + break; + + case FreeRDP_YPan: + return settings->YPan; + break; + + default: + return 0; + break; + } + + return 0; +} + +int freerdp_set_param_int(rdpSettings* settings, int id, int param) +{ + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + + switch (id) + { + case FreeRDP_XPan: + settings->XPan = param; + break; + + case FreeRDP_YPan: + settings->YPan = param; + break; + + default: + return -1; + break; + } + + settings->settings_modified[id] = 1; + + EventArgsInit(&e, "freerdp"); + e.id = id; + PubSub_OnParamChange(context->pubSub, context->instance, &e); + + return 0; +} + UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) { switch (id) @@ -2225,3 +2282,44 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param) return 0; } + +double freerdp_get_param_double(rdpSettings* settings, int id) +{ + switch (id) + { + case FreeRDP_ScalingFactor: + return settings->ScalingFactor; + break; + + default: + return 0; + break; + } + + return 0; +} + +int freerdp_set_param_double(rdpSettings* settings, int id, double param) +{ + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + + switch (id) + { + case FreeRDP_ScalingFactor: + settings->ScalingFactor = param; + break; + + default: + return -1; + break; + } + + settings->settings_modified[id] = 1; + + EventArgsInit(&e, "freerdp"); + e.id = id; + PubSub_OnParamChange(context->pubSub, context->instance, &e); + + return 0; +} From c8a09f3f768b04163add55c823deb9ed6c99b31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Jun 2013 18:57:16 -0400 Subject: [PATCH 38/74] xfreerdp: add ParamChange event handler --- client/X11/xf_client.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 7e958feeb..1bc990262 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1520,6 +1520,18 @@ void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e) } } +void xf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e) +{ + switch (e->id) + { + case FreeRDP_ScalingFactor: + break; + + default: + break; + } +} + /** * Client Interface */ @@ -1643,6 +1655,7 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context) settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler); + PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler); return 0; } From aca13e5eac36cd86c53799ac1ca00c884dcd090e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Jun 2013 19:05:44 -0400 Subject: [PATCH 39/74] freerdp: add new events for scaling and panning changes --- include/freerdp/event.h | 9 +++++++++ libfreerdp/core/freerdp.c | 2 ++ 2 files changed, 11 insertions(+) diff --git a/include/freerdp/event.h b/include/freerdp/event.h index 7753e133d..a41fe0a60 100644 --- a/include/freerdp/event.h +++ b/include/freerdp/event.h @@ -47,6 +47,15 @@ DEFINE_EVENT_BEGIN(EmbedWindow) void* handle; DEFINE_EVENT_END(EmbedWindow) +DEFINE_EVENT_BEGIN(PanningChange) + int XPan; + int YPan; +DEFINE_EVENT_END(PanningChange) + +DEFINE_EVENT_BEGIN(ScalingFactorChange) + double ScalingFactor; +DEFINE_EVENT_END(ScalingFactorChange) + DEFINE_EVENT_BEGIN(ErrorInfo) UINT32 code; DEFINE_EVENT_END(ErrorInfo) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 3c77b8e05..7d0c3c0ba 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -323,6 +323,8 @@ static wEventType FreeRDP_Events[] = DEFINE_EVENT_ENTRY(WindowStateChange) DEFINE_EVENT_ENTRY(ResizeWindow) DEFINE_EVENT_ENTRY(EmbedWindow) + DEFINE_EVENT_ENTRY(PanningChange) + DEFINE_EVENT_ENTRY(ScalingFactorChange) DEFINE_EVENT_ENTRY(ErrorInfo) DEFINE_EVENT_ENTRY(ParamChange) DEFINE_EVENT_ENTRY(Terminate) From b2108839b0d58281037133b896f0fac2ffe189d4 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 27 Jun 2013 13:00:54 +0200 Subject: [PATCH 40/74] utils: fix broken stopwatch implementation Stopwatch (in the way it is used) must be able to measure the wall clock time with high resolution but used clock() which is not appropriate for this purpose: On POSIX systems clock() returns the processor time used by the program. On Windows clock() does measure the wall clock time but has only a resolution of 1ms (if at all). This also renders the freerdp profiler unusable. This commit changes stopwatch to use the performance counters on Windows and gettimeofday() for the rest. Also added a warning about invalid profiling results to the RemoteFX codec if rfxcontext->priv->UseThreads is enabled because stopwatch is currently not used in a thread safe way. Also see GitHub Issue #1325 --- include/freerdp/utils/stopwatch.h | 10 +++---- libfreerdp/codec/rfx.c | 1 + libfreerdp/utils/stopwatch.c | 44 ++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/include/freerdp/utils/stopwatch.h b/include/freerdp/utils/stopwatch.h index 843d1bd12..af6aa1ee3 100644 --- a/include/freerdp/utils/stopwatch.h +++ b/include/freerdp/utils/stopwatch.h @@ -20,17 +20,15 @@ #ifndef FREERDP_UTILS_STOPWATCH_H #define FREERDP_UTILS_STOPWATCH_H -#include - #include #include struct _STOPWATCH { - clock_t start; - clock_t end; - double elapsed; - clock_t count; + UINT64 start; + UINT64 end; + UINT64 elapsed; + UINT32 count; }; typedef struct _STOPWATCH STOPWATCH; diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index a8fbea20c..f12547ce2 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -259,6 +259,7 @@ void rfx_context_free(RFX_CONTEXT* context) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); + IF_PROFILER (fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");) } BufferPool_Free(context->priv->BufferPool); diff --git a/libfreerdp/utils/stopwatch.c b/libfreerdp/utils/stopwatch.c index a9ffd6bb6..fb1c5c161 100644 --- a/libfreerdp/utils/stopwatch.c +++ b/libfreerdp/utils/stopwatch.c @@ -26,9 +26,33 @@ #include +#ifdef _WIN32 +LARGE_INTEGER stopwatch_freq = { 0, 0 }; +#else +#include +#endif + +void stopwatch_set_time(UINT64* usecs) +{ +#ifdef _WIN32 + LARGE_INTEGER perfcount; + QueryPerformanceCounter(&perfcount); + *usecs = (perfcount.QuadPart * 1000000) / stopwatch_freq.QuadPart; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + *usecs = tv.tv_sec * 1000000 + tv.tv_usec; +#endif +} + STOPWATCH* stopwatch_create() { STOPWATCH* sw; +#ifdef _WIN32 + if (stopwatch_freq.QuadPart == 0) { + QueryPerformanceFrequency(&stopwatch_freq); + } +#endif sw = (STOPWATCH*) malloc(sizeof(STOPWATCH)); stopwatch_reset(sw); @@ -43,13 +67,13 @@ void stopwatch_free(STOPWATCH* stopwatch) void stopwatch_start(STOPWATCH* stopwatch) { - stopwatch->start = clock(); + stopwatch_set_time(&stopwatch->start); stopwatch->count++; } void stopwatch_stop(STOPWATCH* stopwatch) { - stopwatch->end = clock(); + stopwatch_set_time(&stopwatch->end); stopwatch->elapsed += (stopwatch->end - stopwatch->start); } @@ -63,22 +87,12 @@ void stopwatch_reset(STOPWATCH* stopwatch) double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch) { - return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC; + return (stopwatch->elapsed/1000000.0); } void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, UINT32* sec, UINT32* usec) { - double uelapsed; - double clocks_per_usec; - - *sec = ((UINT32) stopwatch->elapsed) / CLOCKS_PER_SEC; - uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC); - - clocks_per_usec = (CLOCKS_PER_SEC / 1000000); - - if (clocks_per_usec > 0.0) - *usec = (UINT32)(uelapsed / clocks_per_usec); - else - *usec = 0; + *sec = stopwatch->elapsed / 1000000; + *usec = stopwatch->elapsed % 1000000; } From 40976a91b7849671ec30286b91d5bdba9226f465 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 27 Jun 2013 13:43:29 +0200 Subject: [PATCH 41/74] utils/profiler: fix unix build --- libfreerdp/codec/rfx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index f12547ce2..cfcfeeac7 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -259,7 +259,9 @@ void rfx_context_free(RFX_CONTEXT* context) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); - IF_PROFILER (fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");) +#ifdef WITH_PROFILER + fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); +#endif } BufferPool_Free(context->priv->BufferPool); From 0f24f6490e1d7a141ac786ed683aab0144487d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Thu, 27 Jun 2013 11:22:15 -0400 Subject: [PATCH 42/74] MacFreeRDP - Replaced MRDPView instance in NIB with instance allocated by the API. --- client/Mac/cli/AppDelegate.h | 1 - client/Mac/cli/AppDelegate.m | 23 ++++- client/Mac/cli/MainMenu.xib | 180 ++--------------------------------- client/Mac/mf_client.m | 17 +++- 4 files changed, 41 insertions(+), 180 deletions(-) diff --git a/client/Mac/cli/AppDelegate.h b/client/Mac/cli/AppDelegate.h index 07cdd9732..2ce5ca858 100644 --- a/client/Mac/cli/AppDelegate.h +++ b/client/Mac/cli/AppDelegate.h @@ -20,6 +20,5 @@ @property (assign) IBOutlet NSWindow *window; @property (assign) rdpContext *context; -@property (assign) IBOutlet MRDPView *mrdpView; @end diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m index d92222651..6c53f4805 100644 --- a/client/Mac/cli/AppDelegate.m +++ b/client/Mac/cli/AppDelegate.m @@ -10,6 +10,10 @@ #import "MacFreeRDP/mfreerdp.h" #import "MacFreeRDP/mf_client.h" +static AppDelegate* _singleDelegate = nil; +void AppDelegate_EmbedWindowEventHandler(rdpContext* context, EmbedWindowEventArgs* e); + + @implementation AppDelegate - (void)dealloc @@ -19,7 +23,6 @@ @synthesize window = window; -@synthesize mrdpView = mrdpView; @synthesize context = context; @@ -28,6 +31,7 @@ int status; mfContext* mfc; + _singleDelegate = self; [self CreateContext]; status = [self ParseCommandLineArguments]; @@ -41,6 +45,7 @@ } else { + PubSub_Subscribe(context->pubSub, "EmbedWindow", (pEventHandler) AppDelegate_EmbedWindowEventHandler); freerdp_client_start(context); } } @@ -48,6 +53,7 @@ - (void) applicationWillTerminate:(NSNotification*)notification { [mrdpView releaseResources]; + _singleDelegate = nil; } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender @@ -103,4 +109,19 @@ context = nil; } + @end + +void AppDelegate_EmbedWindowEventHandler(rdpContext* context, EmbedWindowEventArgs* e) +{ + if (_singleDelegate) + { + mfContext* mfc = (mfContext*) context; + _singleDelegate->mrdpView = mfc->view; + + if (_singleDelegate->window) + { + [[_singleDelegate->window contentView] addSubview:mfc->view]; + } + } +} \ No newline at end of file diff --git a/client/Mac/cli/MainMenu.xib b/client/Mac/cli/MainMenu.xib index 90e992462..65e72b118 100755 --- a/client/Mac/cli/MainMenu.xib +++ b/client/Mac/cli/MainMenu.xib @@ -2,18 +2,16 @@ 1070 - 12D78 + 12E55 3084 - 1187.37 + 1187.39 626.00 com.apple.InterfaceBuilder.CocoaPlugin 3084 - IBNSLayoutConstraint NSCustomObject - NSCustomView NSMenu NSMenuItem NSView @@ -257,24 +255,12 @@ 256 - - - - 268 - {1024, 768} - - - - _NS:9 - MRDPView - - + {1024, 768} - - + - {{0, 0}, {1440, 878}} + {{0, 0}, {1920, 1178}} {1024, 790} {1024, 790} 128 @@ -369,14 +355,6 @@ 493 - - - mrdpView - - - - 569 - window @@ -551,73 +529,7 @@ 372 - - - - - 6 - 0 - - 6 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 4 - 0 - - 4 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 3 - 0 - - 3 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - + @@ -657,31 +569,6 @@ - - 551 - - - - - 561 - - - - - 562 - - - - - 563 - - - - - 564 - - - @@ -706,12 +593,6 @@ com.apple.InterfaceBuilder.CocoaPlugin {{380, 496}, {480, 360}} - - - - - - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -720,13 +601,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -738,48 +613,7 @@ 570 - - - - AppDelegate - NSObject - - MRDPView - NSWindow - - - - mrdpView - MRDPView - - - window - NSWindow - - - - IBProjectSource - ./Classes/AppDelegate.h - - - - MRDPView - NSView - - IBProjectSource - ./Classes/MRDPView.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - + 0 IBCocoaFramework diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m index 7913a4ee9..a88309184 100755 --- a/client/Mac/mf_client.m +++ b/client/Mac/mf_client.m @@ -50,7 +50,7 @@ int mfreerdp_client_start(rdpContext* context) if (mfc->view == NULL) { // view not specified beforehand. Create view dynamically - mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, 300, 300)]; + mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)]; mfc->view_ownership = TRUE; } @@ -68,15 +68,21 @@ int mfreerdp_client_stop(rdpContext* context) { wMessageQueue* queue; queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE); - MessageQueue_PostQuit(queue, 0); + if (queue) + { + MessageQueue_PostQuit(queue, 0); + } } if (context->settings->AsyncInput) { wMessageQueue* queue; queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE); - MessageQueue_PostQuit(queue, 0); - } + if (queue) + { + MessageQueue_PostQuit(queue, 0); + } + } else { mfc->disconnect = TRUE; @@ -84,9 +90,10 @@ int mfreerdp_client_stop(rdpContext* context) if (mfc->view_ownership) { - MRDPView* view = (MRDPView*) view; + MRDPView* view = (MRDPView*) mfc->view; [view releaseResources]; [view release]; + mfc->view = nil; } return 0; From 3fbc4f899ff8022b5b866a609f77b805565825d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 27 Jun 2013 14:16:50 -0400 Subject: [PATCH 43/74] libwinpr-utils: fix deadlock in PubSub --- winpr/libwinpr/utils/collections/PubSub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winpr/libwinpr/utils/collections/PubSub.c b/winpr/libwinpr/utils/collections/PubSub.c index 160a0ddf0..1236d6858 100644 --- a/winpr/libwinpr/utils/collections/PubSub.c +++ b/winpr/libwinpr/utils/collections/PubSub.c @@ -167,6 +167,9 @@ int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEvent event = PubSub_FindEventType(pubSub, EventName); + if (pubSub->synchronized) + PubSub_Unlock(pubSub); + if (event) { status = 0; @@ -181,9 +184,6 @@ int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEvent } } - if (pubSub->synchronized) - PubSub_Unlock(pubSub); - return status; } From 1d0a579590c387a00964b7d7fe8538ce82146586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 27 Jun 2013 15:39:56 -0400 Subject: [PATCH 44/74] freerdp-client: use 32bpp with NSCodec --- client/common/cmdline.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 06514b59a..e53b5212c 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1426,6 +1426,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin CommandLineSwitchCase(arg, "nsc") { settings->NSCodec = TRUE; + settings->ColorDepth = 32; } CommandLineSwitchCase(arg, "jpeg") { From 1c2506f937c62b7cfab155417de30d236b7cbfc6 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Fri, 28 Jun 2013 15:17:37 +0200 Subject: [PATCH 45/74] pointer cache: fixed double free --- libfreerdp/cache/pointer.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libfreerdp/cache/pointer.c b/libfreerdp/cache/pointer.c index 484c2985b..57bc3a4ef 100644 --- a/libfreerdp/cache/pointer.c +++ b/libfreerdp/cache/pointer.c @@ -68,9 +68,18 @@ void update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_col pointer->height = pointer_color->height; pointer->lengthAndMask = pointer_color->lengthAndMask; pointer->lengthXorMask = pointer_color->lengthXorMask; - pointer->xorMaskData = pointer_color->xorMaskData; - pointer->andMaskData = pointer_color->andMaskData; + if (pointer->lengthAndMask && pointer_color->xorMaskData) + { + pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask); + CopyMemory(pointer->andMaskData, pointer_color->andMaskData, pointer->lengthAndMask); + } + + if (pointer->lengthXorMask && pointer_color->xorMaskData) + { + pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask); + CopyMemory(pointer->xorMaskData, pointer_color->xorMaskData, pointer->lengthXorMask); + } pointer->New(context, pointer); pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer); Pointer_Set(context, pointer); @@ -202,7 +211,10 @@ void pointer_cache_free(rdpPointerCache* pointer_cache) pointer = pointer_cache->entries[i]; if (pointer != NULL) + { Pointer_Free(pointer_cache->update->context, pointer); + pointer_cache->entries[i] = NULL; + } } free(pointer_cache->entries); From 554268674c673f84da5bc8ebdfadd7613ab1bdf3 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Fri, 28 Jun 2013 15:18:20 +0200 Subject: [PATCH 46/74] cache and core: set pointer to NULL after free --- libfreerdp/cache/glyph.c | 2 ++ libfreerdp/core/freerdp.c | 5 +++++ libfreerdp/core/graphics.c | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index 847ac3849..14f2f69dd 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -500,6 +500,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache) Glyph_Free(glyph_cache->context, glyph); free(glyph->aj); free(glyph); + glyph_cache->glyphCache[i].entries[j] = NULL; } } free(glyph_cache->glyphCache[i].entries); @@ -509,6 +510,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache) { fragment = glyph_cache->fragCache.entries[i].fragment; free(fragment); + glyph_cache->fragCache.entries[i].fragment = NULL; } free(glyph_cache->fragCache.entries); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 51e0158ef..8e06a7c7b 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -31,6 +31,7 @@ #include "message.h" #include +#include #include #include @@ -372,9 +373,13 @@ void freerdp_context_free(freerdp* instance) IFCALL(instance->ContextFree, instance, instance->context); rdp_free(instance->context->rdp); + instance->context->rdp = NULL; + graphics_free(instance->context->graphics); + instance->context->graphics = NULL; free(instance->context->client); + instance->context->client = NULL; free(instance->context); instance->context = NULL; diff --git a/libfreerdp/core/graphics.c b/libfreerdp/core/graphics.c index 18b6d05cb..218f10c60 100644 --- a/libfreerdp/core/graphics.c +++ b/libfreerdp/core/graphics.c @@ -117,10 +117,16 @@ void Pointer_Free(rdpContext* context, rdpPointer* pointer) pointer->Free(context, pointer); if (pointer->xorMaskData) + { free(pointer->xorMaskData); + pointer->xorMaskData = NULL; + } if (pointer->andMaskData) + { free(pointer->andMaskData); + pointer->andMaskData = NULL; + } free(pointer); } From c084e0f8aea86bce8e628ae15c2412c8666f6a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 28 Jun 2013 13:46:58 -0400 Subject: [PATCH 47/74] xfreerdp: improve selection between multitouch and non-multitouch devices with XInput 2 --- client/X11/xf_event.c | 10 ++++++++++ client/X11/xf_input.c | 12 +++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index bf64b63b4..d59898a23 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -176,6 +176,9 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app) { + if (xfc->use_xinput) + return TRUE; + return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y, event->xmotion.state, event->xmotion.window, app); } @@ -278,6 +281,9 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app) { + if (xfc->use_xinput) + return TRUE; + return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y, event->xbutton.button, event->xbutton.window, app); } @@ -290,6 +296,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w rdpInput* input; Window childWindow; + flags = 0; wheel = FALSE; extended = FALSE; @@ -361,6 +368,9 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app) { + if (xfc->use_xinput) + return TRUE; + return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y, event->xbutton.button, event->xbutton.window, app); } diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index 4b7309821..cbc260608 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -163,8 +163,11 @@ int xf_input_init(xfContext* xfc, Window window) if (xfc->use_xinput) { - if (!touch && (class->type == XIButtonClass)) + if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer")) { + printf("%s button device (id: %d, mode: %d)\n", + dev->name, + dev->deviceid, t->mode); XISetMask(masks[nmasks], XI_ButtonPress); XISetMask(masks[nmasks], XI_ButtonRelease); XISetMask(masks[nmasks], XI_Motion); @@ -419,24 +422,23 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype) int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype) { - return TRUE; switch (evtype) { case XI_ButtonPress: - printf("ButtonPress\n"); + //printf("ButtonPress\n"); xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y, event->detail, event->event, xfc->remote_app); break; case XI_ButtonRelease: - printf("ButtonRelease\n"); + //printf("ButtonRelease\n"); xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y, event->detail, event->event, xfc->remote_app); break; case XI_Motion: - printf("Motion\n"); + //printf("Motion\n"); xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y, event->detail, event->event, xfc->remote_app); break; From 87e9a24b1e0204aca4206fdc1ce75fe55a3eb580 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 1 Jul 2013 19:07:35 +0200 Subject: [PATCH 48/74] tls: updated certificate mismatch message Added information to the message if the name found is an CN or an alternative name. Also print a message if no CN was not found instead of (null). --- libfreerdp/crypto/tls.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index a15be3ea4..22a74fdfe 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -685,7 +685,8 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) } #ifndef _WIN32 - free(common_name); + if (common_name) + free(common_name); #endif return verification_status; @@ -715,25 +716,20 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name fprintf(stderr, "@ WARNING: CERTIFICATE NAME MISMATCH! @\n"); fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); fprintf(stderr, "The hostname used for this connection (%s) \n", hostname); - - if (alt_names_count < 1) + fprintf(stderr, "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names"); + fprintf(stderr, "Common Name (CN):\n"); + fprintf(stderr, "\t%s\n", common_name ? common_name : "no CN found in certificate"); + if (alt_names_count > 1) { - fprintf(stderr, "does not match the name given in the certificate:\n"); - fprintf(stderr, "%s\n", common_name); - } - else - { - fprintf(stderr, "does not match the names given in the certificate:\n"); - fprintf(stderr, "%s", common_name); - - for (index = 0; index < alt_names_count; index++) + fprintf(stderr, "Alternative names:\n"); + if (alt_names_count > 1) { - fprintf(stderr, ", %s", alt_names[index]); + for (index = 0; index < alt_names_count; index++) + { + fprintf(stderr, "\t %s\n", alt_names[index]); + } } - - fprintf(stderr, "\n"); } - fprintf(stderr, "A valid certificate for the wrong name should NOT be trusted!\n"); } From 0773bb9303d24473fe1185d85a424dfe159aff53 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 1 Jul 2013 19:24:19 +0200 Subject: [PATCH 49/74] nla: invalidate sec handle after creation If sec pointer isn't invalidated after creation it is not possible to check if the upper and lower pointers are valid. This fixes a segfault in the server part if the client disconnects before the authentication was finished. --- libfreerdp/core/nla.c | 1 + libfreerdp/core/peer.c | 1 + libfreerdp/core/transport.c | 2 ++ winpr/libwinpr/sspi/sspi.c | 6 +++--- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 2b4b71992..875c0ae73 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1245,6 +1245,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* ZeroMemory(&credssp->negoToken, sizeof(SecBuffer)); ZeroMemory(&credssp->pubKeyAuth, sizeof(SecBuffer)); ZeroMemory(&credssp->authInfo, sizeof(SecBuffer)); + SecInvalidateHandle(&credssp->context); if (credssp->server) { diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 3806a736e..eb4ad60ea 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -272,6 +272,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) sspi_CopyAuthIdentity(&client->identity, &(rdp->nego->transport->credssp->identity)); IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE); credssp_free(rdp->nego->transport->credssp); + rdp->nego->transport->credssp = NULL; } else { diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index a9a710511..4afec5a12 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -159,6 +159,7 @@ BOOL transport_connect_nla(rdpTransport* transport) "If credentials are valid, the NTLMSSP implementation may be to blame.\n"); credssp_free(transport->credssp); + transport->credssp = NULL; return FALSE; } @@ -292,6 +293,7 @@ BOOL transport_accept_nla(rdpTransport* transport) { fprintf(stderr, "client authentication failure\n"); credssp_free(transport->credssp); + transport->credssp = NULL; return FALSE; } diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index 8747e3f01..96c959995 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -248,7 +248,7 @@ void* sspi_SecureHandleGetLowerPointer(SecHandle* handle) { void* pointer; - if (!handle) + if (!handle || !SecIsValidHandle(handle)) return NULL; pointer = (void*) ~((size_t) handle->dwLower); @@ -268,7 +268,7 @@ void* sspi_SecureHandleGetUpperPointer(SecHandle* handle) { void* pointer; - if (!handle) + if (!handle || !SecIsValidHandle(handle)) return NULL; pointer = (void*) ~((size_t) handle->dwUpper); @@ -839,7 +839,7 @@ SECURITY_STATUS SEC_ENTRY CompleteAuthToken(PCtxtHandle phContext, PSecBufferDes SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext) { - char* Name; + char* Name = NULL; SECURITY_STATUS status; SecurityFunctionTableA* table; From 96b9972307df568be99319edd12d593cab90f521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Tue, 2 Jul 2013 16:13:43 -0400 Subject: [PATCH 50/74] MacFreeRDP: fixed crash when opening second session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (unrecognized selector sent to instance … ) --- client/Mac/MRDPView.m | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index d4020679f..6a67fbfcf 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -788,8 +788,18 @@ struct rgba_data outerRect.size.height = h + heightDiff; [[self window] setMaxSize:outerRect.size]; [[self window] setMinSize:outerRect.size]; - [[self window] setFrame:outerRect display:YES]; - + + @try + { + [[self window] setFrame:outerRect display:YES]; + } + @catch (NSException * e) { + NSLog(@"Exception: %@", e); + } + @finally { + NSLog(@"finally"); + } + // set client area to specified dimensions innerRect.size.width = w; innerRect.size.height = h; @@ -874,8 +884,7 @@ BOOL mac_pre_connect(freerdp* instance) settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; - [view setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight]; - + [view setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight]; freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; @@ -933,9 +942,6 @@ BOOL mac_post_connect(freerdp* instance) view->pasteboard_rd = [NSPasteboard generalPasteboard]; view->pasteboard_changecount = (int) [view->pasteboard_rd changeCount]; view->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:mfc->view selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES]; - - /* we want to be notified when window resizes */ - [[NSNotificationCenter defaultCenter] addObserver:mfc->view selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil]; return TRUE; } From db6c0083d0ec2640f2a8ced2251ecd5835c3bb5b Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 3 Jul 2013 14:09:04 +0200 Subject: [PATCH 51/74] channels/serial: bring it back to life - Fixes #1166 - Fixed a possible segfault caused by invalid command line parameters - Removed serial->in_event which had no effect at all on the program logic --- channels/serial/client/serial_main.c | 30 +++++++++------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index df4700e9f..fb6b07915 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -67,7 +67,6 @@ struct _SERIAL_DEVICE wQueue* queue; LIST* pending_irps; - HANDLE in_event; fd_set read_fds; fd_set write_fds; @@ -330,7 +329,9 @@ static void* serial_thread_func(void* arg) if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0) break; - if (WaitForSingleObject(Queue_Event(serial->queue), 10) == WAIT_OBJECT_0) + status = WaitForSingleObject(Queue_Event(serial->queue), 10); + + if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT)) break; serial->nfds = 1; @@ -341,18 +342,13 @@ static void* serial_thread_func(void* arg) serial->tv.tv_usec = 0; serial->select_timeout = 0; - irp = (IRP*) Queue_Dequeue(serial->queue); - - if (irp) - serial_process_irp(serial, irp); - - status = WaitForSingleObject(serial->in_event, 0); - - if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT)) + if (status == WAIT_OBJECT_0) { - if (serial_check_fds(serial)) - ResetEvent(serial->in_event); + if ((irp = (IRP*) Queue_Dequeue(serial->queue))) + serial_process_irp(serial, irp); } + + serial_check_fds(serial); } return NULL; @@ -423,7 +419,6 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 Stream_Write_UINT32(irp->output, 0); irp->Complete(irp); - SetEvent(serial->in_event); break; } @@ -460,8 +455,6 @@ static void serial_check_for_events(SERIAL_DEVICE* serial) prev = irp; irp = (IRP*) list_next(serial->pending_irps, irp); list_remove(serial->pending_irps, prev); - - SetEvent(serial->in_event); } } @@ -537,7 +530,6 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp) irp->IoStatus = STATUS_PENDING; list_enqueue(serial->pending_irps, irp); - SetEvent(serial->in_event); } static void __serial_check_fds(SERIAL_DEVICE* serial) @@ -599,10 +591,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial) irp = (IRP*) list_next(serial->pending_irps, irp); if (irp_completed || (prev->IoStatus == STATUS_SUCCESS)) - { list_remove(serial->pending_irps, prev); - SetEvent(serial->in_event); - } } } @@ -692,7 +681,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) name = device->Name; path = device->Path; - if (name[0] && path[0]) + if ((name && name[0]) && (path && path[0])) { serial = (SERIAL_DEVICE*) malloc(sizeof(SERIAL_DEVICE)); ZeroMemory(serial, sizeof(SERIAL_DEVICE)); @@ -711,7 +700,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) serial->path = path; serial->queue = Queue_New(TRUE, -1, -1); serial->pending_irps = list_new(); - serial->in_event = CreateEvent(NULL, TRUE, FALSE, NULL); serial->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); From df2aab92c06da65298b77b72dde6db866f296c37 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 3 Jul 2013 16:41:26 +0200 Subject: [PATCH 52/74] client/common: fixed command line parsing issue fixes #1333 --- client/common/cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 6377456f5..20b08043e 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1667,7 +1667,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin FillMemory(arg->Value, strlen(arg->Value), '*'); } - return 1; + return status; } int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings* settings, char* name, void* data) From 450b64ee731abe5b440294b3dfafdd76dd951b22 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 3 Jul 2013 16:44:06 +0200 Subject: [PATCH 53/74] cmdline: unix/windows return detected error --- client/common/cmdline.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 20b08043e..3fb03f2b2 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -865,13 +865,10 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); - if (detect_status == 0) - { - if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST)) - detect_status = -1; - } + if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST)) + detect_status = -1; - return 0; + return detect_status; } int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* count) @@ -901,13 +898,10 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); - if (detect_status == 0) - { - if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST)) - detect_status = -1; - } + if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST)) + detect_status = -1; - return 0; + return detect_status; } BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) @@ -1034,6 +1028,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); } + arg = CommandLineFindArgumentA(args, "v"); arg = args; From bc631c93a856366e3ccb6ce47fc32430471b7312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 3 Jul 2013 15:07:12 -0400 Subject: [PATCH 54/74] freerdp: separate GatewayUsageMethod from GatewayEnabled --- .../Android/FreeRDPCore/jni/android_freerdp.c | 3 ++- client/common/cmdline.c | 5 ++-- client/common/file.c | 14 ++++++++--- client/iOS/Models/RDPSession.m | 3 ++- include/freerdp/settings.h | 6 +++-- libfreerdp/common/settings.c | 24 ++++++++++++------- libfreerdp/core/connection.c | 2 +- libfreerdp/core/transport.c | 2 +- libfreerdp/crypto/tls.c | 2 +- 9 files changed, 41 insertions(+), 20 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 632ca82c2..f0046dcc5 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -686,7 +686,8 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin settings->GatewayUsername = strdup(gatewayusername); settings->GatewayPassword = strdup(gatewaypassword); settings->GatewayDomain = strdup(gatewaydomain); - settings->GatewayUsageMethod = TRUE; + settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; + settings->GatewayEnabled = TRUE; settings->GatewayUseSameCredentials = FALSE; (*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname); diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 6377456f5..df714be88 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1243,8 +1243,9 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->GatewayHostname = _strdup(settings->ServerHostname); } - settings->GatewayUsageMethod = TRUE; + settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; settings->GatewayUseSameCredentials = TRUE; + settings->GatewayEnabled = TRUE; } CommandLineSwitchCase(arg, "gu") { @@ -1638,7 +1639,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin if (settings->DisableThemes) settings->PerformanceFlags |= PERF_DISABLE_THEMING; - if (settings->GatewayUsageMethod) + if (settings->GatewayEnabled) { if (settings->GatewayUseSameCredentials) { diff --git a/client/common/file.c b/client/common/file.c index afe40e9b1..ea64826a7 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -731,11 +731,19 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~((size_t) file->GatewayHostname)) freerdp_set_param_string(settings, FreeRDP_GatewayHostname, file->GatewayHostname); + if (~file->GatewayUsageMethod) - freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod); + { + freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod); + + if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT) + freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE); + else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT) + freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE); + } + if (~file->PromptCredentialOnce) - freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod); - settings->GatewayUseSameCredentials = TRUE; + freerdp_set_param_bool(settings, FreeRDP_GatewayUseSameCredentials, TRUE); if (~file->RemoteApplicationMode) freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode); diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m index df924e29f..d61d59a57 100644 --- a/client/iOS/Models/RDPSession.m +++ b/client/iOS/Models/RDPSession.m @@ -175,7 +175,8 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" settings->GatewayUsername = strdup([_params UTF8StringForKey:@"tsg_username"]); settings->GatewayPassword = strdup([_params UTF8StringForKey:@"tsg_password"]); settings->GatewayDomain = strdup([_params UTF8StringForKey:@"tsg_domain"]); - settings->GatewayUsageMethod = TRUE; + settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; + settings->GatewayEnabled = TRUE; settings->GatewayUseSameCredentials = FALSE; } diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index b6f34e6f7..b9ca69342 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -633,6 +633,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_GatewayDomain 1989 #define FreeRDP_GatewayCredentialsSource 1990 #define FreeRDP_GatewayUseSameCredentials 1991 +#define FreeRDP_GatewayEnabled 1992 #define FreeRDP_RemoteApplicationMode 2112 #define FreeRDP_RemoteApplicationName 2113 #define FreeRDP_RemoteApplicationIcon 2114 @@ -1019,7 +1020,7 @@ struct rdp_settings */ /* Gateway */ - ALIGN64 BOOL GatewayUsageMethod; /* 1984 */ + ALIGN64 UINT32 GatewayUsageMethod; /* 1984 */ ALIGN64 UINT32 GatewayPort; /* 1985 */ ALIGN64 char* GatewayHostname; /* 1986 */ ALIGN64 char* GatewayUsername; /* 1987 */ @@ -1027,7 +1028,8 @@ struct rdp_settings ALIGN64 char* GatewayDomain; /* 1989 */ ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */ ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */ - UINT64 padding2048[2048 - 1992]; /* 1992 */ + ALIGN64 BOOL GatewayEnabled; /* 1992 */ + UINT64 padding2048[2048 - 1993]; /* 1993 */ UINT64 padding2112[2112 - 2048]; /* 2048 */ /** diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index fb7dfc33e..a3ef341e7 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -562,14 +562,14 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->PlayRemoteFx; break; - case FreeRDP_GatewayUsageMethod: - return settings->GatewayUsageMethod; - break; - case FreeRDP_GatewayUseSameCredentials: return settings->GatewayUseSameCredentials; break; + case FreeRDP_GatewayEnabled: + return settings->GatewayEnabled; + break; + case FreeRDP_RemoteApplicationMode: return settings->RemoteApplicationMode; break; @@ -1017,14 +1017,14 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->PlayRemoteFx = param; break; - case FreeRDP_GatewayUsageMethod: - settings->GatewayUsageMethod = param; - break; - case FreeRDP_GatewayUseSameCredentials: settings->GatewayUseSameCredentials = param; break; + case FreeRDP_GatewayEnabled: + settings->GatewayEnabled = param; + break; + case FreeRDP_RemoteApplicationMode: settings->RemoteApplicationMode = param; break; @@ -1417,6 +1417,10 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) return settings->PercentScreen; break; + case FreeRDP_GatewayUsageMethod: + return settings->GatewayUsageMethod; + break; + case FreeRDP_GatewayPort: return settings->GatewayPort; break; @@ -1736,6 +1740,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) settings->PercentScreen = param; break; + case FreeRDP_GatewayUsageMethod: + settings->GatewayUsageMethod = param; + break; + case FreeRDP_GatewayPort: settings->GatewayPort = param; break; diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 553a27df5..34ae10881 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -75,7 +75,7 @@ BOOL rdp_client_connect(rdpRdp* rdp) nego_init(rdp->nego); nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort); - if (settings->GatewayUsageMethod) + if (settings->GatewayEnabled) { char* user; char* domain; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index a9a710511..781f4ab0d 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -212,7 +212,7 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL); } - if (transport->settings->GatewayUsageMethod) + if (transport->settings->GatewayEnabled) { transport->layer = TRANSPORT_LAYER_TSG; transport->TcpOut = tcp_new(settings); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index a15be3ea4..3e4c2350e 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -184,7 +184,7 @@ BOOL tls_connect(rdpTls* tls) return FALSE; } - if (tls->settings->GatewayUsageMethod) + if (tls->settings->GatewayEnabled) hostname = tls->settings->GatewayHostname; else hostname = tls->settings->ServerHostname; From cbd93f1b3b1b019439734b6507a61de1d3a39f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 3 Jul 2013 16:18:45 -0400 Subject: [PATCH 55/74] freerdp: add ConnectionResult event --- include/freerdp/event.h | 4 ++++ libfreerdp/core/freerdp.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/include/freerdp/event.h b/include/freerdp/event.h index a41fe0a60..2e1fae804 100644 --- a/include/freerdp/event.h +++ b/include/freerdp/event.h @@ -68,6 +68,10 @@ DEFINE_EVENT_BEGIN(Terminate) int code; DEFINE_EVENT_END(Terminate) +DEFINE_EVENT_BEGIN(ConnectionResult) + int result; +DEFINE_EVENT_END(ConnectionResult) + #ifdef __cplusplus } #endif diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index a43f51768..87171d493 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -56,6 +56,7 @@ BOOL freerdp_connect(freerdp* instance) rdpRdp* rdp; rdpSettings* settings; BOOL status = FALSE; + ConnectionResultEventArgs e; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; @@ -169,6 +170,10 @@ BOOL freerdp_connect(freerdp* instance) SetEvent(rdp->transport->connectedEvent); + EventArgsInit(&e, "freerdp"); + e.result = status ? 0 : -1; + PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); + return status; } @@ -331,6 +336,7 @@ static wEventType FreeRDP_Events[] = DEFINE_EVENT_ENTRY(ErrorInfo) DEFINE_EVENT_ENTRY(ParamChange) DEFINE_EVENT_ENTRY(Terminate) + DEFINE_EVENT_ENTRY(ConnectionResult) }; /** Allocator function for a rdp context. From c17c2f811b37cb5e3ebe806e0d10cdd9a1816ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Thu, 4 Jul 2013 14:42:40 -0400 Subject: [PATCH 56/74] FreeRDP: - replaced char* by const char* in function prototypes - MacFreeRDP: moved assignation of context function pointers - freerdp: added more pointer and return value validations to prevent crashes --- client/Mac/MRDPView.h | 5 +++++ client/Mac/MRDPView.m | 16 +--------------- client/Mac/mf_client.m | 7 ++++++- client/common/client.c | 2 +- client/common/file.c | 2 +- include/freerdp/client.h | 2 +- include/freerdp/client/file.h | 2 +- libfreerdp/core/connection.c | 19 +++++++++++++------ libfreerdp/core/gateway/tsg.c | 11 ++++++++++- winpr/libwinpr/synch/wait.c | 3 +++ 10 files changed, 42 insertions(+), 27 deletions(-) diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h index cd4d06b03..653c2d391 100755 --- a/client/Mac/MRDPView.h +++ b/client/Mac/MRDPView.h @@ -109,3 +109,8 @@ #define PTR_FLAGS_BUTTON2 0x2000 #define PTR_FLAGS_BUTTON3 0x4000 #define WheelRotationMask 0x01FF + +BOOL mac_pre_connect(freerdp* instance); +BOOL mac_post_connect(freerdp* instance); +BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain); +int mac_receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size); diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 6a67fbfcf..95dc36f0a 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -75,9 +75,6 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer); void mf_Pointer_SetNull(rdpContext* context); void mf_Pointer_SetDefault(rdpContext* context); // int rdp_connect(void); -BOOL mac_pre_connect(freerdp* instance); -BOOL mac_post_connect(freerdp* instance); -BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain); void mac_set_bounds(rdpContext* context, rdpBounds* bounds); void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap); void mac_begin_paint(rdpContext* context); @@ -141,17 +138,7 @@ struct rgba_data e.handle = (void*) self; PubSub_OnEmbedWindow(context->pubSub, context, &e); - context->instance->PreConnect = mac_pre_connect; - context->instance->PostConnect = mac_post_connect; - context->instance->ReceiveChannelData = mac_receive_channel_data; - context->instance->Authenticate = mac_authenticate; - - // TODO - // instance->Authenticate = mf_authenticate; - // instance->VerifyCertificate = mf_verify_certificate; - // instance->LogonErrorInfo = mf_logon_error_info; - - status = freerdp_connect(context->instance); + status = freerdp_connect(context->instance); if (!status) { @@ -797,7 +784,6 @@ struct rgba_data NSLog(@"Exception: %@", e); } @finally { - NSLog(@"finally"); } // set client area to specified dimensions diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m index a88309184..900c488ed 100755 --- a/client/Mac/mf_client.m +++ b/client/Mac/mf_client.m @@ -106,7 +106,12 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context) mfc = (mfContext*) instance->context; - context->channels = freerdp_channels_new(); + context->instance->PreConnect = mac_pre_connect; + context->instance->PostConnect = mac_post_connect; + context->instance->ReceiveChannelData = mac_receive_channel_data; + context->instance->Authenticate = mac_authenticate; + + context->channels = freerdp_channels_new(); settings = instance->settings; diff --git a/client/common/client.c b/client/common/client.c index acc47d064..b4979d32b 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -121,7 +121,7 @@ int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv return status; } -int freerdp_client_parse_connection_file(rdpContext* context, char* filename) +int freerdp_client_parse_connection_file(rdpContext* context, const char* filename) { rdpFile* file; diff --git a/client/common/file.c b/client/common/file.c index ea64826a7..c708f2b32 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -439,7 +439,7 @@ BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t si return freerdp_client_parse_rdp_file_buffer_ascii(file, buffer, size); } -BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name) +BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name) { BYTE* buffer; FILE* fp = NULL; diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 67d7a5ebf..4edbd4f28 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -84,7 +84,7 @@ FREERDP_API freerdp* freerdp_client_get_instance(rdpContext* context); FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context); FREERDP_API int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv); -FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, char* filename); +FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, const char* filename); FREERDP_API int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size); #ifdef __cplusplus diff --git a/include/freerdp/client/file.h b/include/freerdp/client/file.h index e83aa5ced..cb9984d59 100644 --- a/include/freerdp/client/file.h +++ b/include/freerdp/client/file.h @@ -137,7 +137,7 @@ typedef struct rdp_file rdpFile; extern "C" { #endif -FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name); +FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name); FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size); FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings); diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 34ae10881..247494e07 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -77,15 +77,19 @@ BOOL rdp_client_connect(rdpRdp* rdp) if (settings->GatewayEnabled) { - char* user; + char* user; char* domain; char* cookie; - int user_length; + int user_length = 0; int domain_length; int cookie_length; - user = settings->Username; - user_length = strlen(settings->Username); + + if (settings->Username) + { + user = settings->Username; + user_length = strlen(settings->Username); + } if (settings->Domain) domain = settings->Domain; @@ -100,8 +104,11 @@ BOOL rdp_client_connect(rdpRdp* rdp) CopyMemory(cookie, domain, domain_length); CharUpperBuffA(cookie, domain_length); cookie[domain_length] = '\\'; - CopyMemory(&cookie[domain_length + 1], user, user_length); - cookie[cookie_length] = '\0'; + + if (settings->Username) + CopyMemory(&cookie[domain_length + 1], user, user_length); + + cookie[cookie_length] = '\0'; nego_set_cookie(rdp->nego, cookie); free(cookie); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index c6bb45dd1..cf013f2d8 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1369,6 +1369,10 @@ BOOL tsg_disconnect(rdpTsg* tsg) * | | */ + + if (tsg == NULL) + return FALSE; + tsg->rpc->client->SynchronousReceive = TRUE; /* if we are already in state pending (i.e. if a server initiated disconnect was issued) @@ -1392,7 +1396,12 @@ BOOL tsg_disconnect(rdpTsg* tsg) int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) { int CopyLength; - rdpRpc* rpc = tsg->rpc; + rdpRpc* rpc; + + if (tsg == NULL) + return -1; + + rpc = tsg->rpc; if (tsg->PendingPdu) { diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 3006fe246..8060aa8ed 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -210,6 +210,9 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl return WAIT_FAILED; } + if (fd == -1) + return WAIT_FAILED; + FD_SET(fd, &fds); if (fd > maxfd) From 0ee7ca574185fd4bc864cb7d5a48d10638bd0dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 4 Jul 2013 16:31:54 -0400 Subject: [PATCH 57/74] libfreerdp-codec: add bitmap encoder --- include/freerdp/codec/bitmap.h | 6 + libfreerdp/codec/CMakeLists.txt | 3 +- .../codec/{bitmap.c => bitmap_decode.c} | 2 +- libfreerdp/codec/bitmap_encode.c | 1574 +++++++++++++++++ 4 files changed, 1583 insertions(+), 2 deletions(-) rename libfreerdp/codec/{bitmap.c => bitmap_decode.c} (99%) create mode 100644 libfreerdp/codec/bitmap_encode.c diff --git a/include/freerdp/codec/bitmap.h b/include/freerdp/codec/bitmap.h index a0a2e4c82..c652a921b 100644 --- a/include/freerdp/codec/bitmap.h +++ b/include/freerdp/codec/bitmap.h @@ -23,6 +23,12 @@ #include #include +#include +#include + FREERDP_API BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp); +FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height, + wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e); + #endif /* FREERDP_CODEC_BITMAP_H */ diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index 8895848b2..19533017b 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -20,9 +20,10 @@ set(MODULE_PREFIX "FREERDP_CODEC") set(${MODULE_PREFIX}_SRCS dsp.c - bitmap.c color.c audio.c + bitmap_decode.c + bitmap_encode.c rfx_bitstream.h rfx_constants.h rfx_decode.c diff --git a/libfreerdp/codec/bitmap.c b/libfreerdp/codec/bitmap_decode.c similarity index 99% rename from libfreerdp/codec/bitmap.c rename to libfreerdp/codec/bitmap_decode.c index 598017081..431a213a8 100644 --- a/libfreerdp/codec/bitmap.c +++ b/libfreerdp/codec/bitmap_decode.c @@ -1,6 +1,6 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * Compressed Bitmap + * Bitmap Decompression * * Copyright 2011 Jay Sorg * diff --git a/libfreerdp/codec/bitmap_encode.c b/libfreerdp/codec/bitmap_encode.c new file mode 100644 index 000000000..5cdca0b93 --- /dev/null +++ b/libfreerdp/codec/bitmap_encode.c @@ -0,0 +1,1574 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Bitmap Compression + * + * Copyright 2004-2012 Jay Sorg + * + * 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 + +#define GETPIXEL8(d, x, y, w) (*(((unsigned char*)d) + ((y) * (w) + (x)))) +#define GETPIXEL16(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x)))) +#define GETPIXEL32(d, x, y, w) (*(((unsigned int*)d) + ((y) * (w) + (x)))) + +/*****************************************************************************/ +#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL8(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } + +/*****************************************************************************/ +#define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL16(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } + +/*****************************************************************************/ +#define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL32(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } + +/*****************************************************************************/ +/* color */ +#define OUT_COLOR_COUNT1(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x60); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_data); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf3); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write_UINT8(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* color */ +#define OUT_COLOR_COUNT2(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT16(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x60); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT16(in_s, in_data); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf3); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write_UINT16(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* color */ +#define OUT_COLOR_COUNT3(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_data & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 16) & 0xFF); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x60); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_data & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 16) & 0xFF); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf3); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write_UINT8(in_s, in_data & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_data >> 16) & 0xFF); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* copy */ +#define OUT_COPY_COUNT1(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, Stream_Buffer(in_data), in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x80); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, Stream_Buffer(in_data), in_count); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf4); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write(in_s, Stream_Buffer(in_data), in_count); \ + } \ + } \ + in_count = 0; \ + Stream_SetPosition(in_data, 0); \ + } + +/*****************************************************************************/ +/* copy */ +#define OUT_COPY_COUNT2(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + temp = in_count * 2; \ + Stream_Write(in_s, Stream_Buffer(in_data), temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x80); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + temp = in_count * 2; \ + Stream_Write(in_s, Stream_Buffer(in_data), temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf4); \ + Stream_Write_UINT16(in_s, in_count); \ + temp = in_count * 2; \ + Stream_Write(in_s, Stream_Buffer(in_data), temp); \ + } \ + } \ + in_count = 0; \ + Stream_SetPosition(in_data, 0); \ + } + +/*****************************************************************************/ +/* copy */ +#define OUT_COPY_COUNT3(in_count, in_s, in_data) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + temp = in_count * 3; \ + Stream_Write(in_s, Stream_Pointer(in_data), temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x80); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + temp = in_count * 3; \ + Stream_Write(in_s, Stream_Pointer(in_data), temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf4); \ + Stream_Write_UINT16(in_s, in_count); \ + temp = in_count * 3; \ + Stream_Write(in_s, Stream_Pointer(in_data), temp); \ + } \ + } \ + in_count = 0; \ + Stream_SetPosition(in_data, 0); \ + } + +/*****************************************************************************/ +/* bicolor */ +#define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \ + { \ + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1); \ + Stream_Write_UINT8(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + Stream_Write_UINT8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1); \ + Stream_Write_UINT8(in_s, in_color2); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf8); \ + temp = in_count / 2; \ + Stream_Write_UINT16(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1); \ + Stream_Write_UINT8(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* bicolor */ +#define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \ + { \ + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT16(in_s, in_color1); \ + Stream_Write_UINT16(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + Stream_Write_UINT8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT16(in_s, in_color1); \ + Stream_Write_UINT16(in_s, in_color2); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf8); \ + temp = in_count / 2; \ + Stream_Write_UINT16(in_s, temp); \ + Stream_Write_UINT16(in_s, in_color1); \ + Stream_Write_UINT16(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* bicolor */ +#define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \ + { \ + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 16) & 0xFF); \ + Stream_Write_UINT8(in_s, in_color2 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 16) & 0xFF); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + Stream_Write_UINT8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 16) & 0xFF); \ + Stream_Write_UINT8(in_s, in_color2 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 16) & 0xFF); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf8); \ + temp = in_count / 2; \ + Stream_Write_UINT16(in_s, temp); \ + Stream_Write_UINT8(in_s, in_color1 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color1 >> 16) & 0xFF); \ + Stream_Write_UINT8(in_s, in_color2 & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 8) & 0xFF); \ + Stream_Write_UINT8(in_s, (in_color2 >> 16) & 0xFF); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fill */ +#define OUT_FILL_COUNT1(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + Stream_Write_UINT8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x0); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf0); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fill */ +#define OUT_FILL_COUNT2(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + Stream_Write_UINT8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x0); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf0); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fill */ +#define OUT_FILL_COUNT3(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + Stream_Write_UINT8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x0); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf0); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* mix */ +#define OUT_MIX_COUNT1(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x20); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf1); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* mix */ +#define OUT_MIX_COUNT2(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x20); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf1); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* mix */ +#define OUT_MIX_COUNT3(in_count, in_s) \ + { \ + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + Stream_Write_UINT8(in_s, 0x20); \ + temp = in_count - 32; \ + Stream_Write_UINT8(in_s, temp); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf1); \ + Stream_Write_UINT16(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fom */ +#define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \ + { \ + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + Stream_Write_UINT8(in_s, 0x40); \ + temp = in_count - 1; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf2); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fom */ +#define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \ + { \ + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + Stream_Write_UINT8(in_s, 0x40); \ + temp = in_count - 1; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf2); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +/* fill or mix (fom) */ +#define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \ + { \ + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + Stream_Write_UINT8(in_s, 0x40); \ + temp = in_count - 1; \ + Stream_Write_UINT8(in_s, temp); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + Stream_Write_UINT8(in_s, 0xf2); \ + Stream_Write_UINT16(in_s, in_count); \ + Stream_Write(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } + +/*****************************************************************************/ +#define TEST_FILL \ + ((last_line == 0 && pixel == 0) || \ + (last_line != 0 && pixel == ypixel)) +#define TEST_MIX \ + ((last_line == 0 && pixel == mix) || \ + (last_line != 0 && pixel == (ypixel ^ mix))) +#define TEST_FOM (TEST_FILL || TEST_MIX) +#define TEST_COLOR (pixel == last_pixel) +#define TEST_BICOLOR \ + ( \ + (pixel != last_pixel) && \ + ( \ + (!bicolor_spin && pixel == bicolor1 && last_pixel == bicolor2) || \ + (bicolor_spin && pixel == bicolor2 && last_pixel == bicolor1) \ + ) \ + ) +#define RESET_COUNTS \ + { \ + bicolor_count = 0; \ + fill_count = 0; \ + color_count = 0; \ + mix_count = 0; \ + fom_count = 0; \ + fom_mask_len = 0; \ + bicolor_spin = 0; \ + } + +/*****************************************************************************/ +int freerdp_bitmap_compress(char* in_data, int width, int height, + wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e) +{ + char *line; + char *last_line; + char fom_mask[8192]; /* good for up to 64K bitmap */ + int lines_sent; + int pixel; + int count; + int color_count; + int last_pixel; + int bicolor_count; + int bicolor1; + int bicolor2; + int bicolor_spin; + int end; + int i; + int out_count; + int ypixel; + int last_ypixel; + int fill_count; + int mix_count; + int mix; + int fom_count; + int fom_mask_len; + int temp; /* used in macros */ + + Stream_SetPosition(temp_s, 0); + fom_mask_len = 0; + last_line = 0; + lines_sent = 0; + end = width + e; + count = 0; + color_count = 0; + last_pixel = 0; + last_ypixel = 0; + bicolor_count = 0; + bicolor1 = 0; + bicolor2 = 0; + bicolor_spin = 0; + fill_count = 0; + mix_count = 0; + fom_count = 0; + + if (bpp == 8) + { + mix = 0xFF; + out_count = end; + line = in_data + width * start_line; + + while (start_line >= 0 && out_count < 32768) + { + i = Stream_GetPosition(s) + count; + + if (i - color_count >= byte_limit && + i - bicolor_count >= byte_limit && + i - fill_count >= byte_limit && + i - mix_count >= byte_limit && + i - fom_count >= byte_limit) + { + break; + } + + out_count += end; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL8(line, i, 0, width, last_pixel, pixel); + IN_PIXEL8(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_COLOR_COUNT1(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + Stream_Write_UINT8(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width; + start_line--; + lines_sent++; + } + + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + } + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + } + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_COLOR_COUNT1(color_count, s, last_pixel); + } + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + } + + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + } + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + } + else + { + OUT_COPY_COUNT1(count, s, temp_s); + } + } + else if ((bpp == 15) || (bpp == 16)) + { + mix = (bpp == 15) ? 0xBA1F : 0xFFFF; + out_count = end * 2; + line = in_data + width * start_line * 2; + + while (start_line >= 0 && out_count < 32768) + { + i = Stream_GetPosition(s) + count * 2; + + if (i - (color_count * 2) >= byte_limit && + i - (bicolor_count * 2) >= byte_limit && + i - (fill_count * 2) >= byte_limit && + i - (mix_count * 2) >= byte_limit && + i - (fom_count * 2) >= byte_limit) + { + break; + } + + out_count += end * 2; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL16(line, i, 0, width, last_pixel, pixel); + IN_PIXEL16(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_COLOR_COUNT2(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + Stream_Write_UINT16(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 2; + start_line--; + lines_sent++; + } + + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + } + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + } + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_COLOR_COUNT2(color_count, s, last_pixel); + } + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + } + + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + } + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + } + else + { + OUT_COPY_COUNT2(count, s, temp_s); + } + } + else if (bpp == 24) + { + mix = 0xFFFFFF; + out_count = end * 3; + line = in_data + width * start_line * 4; + + while (start_line >= 0 && out_count < 32768) + { + i = Stream_GetPosition(s) + count * 3; + + if (i - (color_count * 3) >= byte_limit && + i - (bicolor_count * 3) >= byte_limit && + i - (fill_count * 3) >= byte_limit && + i - (mix_count * 3) >= byte_limit && + i - (fom_count * 3) >= byte_limit) + { + break; + } + + out_count += end * 3; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL32(line, i, 0, width, last_pixel, pixel); + IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_COLOR_COUNT3(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + Stream_Write_UINT8(temp_s, pixel & 0xff); + Stream_Write_UINT8(temp_s, (pixel >> 8) & 0xff); + Stream_Write_UINT8(temp_s, (pixel >> 16) & 0xff); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 4; + start_line--; + lines_sent++; + } + + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + } + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + } + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_COLOR_COUNT3(color_count, s, last_pixel); + } + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + } + + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + } + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + } + else + { + OUT_COPY_COUNT3(count, s, temp_s); + } + } + + return lines_sent; +} From 1159d55569edb086e9cc4514bfce8430154ba35f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 4 Jul 2013 22:39:32 -0400 Subject: [PATCH 58/74] libfreerdp-core: fix unused variable --- libfreerdp/core/transport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 19a0ec6eb..40885442b 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -788,7 +788,6 @@ static void* transport_client_thread(void* arg) freerdp* instance; rdpContext* context; rdpTransport* transport; - TerminateEventArgs e; transport = (rdpTransport*) arg; instance = (freerdp*) transport->settings->instance; From df7526f888159f81de1e9ec2cb9a574923465869 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Fri, 5 Jul 2013 12:30:13 +0200 Subject: [PATCH 59/74] codec/rfx: Fixed bufferpool size used for RemoteFX y_r_buffer, cb_g_buffer, cr_b_buffer and dwt_buffer are all word arrays (16bit) but obviously the bufferpool size was calculated based on the wrong assumption that these are 32 bit values in commit 37a59efbe36c1e6dc200251e13492f20f63ff8b9 --- libfreerdp/codec/rfx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index cfcfeeac7..b007ea21f 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -137,6 +137,7 @@ static void rfx_profiler_print(RFX_CONTEXT* context) PROFILER_PRINT_FOOTER; } + RFX_CONTEXT* rfx_context_new(void) { HKEY hKey; @@ -159,8 +160,8 @@ RFX_CONTEXT* rfx_context_new(void) /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) * - * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * 4 = 16384 (0x4000) - * dwt_buffer: 32 * 32 * 2 * 2 * 4 = 16384, maximum sub-band width is 32 + * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * sizeof(INT16) = 8192 (0x2000) + * dwt_buffer: 32 * 32 * 2 * 2 * sizeof(INT16) = 8192, maximum sub-band width is 32 * * Additionally we add 32 bytes (16 in front and 16 at the back of the buffer) * in order to allow optimized functions (SEE, NEON) to read from positions @@ -168,7 +169,7 @@ RFX_CONTEXT* rfx_context_new(void) * performed at the BufferPool_Take function calls in rfx_encode/decode.c. */ - context->priv->BufferPool = BufferPool_New(TRUE, 16384 + 32, 16); + context->priv->BufferPool = BufferPool_New(TRUE, 8192 + 32, 16); #ifdef _WIN32 { From b3265b69585b177fdf4882b8f57152129afefcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 5 Jul 2013 18:23:26 -0400 Subject: [PATCH 60/74] libwinpr-utils: implement ListDictionary --- winpr/include/winpr/collections.h | 26 +++ .../utils/collections/ListDictionary.c | 161 +++++++++++++++++- winpr/libwinpr/utils/test/CMakeLists.txt | 1 + .../libwinpr/utils/test/TestListDictionary.c | 130 ++++++++++++++ 4 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 winpr/libwinpr/utils/test/TestListDictionary.c diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 03d06a9a8..4ef2e3b19 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -171,13 +171,39 @@ typedef struct _wDictionary wDictionary; /* System.Collections.Specialized.ListDictionary */ +typedef struct _wListDictionaryItem wListDictionaryItem; + +struct _wListDictionaryItem +{ + void* key; + void* value; + + wListDictionaryItem* next; +}; + struct _wListDictionary { BOOL synchronized; HANDLE mutex; + + wListDictionaryItem* head; }; typedef struct _wListDictionary wListDictionary; +WINPR_API int ListDictionary_Count(wListDictionary* listDictionary); + +WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value); +WINPR_API void ListDictionary_Remove(wListDictionary* listDictionary, void* key); +WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary); + +WINPR_API BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key); + +WINPR_API void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key); +WINPR_API BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value); + +WINPR_API wListDictionary* ListDictionary_New(BOOL synchronized); +WINPR_API void ListDictionary_Free(wListDictionary* listDictionary); + /* System.Collections.Generic.KeyValuePair */ struct _wKeyValuePair diff --git a/winpr/libwinpr/utils/collections/ListDictionary.c b/winpr/libwinpr/utils/collections/ListDictionary.c index 2216384a7..d097035ef 100644 --- a/winpr/libwinpr/utils/collections/ListDictionary.c +++ b/winpr/libwinpr/utils/collections/ListDictionary.c @@ -26,6 +26,8 @@ /** * C equivalent of the C# ListDictionary Class: * http://msdn.microsoft.com/en-us/library/system.collections.specialized.listdictionary.aspx + * + * Internal implementation uses a singly-linked list */ /** @@ -38,7 +40,21 @@ int ListDictionary_Count(wListDictionary* listDictionary) { - return 0; + int count = 0; + wListDictionaryItem* item; + + if (!listDictionary->head) + return 0; + + item = listDictionary->head; + + while (item) + { + count++; + item = item->next; + } + + return count; } /** @@ -78,7 +94,28 @@ BOOL ListDictionary_IsSynchronized(wListDictionary* listDictionary) void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value) { + wListDictionaryItem* item; + wListDictionaryItem* lastItem; + item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem)); + + item->key = key; + item->value = value; + + item->next = NULL; + + if (!listDictionary->head) + { + listDictionary->head = item; + return; + } + + lastItem = listDictionary->head; + + while (lastItem->next) + lastItem = lastItem->next; + + lastItem->next = item; } /** @@ -87,7 +124,22 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value) void ListDictionary_Clear(wListDictionary* listDictionary) { + wListDictionaryItem* item; + wListDictionaryItem* nextItem; + if (!listDictionary->head) + return; + + item = listDictionary->head; + + while (item) + { + nextItem = item->next; + free(item); + item = nextItem; + } + + listDictionary->head = NULL; } /** @@ -96,7 +148,22 @@ void ListDictionary_Clear(wListDictionary* listDictionary) BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key) { - return FALSE; + wListDictionaryItem* item; + + if (!listDictionary->head) + return FALSE; + + item = listDictionary->head; + + while (item) + { + if (item->key == key) + break; + + item = item->next; + } + + return (item) ? TRUE : FALSE; } /** @@ -105,7 +172,89 @@ BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key) void ListDictionary_Remove(wListDictionary* listDictionary, void* key) { + wListDictionaryItem* item; + wListDictionaryItem* prevItem; + if (!listDictionary->head) + return; + + item = listDictionary->head; + + if (listDictionary->head->key == key) + { + listDictionary->head = listDictionary->head->next; + free(item); + return; + } + + if (!item->next) + return; + + prevItem = item; + item = item->next; + + while (item) + { + if (item->key == key) + { + prevItem->next = item->next; + free(item); + break; + } + + item = item->next; + } +} + +/** + * Get an item value using key + */ + +void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key) +{ + wListDictionaryItem* item; + + if (!listDictionary->head) + return NULL; + + item = listDictionary->head; + + while (item) + { + if (item->key == key) + break; + + item = item->next; + } + + return (item) ? item->value : NULL; +} + +/** + * Set an item value using key + */ + +BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value) +{ + wListDictionaryItem* item; + + if (!listDictionary->head) + return FALSE; + + item = listDictionary->head; + + while (item) + { + if (item->key == key) + break; + + item = item->next; + } + + if (item) + item->value = value; + + return (item) ? TRUE : FALSE; } /** @@ -121,6 +270,8 @@ wListDictionary* ListDictionary_New(BOOL synchronized) if (listDictionary) { listDictionary->synchronized = synchronized; + + listDictionary->head = NULL; } return listDictionary; @@ -128,6 +279,10 @@ wListDictionary* ListDictionary_New(BOOL synchronized) void ListDictionary_Free(wListDictionary* listDictionary) { - free(listDictionary); + if (listDictionary) + { + ListDictionary_Clear(listDictionary); + free(listDictionary); + } } diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt index 2656109b0..1455779ef 100644 --- a/winpr/libwinpr/utils/test/CMakeLists.txt +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -9,6 +9,7 @@ set(${MODULE_PREFIX}_TESTS TestPrint.c TestPubSub.c TestArrayList.c + TestListDictionary.c TestCmdLine.c TestStreamPool.c TestMessageQueue.c diff --git a/winpr/libwinpr/utils/test/TestListDictionary.c b/winpr/libwinpr/utils/test/TestListDictionary.c new file mode 100644 index 000000000..133271c23 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestListDictionary.c @@ -0,0 +1,130 @@ + +#include +#include +#include + +static char* key1 = "key1"; +static char* key2 = "key2"; +static char* key3 = "key3"; + +static char* val1 = "val1"; +static char* val2 = "val2"; +static char* val3 = "val3"; + +int TestListDictionary(int argc, char* argv[]) +{ + int count; + char* value; + wListDictionary* list; + + list = ListDictionary_New(FALSE); + + ListDictionary_Add(list, key1, val1); + ListDictionary_Add(list, key2, val2); + ListDictionary_Add(list, key3, val3); + + count = ListDictionary_Count(list); + + if (count != 3) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); + return -1; + } + + ListDictionary_Remove(list, key2); + + count = ListDictionary_Count(list); + + if (count != 2) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 2, count); + return -1; + } + + ListDictionary_Remove(list, key3); + + count = ListDictionary_Count(list); + + if (count != 1) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 1, count); + return -1; + } + + ListDictionary_Remove(list, key1); + + count = ListDictionary_Count(list); + + if (count != 0) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); + return -1; + } + + ListDictionary_Add(list, key1, val1); + ListDictionary_Add(list, key2, val2); + ListDictionary_Add(list, key3, val3); + + count = ListDictionary_Count(list); + + if (count != 3) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); + return -1; + } + + value = (char*) ListDictionary_GetItemValue(list, key1); + + if (strcmp(value, val1) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val1, value); + return -1; + } + + value = (char*) ListDictionary_GetItemValue(list, key2); + + if (strcmp(value, val2) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val2, value); + return -1; + } + + value = (char*) ListDictionary_GetItemValue(list, key3); + + if (strcmp(value, val3) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val3, value); + return -1; + } + + ListDictionary_SetItemValue(list, key2, "apple"); + + value = (char*) ListDictionary_GetItemValue(list, key2); + + if (strcmp(value, "apple") != 0) + { + printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", "apple", value); + return -1; + } + + if (!ListDictionary_Contains(list, key2)) + { + printf("ListDictionary_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE); + return -1; + } + + ListDictionary_Clear(list); + + count = ListDictionary_Count(list); + + if (count != 0) + { + printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); + return -1; + } + + ListDictionary_Free(list); + + return 0; +} + From f9bac0fce9836ebe2bc5c8f9bca7d544fa9b9cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 5 Jul 2013 23:20:56 -0400 Subject: [PATCH 61/74] Added public API function freerdp_client_write_connection_file() For now, all settings are written to the RDP file. This can be switched with the WRITE_ALL_SETTINGS define in file.c --- client/common/client.c | 35 ++++++++++++++++++++++++++++------- client/common/file.c | 15 ++++++++------- include/freerdp/client.h | 1 + include/freerdp/client/file.h | 2 +- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index b4979d32b..2b1c49242 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -112,10 +112,7 @@ int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv if (settings->ConnectionFile) { - rdpFile* file = freerdp_client_rdp_file_new(); - freerdp_client_parse_rdp_file(file, settings->ConnectionFile); - freerdp_client_populate_settings_from_rdp_file(file, settings); - freerdp_client_rdp_file_free(file); + return freerdp_client_parse_connection_file(context, settings->ConnectionFile); } return status; @@ -136,11 +133,35 @@ int freerdp_client_parse_connection_file(rdpContext* context, const char* filena int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size) { rdpFile* file; + int status = -1; file = freerdp_client_rdp_file_new(); - freerdp_client_parse_rdp_file_buffer(file, buffer, size); - freerdp_client_populate_settings_from_rdp_file(file, context->settings); + if (freerdp_client_parse_rdp_file_buffer(file, buffer, size) + && freerdp_client_populate_settings_from_rdp_file(file, context->settings)) + { + status = 0; + } + freerdp_client_rdp_file_free(file); - return 0; + return status; +} + +int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode) +{ + rdpFile* file; + int status = -1; + + file = freerdp_client_rdp_file_new(); + if (freerdp_client_populate_rdp_file_from_settings(file, context->settings)) + { + if (freerdp_client_write_rdp_file(file, filename, unicode)) + { + status = 0; + } + } + + freerdp_client_rdp_file_free(file); + + return status; } diff --git a/client/common/file.c b/client/common/file.c index c708f2b32..324b4d619 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -480,7 +480,8 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name) return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size); } -#define SETTING_MODIFIED(_settings, _field) (_settings->settings_modified[FreeRDP_##_field]) +#define WRITE_ALL_SETTINGS TRUE +#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->settings_modified[FreeRDP_##_field]) #define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings) @@ -529,9 +530,9 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* } -BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode) +BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode) { - BOOL success = FALSE; + int rc = 0; char* buffer; int len, len2; FILE* fp = NULL; @@ -559,22 +560,22 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode) fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp); fwrite(unicodestr, 2, len, fp); - free(unicodestr); + free(unicodestr); } else { fwrite(buffer, 1, len, fp); } - fflush(fp); - fclose(fp); + rc = fflush(fp); + rc = fclose(fp); } } if (buffer != NULL) free(buffer); - return success; + return (rc == 0); } #define WRITE_RDP_FILE_DECLARE(_file, _buffer, _size) \ diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 4edbd4f28..ddca7169c 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -86,6 +86,7 @@ FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context); FREERDP_API int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv); FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, const char* filename); FREERDP_API int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size); +FREERDP_API int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode); #ifdef __cplusplus } diff --git a/include/freerdp/client/file.h b/include/freerdp/client/file.h index cb9984d59..8fffdfbe8 100644 --- a/include/freerdp/client/file.h +++ b/include/freerdp/client/file.h @@ -142,7 +142,7 @@ FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffe FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings); FREERDP_API BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings); -FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode); +FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode); FREERDP_API size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size); FREERDP_API rdpFile* freerdp_client_rdp_file_new(void); From f8fa2f9f5d534f6145907b1d6b3e5ec3567b3702 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 7 Jul 2013 12:14:38 +0530 Subject: [PATCH 62/74] fixed error on compilation WITH_DEBUG_RDP ON that was raising due to wrong variable in debug statement --- libfreerdp/core/fastpath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index b8569fc61..872b57e51 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -209,7 +209,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s #ifdef WITH_DEBUG_RDP DEBUG_RDP("recv Fast-Path %s Update (0x%X), length:%d", - updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, capacity); + updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, size); #endif switch (updateCode) From eca98fe8ccbb809295391c35801c604b97aef01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 8 Jul 2013 18:36:03 -0400 Subject: [PATCH 63/74] channels/disp: initial RDP8.1 MS-RDPEDISP implementation --- channels/disp/CMakeLists.txt | 22 +++ channels/disp/ChannelOptions.cmake | 12 ++ channels/disp/client/CMakeLists.txt | 47 +++++ channels/disp/client/disp_main.c | 279 ++++++++++++++++++++++++++++ channels/disp/client/disp_main.h | 38 ++++ include/freerdp/client/disp.h | 57 ++++++ 6 files changed, 455 insertions(+) create mode 100644 channels/disp/CMakeLists.txt create mode 100644 channels/disp/ChannelOptions.cmake create mode 100644 channels/disp/client/CMakeLists.txt create mode 100644 channels/disp/client/disp_main.c create mode 100644 channels/disp/client/disp_main.h create mode 100644 include/freerdp/client/disp.h diff --git a/channels/disp/CMakeLists.txt b/channels/disp/CMakeLists.txt new file mode 100644 index 000000000..541892d95 --- /dev/null +++ b/channels/disp/CMakeLists.txt @@ -0,0 +1,22 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# 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("disp") + +if(WITH_CLIENT_CHANNELS) + add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) +endif() diff --git a/channels/disp/ChannelOptions.cmake b/channels/disp/ChannelOptions.cmake new file mode 100644 index 000000000..0e254adad --- /dev/null +++ b/channels/disp/ChannelOptions.cmake @@ -0,0 +1,12 @@ + +set(OPTION_DEFAULT OFF) +set(OPTION_CLIENT_DEFAULT ON) +set(OPTION_SERVER_DEFAULT OFF) + +define_channel_options(NAME "disp" TYPE "dynamic" + DESCRIPTION "Display Update Virtual Channel Extension" + SPECIFICATIONS "[MS-RDPEDISP]" + DEFAULT ${OPTION_DEFAULT}) + +define_channel_client_options(${OPTION_CLIENT_DEFAULT}) +define_channel_server_options(${OPTION_SERVER_DEFAULT}) diff --git a/channels/disp/client/CMakeLists.txt b/channels/disp/client/CMakeLists.txt new file mode 100644 index 000000000..403a15ce4 --- /dev/null +++ b/channels/disp/client/CMakeLists.txt @@ -0,0 +1,47 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2013 Marc-Andre Moreau +# +# 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_client("disp") + +set(${MODULE_PREFIX}_SRCS + disp_main.c + disp_main.h) + +include_directories(..) + +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry") + +set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-common freerdp-utils) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-sysinfo) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") + diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c new file mode 100644 index 000000000..76ce8be97 --- /dev/null +++ b/channels/disp/client/disp_main.c @@ -0,0 +1,279 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display Update Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "disp_main.h" + +struct _DISP_CHANNEL_CALLBACK +{ + IWTSVirtualChannelCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + IWTSVirtualChannel* channel; +}; +typedef struct _DISP_CHANNEL_CALLBACK DISP_CHANNEL_CALLBACK; + +struct _DISP_LISTENER_CALLBACK +{ + IWTSListenerCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + DISP_CHANNEL_CALLBACK* channel_callback; +}; +typedef struct _DISP_LISTENER_CALLBACK DISP_LISTENER_CALLBACK; + +struct _DISP_PLUGIN +{ + IWTSPlugin iface; + + IWTSListener* listener; + DISP_LISTENER_CALLBACK* listener_callback; + + UINT32 MaxNumMonitors; + UINT32 MaxMonitorWidth; + UINT32 MaxMonitorHeight; +}; +typedef struct _DISP_PLUGIN DISP_PLUGIN; + +int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors) +{ + int index; + int status; + wStream* s; + UINT32 type; + UINT32 length; + + length = 8 + 4 + NumMonitors * 32; + type = DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT; + + s = Stream_New(NULL, length); + + Stream_Write_UINT32(s, type); /* Type (4 bytes) */ + Stream_Write_UINT32(s, length); /* Length (4 bytes) */ + + Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */ + + for (index = 0; index < NumMonitors; index++) + { + Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].Width); /* Width (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].Height); /* Height (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */ + } + + Stream_SealLength(s); + + status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL); + + Stream_Free(s, TRUE); + + return status; +} + +int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) +{ + DISP_PLUGIN* disp; + + disp = (DISP_PLUGIN*) callback->plugin; + + Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */ + Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */ + Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */ + + return 0; +} + +int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) +{ + UINT32 type; + UINT32 length; + + Stream_Read_UINT32(s, type); /* Type (4 bytes) */ + Stream_Read_UINT32(s, length); /* Length (4 bytes) */ + + switch (type) + { + case DISPLAY_CONTROL_PDU_TYPE_CAPS: + disp_recv_display_control_caps_pdu(callback, s); + break; + + default: + break; + } + + return 0; +} + +static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer) +{ + wStream* s; + int status = 0; + DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback; + + s = Stream_New(pBuffer, cbSize); + + status = disp_recv_pdu(callback, s); + + Stream_Free(s, FALSE); + + return status; +} + +static int disp_on_close(IWTSVirtualChannelCallback* pChannelCallback) +{ + DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback; + + if (callback) + { + free(callback); + } + + return 0; +} + +static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, + IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept, + IWTSVirtualChannelCallback** ppCallback) +{ + DISP_CHANNEL_CALLBACK* callback; + DISP_LISTENER_CALLBACK* listener_callback = (DISP_LISTENER_CALLBACK*) pListenerCallback; + + callback = (DISP_CHANNEL_CALLBACK*) malloc(sizeof(DISP_CHANNEL_CALLBACK)); + ZeroMemory(callback, sizeof(DISP_CHANNEL_CALLBACK)); + + callback->iface.OnDataReceived = disp_on_data_received; + callback->iface.OnClose = disp_on_close; + callback->plugin = listener_callback->plugin; + callback->channel_mgr = listener_callback->channel_mgr; + callback->channel = pChannel; + listener_callback->channel_callback = callback; + + *ppCallback = (IWTSVirtualChannelCallback*) callback; + + return 0; +} + +static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) +{ + int status; + DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin; + + disp->listener_callback = (DISP_LISTENER_CALLBACK*) malloc(sizeof(DISP_LISTENER_CALLBACK)); + ZeroMemory(disp->listener_callback, sizeof(DISP_LISTENER_CALLBACK)); + + disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection; + disp->listener_callback->plugin = pPlugin; + disp->listener_callback->channel_mgr = pChannelMgr; + + status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0, + (IWTSListenerCallback*) disp->listener_callback, &(disp->listener)); + + disp->listener->pInterface = disp->iface.pInterface; + + return status; +} + +static int disp_plugin_terminated(IWTSPlugin* pPlugin) +{ + DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin; + + if (disp) + { + free(disp); + } + + return 0; +} + +/** + * Channel Client Interface + */ + +int disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors) +{ + DISP_PLUGIN* disp = (DISP_PLUGIN*) context->handle; + DISP_CHANNEL_CALLBACK* callback = disp->listener_callback->channel_callback; + + disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors); + + return 1; +} + +#ifdef STATIC_CHANNELS +#define DVCPluginEntry disp_DVCPluginEntry +#endif + +int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +{ + int error = 0; + DISP_PLUGIN* disp; + DispClientContext* context; + + disp = (DISP_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "disp"); + + if (disp == NULL) + { + disp = (DISP_PLUGIN*) malloc(sizeof(DISP_PLUGIN)); + + if (disp) + { + ZeroMemory(disp, sizeof(DISP_PLUGIN)); + + disp->iface.Initialize = disp_plugin_initialize; + disp->iface.Connected = NULL; + disp->iface.Disconnected = NULL; + disp->iface.Terminated = disp_plugin_terminated; + + context = (DispClientContext*) malloc(sizeof(DispClientContext)); + + context->handle = (void*) disp; + + context->SendMonitorLayout = disp_send_monitor_layout; + + disp->iface.pInterface = (void*) context; + + error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp); + } + } + + return error; +} diff --git a/channels/disp/client/disp_main.h b/channels/disp/client/disp_main.h new file mode 100644 index 000000000..9e99abaad --- /dev/null +++ b/channels/disp/client/disp_main.h @@ -0,0 +1,38 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display Update Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * 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_DISP_CLIENT_MAIN_H +#define FREERDP_CHANNEL_DISP_CLIENT_MAIN_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000001 +#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002 + +#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */ + diff --git a/include/freerdp/client/disp.h b/include/freerdp/client/disp.h new file mode 100644 index 000000000..d51819ccd --- /dev/null +++ b/include/freerdp/client/disp.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display Update Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * 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_CLIENT_DISP_H +#define FREERDP_CHANNEL_CLIENT_DISP_H + +#define DISPLAY_CONTROL_MONITOR_PRIMARY 0x00000001 + +struct _DISPLAY_CONTROL_MONITOR_LAYOUT +{ + UINT32 Flags; + INT32 Left; + INT32 Top; + UINT32 Width; + UINT32 Height; + UINT32 PhysicalWidth; + UINT32 PhysicalHeight; + UINT32 Orientation; +}; +typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT; + +/** + * Client Interface + */ + +#define DISP_DVC_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl" + +typedef struct _disp_client_context DispClientContext; + +typedef int (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors); + +struct _disp_client_context +{ + void* handle; + void* custom; + + pcDispSendMonitorLayout SendMonitorLayout; +}; + +#endif /* FREERDP_CHANNEL_CLIENT_DISP_H */ + From b93898e5ec4fb022a2c9ac15840d1dad33f5ab7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 9 Jul 2013 16:10:59 -0400 Subject: [PATCH 64/74] client: add option for MS-RDPEDISP (/disp) --- client/common/cmdline.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index afe978df2..1796983b4 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -91,6 +91,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" }, { "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" }, { "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" }, + { "disp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Display control" }, { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" }, { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" }, { "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Full window drag" }, @@ -607,6 +608,16 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT freerdp_client_add_dynamic_channel(settings, count, p); } + CommandLineSwitchCase(arg, "disp") + { + char* p[1]; + int count; + + count = 1; + p[0] = "disp"; + + freerdp_client_add_dynamic_channel(settings, count, p); + } CommandLineSwitchCase(arg, "sound") { if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) From b9c8ac652796b869992c1e60f9be3b1372aaab67 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 10 Jul 2013 07:14:26 +0200 Subject: [PATCH 65/74] codec/rfx: use function pointer for rlgr codec Option to switch the rlgr implementation during runtime - exactly like we do it with the ycbcr, dwt and quantization functions. --- include/freerdp/codec/rfx.h | 2 ++ libfreerdp/codec/rfx.c | 3 +++ libfreerdp/codec/rfx_decode.c | 2 +- libfreerdp/codec/rfx_encode.c | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index d3ba0536a..97f5763d9 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -106,6 +106,8 @@ struct _RFX_CONTEXT void (*quantization_encode)(INT16* buffer, const UINT32* quantization_values); void (*dwt_2d_decode)(INT16* buffer, INT16* dwt_buffer); void (*dwt_2d_encode)(INT16* buffer, INT16* dwt_buffer); + int (*rlgr_decode)(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size); + int (*rlgr_encode)(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size); /* private definitions */ RFX_CONTEXT_PRIV* priv; diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index b007ea21f..49a81d26f 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -45,6 +45,7 @@ #include "rfx_encode.h" #include "rfx_quantization.h" #include "rfx_dwt.h" +#include "rfx_rlgr.h" #include "rfx_sse2.h" #include "rfx_neon.h" @@ -240,6 +241,8 @@ RFX_CONTEXT* rfx_context_new(void) context->quantization_encode = rfx_quantization_encode; context->dwt_2d_decode = rfx_dwt_2d_decode; context->dwt_2d_encode = rfx_dwt_2d_encode; + context->rlgr_decode = rfx_rlgr_decode; + context->rlgr_encode = rfx_rlgr_encode; RFX_INIT_SIMD(context); diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index 051a44b20..ff6161590 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -103,7 +103,7 @@ static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantizatio PROFILER_ENTER(context->priv->prof_rfx_decode_component); PROFILER_ENTER(context->priv->prof_rfx_rlgr_decode); - rfx_rlgr_decode(context->mode, data, size, buffer, 4096); + context->rlgr_decode(context->mode, data, size, buffer, 4096); PROFILER_EXIT(context->priv->prof_rfx_rlgr_decode); PROFILER_ENTER(context->priv->prof_rfx_differential_decode); diff --git a/libfreerdp/codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c index b59570bec..2b758988f 100644 --- a/libfreerdp/codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -209,7 +209,7 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio PROFILER_EXIT(context->priv->prof_rfx_differential_encode); PROFILER_ENTER(context->priv->prof_rfx_rlgr_encode); - *size = rfx_rlgr_encode(context->mode, data, 4096, buffer, buffer_size); + *size = context->rlgr_encode(context->mode, data, 4096, buffer, buffer_size); PROFILER_EXIT(context->priv->prof_rfx_rlgr_encode); PROFILER_EXIT(context->priv->prof_rfx_encode_component); From f5c2181218256f2711f8029fd412a4a4a399522e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 10 Jul 2013 14:04:43 -0700 Subject: [PATCH 66/74] channels/disp: update --- channels/disp/client/disp_main.c | 3 +++ include/freerdp/client/disp.h | 2 ++ include/freerdp/event.h | 5 +++++ libfreerdp/core/freerdp.c | 1 + 4 files changed, 11 insertions(+) diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index 76ce8be97..1e7463c0a 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -98,6 +98,9 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */ + + //Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */ + //Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ } Stream_SealLength(s); diff --git a/include/freerdp/client/disp.h b/include/freerdp/client/disp.h index d51819ccd..e13bdea0b 100644 --- a/include/freerdp/client/disp.h +++ b/include/freerdp/client/disp.h @@ -32,6 +32,8 @@ struct _DISPLAY_CONTROL_MONITOR_LAYOUT UINT32 PhysicalWidth; UINT32 PhysicalHeight; UINT32 Orientation; + UINT32 DesktopScaleFactor; + UINT32 DeviceScaleFactor; }; typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT; diff --git a/include/freerdp/event.h b/include/freerdp/event.h index 2e1fae804..cd4c7e7f1 100644 --- a/include/freerdp/event.h +++ b/include/freerdp/event.h @@ -41,6 +41,11 @@ DEFINE_EVENT_BEGIN(ResizeWindow) int width; int height; DEFINE_EVENT_END(ResizeWindow) + +DEFINE_EVENT_BEGIN(LocalResizeWindow) + int width; + int height; +DEFINE_EVENT_END(LocalResizeWindow) DEFINE_EVENT_BEGIN(EmbedWindow) BOOL embed; diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 87171d493..85f5c3235 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -330,6 +330,7 @@ static wEventType FreeRDP_Events[] = { DEFINE_EVENT_ENTRY(WindowStateChange) DEFINE_EVENT_ENTRY(ResizeWindow) + DEFINE_EVENT_ENTRY(LocalResizeWindow) DEFINE_EVENT_ENTRY(EmbedWindow) DEFINE_EVENT_ENTRY(PanningChange) DEFINE_EVENT_ENTRY(ScalingFactorChange) From 5926fa36ddc27bcedec24b5884e59083b8789d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 11 Jul 2013 08:53:15 -0700 Subject: [PATCH 67/74] libfreerdp-client: use PubSub for OnChannelConnected/OnChannelDisconnected --- channels/client/channels.c | 12 ++++++++++-- channels/disp/client/disp_main.c | 11 +++++++++++ client/X11/xf_channels.c | 14 ++++++-------- client/X11/xf_channels.h | 3 +++ client/X11/xf_client.c | 7 +++++-- client/common/client.c | 4 ++-- include/freerdp/event.h | 10 ++++++++++ include/freerdp/freerdp.h | 6 ------ libfreerdp/core/freerdp.c | 2 ++ 9 files changed, 49 insertions(+), 20 deletions(-) diff --git a/channels/client/channels.c b/channels/client/channels.c index a9ea2b0dc..bf886dba4 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -441,10 +441,14 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface) { int status = 0; + ChannelConnectedEventArgs e; rdpChannels* channels = (rdpChannels*) context->custom; freerdp* instance = channels->instance; - IFCALLRET(instance->OnChannelConnected, status, instance, name, pInterface); + EventArgsInit(&e, "freerdp"); + e.name = name; + e.pInterface = pInterface; + PubSub_OnChannelConnected(instance->context->pubSub, instance->context, &e); return status; } @@ -452,10 +456,14 @@ int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const ch int freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, const char* name, void* pInterface) { int status = 0; + ChannelDisconnectedEventArgs e; rdpChannels* channels = (rdpChannels*) context->custom; freerdp* instance = channels->instance; - IFCALLRET(instance->OnChannelDisconnected, status, instance, name, pInterface); + EventArgsInit(&e, "freerdp"); + e.name = name; + e.pInterface = pInterface; + PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e); return status; } diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index 1e7463c0a..5983c9d6f 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -78,6 +78,8 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback UINT32 type; UINT32 length; + fprintf(stderr, "DisplayControlMonitorLayout\n"); + length = 8 + 4 + NumMonitors * 32; type = DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT; @@ -122,6 +124,9 @@ int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */ + fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n", + disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight); + return 0; } @@ -133,6 +138,8 @@ int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, type); /* Type (4 bytes) */ Stream_Read_UINT32(s, length); /* Length (4 bytes) */ + fprintf(stderr, "Type: %d Length: %d\n", type, length); + switch (type) { case DISPLAY_CONTROL_PDU_TYPE_CAPS: @@ -152,6 +159,8 @@ static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, U int status = 0; DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback; + fprintf(stderr, "DisplayControlOnDataReceived\n"); + s = Stream_New(pBuffer, cbSize); status = disp_recv_pdu(callback, s); @@ -192,6 +201,8 @@ static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac *ppCallback = (IWTSVirtualChannelCallback*) callback; + fprintf(stderr, "DisplayControlNewChannelConnection\n"); + return 0; } diff --git a/client/X11/xf_channels.c b/client/X11/xf_channels.c index 91dda0b8e..24325046e 100644 --- a/client/X11/xf_channels.c +++ b/client/X11/xf_channels.c @@ -26,19 +26,17 @@ #include "xf_client.h" #include "xfreerdp.h" -int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface) +void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e) { - xfContext* xfc = (xfContext*) instance->context; + xfContext* xfc = (xfContext*) context; - if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0) + if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) { - xfc->rdpei = (RdpeiClientContext*) pInterface; + xfc->rdpei = (RdpeiClientContext*) e->pInterface; } - - return 0; } -int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface) +void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e) { - return 0; + } diff --git a/client/X11/xf_channels.h b/client/X11/xf_channels.h index 1aeaf1a66..bb52d5e52 100644 --- a/client/X11/xf_channels.h +++ b/client/X11/xf_channels.h @@ -27,4 +27,7 @@ int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface); int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface); +void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e); +void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e); + #endif diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 1bc990262..0bb180de3 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -666,8 +666,11 @@ BOOL xf_pre_connect(freerdp* instance) settings = instance->settings; channels = instance->context->channels; - instance->OnChannelConnected = xf_on_channel_connected; - instance->OnChannelDisconnected = xf_on_channel_disconnected; + PubSub_SubscribeChannelConnected(instance->context->pubSub, + (pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler); + + PubSub_SubscribeChannelDisconnected(instance->context->pubSub, + (pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler); freerdp_client_load_addins(channels, instance->settings); diff --git a/client/common/client.c b/client/common/client.c index acc47d064..778c41373 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -56,8 +56,8 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) freerdp_context_new(instance); context = instance->context; - context->instance = instance; - context->settings = instance->settings; + context->instance = instance; + context->settings = instance->settings; return context; } diff --git a/include/freerdp/event.h b/include/freerdp/event.h index cd4c7e7f1..812609a36 100644 --- a/include/freerdp/event.h +++ b/include/freerdp/event.h @@ -77,6 +77,16 @@ DEFINE_EVENT_BEGIN(ConnectionResult) int result; DEFINE_EVENT_END(ConnectionResult) +DEFINE_EVENT_BEGIN(ChannelConnected) + const char* name; + void* pInterface; +DEFINE_EVENT_END(ChannelConnected) + +DEFINE_EVENT_BEGIN(ChannelDisconnected) + const char* name; + void* pInterface; +DEFINE_EVENT_END(ChannelDisconnected) + #ifdef __cplusplus } #endif diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 214c2f719..e3ce2bf84 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -66,9 +66,6 @@ typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size); typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size); -typedef int (*pOnChannelConnected)(freerdp* instance, const char* name, void* pInterface); -typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void* pInterface); - /** * Defines the context for a given instance of RDP connection. * It is embedded in the rdp_freerdp structure, and allocated by a call to freerdp_context_new(). @@ -208,9 +205,6 @@ struct rdp_freerdp This is called by freerdp_channel_process() (if not NULL). Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */ - ALIGN64 pOnChannelConnected OnChannelConnected; - ALIGN64 pOnChannelDisconnected OnChannelDisconnected; - UINT64 paddingE[80 - 66]; /* 66 */ }; diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 85f5c3235..396750081 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -338,6 +338,8 @@ static wEventType FreeRDP_Events[] = DEFINE_EVENT_ENTRY(ParamChange) DEFINE_EVENT_ENTRY(Terminate) DEFINE_EVENT_ENTRY(ConnectionResult) + DEFINE_EVENT_ENTRY(ChannelConnected) + DEFINE_EVENT_ENTRY(ChannelDisconnected) }; /** Allocator function for a rdp context. From a306d3f9fc4f2e877f5b191f514ffbc687314553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 11 Jul 2013 11:04:20 -0700 Subject: [PATCH 68/74] channels/rdpei: fix multitouch with Word 2013 --- channels/rdpei/client/rdpei_main.c | 17 +++++++++++++---- channels/rdpei/client/rdpei_main.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 854fd46ab..3984b6c32 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -212,7 +212,7 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) Stream_Seek(s, RDPINPUT_HEADER_LENGTH); Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ - Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V1); /* protocolVersion (4 bytes) */ + Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V10); /* protocolVersion (4 bytes) */ Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */ Stream_SealLength(s); @@ -249,6 +249,7 @@ void rdpei_print_contact_flags(UINT32 contactFlags) int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) { int index; + int rectSize = 2; RDPINPUT_CONTACT_DATA* contact; #ifdef WITH_DEBUG_RDPEI @@ -264,12 +265,18 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) */ rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ - Stream_EnsureRemainingCapacity(s, frame->contactCount * 32); + Stream_EnsureRemainingCapacity(s, frame->contactCount * 64); for (index = 0; index < frame->contactCount; index++) { contact = &frame->contacts[index]; + contact->fieldsPresent |= CONTACT_DATA_CONTACTRECT_PRESENT; + contact->contactRectLeft = contact->x - rectSize; + contact->contactRectTop = contact->y - rectSize; + contact->contactRectRight = contact->x + rectSize; + contact->contactRectBottom = contact->y + rectSize; + #ifdef WITH_DEBUG_RDPEI printf("contact[%d].contactId: %d\n", index, contact->contactId); printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent); @@ -325,7 +332,7 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_ wStream* s; UINT32 pduLength; - pduLength = 64 + (frame->contactCount * 32); + pduLength = 64 + (frame->contactCount * 64); s = Stream_New(NULL, pduLength); Stream_Seek(s, RDPINPUT_HEADER_LENGTH); @@ -355,11 +362,13 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */ - if (protocolVersion != RDPINPUT_PROTOCOL_V1) +#if 0 + if (protocolVersion != RDPINPUT_PROTOCOL_V10) { fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); return -1; } +#endif return 0; } diff --git a/channels/rdpei/client/rdpei_main.h b/channels/rdpei/client/rdpei_main.h index c0d0d2d67..cf4dccee0 100644 --- a/channels/rdpei/client/rdpei_main.h +++ b/channels/rdpei/client/rdpei_main.h @@ -35,7 +35,8 @@ /* Protocol Version */ -#define RDPINPUT_PROTOCOL_V1 0x00010000 +#define RDPINPUT_PROTOCOL_V10 0x00010000 +#define RDPINPUT_PROTOCOL_V101 0x00010001 /* Client Ready Flags */ From 44ead029f7dada5ad6cb71848d9605eb1cf9e7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Thu, 11 Jul 2013 11:19:21 -0700 Subject: [PATCH 69/74] MacFreeRDP: fixed incorrect invalidation region that caused "tiles". Removed unused variables. --- client/Mac/MRDPView.m | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 95dc36f0a..0accf655b 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -889,13 +889,7 @@ BOOL mac_pre_connect(freerdp* instance) BOOL mac_post_connect(freerdp* instance) { - int index; - int fds[32]; UINT32 flags; - int rd_count = 0; - int wr_count = 0; - void* rd_fds[32]; - void* wr_fds[32]; rdpPointer rdp_pointer; mfContext *mfc = (mfContext*) instance->context; @@ -1150,10 +1144,10 @@ void mac_end_paint(rdpContext* context) for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++) { - drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x; - drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y; - drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w; - drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h; + drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x - 1; + drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y - 1; + drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w + 1; + drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h + 1; windows_to_apple_cords(mfc->view, &drawRect); [view setNeedsDisplayInRect:drawRect]; } From 6e6581ab8729450b94e7c3aa8da96e3f813a34fa Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 15 Jul 2013 10:20:24 +0200 Subject: [PATCH 70/74] Fix for Issue #1349 --- libfreerdp/core/license.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index b98d41e9a..ebc462fa5 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -107,7 +107,7 @@ void license_print_scope_list(SCOPE_LIST* scopeList) for (index = 0; index < scopeList->count; index++) { scope = &scopeList->array[index]; - fprintf(stderr, "\t%s\n", (char*) scope->buffer); + fprintf(stderr, "\t%s\n", (char*) scope->data); } } @@ -810,11 +810,11 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s) fprintf(stderr, "\n"); fprintf(stderr, "EncryptedPlatformChallenge:\n"); - winpr_HexDump(license->EncryptedPlatformChallenge->buffer, license->EncryptedPlatformChallenge->length); + winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length); fprintf(stderr, "\n"); fprintf(stderr, "PlatformChallenge:\n"); - winpr_HexDump(license->PlatformChallenge->buffer, license->PlatformChallenge->length); + winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length); fprintf(stderr, "\n"); fprintf(stderr, "MacData:\n"); @@ -937,13 +937,13 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s) fprintf(stderr, "\n"); fprintf(stderr, "EncryptedPremasterSecret\n"); - winpr_HexDump(license->EncryptedPremasterSecret->buffer, license->EncryptedPremasterSecret->length); + winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length); fprintf(stderr, "\n"); - fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->buffer); + fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data); fprintf(stderr, "\n"); - fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->buffer); + fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data); fprintf(stderr, "\n"); #endif } @@ -1048,7 +1048,7 @@ void license_send_platform_challenge_response_packet(rdpLicense* license) fprintf(stderr, "\n"); fprintf(stderr, "EncryptedHardwareId:\n"); - winpr_HexDump(license->EncryptedHardwareId->buffer, 20); + winpr_HexDump(license->EncryptedHardwareId->data, 20); fprintf(stderr, "\n"); #endif From e0e337e27888e6e6c5b68f74ef56a523fa020b6e Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Mon, 15 Jul 2013 15:00:18 +0200 Subject: [PATCH 71/74] libfreerdp-gdi: added gdi_surface_frame_marker Frame markes are not really implemented. Just SendFrameAcknowledge on SURFACECMD_FRAMEACTION_END if settings->FrameAcknowledge > 0 This fixes issue #1352 --- libfreerdp/gdi/gdi.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 7e64be5e2..6a9cea2f3 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -739,6 +739,28 @@ void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) fprintf(stderr, "EllipseCB\n"); } +void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +{ + DEBUG_GDI("frameId %d frameAction %d", + surface_frame_marker->frameId, + surface_frame_marker->frameAction); + + /* TODO: Implement frame marker completely */ + + switch (surface_frame_marker->frameAction) + { + case SURFACECMD_FRAMEACTION_BEGIN: + break; + + case SURFACECMD_FRAMEACTION_END: + if (context->instance->settings->FrameAcknowledge > 0) + { + IFCALL(context->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId); + } + break; + } +} + int tilenum = 0; void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) @@ -890,6 +912,7 @@ void gdi_register_update_callbacks(rdpUpdate* update) primary->EllipseCB = gdi_ellipse_cb; update->SurfaceBits = gdi_surface_bits; + update->SurfaceFrameMarker = gdi_surface_frame_marker; } void gdi_init_primary(rdpGdi* gdi) From b0450f556ed396b885d6f6fe58d1843789d5fa1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 15 Jul 2013 10:43:38 -0400 Subject: [PATCH 72/74] channels/disp: initial MS-RDPEDISP support (8.1 Preview build) --- channels/disp/client/disp_main.c | 70 +++++++++++++++++++++++++++----- channels/disp/client/disp_main.h | 4 +- include/freerdp/client/disp.h | 5 +++ 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index 5983c9d6f..feb971550 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -77,10 +78,19 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback wStream* s; UINT32 type; UINT32 length; + DISP_PLUGIN* disp; + UINT32 MonitorLayoutSize; - fprintf(stderr, "DisplayControlMonitorLayout\n"); + disp = (DISP_PLUGIN*) callback->plugin; + +#ifdef DISP_PREVIEW + MonitorLayoutSize = 32; +#else + MonitorLayoutSize = 40; +#endif + + length = 8 + 8 + (NumMonitors * MonitorLayoutSize); - length = 8 + 4 + NumMonitors * 32; type = DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT; s = Stream_New(NULL, length); @@ -88,10 +98,35 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, type); /* Type (4 bytes) */ Stream_Write_UINT32(s, length); /* Length (4 bytes) */ + if (NumMonitors > disp->MaxNumMonitors) + NumMonitors = disp->MaxNumMonitors; + +#ifdef DISP_PREVIEW Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */ +#else + Stream_Write_UINT32(s, MonitorLayoutSize); /* MonitorLayoutSize (4 bytes) */ +#endif + + Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */ + + //fprintf(stderr, "NumMonitors: %d\n", NumMonitors); for (index = 0; index < NumMonitors; index++) { + Monitors[index].Width -= (Monitors[index].Width % 2); + + if (Monitors[index].Width < 200) + Monitors[index].Width = 200; + + if (Monitors[index].Width > disp->MaxMonitorWidth) + Monitors[index].Width = disp->MaxMonitorWidth; + + if (Monitors[index].Height < 200) + Monitors[index].Height = 200; + + if (Monitors[index].Height > disp->MaxMonitorHeight) + Monitors[index].Height = disp->MaxMonitorHeight; + Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */ @@ -101,8 +136,21 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */ - //Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */ - //Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ +#if 0 + fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags); + fprintf(stderr, "\t: Left: %d\n", Monitors[index].Left); + fprintf(stderr, "\t: Top: %d\n", Monitors[index].Top); + fprintf(stderr, "\t: Width: %d\n", Monitors[index].Width); + fprintf(stderr, "\t: Height: %d\n", Monitors[index].Height); + fprintf(stderr, "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth); + fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight); + fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation); +#endif + +#ifndef DISP_PREVIEW + Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ +#endif } Stream_SealLength(s); @@ -124,8 +172,8 @@ int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */ - fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n", - disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight); + //fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n", + // disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight); return 0; } @@ -138,7 +186,7 @@ int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, type); /* Type (4 bytes) */ Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - fprintf(stderr, "Type: %d Length: %d\n", type, length); + //fprintf(stderr, "Type: %d Length: %d\n", type, length); switch (type) { @@ -159,8 +207,6 @@ static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, U int status = 0; DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback; - fprintf(stderr, "DisplayControlOnDataReceived\n"); - s = Stream_New(pBuffer, cbSize); status = disp_recv_pdu(callback, s); @@ -201,8 +247,6 @@ static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac *ppCallback = (IWTSVirtualChannelCallback*) callback; - fprintf(stderr, "DisplayControlNewChannelConnection\n"); - return 0; } @@ -285,6 +329,10 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) disp->iface.pInterface = (void*) context; + disp->MaxNumMonitors = 16; + disp->MaxMonitorWidth = 8192; + disp->MaxMonitorHeight = 8192; + error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp); } } diff --git a/channels/disp/client/disp_main.h b/channels/disp/client/disp_main.h index 9e99abaad..db1ce10c5 100644 --- a/channels/disp/client/disp_main.h +++ b/channels/disp/client/disp_main.h @@ -31,8 +31,10 @@ #include -#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000001 #define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002 +#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000003 + +#define DISP_PREVIEW 1 #endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */ diff --git a/include/freerdp/client/disp.h b/include/freerdp/client/disp.h index e13bdea0b..fa747db52 100644 --- a/include/freerdp/client/disp.h +++ b/include/freerdp/client/disp.h @@ -20,6 +20,11 @@ #ifndef FREERDP_CHANNEL_CLIENT_DISP_H #define FREERDP_CHANNEL_CLIENT_DISP_H +#define ORIENTATION_LANDSCAPE 0 +#define ORIENTATION_PORTRAIT 90 +#define ORIENTATION_LANDSCAPE_FLIPPED 180 +#define ORIENTATION_PORTRAIT_FLIPPED 270 + #define DISPLAY_CONTROL_MONITOR_PRIMARY 0x00000001 struct _DISPLAY_CONTROL_MONITOR_LAYOUT From a2992b06b72ebe52a580c14bfbd666efca691e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 15 Jul 2013 17:37:46 -0400 Subject: [PATCH 73/74] freerdp: merge with master --- buildx/client/Mac/cli/Info.plist | 34 -------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 buildx/client/Mac/cli/Info.plist diff --git a/buildx/client/Mac/cli/Info.plist b/buildx/client/Mac/cli/Info.plist deleted file mode 100644 index cb6976502..000000000 --- a/buildx/client/Mac/cli/Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - - CFBundleIconFile - FreeRDP - CFBundleIdentifier - FreeRDP.Mac - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSMinimumSystemVersion - - NSHumanReadableCopyright - Copyright © 2012 __MyCompanyName__. All rights reserved. - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - From 67b972a021d1672f0b8c0aadcb37453aa0563d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 16 Jul 2013 14:44:49 -0400 Subject: [PATCH 74/74] mfreerdp: fix cursor rendering --- client/Mac/MRDPView.m | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 0accf655b..c92731914 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -903,7 +903,7 @@ BOOL mac_post_connect(freerdp* instance) rdp_pointer.SetNull = mf_Pointer_SetNull; rdp_pointer.SetDefault = mf_Pointer_SetDefault; - flags = CLRBUF_32BPP; + flags = CLRBUF_32BPP | CLRCONV_ALPHA; gdi_init(instance, flags, NULL); rdpGdi* gdi = instance->context->gdi; @@ -975,7 +975,7 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer) MRDPCursor* mrdpCursor = [[MRDPCursor alloc] init]; mfContext* mfc = (mfContext*) context; MRDPView* view = (MRDPView*) mfc->view; - + rect.size.width = pointer->width; rect.size.height = pointer->height; rect.origin.x = pointer->xPos; @@ -986,10 +986,7 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer) freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData, pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv); - - // TODO if xorBpp is > 24 need to call freerdp_image_swap_color_order - // see file df_graphics.c - + /* store cursor bitmap image in representation - required by NSImage */ bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data pixelsWide:rect.size.width @@ -1057,8 +1054,6 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer) MRDPView* view = (MRDPView*) mfc->view; NSMutableArray* ma = view->cursors; - - return; /* disable pointer until it is fixed */ if (!view->mouseInClientArea) return; @@ -1227,6 +1222,7 @@ static void channel_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBac freerdp_channels_process_pending_messages(instance); event = freerdp_channels_pop_event(instance->context->channels); + if (event) { switch (GetMessageClass(event->id))