Merge branch 'master' of git://github.com/FreeRDP/FreeRDP

This commit is contained in:
LawrenceK 2012-08-20 19:37:37 +01:00
commit 28813f3779
468 changed files with 12070 additions and 2035 deletions

2
.gitignore vendored
View File

@ -39,10 +39,12 @@ Debug
*.dylib *.dylib
cunit/test_freerdp cunit/test_freerdp
client/X11/xfreerdp client/X11/xfreerdp
client/Mac/xcode
client/test/freerdp-test client/test/freerdp-test
client/DirectFB/dfreerdp client/DirectFB/dfreerdp
server/test/tfreerdp-server server/test/tfreerdp-server
server/X11/xfreerdp-server server/X11/xfreerdp-server
xcode
# Other # Other
*~ *~

View File

@ -44,6 +44,9 @@ set(FREERDP_VERSION_MINOR "0")
set(FREERDP_VERSION_REVISION "1") set(FREERDP_VERSION_REVISION "1")
set(FREERDP_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}") set(FREERDP_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}")
set(FREERDP_VERSION_FULL "${FREERDP_VERSION}.${FREERDP_VERSION_REVISION}") set(FREERDP_VERSION_FULL "${FREERDP_VERSION}.${FREERDP_VERSION_REVISION}")
include(GetGitRevisionDescription)
git_describe(GIT_REVISION --match "[0-9]*" --abbrev=4 --tags --always)
message(STATUS "Git Revision ${GIT_REVISION}")
# Default to release build type # Default to release build type
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
@ -52,7 +55,7 @@ endif()
# Default to build shared libs # Default to build shared libs
if(NOT DEFINED BUILD_SHARED_LIBS) if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON) set(BUILD_SHARED_LIBS ON)
endif() endif()
# Compiler-specific flags # Compiler-specific flags
@ -78,7 +81,11 @@ endif()
if(MSVC) if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd /MT") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd /MT")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
@ -88,6 +95,29 @@ if(MSVC)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
endif() endif()
# This forces the MSVC runtime to be statically linked
if(MSVC)
foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "MSVC C Debug MT flags " FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "MSVC CXX Debug MT flags " FORCE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "MSVC C Release MT flags " FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "MSVC CXX Release MT flags " FORCE)
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}" CACHE STRING "MSVC C Debug MT flags " FORCE)
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "MSVC C Release MT flags " FORCE)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}" CACHE STRING "MSVC CXX Debug MT flags " FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "MSVC CXX Release MT flags " FORCE)
endif()
# config.h definition for installable headers
check_include_files(limits.h FREERDP_HAVE_LIMITS_H)
check_include_files(stdint.h FREERDP_HAVE_STDINT_H)
check_include_files(stdbool.h FREERDP_HAVE_STDBOOL_H)
check_include_files(inttypes.h FREERDP_HAVE_INTTYPES_H)
# Include files # Include files
check_include_files(fcntl.h HAVE_FCNTL_H) check_include_files(fcntl.h HAVE_FCNTL_H)
check_include_files(unistd.h HAVE_UNISTD_H) check_include_files(unistd.h HAVE_UNISTD_H)
@ -95,6 +125,9 @@ check_include_files(limits.h HAVE_LIMITS_H)
check_include_files(stdint.h HAVE_STDINT_H) check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdbool.h HAVE_STDBOOL_H) check_include_files(stdbool.h HAVE_STDBOOL_H)
check_include_files(inttypes.h HAVE_INTTYPES_H) check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(sys/modem.h HAVE_SYS_MODEM_H)
check_include_files(sys/filio.h HAVE_SYS_FILIO_H)
check_include_files(sys/strtio.h HAVE_SYS_STRTIO_H)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF) check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
@ -105,14 +138,23 @@ endif()
# Mac OS X # Mac OS X
if(APPLE) if(APPLE)
include_directories(/opt/local/include) if(IS_DIRECTORY /opt/local/include)
link_directories(/opt/local/lib) include_directories(/opt/local/include)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4") link_directories(/opt/local/lib)
endif()
if(WITH_CLANG)
set(CMAKE_C_COMPILER "clang")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl-framework,CoreFoundation")
endif() endif()
if(NOT WIN32) if(NOT WIN32)
find_required_package(ZLIB) find_required_package(ZLIB)
find_optional_package(PulseAudio) find_optional_package(PulseAudio)
find_optional_package(MacAudio)
find_optional_package(PCSC) find_optional_package(PCSC)
find_suggested_package(Cups) find_suggested_package(Cups)
@ -131,59 +173,64 @@ set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp")
set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps") set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps")
# Path to put plugins # Path to put plugins
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp") set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp")
# Path to put extensions # Path to put extensions
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp/extensions") set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions")
# Include directories # Include directories
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# WinPR
set(WINPR_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/winpr/include")
include_directories(${WINPR_INCLUDE_DIR})
# Configure files # Configure files
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) add_definitions("-DHAVE_CONFIG_H")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/freerdp/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/freerdp/config.h)
# Generate pkg-config # Generate pkg-config
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc @ONLY) if(NOT MSVC)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
# Build CUnit # Build CUnit
find_optional_package(CUnit) find_optional_package(CUnit)
if(WITH_CUNIT) if(WITH_CUNIT)
enable_testing() enable_testing()
add_subdirectory(cunit) add_subdirectory(cunit)
endif() endif()
# Sub-directories # Sub-directories
add_subdirectory(include) add_subdirectory(include)
add_subdirectory(libfreerdp-utils)
add_subdirectory(winpr) add_subdirectory(winpr)
add_subdirectory(libfreerdp-gdi) add_subdirectory(libfreerdp)
add_subdirectory(libfreerdp-rail)
add_subdirectory(libfreerdp-cache)
add_subdirectory(libfreerdp-codec)
add_subdirectory(libfreerdp-crypto)
add_subdirectory(libfreerdp-channels)
add_subdirectory(libfreerdp-locale)
add_subdirectory(libfreerdp-core)
if(NOT WIN32) if(WITH_CHANNELS)
add_subdirectory(channels) add_subdirectory(channels)
endif() endif()
option(WITH_CLIENT "Build client binaries" ON)
if(WITH_CLIENT) if(WITH_CLIENT)
add_subdirectory(client) add_subdirectory(client)
endif() endif()
option(WITH_SERVER "Build server binaries" OFF)
if(WITH_SERVER) if(WITH_SERVER)
add_subdirectory(server) add_subdirectory(server)
endif() endif()
add_subdirectory(keymaps) if(WITH_THIRD_PARTY)
add_subdirectory(third-party)
endif()
if(NOT MSVC)
add_subdirectory(keymaps)
endif()
# Source package # Source package
set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt") set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt")
@ -192,4 +239,3 @@ string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_PROJECT_NAME_lower)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}-${FREERDP_VERSION_FULL}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}-${FREERDP_VERSION_FULL}")
include(CPack) include(CPack)

View File

@ -19,9 +19,11 @@
add_subdirectory(cliprdr) add_subdirectory(cliprdr)
add_subdirectory(drdynvc) add_subdirectory(drdynvc)
add_subdirectory(rdpdbg)
add_subdirectory(rdpdr)
add_subdirectory(rail) add_subdirectory(rail)
add_subdirectory(rdpsnd) add_subdirectory(rdpdbg)
add_subdirectory(skel) add_subdirectory(skel)
if(NOT WIN32)
add_subdirectory(rdpdr)
add_subdirectory(rdpsnd)
endif()

View File

@ -22,12 +22,15 @@ set(CLIPRDR_SRCS
cliprdr_format.c cliprdr_format.c
cliprdr_format.h cliprdr_format.h
cliprdr_main.c cliprdr_main.c
cliprdr_main.h cliprdr_main.h)
)
add_library(cliprdr ${CLIPRDR_SRCS}) add_library(cliprdr ${CLIPRDR_SRCS})
set_target_properties(cliprdr PROPERTIES PREFIX "") set_target_properties(cliprdr PROPERTIES PREFIX "")
target_link_libraries(cliprdr freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(cliprdr freerdp)
else()
target_link_libraries(cliprdr freerdp-utils)
endif()
install(TARGETS cliprdr DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS cliprdr DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -18,7 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -28,10 +28,16 @@ set(DRDYNVC_SRCS
add_library(drdynvc ${DRDYNVC_SRCS}) add_library(drdynvc ${DRDYNVC_SRCS})
set_target_properties(drdynvc PROPERTIES PREFIX "") set_target_properties(drdynvc PROPERTIES PREFIX "")
target_link_libraries(drdynvc freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(drdynvc freerdp)
else()
target_link_libraries(drdynvc freerdp-utils)
endif()
install(TARGETS drdynvc DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS drdynvc DESTINATION ${FREERDP_PLUGIN_PATH})
add_subdirectory(tsmf) if(NOT WIN32)
add_subdirectory(audin) add_subdirectory(tsmf)
endif()
add_subdirectory(audin)

View File

@ -19,15 +19,18 @@
set(AUDIN_SRCS set(AUDIN_SRCS
audin_main.c audin_main.c
audin_main.h audin_main.h)
)
include_directories(..) include_directories(..)
add_library(audin ${AUDIN_SRCS}) add_library(audin ${AUDIN_SRCS})
set_target_properties(audin PROPERTIES PREFIX "") set_target_properties(audin PROPERTIES PREFIX "")
target_link_libraries(audin freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(audin freerdp)
else()
target_link_libraries(audin freerdp-utils)
endif()
install(TARGETS audin DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS audin DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,8 +18,7 @@
# limitations under the License. # limitations under the License.
set(AUDIN_ALSA_SRCS set(AUDIN_ALSA_SRCS
audin_alsa.c audin_alsa.c)
)
include_directories(..) include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS}) include_directories(${ALSA_INCLUDE_DIRS})
@ -27,7 +26,12 @@ include_directories(${ALSA_INCLUDE_DIRS})
add_library(audin_alsa ${AUDIN_ALSA_SRCS}) add_library(audin_alsa ${AUDIN_ALSA_SRCS})
set_target_properties(audin_alsa PROPERTIES PREFIX "") set_target_properties(audin_alsa PROPERTIES PREFIX "")
target_link_libraries(audin_alsa freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(audin_alsa freerdp)
else()
target_link_libraries(audin_alsa freerdp-utils)
endif()
target_link_libraries(audin_alsa ${ALSA_LIBRARIES}) target_link_libraries(audin_alsa ${ALSA_LIBRARIES})
install(TARGETS audin_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS audin_alsa DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/thread.h> #include <freerdp/utils/thread.h>

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/load_plugin.h> #include <freerdp/utils/load_plugin.h>
@ -248,7 +253,7 @@ static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, STRE
DEBUG_DVC("FramesPerPacket=%d initialFormat=%d", DEBUG_DVC("FramesPerPacket=%d initialFormat=%d",
FramesPerPacket, initialFormat); FramesPerPacket, initialFormat);
if (initialFormat >= callback->formats_count) if (initialFormat >= (uint32) callback->formats_count)
{ {
DEBUG_WARN("invalid format index %d (total %d)", DEBUG_WARN("invalid format index %d (total %d)",
initialFormat, callback->formats_count); initialFormat, callback->formats_count);
@ -279,7 +284,7 @@ static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallb
DEBUG_DVC("NewFormat=%d", NewFormat); DEBUG_DVC("NewFormat=%d", NewFormat);
if (NewFormat >= callback->formats_count) if (NewFormat >= (uint32) callback->formats_count)
{ {
DEBUG_WARN("invalid format index %d (total %d)", DEBUG_WARN("invalid format index %d (total %d)",
NewFormat, callback->formats_count); NewFormat, callback->formats_count);

View File

@ -27,7 +27,12 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR})
add_library(audin_pulse ${AUDIN_PULSE_SRCS}) add_library(audin_pulse ${AUDIN_PULSE_SRCS})
set_target_properties(audin_pulse PROPERTIES PREFIX "") set_target_properties(audin_pulse PROPERTIES PREFIX "")
target_link_libraries(audin_pulse freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(audin_pulse freerdp)
else()
target_link_libraries(audin_pulse freerdp-utils)
endif()
target_link_libraries(audin_pulse ${PULSEAUDIO_LIBRARY}) target_link_libraries(audin_pulse ${PULSEAUDIO_LIBRARY})
install(TARGETS audin_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS audin_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>

View File

@ -20,7 +20,10 @@
#ifndef __DRDYNVC_TYPES_H #ifndef __DRDYNVC_TYPES_H
#define __DRDYNVC_TYPES_H #define __DRDYNVC_TYPES_H
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <freerdp/dvc.h> #include <freerdp/dvc.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/debug.h> #include <freerdp/utils/debug.h>

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h> #include <freerdp/utils/list.h>
@ -194,7 +199,7 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA*
while (data && data->size > 0) while (data && data->size > 0)
{ {
pDVCPluginEntry = freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry"); pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry");
if (pDVCPluginEntry != NULL) if (pDVCPluginEntry != NULL)
{ {
@ -206,7 +211,7 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA*
pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
} }
data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); data = (RDP_PLUGIN_DATA*)(((uint8*) data) + data->size);
} }
return 0; return 0;
@ -414,7 +419,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 C
if (channel->dvc_data) if (channel->dvc_data)
{ {
/* Fragmented data */ /* Fragmented data */
if (stream_get_length(channel->dvc_data) + data_size > stream_get_size(channel->dvc_data)) if (stream_get_length(channel->dvc_data) + data_size > (uint32) stream_get_size(channel->dvc_data))
{ {
DEBUG_WARN("data exceeding declared length!"); DEBUG_WARN("data exceeding declared length!");
stream_free(channel->dvc_data); stream_free(channel->dvc_data);

View File

@ -32,15 +32,18 @@ set(TSMF_SRCS
tsmf_main.h tsmf_main.h
tsmf_media.c tsmf_media.c
tsmf_media.h tsmf_media.h
tsmf_types.h tsmf_types.h)
)
include_directories(..) include_directories(..)
add_library(tsmf ${TSMF_SRCS}) add_library(tsmf ${TSMF_SRCS})
set_target_properties(tsmf PROPERTIES PREFIX "") set_target_properties(tsmf PROPERTIES PREFIX "")
target_link_libraries(tsmf freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(tsmf freerdp)
else()
target_link_libraries(tsmf freerdp-utils)
endif()
install(TARGETS tsmf DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS tsmf DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -27,7 +27,12 @@ include_directories(${ALSA_INCLUDE_DIRS})
add_library(tsmf_alsa ${TSMF_ALSA_SRCS}) add_library(tsmf_alsa ${TSMF_ALSA_SRCS})
set_target_properties(tsmf_alsa PROPERTIES PREFIX "") set_target_properties(tsmf_alsa PROPERTIES PREFIX "")
target_link_libraries(tsmf_alsa freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(tsmf_alsa freerdp)
else()
target_link_libraries(tsmf_alsa freerdp-utils)
endif()
target_link_libraries(tsmf_alsa ${ALSA_LIBRARIES}) target_link_libraries(tsmf_alsa ${ALSA_LIBRARIES})
install(TARGETS tsmf_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS tsmf_alsa DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,6 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -34,7 +34,12 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif() endif()
endif() endif()
target_link_libraries(tsmf_ffmpeg freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(tsmf_ffmpeg freerdp)
else()
target_link_libraries(tsmf_ffmpeg freerdp-utils)
endif()
target_link_libraries(tsmf_ffmpeg ${FFMPEG_LIBRARIES}) target_link_libraries(tsmf_ffmpeg ${FFMPEG_LIBRARIES})
install(TARGETS tsmf_ffmpeg DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS tsmf_ffmpeg DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/event.h> #include <freerdp/utils/event.h>
#include <freerdp/plugins/tsmf.h> #include <freerdp/plugins/tsmf.h>

View File

@ -27,7 +27,12 @@ include_directories(${GSTREAMER_INCLUDE_DIRS})
add_library(tsmf_gstreamer ${TSMF_GSTREAMER_SRCS}) add_library(tsmf_gstreamer ${TSMF_GSTREAMER_SRCS})
set_target_properties(tsmf_gstreamer PROPERTIES PREFIX "") set_target_properties(tsmf_gstreamer PROPERTIES PREFIX "")
target_link_libraries(tsmf_gstreamer freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(tsmf_gstreamer freerdp)
else()
target_link_libraries(tsmf_gstreamer freerdp-utils)
endif()
target_link_libraries(tsmf_gstreamer ${GSTREAMER_LIBRARIES} gstapp-0.10 gstinterfaces-0.10 Xrandr X11 Xext) target_link_libraries(tsmf_gstreamer ${GSTREAMER_LIBRARIES} gstapp-0.10 gstinterfaces-0.10 Xrandr X11 Xext)
install(TARGETS tsmf_gstreamer DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS tsmf_gstreamer DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,6 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>

View File

@ -18,8 +18,7 @@
# limitations under the License. # limitations under the License.
set(TSMF_PULSE_SRCS set(TSMF_PULSE_SRCS
tsmf_pulse.c tsmf_pulse.c)
)
include_directories(..) include_directories(..)
include_directories(${PULSEAUDIO_INCLUDE_DIR}) include_directories(${PULSEAUDIO_INCLUDE_DIR})
@ -27,8 +26,11 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR})
add_library(tsmf_pulse ${TSMF_PULSE_SRCS}) add_library(tsmf_pulse ${TSMF_PULSE_SRCS})
set_target_properties(tsmf_pulse PROPERTIES PREFIX "") set_target_properties(tsmf_pulse PROPERTIES PREFIX "")
target_link_libraries(tsmf_pulse freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY}) target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY} freerdp)
else()
target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY} freerdp-utils)
endif()
install(TARGETS tsmf_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS tsmf_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,10 +17,15 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h> #include <freerdp/utils/load_plugin.h>

View File

@ -34,6 +34,8 @@ struct _ITSMFAudioDevice
boolean (*Play) (ITSMFAudioDevice* audio, uint8* data, uint32 data_size); boolean (*Play) (ITSMFAudioDevice* audio, uint8* data, uint32 data_size);
/* Get the latency of the last written sample, in 100ns */ /* Get the latency of the last written sample, in 100ns */
uint64 (*GetLatency) (ITSMFAudioDevice* audio); uint64 (*GetLatency) (ITSMFAudioDevice* audio);
/* Change the playback volume level */
void (*ChangeVolume) (ITSMFAudioDevice* audio, uint32 newVolume, uint32 muted);
/* Flush queued audio data */ /* Flush queued audio data */
void (*Flush) (ITSMFAudioDevice* audio); void (*Flush) (ITSMFAudioDevice* audio);
/* Free the audio device */ /* Free the audio device */

View File

@ -18,9 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/hexdump.h> #include <freerdp/utils/hexdump.h>

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h> #include <freerdp/utils/load_plugin.h>

View File

@ -18,9 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
@ -228,14 +233,18 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
{ {
DEBUG_DVC("on stream volume");
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_DVC("on stream volume");
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation) if (presentation)
{ {
stream_seek(ifman->input, 16);
uint32 newVolume; uint32 newVolume;
uint32 muted; uint32 muted;
stream_seek(ifman->input, 16);
stream_read_uint32(ifman->input, newVolume); stream_read_uint32(ifman->input, newVolume);
DEBUG_DVC("on stream volume: new volume=[%d]", newVolume); DEBUG_DVC("on stream volume: new volume=[%d]", newVolume);
stream_read_uint32(ifman->input, muted); stream_read_uint32(ifman->input, muted);
@ -243,28 +252,37 @@ int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
tsmf_presentation_volume_changed(presentation, newVolume, muted); tsmf_presentation_volume_changed(presentation, newVolume, muted);
} }
else else
{
DEBUG_WARN("unknown presentation id"); DEBUG_WARN("unknown presentation id");
}
ifman->output_pending = true; ifman->output_pending = true;
return 0; return 0;
} }
int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
{ {
DEBUG_DVC("on channel volume");
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_DVC("on channel volume");
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation) if (presentation)
{ {
stream_seek(ifman->input, 16);
uint32 channelVolume; uint32 channelVolume;
uint32 changedChannel; uint32 changedChannel;
stream_seek(ifman->input, 16);
stream_read_uint32(ifman->input, channelVolume); stream_read_uint32(ifman->input, channelVolume);
DEBUG_DVC("on channel volume: channel volume=[%d]", channelVolume); DEBUG_DVC("on channel volume: channel volume=[%d]", channelVolume);
stream_read_uint32(ifman->input, changedChannel); stream_read_uint32(ifman->input, changedChannel);
DEBUG_DVC("on stream volume: changed channel=[%d]", changedChannel); DEBUG_DVC("on stream volume: changed channel=[%d]", changedChannel);
} }
ifman->output_pending = true; ifman->output_pending = true;
return 0; return 0;
} }
@ -310,7 +328,9 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects);
if (presentation == NULL) if (presentation == NULL)
{
error = 1; error = 1;
}
else else
{ {
if (num_rects > 0) if (num_rects > 0)
@ -335,7 +355,9 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
} }
tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects); tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects);
} }
ifman->output_pending = true; ifman->output_pending = true;
return error; return error;
} }
@ -472,11 +494,13 @@ int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation;
DEBUG_DVC(""); DEBUG_DVC("");
ifman->output_pending = true; ifman->output_pending = true;
/* Added pause control so gstreamer pipeline can be paused accordingly */ /* Added pause control so gstreamer pipeline can be paused accordingly */
TSMF_PRESENTATION* presentation;
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation) if (presentation)
tsmf_presentation_paused(presentation); tsmf_presentation_paused(presentation);
@ -487,16 +511,20 @@ int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation;
DEBUG_DVC(""); DEBUG_DVC("");
ifman->output_pending = true; ifman->output_pending = true;
/* Added restart control so gstreamer pipeline can be resumed accordingly */ /* Added restart control so gstreamer pipeline can be resumed accordingly */
TSMF_PRESENTATION* presentation;
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation) if (presentation)
tsmf_presentation_restarted(presentation); tsmf_presentation_restarted(presentation);
else else
DEBUG_WARN("unknown presentation id"); DEBUG_WARN("unknown presentation id");
return 0; return 0;
} }
@ -507,6 +535,7 @@ int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
DEBUG_DVC(""); DEBUG_DVC("");
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation) if (presentation)
tsmf_presentation_stop(presentation); tsmf_presentation_stop(presentation);
else else

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
@ -416,7 +421,7 @@ static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
} }
} }
data = (RDP_PLUGIN_DATA*)(((void*)data) + data->size); data = (RDP_PLUGIN_DATA*)(((uint8*)data) + data->size);
} }
} }

View File

@ -18,12 +18,23 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#endif
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h> #include <freerdp/utils/list.h>
@ -238,18 +249,19 @@ static void tsmf_stream_process_ack(TSMF_STREAM* stream)
TSMF_PRESENTATION* tsmf_presentation_new(const uint8* guid, IWTSVirtualChannelCallback* pChannelCallback) TSMF_PRESENTATION* tsmf_presentation_new(const uint8* guid, IWTSVirtualChannelCallback* pChannelCallback)
{ {
TSMF_PRESENTATION* presentation;
pthread_t thid = pthread_self(); pthread_t thid = pthread_self();
FILE* fout = NULL; FILE* fout = NULL;
fout = fopen("/tmp/tsmf.tid", "wt"); fout = fopen("/tmp/tsmf.tid", "wt");
if (fout) if (fout)
{ {
fprintf(fout, "%d\n", (int) thid); fprintf(fout, "%d\n", (int) thid);
fclose(fout); fclose(fout);
} }
TSMF_PRESENTATION* presentation;
presentation = tsmf_presentation_find_by_id(guid); presentation = tsmf_presentation_find_by_id(guid);
if (presentation) if (presentation)
{ {
DEBUG_WARN("duplicated presentation id!"); DEBUG_WARN("duplicated presentation id!");
@ -319,6 +331,7 @@ static void tsmf_sample_playback_video(TSMF_SAMPLE* sample)
if (sample->data) if (sample->data)
{ {
t = get_current_time(); t = get_current_time();
if (stream->next_start_time > t && if (stream->next_start_time > t &&
(sample->end_time >= presentation->audio_start_time || (sample->end_time >= presentation->audio_start_time ||
sample->end_time < stream->last_end_time)) sample->end_time < stream->last_end_time))
@ -726,14 +739,15 @@ static void tsmf_stream_change_volume(TSMF_STREAM* stream, uint32 newVolume, uin
{ {
if (!stream) if (!stream)
return; return;
if (!stream->decoder) if (stream->decoder != NULL && stream->decoder->ChangeVolume)
return;
if (stream->decoder->ChangeVolume)
{ {
stream->decoder->ChangeVolume(stream->decoder, newVolume, muted); stream->decoder->ChangeVolume(stream->decoder, newVolume, muted);
} }
else if (stream->audio != NULL && stream->audio->ChangeVolume)
{
stream->audio->ChangeVolume(stream->audio, newVolume, muted);
}
} }
void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, uint32 newVolume, uint32 muted) void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, uint32 newVolume, uint32 muted)
@ -1006,14 +1020,17 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
uint32 sample_id, uint64 start_time, uint64 end_time, uint64 duration, uint32 extensions, uint32 sample_id, uint64 start_time, uint64 end_time, uint64 duration, uint32 extensions,
uint32 data_size, uint8* data) uint32 data_size, uint8* data)
{ {
TSMF_SAMPLE* sample;
pthread_mutex_lock(&tsmf_mutex); pthread_mutex_lock(&tsmf_mutex);
if (TERMINATING) if (TERMINATING)
{ {
pthread_mutex_unlock(&tsmf_mutex); pthread_mutex_unlock(&tsmf_mutex);
return; return;
} }
pthread_mutex_unlock(&tsmf_mutex); pthread_mutex_unlock(&tsmf_mutex);
TSMF_SAMPLE* sample;
sample = xnew(TSMF_SAMPLE); sample = xnew(TSMF_SAMPLE);
@ -1033,6 +1050,8 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
freerdp_thread_unlock(stream->thread); freerdp_thread_unlock(stream->thread);
} }
#ifndef _WIN32
static void tsmf_signal_handler(int s) static void tsmf_signal_handler(int s)
{ {
pthread_mutex_lock(&tsmf_mutex); pthread_mutex_lock(&tsmf_mutex);
@ -1069,14 +1088,18 @@ static void tsmf_signal_handler(int s)
} }
} }
#endif
void tsmf_media_init(void) void tsmf_media_init(void)
{ {
#ifndef _WIN32
struct sigaction sigtrap; struct sigaction sigtrap;
sigtrap.sa_handler = tsmf_signal_handler; sigtrap.sa_handler = tsmf_signal_handler;
sigemptyset(&sigtrap.sa_mask); sigemptyset(&sigtrap.sa_mask);
sigtrap.sa_flags = 0; sigtrap.sa_flags = 0;
sigaction(SIGINT, &sigtrap, 0); sigaction(SIGINT, &sigtrap, 0);
sigaction(SIGUSR1, &sigtrap, 0); sigaction(SIGUSR1, &sigtrap, 0);
#endif
if (presentation_list == NULL) if (presentation_list == NULL)
presentation_list = list_new(); presentation_list = list_new();

View File

@ -26,7 +26,11 @@ set(RAIL_SRCS
add_library(rail ${RAIL_SRCS}) add_library(rail ${RAIL_SRCS})
set_target_properties(rail PROPERTIES PREFIX "") set_target_properties(rail PROPERTIES PREFIX "")
target_link_libraries(rail freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rail freerdp)
else()
target_link_libraries(rail freerdp-utils)
endif()
install(TARGETS rail DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rail DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -19,9 +19,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
@ -128,7 +133,7 @@ static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* e
while (data && data->size > 0) while (data && data->size > 0)
{ {
rail_process_plugin_data(rail_order, data); rail_process_plugin_data(rail_order, data);
data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); data = (RDP_PLUGIN_DATA*)((char *)(data) + data->size);
} }
} }

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/utils/rail.h> #include <freerdp/utils/rail.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -24,6 +24,10 @@ set(RDPDBG_SRCS
add_library(rdpdbg ${RDPDBG_SRCS}) add_library(rdpdbg ${RDPDBG_SRCS})
set_target_properties(rdpdbg PROPERTIES PREFIX "") set_target_properties(rdpdbg PROPERTIES PREFIX "")
target_link_libraries(rdpdbg freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpdbg freerdp)
else()
target_link_libraries(rdpdbg freerdp-utils)
endif()
install(TARGETS rdpdbg DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rdpdbg DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,9 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -27,20 +27,25 @@ set(RDPDR_SRCS
irp.c irp.c
irp.h irp.h
rdpdr_main.c rdpdr_main.c
rdpdr_main.h rdpdr_main.h)
)
add_library(rdpdr ${RDPDR_SRCS}) add_library(rdpdr ${RDPDR_SRCS})
set_target_properties(rdpdr PROPERTIES PREFIX "") set_target_properties(rdpdr PROPERTIES PREFIX "")
target_link_libraries(rdpdr freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpdr freerdp)
else()
target_link_libraries(rdpdr freerdp-utils)
endif()
install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH})
add_subdirectory(disk) if(NOT WIN32)
add_subdirectory(printer) add_subdirectory(disk)
add_subdirectory(parallel) add_subdirectory(printer)
add_subdirectory(serial) add_subdirectory(parallel)
add_subdirectory(serial)
endif()
if(WITH_PCSC) if(WITH_PCSC)
add_subdirectory(smartcard) add_subdirectory(smartcard)

View File

@ -18,10 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>

View File

@ -20,14 +20,17 @@
set(DISK_SRCS set(DISK_SRCS
disk_file.c disk_file.c
disk_file.h disk_file.h
disk_main.c disk_main.c)
)
include_directories(..) include_directories(..)
add_library(disk ${DISK_SRCS}) add_library(disk ${DISK_SRCS})
set_target_properties(disk PROPERTIES PREFIX "") set_target_properties(disk PROPERTIES PREFIX "")
target_link_libraries(disk freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(disk freerdp)
else()
target_link_libraries(disk freerdp-utils)
endif()
install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#define __USE_LARGEFILE64 #define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE
@ -26,7 +30,6 @@
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "config.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -199,10 +202,14 @@ static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 Crea
file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? true : false); file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? true : false);
if (file->is_dir) if (file->is_dir)
{ {
if (mkdir(file->fullpath, mode) != 0) //Should only create the directory if the disposition allows for it
if ((CreateDisposition == FILE_OPEN_IF) || (CreateDisposition == FILE_CREATE))
{ {
if (mkdir(file->fullpath, mode) != 0)
{
file->err = errno; file->err = errno;
return true; return true;
}
} }
} }
exists = false; exists = false;

View File

@ -22,11 +22,14 @@
#define __DISK_FILE_H #define __DISK_FILE_H
#include <sys/types.h> #include <sys/types.h>
#include <sys/statvfs.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h>
#if defined WIN32 #ifndef _WIN32
#include <dirent.h>
#include <sys/statvfs.h>
#endif
#ifdef _WIN32
#define STAT stat #define STAT stat
#define OPEN open #define OPEN open
#define LSEEK lseek #define LSEEK lseek
@ -60,10 +63,6 @@
(_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \ (_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \
(st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY)) (st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY))
typedef struct _DISK_FILE DISK_FILE; typedef struct _DISK_FILE DISK_FILE;
struct _DISK_FILE struct _DISK_FILE
{ {

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#define __USE_LARGEFILE64 #define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE
@ -26,12 +30,11 @@
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "config.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h> #include <freerdp/utils/unicode.h>

View File

@ -18,7 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -26,6 +26,10 @@ include_directories(..)
add_library(parallel ${PARALLEL_SRCS}) add_library(parallel ${PARALLEL_SRCS})
set_target_properties(parallel PROPERTIES PREFIX "") set_target_properties(parallel PROPERTIES PREFIX "")
target_link_libraries(parallel freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(parallel freerdp)
else()
target_link_libraries(parallel freerdp-utils)
endif()
install(TARGETS parallel DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS parallel DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,16 +18,27 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <termios.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32
#include <termios.h>
#include <strings.h> #include <strings.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef __LINUX__ #ifdef __LINUX__
#include <linux/ppdev.h> #include <linux/ppdev.h>
#include <linux/parport.h> #include <linux/parport.h>
@ -74,6 +85,7 @@ static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp)
parallel->id = irp->devman->id_sequence++; parallel->id = irp->devman->id_sequence++;
parallel->file = open(parallel->path, O_RDWR); parallel->file = open(parallel->path, O_RDWR);
if (parallel->file < 0) if (parallel->file < 0)
{ {
irp->IoStatus = STATUS_ACCESS_DENIED; irp->IoStatus = STATUS_ACCESS_DENIED;
@ -163,6 +175,7 @@ static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp)
DEBUG_SVC("Length %u Offset %llu", Length, Offset); DEBUG_SVC("Length %u Offset %llu", Length, Offset);
len = Length; len = Length;
while (len > 0) while (len > 0)
{ {
status = write(parallel->file, stream_get_tail(irp->input), len); status = write(parallel->file, stream_get_tail(irp->input), len);

View File

@ -19,15 +19,14 @@
set(PRINTER_SRCS set(PRINTER_SRCS
printer_main.c printer_main.c
printer_main.h printer_main.h)
)
if(WITH_CUPS) if(WITH_CUPS)
set(PRINTER_SRCS set(PRINTER_SRCS
${PRINTER_SRCS} ${PRINTER_SRCS}
printer_cups.c printer_cups.c
printer_cups.h printer_cups.h)
)
include_directories(${CUPS_INCLUDE_DIR}) include_directories(${CUPS_INCLUDE_DIR})
add_definitions(-DWITH_CUPS) add_definitions(-DWITH_CUPS)
endif() endif()
@ -37,7 +36,11 @@ include_directories(..)
add_library(printer ${PRINTER_SRCS}) add_library(printer ${PRINTER_SRCS})
set_target_properties(printer PROPERTIES PREFIX "") set_target_properties(printer PROPERTIES PREFIX "")
target_link_libraries(printer freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(printer freerdp)
else()
target_link_libraries(printer freerdp-utils)
endif()
if(WITH_CUPS) if(WITH_CUPS)
target_link_libraries(printer ${CUPS_LIBRARIES}) target_link_libraries(printer ${CUPS_LIBRARIES})

View File

@ -17,12 +17,18 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#include <cups/cups.h> #include <cups/cups.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/svc_plugin.h> #include <freerdp/utils/svc_plugin.h>

View File

@ -17,10 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h> #include <freerdp/utils/unicode.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -18,10 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h> #include <freerdp/utils/svc_plugin.h>

View File

@ -124,6 +124,8 @@ enum FILE_CREATE_OPTION
}; };
/* DR_CREATE_REQ.DesiredAccess [MS-SMB2] */ /* DR_CREATE_REQ.DesiredAccess [MS-SMB2] */
#ifndef _WIN32
enum FILE_ACCESS enum FILE_ACCESS
{ {
FILE_READ_DATA = 0x00000001, FILE_READ_DATA = 0x00000001,
@ -146,6 +148,7 @@ enum FILE_ACCESS
GENERIC_WRITE = 0x40000000, GENERIC_WRITE = 0x40000000,
GENERIC_READ = 0x80000000 GENERIC_READ = 0x80000000
}; };
#endif
/* DR_CREATE_RSP.Information */ /* DR_CREATE_RSP.Information */
/* DR_DRIVE_CREATE_RSP.DeviceCreateResponse */ /* DR_DRIVE_CREATE_RSP.DeviceCreateResponse */
@ -221,8 +224,10 @@ enum RDP_LOWIO_OP
enum NTSTATUS enum NTSTATUS
{ {
STATUS_SUCCESS = 0x00000000, STATUS_SUCCESS = 0x00000000,
#ifndef _WIN32
STATUS_TIMEOUT = 0x00000102, STATUS_TIMEOUT = 0x00000102,
STATUS_PENDING = 0x00000103, STATUS_PENDING = 0x00000103,
#endif
STATUS_REPARSE = 0x00000104, STATUS_REPARSE = 0x00000104,
STATUS_MORE_ENTRIES = 0x00000105, STATUS_MORE_ENTRIES = 0x00000105,
STATUS_NOT_ALL_ASSIGNED = 0x00000106, STATUS_NOT_ALL_ASSIGNED = 0x00000106,
@ -245,8 +250,10 @@ enum NTSTATUS
STATUS_UNSUCCESSFUL = 0xC0000001, STATUS_UNSUCCESSFUL = 0xC0000001,
STATUS_NOT_IMPLEMENTED = 0xC0000002, STATUS_NOT_IMPLEMENTED = 0xC0000002,
STATUS_INVALID_INFO_CLASS = 0xC0000003, STATUS_INVALID_INFO_CLASS = 0xC0000003,
#ifndef _WIN32
STATUS_INVALID_HANDLE = 0xC0000008, STATUS_INVALID_HANDLE = 0xC0000008,
STATUS_INVALID_PARAMETER = 0xC000000D, STATUS_INVALID_PARAMETER = 0xC000000D,
#endif
STATUS_NO_SUCH_DEVICE = 0xC000000E, STATUS_NO_SUCH_DEVICE = 0xC000000E,
STATUS_NO_SUCH_FILE = 0xC000000F, STATUS_NO_SUCH_FILE = 0xC000000F,
STATUS_INVALID_DEVICE_REQUEST = 0xC0000010, STATUS_INVALID_DEVICE_REQUEST = 0xC0000010,
@ -289,6 +296,9 @@ enum RDPDR_PRINTER_ANNOUNCE_FLAG
}; };
/* [MS-FSCC] FileAttributes */ /* [MS-FSCC] FileAttributes */
#ifndef _WIN32
enum FILE_ATTRIBUTE enum FILE_ATTRIBUTE
{ {
FILE_ATTRIBUTE_ARCHIVE = 0x00000020, FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
@ -306,6 +316,8 @@ enum FILE_ATTRIBUTE
FILE_ATTRIBUTE_TEMPORARY = 0x00000100 FILE_ATTRIBUTE_TEMPORARY = 0x00000100
}; };
#endif
/* [MS-FSCC] FSCTL Structures */ /* [MS-FSCC] FSCTL Structures */
enum FSCTL_STRUCTURE enum FSCTL_STRUCTURE
{ {
@ -337,6 +349,9 @@ enum FSCTL_STRUCTURE
}; };
/* [MS-FSCC] FileFsAttributeInformation.FileSystemAttributes */ /* [MS-FSCC] FileFsAttributeInformation.FileSystemAttributes */
#ifndef _WIN32
enum FILE_FS_ATTRIBUTE_INFORMATION enum FILE_FS_ATTRIBUTE_INFORMATION
{ {
FILE_SUPPORTS_USN_JOURNAL = 0x02000000, FILE_SUPPORTS_USN_JOURNAL = 0x02000000,
@ -361,6 +376,8 @@ enum FILE_FS_ATTRIBUTE_INFORMATION
FILE_CASE_SENSITIVE_SEARCH = 0x00000001 FILE_CASE_SENSITIVE_SEARCH = 0x00000001
}; };
#endif
/* [MS-FSCC] FileFsDeviceInformation.DeviceType */ /* [MS-FSCC] FileFsDeviceInformation.DeviceType */
enum FILE_FS_DEVICE_TYPE enum FILE_FS_DEVICE_TYPE
{ {

View File

@ -18,10 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
@ -59,7 +63,7 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin)
{ {
devman_load_device_service(rdpdr->devman, data); devman_load_device_service(rdpdr->devman, data);
} }
data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); data = (RDP_PLUGIN_DATA*) (((uint8*) data) + data->size);
} }
} }
@ -83,7 +87,7 @@ static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
stream_write_uint16(data_out, rdpdr->versionMajor); stream_write_uint16(data_out, rdpdr->versionMajor);
stream_write_uint16(data_out, rdpdr->versionMinor); stream_write_uint16(data_out, rdpdr->versionMinor);
stream_write_uint32(data_out, rdpdr->clientID); stream_write_uint32(data_out, (uint32) rdpdr->clientID);
svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out);
} }

View File

@ -21,7 +21,6 @@
#ifndef __RDPDR_TYPES_H #ifndef __RDPDR_TYPES_H
#define __RDPDR_TYPES_H #define __RDPDR_TYPES_H
#include "config.h"
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h> #include <freerdp/utils/list.h>
#include <freerdp/utils/svc_plugin.h> #include <freerdp/utils/svc_plugin.h>

View File

@ -21,14 +21,17 @@ set(serial_SRCS
serial_tty.c serial_tty.c
serial_tty.h serial_tty.h
serial_constants.h serial_constants.h
serial_main.c serial_main.c)
)
include_directories(..) include_directories(..)
add_library(serial ${serial_SRCS}) add_library(serial ${serial_SRCS})
set_target_properties(serial PROPERTIES PREFIX "") set_target_properties(serial PROPERTIES PREFIX "")
target_link_libraries(serial freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(serial freerdp)
else()
target_link_libraries(serial freerdp-utils)
endif()
install(TARGETS serial DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS serial DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,13 +18,15 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h"
#ifdef HAVE_SYS_MODEM_H #ifdef HAVE_SYS_MODEM_H
#include <sys/modem.h> #include <sys/modem.h>
#endif #endif

View File

@ -18,10 +18,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h> #include <freerdp/utils/unicode.h>
@ -30,13 +34,16 @@
#include <freerdp/utils/svc_plugin.h> #include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/hexdump.h> #include <freerdp/utils/hexdump.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#include <termios.h> #include <termios.h>
#include <dirent.h>
#include <sys/ioctl.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <errno.h> #include <errno.h>
#include "rdpdr_constants.h" #include "rdpdr_constants.h"
@ -67,7 +74,6 @@
#define TIOCOUTQ FIONWRITE #define TIOCOUTQ FIONWRITE
#endif #endif
static uint32 tty_write_data(SERIAL_TTY* tty, uint8* data, int len); static uint32 tty_write_data(SERIAL_TTY* tty, uint8* data, int len);
static void tty_set_termios(SERIAL_TTY* tty); static void tty_set_termios(SERIAL_TTY* tty);
static boolean tty_get_termios(SERIAL_TTY* tty); static boolean tty_get_termios(SERIAL_TTY* tty);

View File

@ -23,7 +23,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef _WIN32
#include <dirent.h> #include <dirent.h>
#endif
typedef struct _SERIAL_TTY SERIAL_TTY; typedef struct _SERIAL_TTY SERIAL_TTY;
struct _SERIAL_TTY struct _SERIAL_TTY
@ -59,7 +62,6 @@ struct _SERIAL_TTY
int event_pending; int event_pending;
}; };
SERIAL_TTY* serial_tty_new(const char* path, uint32 id); SERIAL_TTY* serial_tty_new(const char* path, uint32 id);
void serial_tty_free(SERIAL_TTY* tty); void serial_tty_free(SERIAL_TTY* tty);

View File

@ -28,7 +28,12 @@ include_directories(${PCSC_INCLUDE_DIRS})
add_library(scard ${SCARD_SRCS}) add_library(scard ${SCARD_SRCS})
set_target_properties(scard PROPERTIES PREFIX "") set_target_properties(scard PROPERTIES PREFIX "")
target_link_libraries(scard freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(scard freerdp)
else()
target_link_libraries(scard freerdp-utils)
endif()
target_link_libraries(scard ${PCSC_LIBRARIES}) target_link_libraries(scard ${PCSC_LIBRARIES})
install(TARGETS scard DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS scard DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -1,25 +1,27 @@
/* /**
FreeRDP: A Remote Desktop Protocol client. * FreeRDP: A Remote Desktop Protocol client.
Redirected Smart Card Device Service * Smartcard Device Service Virtual Channel
*
Copyright 2011 O.S. Systems Software Ltda. * Copyright 2011 O.S. Systems Software Ltda.
Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br> * Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
Copyright 2011 Anthony Tong <atong@trustedcs.com> * Copyright 2011 Anthony Tong <atong@trustedcs.com>
*
Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
You may obtain a copy of the License at * You may obtain a copy of the License at
*
http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*
Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -28,18 +30,20 @@
#include <freerdp/utils/list.h> #include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h> #include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h> #include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/mutex.h>
#include <freerdp/utils/debug.h>
#include "rdpdr_types.h" #include "rdpdr_types.h"
#include "rdpdr_constants.h" #include "rdpdr_constants.h"
#include "scard_main.h" #include "scard_main.h"
static void static void
scard_free(DEVICE* dev) scard_free(DEVICE* dev)
{ {
SCARD_DEVICE* scard = (SCARD_DEVICE*)dev; SCARD_DEVICE* scard = (SCARD_DEVICE*)dev;
IRP* irp; IRP* irp;
COMPLETIONIDINFO* CompletionIdInfo;
freerdp_thread_stop(scard->thread); freerdp_thread_stop(scard->thread);
freerdp_thread_free(scard->thread); freerdp_thread_free(scard->thread);
@ -48,6 +52,12 @@ scard_free(DEVICE* dev)
irp->Discard(irp); irp->Discard(irp);
list_free(scard->irp_list); list_free(scard->irp_list);
/* Begin TS Client defect workaround. */
while ((CompletionIdInfo = (COMPLETIONIDINFO*)list_dequeue(scard->CompletionIds)) != NULL)
xfree(CompletionIdInfo);
list_free(scard->CompletionIds);
/* End TS Client defect workaround. */
xfree(dev); xfree(dev);
return; return;
} }
@ -130,11 +140,138 @@ scard_thread_func(void* arg)
} }
/* Begin TS Client defect workaround. */
static COMPLETIONIDINFO*
scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
{
/*
* Search from the beginning of the LIST for one outstanding "CompletionID"
* that matches the one passed in. If there is one, mark it as a duplicate
* if it is not already marked.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
for (item = scard->CompletionIds->head; item; item = item->next)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
if (CompletionIdInfo->ID == CompletionId)
{
if (false == CompletionIdInfo->duplicate)
{
CompletionIdInfo->duplicate = true;
DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId);
}
return CompletionIdInfo;
}
}
return NULL; /* Either no items in the list or no match. */
}
static boolean
scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
{
/*
* Search from the end of the LIST for one outstanding "CompletionID"
* that matches the one passed in. Remove it from the list and free the
* memory associated with it. Return whether or not it was marked
* as a duplicate.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
boolean duplicate;
for (item = scard->CompletionIds->tail; item; item = item->prev)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
if (CompletionIdInfo->ID == CompletionId)
{
duplicate = CompletionIdInfo->duplicate;
if (true == duplicate)
{
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate. The response to the command is removed.", CompletionId);
}
list_remove(scard->CompletionIds, CompletionIdInfo);
xfree(CompletionIdInfo);
return duplicate;
}
}
/* This function should only be called when there is
* at least one outstanding CompletionID item in the list.
*/
DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
return false;
}
static void
scard_irp_complete(IRP* irp)
{
/* This function is (mostly) a copy of the statically-declared "irp_complete()"
* function except that this function adds extra operations for the
* smart card's handling of duplicate "CompletionID"s. This function needs
* to be in this file so that "scard_irp_request()" can reference it.
*/
int pos;
boolean duplicate;
SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device;
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
pos = stream_get_pos(irp->output);
stream_set_pos(irp->output, 12);
stream_write_uint32(irp->output, irp->IoStatus);
stream_set_pos(irp->output, pos);
/* Begin TS Client defect workaround. */
freerdp_mutex_lock(scard->CompletionIdsMutex);
/* Remove from the list the item identified by the CompletionID.
* The function returns whether or not it was a duplicate CompletionID.
*/
duplicate = scard_check_for_duplicate_id(scard, irp->CompletionId);
freerdp_mutex_unlock(scard->CompletionIdsMutex);
if (false == duplicate)
{
svc_plugin_send(irp->devman->plugin, irp->output);
irp->output = NULL;
}
/* End TS Client defect workaround. */
/* irp_free(irp); The "irp_free()" function is statically-declared
* and so is not available to be called
* here. Instead, call it indirectly by calling
* the IRP's "Discard()" function,
* which has already been assigned
* to point to "irp_free()" in "irp_new()".
*/
irp->Discard(irp);
}
/* End TS Client defect workaround. */
static void static void
scard_irp_request(DEVICE* device, IRP* irp) scard_irp_request(DEVICE* device, IRP* irp)
{ {
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*)device; SCARD_DEVICE* scard = (SCARD_DEVICE*)device;
/* Begin TS Client defect workaround. */
CompletionIdInfo= xnew(COMPLETIONIDINFO);
CompletionIdInfo->ID = irp->CompletionId;/* "duplicate" member is set
* to false by "xnew()"
*/
freerdp_mutex_lock(scard->CompletionIdsMutex);
scard_mark_duplicate_id(scard, irp->CompletionId);
list_enqueue(scard->CompletionIds, CompletionIdInfo);
freerdp_mutex_unlock(scard->CompletionIdsMutex);
irp->Complete = scard_irp_complete; /* Overwrite the previous
* assignment made in
* "irp_new()".
*/
/* End TS Client defect workaround. */
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL && if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
scard_async_op(irp)) scard_async_op(irp))
{ {
@ -161,7 +298,6 @@ scard_irp_request(DEVICE* device, IRP* irp)
freerdp_thread_signal(scard->thread); freerdp_thread_signal(scard->thread);
} }
int int
DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{ {
@ -195,6 +331,9 @@ DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
scard->irp_list = list_new(); scard->irp_list = list_new();
scard->thread = freerdp_thread_new(); scard->thread = freerdp_thread_new();
scard->CompletionIds = list_new();
scard->CompletionIdsMutex = freerdp_mutex_new();
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard);
freerdp_thread_start(scard->thread, scard_thread_func, scard); freerdp_thread_start(scard->thread, scard_thread_func, scard);

View File

@ -1,22 +1,22 @@
/* /**
FreeRDP: A Remote Desktop Protocol client. * FreeRDP: A Remote Desktop Protocol client.
Redirected Smart Card Device Service * Smartcard Device Service Virtual Channel
*
Copyright 2011 O.S. Systems Software Ltda. * Copyright 2011 O.S. Systems Software Ltda.
Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br> * Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
*
Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
You may obtain a copy of the License at * You may obtain a copy of the License at
*
http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*
Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
limitations under the License. * limitations under the License.
*/ */
#ifndef __SCARD_MAIN_H #ifndef __SCARD_MAIN_H
#define __SCARD_MAIN_H #define __SCARD_MAIN_H
@ -25,8 +25,74 @@
#include "devman.h" #include "devman.h"
#include "rdpdr_types.h" #include "rdpdr_types.h"
#include <freerdp/utils/mutex.h> /* For CompletionIdsMutex */
#include <freerdp/utils/list.h>
#include <freerdp/utils/debug.h> #include <freerdp/utils/debug.h>
/*
* When using Windows Server 2008 R2 as the Terminal Services (TS)
* server, and with a smart card reader connected to the TS client machine
* and used to authenticate to an existing login session, the TS server
* will initiate the protocol initialization of MS-RDPEFS, Section 1.3.1,
* twice as it re-establishes a connection. The TS server starts both
* initializations with a "Server Announce Request" message.
* When the TS client receives this message, as per Section 3.2.5.1.2,
*
* The client SHOULD treat this packet as the beginning
* of a new sequence. The client SHOULD also cancel all
* outstanding requests and release previous references to
* all devices.
*
* As of this writing, the code does not cancel all outstanding requests.
* This leads to a problem where, after the first MS-RDPEFS initialization,
* the TS server sends an SCARD_IOCTL_GETSTATUSCHANGEx control in a message
* that uses an available "CompletionID". The
* TS client doesn't respond immediately because it is blocking while
* waiting for a change in the smart card's status in the reader.
* Then the TS server initiates a second MS-RDPEFS initialization sequence.
* As noted above, this should cancel the outstanding
* SCARD_IOCTL_GETSTATUSCHANGEx request, but it does not.
* At this point, the TS server is free to reuse the previously used
* "CompletionID", and it does reuse it for other SCARD_IOCTLs.
* Therefore, when the user removes (for example) the card from the reader,
* the TS client sends an "IOCompetion" message in response to the
* GETSTATUSCHANGEx using the original "CompletionID". The TS server does not
* expect this "CompletionID" and so, as per Section 3.1.5.2 of MS-RDPEFS,
* it treats that "IOCompletion" message as an error and terminates the
* virtual channel.
*
* The following structure is part of a work-around for this missing
* capability of canceling outstanding requests. This work-around
* allows the TS client to send an "IOCompletion" back to the
* TS server for the second (and subsequent) SCARD_IOCTLs that use
* the same "CompletionID" as the still outstanding
* SCARD_IOCTL_GETSTATUSCHANGEx. The work-around in the TS client
* prevents the client from sending the "IOCompletion" back (when
* the user removes the card) for the SCARD_IOCTL_GETSTATUSCHANGEx.
*
* This TS client expects the responses from the PCSC daemon for the second
* and subsequent SCARD_IOCTLs that use the same "CompletionID"
* to arrive at the TS client before the daemon's response to the
* SCARD_IOCTL_GETSTATUSCHANGEx. This is a race condition.
*
* The "CompletionIDs" are a global pool of IDs across all "DeviceIDs".
* However, this problem of duplicate "CompletionIDs" only affects smart cards.
*
* This structure tracks outstanding Terminal Services server "CompletionIDs"
* used by the redirected smart card device.
*/
struct _COMPLETIONIDINFO
{
uint32 ID; /* CompletionID */
boolean duplicate; /* Indicates whether or not this
* CompletionID is a duplicate of an
* earlier, outstanding, CompletionID.
*/
};
typedef struct _COMPLETIONIDINFO COMPLETIONIDINFO;
struct _SCARD_DEVICE struct _SCARD_DEVICE
{ {
DEVICE device; DEVICE device;
@ -37,6 +103,11 @@ struct _SCARD_DEVICE
LIST* irp_list; LIST* irp_list;
freerdp_thread* thread; freerdp_thread* thread;
LIST* CompletionIds;
freerdp_mutex CompletionIdsMutex; /* Protect the LIST from
* multiple thread writers.
*/
}; };
typedef struct _SCARD_DEVICE SCARD_DEVICE; typedef struct _SCARD_DEVICE SCARD_DEVICE;

View File

@ -1,25 +1,27 @@
/* /**
FreeRDP: A Remote Desktop Protocol client. * FreeRDP: A Remote Desktop Protocol client.
Redirected Smart Card Device Service * Smartcard Device Service Virtual Channel
*
Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006 * Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006
Copyright 2011 O.S. Systems Software Ltda. * Copyright 2011 O.S. Systems Software Ltda.
Copyright 2011 Anthony Tong <atong@trustedcs.com> * Copyright 2011 Anthony Tong <atong@trustedcs.com>
*
Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
You may obtain a copy of the License at * You may obtain a copy of the License at
*
http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*
Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -114,7 +116,12 @@ static uint32 sc_output_string(IRP* irp, char *src, boolean wide)
static void sc_output_alignment(IRP *irp, uint32 seed) static void sc_output_alignment(IRP *irp, uint32 seed)
{ {
uint32 size = stream_get_length(irp->output) - 20; const uint32 field_lengths = 20;/* Remove the lengths of the fields
* RDPDR_HEADER, DeviceID,
* CompletionID, and IoStatus
* of Section 2.2.1.5.5 of MS-RDPEFS.
*/
uint32 size = stream_get_length(irp->output) - field_lengths;
uint32 add = (seed - (size % seed)) % seed; uint32 add = (seed - (size % seed)) % seed;
if (add > 0) if (add > 0)
@ -270,14 +277,15 @@ static uint32 handle_EstablishContext(IRP* irp)
rv = SCardEstablishContext(scope, NULL, NULL, &hContext); rv = SCardEstablishContext(scope, NULL, NULL, &hContext);
stream_write_uint32(irp->output, 4); // ? stream_write_uint32(irp->output, 4); // cbContext
stream_write_uint32(irp->output, -1); // ? stream_write_uint32(irp->output, -1); // ReferentID
stream_write_uint32(irp->output, 4); stream_write_uint32(irp->output, 4);
stream_write_uint32(irp->output, hContext); stream_write_uint32(irp->output, hContext);
/* TODO: store hContext in allowed context list */ /* TODO: store hContext in allowed context list */
sc_output_alignment(irp, 8);
return SCARD_S_SUCCESS; return SCARD_S_SUCCESS;
} }
@ -298,6 +306,7 @@ static uint32 handle_ReleaseContext(IRP* irp)
else else
DEBUG_SCARD("success 0x%08lx", hContext); DEBUG_SCARD("success 0x%08lx", hContext);
sc_output_alignment(irp, 8);
return rv; return rv;
} }
@ -316,7 +325,7 @@ static uint32 handle_IsValidContext(IRP* irp)
else else
DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext);
stream_write_uint32(irp->output, rv); sc_output_alignment(irp, 8);
return rv; return rv;
} }
@ -454,7 +463,6 @@ static uint32 handle_GetStatusChange(IRP* irp, boolean wide)
/* reset high bytes? */ /* reset high bytes? */
cur->dwCurrentState &= 0x0000FFFF; cur->dwCurrentState &= 0x0000FFFF;
cur->dwEventState &= 0x0000FFFF;
cur->dwEventState = 0; cur->dwEventState = 0;
} }
@ -576,7 +584,6 @@ static uint32 handle_Connect(IRP* irp, boolean wide)
stream_write_uint32(irp->output, dwActiveProtocol); stream_write_uint32(irp->output, dwActiveProtocol);
stream_write_uint32(irp->output, 0x00000004); stream_write_uint32(irp->output, 0x00000004);
stream_write_uint32(irp->output, hCard); stream_write_uint32(irp->output, hCard);
stream_seek(irp->output, 28);
sc_output_alignment(irp, 8); sc_output_alignment(irp, 8);
@ -616,8 +623,8 @@ static uint32 handle_Reconnect(IRP* irp)
else else
DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol); DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol);
stream_write_uint32(irp->output, dwActiveProtocol);
sc_output_alignment(irp, 8); sc_output_alignment(irp, 8);
stream_write_uint32(irp->output, dwActiveProtocol); /* reversed? */
return rv; return rv;
} }
@ -1165,7 +1172,7 @@ static uint32 handle_GetAttrib(IRP* irp)
static uint32 handle_AccessStartedEvent(IRP* irp) static uint32 handle_AccessStartedEvent(IRP* irp)
{ {
stream_write_zero(irp->output, 8); sc_output_alignment(irp, 8);
return SCARD_S_SUCCESS; return SCARD_S_SUCCESS;
} }
@ -1365,8 +1372,10 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp)
uint32 output_len, input_len, ioctl_code; uint32 output_len, input_len, ioctl_code;
uint32 stream_len, result; uint32 stream_len, result;
uint32 pos, pad_len; uint32 pos, pad_len;
uint32 irp_len;
uint32 irp_result_pos, output_len_pos, result_pos; uint32 irp_result_pos, output_len_pos, result_pos;
const uint32 header_lengths = 16; /* MS-RPCE, Sections 2.2.6.1
* and 2.2.6.2.
*/
stream_read_uint32(irp->input, output_len); stream_read_uint32(irp->input, output_len);
stream_read_uint32(irp->input, input_len); stream_read_uint32(irp->input, input_len);
@ -1383,8 +1392,12 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp)
irp_result_pos = stream_get_pos(irp->output); irp_result_pos = stream_get_pos(irp->output);
stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0x00000000); /* MS-RDPEFS
* OutputBufferLength
* will be updated
* later in this
* function.
*/
/* [MS-RPCE] 2.2.6.1 */ /* [MS-RPCE] 2.2.6.1 */
stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */
stream_write_uint32(irp->output, 0xcccccccc); /* filler */ stream_write_uint32(irp->output, 0xcccccccc); /* filler */
@ -1510,26 +1523,21 @@ void scard_device_control(SCARD_DEVICE* scard, IRP* irp)
/* handle response packet */ /* handle response packet */
pos = stream_get_pos(irp->output); pos = stream_get_pos(irp->output);
stream_len = pos - irp_result_pos - 4; stream_len = pos - irp_result_pos - 4; /* Value of OutputBufferLength */
stream_set_pos(irp->output, irp_result_pos);
stream_write_uint32(irp->output, stream_len);
stream_set_pos(irp->output, output_len_pos); stream_set_pos(irp->output, output_len_pos);
stream_write_uint32(irp->output, stream_len - 24); /* Remove the effect of the MS-RPCE Common Type Header and Private
* Header (Sections 2.2.6.1 and 2.2.6.2).
*/
stream_write_uint32(irp->output, stream_len - header_lengths);
stream_set_pos(irp->output, result_pos); stream_set_pos(irp->output, result_pos);
stream_write_uint32(irp->output, result); stream_write_uint32(irp->output, result);
stream_set_pos(irp->output, pos); stream_set_pos(irp->output, pos);
/* pad stream to 16 byte align */
pad_len = stream_len % 16;
stream_write_zero(irp->output, pad_len);
pos = stream_get_pos(irp->output);
irp_len = stream_len + pad_len;
stream_set_pos(irp->output, irp_result_pos);
stream_write_uint32(irp->output, irp_len);
stream_set_pos(irp->output, pos);
#ifdef WITH_DEBUG_SCARD #ifdef WITH_DEBUG_SCARD
freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output));
#endif #endif

View File

@ -19,13 +19,16 @@
set(RDPSND_SRCS set(RDPSND_SRCS
rdpsnd_main.c rdpsnd_main.c
rdpsnd_main.h rdpsnd_main.h)
)
add_library(rdpsnd ${RDPSND_SRCS}) add_library(rdpsnd ${RDPSND_SRCS})
set_target_properties(rdpsnd PROPERTIES PREFIX "") set_target_properties(rdpsnd PROPERTIES PREFIX "")
target_link_libraries(rdpsnd freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpsnd freerdp)
else()
target_link_libraries(rdpsnd freerdp-utils)
endif()
install(TARGETS rdpsnd DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rdpsnd DESTINATION ${FREERDP_PLUGIN_PATH})
@ -37,3 +40,7 @@ if(WITH_PULSEAUDIO)
add_subdirectory(pulse) add_subdirectory(pulse)
endif() endif()
if(WITH_MACAUDIO)
add_subdirectory(mac_audio)
endif()

View File

@ -27,7 +27,12 @@ include_directories(${ALSA_INCLUDE_DIRS})
add_library(rdpsnd_alsa ${RDPSND_ALSA_SRCS}) add_library(rdpsnd_alsa ${RDPSND_ALSA_SRCS})
set_target_properties(rdpsnd_alsa PROPERTIES PREFIX "") set_target_properties(rdpsnd_alsa PROPERTIES PREFIX "")
target_link_libraries(rdpsnd_alsa freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpsnd_alsa freerdp)
else()
target_link_libraries(rdpsnd_alsa freerdp-utils)
endif()
target_link_libraries(rdpsnd_alsa ${ALSA_LIBRARIES}) target_link_libraries(rdpsnd_alsa ${ALSA_LIBRARIES})
install(TARGETS rdpsnd_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rdpsnd_alsa DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -18,10 +18,16 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h> #include <freerdp/utils/dsp.h>

View File

@ -0,0 +1,40 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP cmake build script
#
# Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(RDPSND_MACAUDIO_SRCS
rdpsnd_audio_q.c)
include_directories(..)
include_directories(${MACAUDIO_INCLUDE_DIRS})
add_library(rdpsnd_macaudio ${RDPSND_MACAUDIO_SRCS})
set_target_properties(rdpsnd_macaudio PROPERTIES PREFIX "")
if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpsnd_macaudio freerdp)
else()
target_link_libraries(rdpsnd_macaudio freerdp-utils)
endif()
target_link_libraries(rdpsnd_macaudio ${MAC_AUDIOTOOLBOX_LIBRARY_PATH})
target_link_libraries(rdpsnd_macaudio ${MAC_COREFOUNDATION_LIBRARY_PATH})
install(TARGETS rdpsnd_macaudio DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -0,0 +1,229 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* Audio Output Virtual Channel
*
* Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Use AudioQueue to implement audio redirection
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioToolbox/AudioQueue.h>
#include "rdpsnd_main.h"
#define AQ_NUM_BUFFERS 10
#define AQ_BUF_SIZE (32 * 1024)
static void aq_playback_cb(void *user_data,
AudioQueueRef aq_ref,
AudioQueueBufferRef aq_buf_ref
);
struct rdpsnd_audio_q_plugin
{
rdpsndDevicePlugin device;
/* audio queue player state */
int is_open; // true when audio_q has been inited
char * device_name;
int is_playing;
int buf_index;
AudioStreamBasicDescription data_format;
AudioQueueRef aq_ref;
AudioQueueBufferRef buffers[AQ_NUM_BUFFERS];
};
typedef struct rdpsnd_audio_q_plugin rdpsndAudioQPlugin;
static void rdpsnd_audio_close(rdpsndDevicePlugin* device)
{
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin*) device;
AudioQueueStop(aq_plugin_p->aq_ref, 0);
aq_plugin_p->is_open = 0;
}
static void rdpsnd_audio_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
int rv;
int i;
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
if (aq_plugin_p->is_open) {
return;
}
aq_plugin_p->buf_index = 0;
// setup AudioStreamBasicDescription
aq_plugin_p->data_format.mSampleRate = 44100;
aq_plugin_p->data_format.mFormatID = kAudioFormatLinearPCM;
aq_plugin_p->data_format.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
// until we know better, assume that one packet = one frame
// one frame = bytes_per_sample x number_of_channels
aq_plugin_p->data_format.mBytesPerPacket = 4;
aq_plugin_p->data_format.mFramesPerPacket = 1;
aq_plugin_p->data_format.mBytesPerFrame = 4;
aq_plugin_p->data_format.mChannelsPerFrame = 2;
aq_plugin_p->data_format.mBitsPerChannel = 16;
rv = AudioQueueNewOutput(&aq_plugin_p->data_format, // audio stream basic desc
aq_playback_cb, // callback when more data is required
aq_plugin_p, // data to pass to callback
CFRunLoopGetCurrent(), // The current run loop, and the one on
// which the audio queue playback callback
// will be invoked
kCFRunLoopCommonModes, // run loop modes in which callbacks can
// be invoked
0, // flags - reserved
&aq_plugin_p->aq_ref
);
if (rv != 0) {
printf("rdpsnd_audio_open: AudioQueueNewOutput() failed with error %d\n", rv);
aq_plugin_p->is_open = 1;
return;
}
for (i = 0; i < AQ_NUM_BUFFERS; i++)
{
rv = AudioQueueAllocateBuffer(aq_plugin_p->aq_ref, AQ_BUF_SIZE, &aq_plugin_p->buffers[i]);
}
aq_plugin_p->is_open = 1;
}
static void rdpsnd_audio_free(rdpsndDevicePlugin* device)
{
}
static boolean rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
{
switch (format->wFormatTag)
{
case 1: /* PCM */
if (format->cbSize == 0 &&
(format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
{
return 1;
}
break;
}
return 0;
}
static void rdpsnd_audio_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
}
static void rdpsnd_audio_set_volume(rdpsndDevicePlugin* device, uint32 value)
{
}
static void rdpsnd_audio_play(rdpsndDevicePlugin* device, uint8* data, int size)
{
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
AudioQueueBufferRef aq_buf_ref;
int len;
if (!aq_plugin_p->is_open) {
return;
}
/* get next empty buffer */
aq_buf_ref = aq_plugin_p->buffers[aq_plugin_p->buf_index];
// fill aq_buf_ref with audio data
len = size > AQ_BUF_SIZE ? AQ_BUF_SIZE : size;
memcpy(aq_buf_ref->mAudioData, (char *) data, len);
aq_buf_ref->mAudioDataByteSize = len;
// add buffer to audioqueue
AudioQueueEnqueueBuffer(aq_plugin_p->aq_ref, aq_buf_ref, 0, 0);
// update buf_index
aq_plugin_p->buf_index++;
if (aq_plugin_p->buf_index >= AQ_NUM_BUFFERS) {
aq_plugin_p->buf_index = 0;
}
}
static void rdpsnd_audio_start(rdpsndDevicePlugin* device)
{
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
AudioQueueStart(aq_plugin_p->aq_ref, NULL);
}
/**
* AudioQueue Playback callback
*
* our job here is to fill aq_buf_ref with audio data and enqueue it
*/
static void aq_playback_cb(void *user_data,
AudioQueueRef aq_ref,
AudioQueueBufferRef aq_buf_ref
)
{
}
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
rdpsndAudioQPlugin* aqPlugin;
RDP_PLUGIN_DATA* data;
aqPlugin = xnew(rdpsndAudioQPlugin);
aqPlugin->device.Open = rdpsnd_audio_open;
aqPlugin->device.FormatSupported = rdpsnd_audio_format_supported;
aqPlugin->device.SetFormat = rdpsnd_audio_set_format;
aqPlugin->device.SetVolume = rdpsnd_audio_set_volume;
aqPlugin->device.Play = rdpsnd_audio_play;
aqPlugin->device.Start = rdpsnd_audio_start;
aqPlugin->device.Close = rdpsnd_audio_close;
aqPlugin->device.Free = rdpsnd_audio_free;
data = pEntryPoints->plugin_data;
if (data && strcmp((char *)data->data[0], "macaudio") == 0) {
if(strlen((char *)data->data[1]) > 0)
aqPlugin->device_name = strdup((char *)data->data[1]);
else
aqPlugin->device_name = NULL;
}
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)aqPlugin);
return 0;
}

View File

@ -18,8 +18,7 @@
# limitations under the License. # limitations under the License.
set(RDPSND_PULSE_SRCS set(RDPSND_PULSE_SRCS
rdpsnd_pulse.c rdpsnd_pulse.c)
)
include_directories(..) include_directories(..)
include_directories(${PULSEAUDIO_INCLUDE_DIR}) include_directories(${PULSEAUDIO_INCLUDE_DIR})
@ -27,7 +26,12 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR})
add_library(rdpsnd_pulse ${RDPSND_PULSE_SRCS}) add_library(rdpsnd_pulse ${RDPSND_PULSE_SRCS})
set_target_properties(rdpsnd_pulse PROPERTIES PREFIX "") set_target_properties(rdpsnd_pulse PROPERTIES PREFIX "")
target_link_libraries(rdpsnd_pulse freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(rdpsnd_pulse freerdp)
else()
target_link_libraries(rdpsnd_pulse freerdp-utils)
endif()
target_link_libraries(rdpsnd_pulse ${PULSEAUDIO_LIBRARY}) target_link_libraries(rdpsnd_pulse ${PULSEAUDIO_LIBRARY})
install(TARGETS rdpsnd_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS rdpsnd_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -17,9 +17,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -25,6 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
@ -477,7 +482,7 @@ static void rdpsnd_process_plugin_data(rdpsndPlugin* rdpsnd, RDP_PLUGIN_DATA* da
static void rdpsnd_process_connect(rdpSvcPlugin* plugin) static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
{ {
rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
RDP_PLUGIN_DATA* data; RDP_PLUGIN_DATA* data;
RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } }; RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } };
@ -489,10 +494,11 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
rdpsnd->latency = -1; rdpsnd->latency = -1;
data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData; data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData;
while (data && data->size > 0) while (data && data->size > 0)
{ {
rdpsnd_process_plugin_data(rdpsnd, data); rdpsnd_process_plugin_data(rdpsnd, data);
data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); data = (RDP_PLUGIN_DATA*) (((uint8*) data) + data->size);
} }
if (rdpsnd->device == NULL) if (rdpsnd->device == NULL)
@ -504,7 +510,22 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
{ {
default_data[0].data[0] = "alsa"; default_data[0].data[0] = "alsa";
default_data[0].data[1] = "default"; default_data[0].data[1] = "default";
rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data);
if (!rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data))
{
default_data[0].data[0] = "macaudio";
default_data[0].data[1] = "default";
rdpsnd_load_device_plugin(rdpsnd, "macaudio", default_data);
}
else
{
printf("rdpsnd: successfully loaded alsa plugin\n");
}
}
else
{
printf("rdpsnd: successfully loaded pulseaudio plugin\n");
} }
} }
if (rdpsnd->device == NULL) if (rdpsnd->device == NULL)

View File

@ -19,12 +19,15 @@
set(SKEL_SRCS set(SKEL_SRCS
skel_main.c skel_main.c
skel_main.h skel_main.h)
)
add_library(skel ${SKEL_SRCS}) add_library(skel ${SKEL_SRCS})
set_target_properties(skel PROPERTIES PREFIX "") set_target_properties(skel PROPERTIES PREFIX "")
target_link_libraries(skel freerdp-utils) if(WITH_MONOLITHIC_BUILD)
target_link_libraries(skel freerdp)
else()
target_link_libraries(skel freerdp-utils)
endif()
install(TARGETS skel DESTINATION ${FREERDP_PLUGIN_PATH}) install(TARGETS skel DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -4,4 +4,8 @@ To create your own virtual channel plugin, copy this directory
then change all references of "skel" to your plugin name then change all references of "skel" to your plugin name
remember, plugin name are 7 chars or less, no spaces or funny chars remember, plugin name are 7 chars or less, no spaces or funny chars
server_chan_test.cpp is an example of how to open a channel to the client
this code needs to be compiled and run on the server in an rdp session
when connect with a client that has the "skel" plugin loaded
Jay Jay

View File

@ -0,0 +1,60 @@
// xrdp_chan_test.cpp : Basic test for virtual channel use.
// These headers are required for the windows terminal service calls.
#include "windows.h"
#include "wtsapi32.h"
#include <string>
#define DSIZE 1024
int main()
{
// Initialize the data for send/receive
char* data;
char* data1;
data = (char*)malloc(DSIZE);
data1 = (char*)malloc(DSIZE);
memset(data, 0xca, DSIZE);
memset(data1, 0, DSIZE);
// Open the skel channel in current session
void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0);
unsigned long written = 0;
// Write the data to the channel
bool ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written);
if (!ret)
{
long err = GetLastError();
printf("error 0x%8.8x\n", err);
return 1;
}
ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written);
if (!ret)
{
long err = GetLastError();
printf("error 0x%8.8x\n", err);
return 1;
}
if (written != DSIZE)
{
printf("error read %d\n", written);
return 1;
}
ret = WTSVirtualChannelClose(channel);
if (memcmp(data, data1, DSIZE) == 0)
{
}
else
{
printf("error data no match\n");
return 1;
}
printf("Success!\n");
Sleep(2000);
return 0;
}

View File

@ -18,6 +18,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -25,6 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <freerdp/constants.h> #include <freerdp/constants.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
@ -58,19 +63,25 @@ static void skel_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
if (skel == NULL) if (skel == NULL)
{ {
printf("skel_process_receive: skel is nil\n");
return; return;
} }
/* process data in(from server) here */ /* process data in(from server) here */
/* here we just send the same data back */ /* here we just send the same data back */
bytes = stream_get_length(data_in); bytes = stream_get_size(data_in);
printf("skel_process_receive: got bytes %d\n", bytes);
if (bytes > 0) if (bytes > 0)
{ {
data_out = stream_new(bytes); data_out = stream_new(bytes);
stream_copy(data_out, data_in, bytes); stream_copy(data_out, data_in, bytes);
/* svc_plugin_send takes ownership of data_out, that is why /* svc_plugin_send takes ownership of data_out, that is why
we do not free it */ we do not free it */
bytes = stream_get_length(data_in);
printf("skel_process_receive: sending bytes %d\n", bytes);
svc_plugin_send(plugin, data_out); svc_plugin_send(plugin, data_out);
} }

View File

@ -19,7 +19,7 @@
include_directories(${DIRECTFB_INCLUDE_DIRS}) include_directories(${DIRECTFB_INCLUDE_DIRS})
add_executable(dfreerdp set(FREERDP_CLIENT_DIRECTFB_SRCS
df_event.c df_event.c
df_event.h df_event.h
df_graphics.c df_graphics.c
@ -27,11 +27,20 @@ add_executable(dfreerdp
dfreerdp.c dfreerdp.c
dfreerdp.h) dfreerdp.h)
target_link_libraries(dfreerdp freerdp-core) add_executable(dfreerdp ${FREERDP_CLIENT_DIRECTFB_SRCS})
target_link_libraries(dfreerdp freerdp-gdi)
target_link_libraries(dfreerdp freerdp-locale)
target_link_libraries(dfreerdp freerdp-channels)
target_link_libraries(dfreerdp freerdp-utils)
target_link_libraries(dfreerdp ${DIRECTFB_LIBRARIES})
set(FREERDP_CLIENT_DIRECTFB_LIBS ${DIRECTFB_LIBRARIES})
if(WITH_MONOLITHIC_BUILD)
set(FREERDP_CLIENT_DIRECTFB_LIBS ${FREERDP_CLIENT_DIRECTFB_LIBS} freerdp)
else()
set(FREERDP_CLIENT_DIRECTFB_LIBS ${FREERDP_CLIENT_DIRECTFB_LIBS}
freerdp-core
freerdp-gdi
freerdp-locale
freerdp-channels
freerdp-utils)
endif()
target_link_libraries(dfreerdp ${FREERDP_CLIENT_DIRECTFB_LIBS})
install(TARGETS dfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS dfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -155,6 +155,8 @@ boolean df_pre_connect(freerdp* instance)
dfi->clrconv->palette = xnew(rdpPalette); dfi->clrconv->palette = xnew(rdpPalette);
freerdp_channels_pre_connect(instance->context->channels, instance); freerdp_channels_pre_connect(instance->context->channels, instance);
instance->context->cache = cache_new(instance->settings);
return true; return true;
} }

19
client/Mac/AppDelegate.h Normal file
View File

@ -0,0 +1,19 @@
//
// AppDelegate.h
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "MRDPView.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet MRDPView *mrdpView;
@property (assign) IBOutlet NSWindow *window;
int rdp_connect();
@end

26
client/Mac/AppDelegate.m Normal file
View File

@ -0,0 +1,26 @@
//
// AppDelegate.m
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "AppDelegate.h"
@implementation AppDelegate
//@synthesize window = _window;
//@synthesize mrdpView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
rdp_connect();
}
- (void) applicationWillTerminate:(NSNotification *)notification
{
//[mrdpView releaseResources];
}
@end

146
client/Mac/CMakeLists.txt Normal file
View File

@ -0,0 +1,146 @@
cmake_minimum_required (VERSION 2.8)
project (MacFreeRDP)
set(CMAKE_COLOR_MAKEFILE ON)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckStructHasMember)
include(FindPkgConfig)
include(TestBigEndian)
# Include our extra modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../../cmake/)
include(AutoVersioning)
include(ConfigOptions)
include(FindOptionalPackage)
include(CheckCCompilerFlag)
include(GNUInstallDirsWrapper)
# Default to debug build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
# Default to build shared libs
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif()
# Compiler-specific flags
if(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
endif()
if(WITH_SSE2_TARGET)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2")
endif()
endif()
# Libraries that we have a hard dependency on
if(NOT DEFINED OPENSSL_INCLUDE_DIR OR NOT DEFINED OPENSSL_LIBRARIES)
find_required_package(OpenSSL)
endif()
# Mac OS X
if(APPLE)
# Set the include files for FreeRDP to the relative path
set(FREERDP_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/../../include/)
set(FRAMEWORK_HEADERS_PATH /System/Library/Frameworks/Cocoa.framework/Versions/A/Headers/)
include_directories (${FREERDP_INCLUDE_PATH} ${FRAMEWORK_HEADERS_PATH} /System/Library/Frameworks)
# set(CMAKE_OSX_SYSROOT MacOSX10.7.sdk) # uncomment to specify SDK version
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4")
set(GUI_TYPE MACOSX_BUNDLE)
# Import libraries
find_library(FOUNDATION_LIBRARY Foundation)
message("+ Using foundation library ${FOUNDATION_LIBRARY}")
find_library(COCOA_LIBRARY Cocoa)
message("+ Using cocoa library ${COCOA_LIBRARY}")
find_library(APPKIT_LIBRARY AppKit)
message("+ Using appkit library ${APPKIT_LIBRARY}")
message(" Current source dir: ${CMAKE_CURRENT_SOURCE_DIR}")
# Set the OS X Bundle specific CMake variables which will be used to populate the plist for
# the application bundle
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP.Mac")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} Version 1.0.1")
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME})
set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.0.1)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.0.1)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.")
# Specific plist and NOT standard CMake variables
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
mark_as_advanced(COCOA_LIBRARY
FOUNDATION_LIBRARY
APPKIT_LIBRARY)
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
set(APP_TYPE MACOSX_BUNDLE)
endif()
# OS X Interface Builder files
file (GLOB MacFreeRDP_XIBS
*.xib
)
# Headers
file (GLOB MacFreeRDP_Headers
*.h
)
# Source
file (GLOB MacFreeRDP_Source
*.m
)
add_executable(MacFreeRDP
${APP_TYPE}
${MacFreeRDP_Headers}
${MacFreeRDP_Source}
${MacFreeRDP_XIBS})
# This is necessary for the xib file part below
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
# This allows for automatic xib to nib ibitool
set_target_properties(MacFreeRDP PROPERTIES RESOURCE "${MacFreeRDP_XIBS}")
# Automatic ref counting
set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
# XCode project architecture to native architecture of build machine
# -----------------------------------------------------------------------------------------------------
# Issue: Had some issues with FreeRDP project building only 64 bit and
# MacFreeRDP attempting to link to both 32 and 64 for dual target.
# In the future the FreeRDP Xcode project should be pulled in for a couple of reasons:
# 1) better step-into debugging 2) automatic dependency compilation and multi-arch compilation + linkage
# If you know the solutions for 1 and 2, please add below.
set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
# Set the info plist to the custom instance
set_target_properties(MacFreeRDP PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
if(NOT WIN32)
find_optional_package(MacAudio)
endif()
# Add all libraries
target_link_libraries(MacFreeRDP ${EXTRA_LIBS})
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-core/Debug/libfreerdp-core.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-channels/Debug/libfreerdp-channels.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-cache/Debug/libfreerdp-cache.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-gdi/Debug/libfreerdp-gdi.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-utils/Debug/libfreerdp-utils.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-codec/Debug/libfreerdp-codec.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-rail/Debug/libfreerdp-rail.dylib)

21
client/Mac/Credits.rtf Executable file
View File

@ -0,0 +1,21 @@
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\vieww9600\viewh8400\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
\f0\b\fs24 \cf0 Engineering:
\b0 \
Jay sorg\
Marc-Andre Moreau\
Vic Lee\
Otvaio Salvador \
Laxmikant Rashinkar\
and others\
\
\b Human Interface Design:
\b0 \
Laxmikant Rashinkar\
Jay Sorg\
}

34
client/Mac/Info.plist Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>FreeRDP.Mac</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

25
client/Mac/MRDPCursor.h Normal file
View File

@ -0,0 +1,25 @@
//
// MRDPCursor.h
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import <Cocoa/Cocoa.h>
#define boolean int
#include "freerdp/graphics.h"
@interface MRDPCursor : NSObject
{
@public
rdpPointer *pointer;
uint8 *cursor_data; // bitmapped pixel data
NSBitmapImageRep *bmiRep;
NSCursor *nsCursor;
NSImage *nsImage;
}
@end

12
client/Mac/MRDPCursor.m Normal file
View File

@ -0,0 +1,12 @@
//
// MRDPCursor.m
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import "MRDPCursor.h"
@implementation MRDPCursor
@end

61
client/Mac/MRDPRailView.h Normal file
View File

@ -0,0 +1,61 @@
#import <Cocoa/Cocoa.h>
#define boolean int
#import "freerdp/gdi/gdi.h"
#import "freerdp/rail/rail.h"
#import "MRDPRailWindow.h"
@interface MRDPRailView : NSView
{
freerdp * rdp_instance;
rdpContext * context;
NSBitmapImageRep * bmiRep;
NSPoint savedDragLocation;
char * pixelData;
boolean mouseInClientArea;
boolean titleBarClicked;
boolean gestureEventInProgress;
int width;
int height;
int savedWindowId;
int scrollWheelCount;
// store state info for some keys
int kdlshift;
int kdrshift;
int kdlctrl;
int kdrctrl;
int kdlalt;
int kdralt;
int kdlmeta;
int kdrmeta;
int kdcapslock;
@public
boolean isMoveSizeInProgress;
boolean saveInitialDragLoc;
boolean skipMoveWindowOnce;
int localMoveType;
}
@property (assign) MRDPRailWindow * mrdpRailWindow;
@property (assign) int windowIndex;
@property (assign) boolean activateWindow;
- (void) windowDidMove:(NSNotification *) notification;
- (void) updateDisplay;
- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID;
- (BOOL) eventIsInClientArea :(NSEvent *) event :(int *) xptr :(int *) yptr;
- (void) setupBmiRep:(int) width :(int) height;
- (void) releaseResources;
void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window);
void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove);
void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param);
void windows_to_apple_cords(NSRect * r);
void rail_MoveWindow(rdpRail * rail, rdpWindow * window);
void mac_rail_send_activate(int window_id);
@end

857
client/Mac/MRDPRailView.m Normal file
View File

@ -0,0 +1,857 @@
#include "MRDPRailView.h"
#define USE_RAIL_CVT
@implementation MRDPRailView
@synthesize mrdpRailWindow, windowIndex, activateWindow;
MRDPRailView * g_mrdpRailView;
struct kkey
{
int key_code;
int flags;
};
extern struct kkey g_keys[];
- (void) updateDisplay
{
boolean moveWindow = NO;
NSRect srcRectOuter;
NSRect destRectOuter;
rdpGdi * gdi;
if ((context == 0) || (context->gdi == 0))
return;
if (context->gdi->primary->hdc->hwnd->invalid->null)
return;
if (context->gdi->drawing != context->gdi->primary)
return;
gdi = context->gdi;
srcRectOuter = NSMakeRect(0, 0, self->width, self->height);
destRectOuter = [[self window] frame];
// cannot be bigger than our current screen size
NSRect screenSize = [[NSScreen mainScreen] frame];
if (destRectOuter.size.width > screenSize.size.width) {
destRectOuter.size.width = screenSize.size.width;
moveWindow = YES;
}
if (destRectOuter.size.height > screenSize.size.height) {
destRectOuter.size.height = screenSize.size.height;
moveWindow = YES;
}
if (destRectOuter.origin.x + destRectOuter.size.width > width)
destRectOuter.size.width = width - destRectOuter.origin.x;
[self setupBmiRep:destRectOuter.size.width :destRectOuter.size.height];
if (moveWindow) {
moveWindow = NO;
RAIL_WINDOW_MOVE_ORDER newWndLoc;
apple_to_windowMove(&destRectOuter, &newWndLoc);
newWndLoc.windowId = savedWindowId;
//skipMoveWindowOnce = TRUE;
//mac_send_rail_client_event(g_mrdpRailView->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &newWndLoc);
}
destRectOuter.origin.y = height - destRectOuter.origin.y - destRectOuter.size.height;
rail_convert_color_space(pixelData, (char *) gdi->primary_buffer,
&destRectOuter, self->width, self->height);
if (moveWindow)
[self setNeedsDisplayInRect:destRectOuter];
else
[self setNeedsDisplayInRect:[self frame]];
gdi->primary->hdc->hwnd->ninvalid = 0;
}
/** *********************************************************************
* called when our view needs to be redrawn
***********************************************************************/
- (void) drawRect:(NSRect)dirtyRect
{
[bmiRep drawInRect:dirtyRect fromRect:dirtyRect operation:NSCompositeCopy fraction:1.0 respectFlipped:NO hints:nil];
if (pixelData) {
free(pixelData);
pixelData = NULL;
}
bmiRep = nil;
}
/** *********************************************************************
* become first responder so we can get keyboard and mouse events
***********************************************************************/
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
return NO;
}
/** *********************************************************************
* called when a mouse move event occurrs
*
* ideally we want to be called when the mouse moves over NSView client area,
* but in reality we get called any time the mouse moves anywhere on the screen;
* we could use NSTrackingArea class to handle this but this class is available
* on Mac OS X v10.5 and higher; since we want to be compatible with older
* versions, we do this manually.
*
* TODO: here is how it can be done using legacy methods
* http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1
***********************************************************************/
- (void) mouseMoved:(NSEvent *)event
{
[super mouseMoved:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
// send mouse motion event to RDP server
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y);
}
/** *********************************************************************
* called when left mouse button is pressed down
***********************************************************************/
- (void)mouseDown:(NSEvent *) event
{
[super mouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
int yPos = (int) (winFrame.size.height - loc.y);
y = height - y;
if ((yPos >= 4) && (yPos <= 20))
titleBarClicked = YES;
else
titleBarClicked = NO;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
}
/** *********************************************************************
* called when left mouse button is released
***********************************************************************/
- (void) mouseUp:(NSEvent *) event
{
[super mouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y);
titleBarClicked = NO;
}
/** *********************************************************************
* called when right mouse button is pressed down
***********************************************************************/
- (void) rightMouseDown:(NSEvent *)event
{
[super rightMouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when right mouse button is released
***********************************************************************/
- (void) rightMouseUp:(NSEvent *)event
{
[super rightMouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when middle mouse button is pressed
***********************************************************************/
- (void) otherMouseDown:(NSEvent *)event
{
[super otherMouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
}
/** *********************************************************************
* called when middle mouse button is released
***********************************************************************/
- (void) otherMouseUp:(NSEvent *)event
{
[super otherMouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y);
}
- (void) scrollWheel:(NSEvent *)event
{
uint16 flags;
[super scrollWheel:event];
// we get more two finger trackpad scroll events
// than scrollWheel events, so we drop some
if (gestureEventInProgress) {
scrollWheelCount++;
if (scrollWheelCount % 8 != 0)
return;
}
if ([event scrollingDeltaY] < 0) {
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
}
else {
flags = PTR_FLAGS_WHEEL | 0x78;
}
rdp_instance->input->MouseEvent(rdp_instance->input, flags, 0, 0);
}
/** *********************************************************************
* called when mouse is moved with left button pressed
* note: invocation order is: mouseDown, mouseDragged, mouseUp
***********************************************************************/
- (void) mouseDragged:(NSEvent *)event
{
[super mouseDragged:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) loc.x;
int y = (int) loc.y;
if (titleBarClicked) {
// window is being dragged to a new location
int newX = x - savedDragLocation.x;
int newY = y - savedDragLocation.y;
if ((newX == 0) && (newY == 0))
return;
winFrame.origin.x += newX;
winFrame.origin.y += newY;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_LEFT) {
// left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff == 0)
return;
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_RIGHT) {
// right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff == 0)
return;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
winFrame.size.width += diff;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOP) {
// top border resize taking place
int diff = (int) (loc.y - savedDragLocation.y);
if (diff == 0)
return;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
winFrame.size.height += diff;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOM) {
// bottom border resize taking place
int diff = (int) (loc.y - savedDragLocation.y);
if (diff == 0)
return;
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOPLEFT) {
// top left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
savedDragLocation.y = loc.y;
winFrame.size.height += diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOPRIGHT) {
// top right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
winFrame.size.width += diff;
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
winFrame.size.height += diff;
}
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOMLEFT) {
// bottom left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOMRIGHT) {
// bottom right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
savedDragLocation.x = loc.x;
//savedDragLocation.y = loc.y;
winFrame.size.width += diff;
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
}
[[self window] setFrame:winFrame display:YES];
return;
}
x = (int) (winFrame.origin.x + loc.x);
y = (int) (winFrame.origin.y + loc.y);
y = height - y;
// send mouse motion event to RDP server
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y);
}
/** *********************************************************************
* called when a key is pressed
***********************************************************************/
- (void) keyDown:(NSEvent *) event
{
int key;
key = [event keyCode];
rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_DOWN, g_keys[key].key_code);
}
/** *********************************************************************
* called when a key is released
***********************************************************************/
- (void) keyUp:(NSEvent *) event
{
int key;
key = [event keyCode];
rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_RELEASE, g_keys[key].key_code);
}
/** *********************************************************************
* called when shift, control, alt and meta keys are pressed/released
***********************************************************************/
- (void) flagsChanged:(NSEvent *) event
{
NSUInteger mf = [event modifierFlags];
// caps lock
if (mf == 0x10100) {
printf("TODO: caps lock is on\n");
kdcapslock = 1;
}
if (kdcapslock && (mf == 0x100)) {
kdcapslock = 0;
printf("TODO: caps lock is off\n");
}
// left shift
if ((kdlshift == 0) && ((mf & 2) != 0)) {
// left shift went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a);
kdlshift = 1;
}
if ((kdlshift != 0) && ((mf & 2) == 0)) {
// left shift went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a);
kdlshift = 0;
}
// right shift
if ((kdrshift == 0) && ((mf & 4) != 0)) {
// right shift went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36);
kdrshift = 1;
}
if ((kdrshift != 0) && ((mf & 4) == 0)) {
// right shift went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36);
kdrshift = 0;
}
// left ctrl
if ((kdlctrl == 0) && ((mf & 1) != 0)) {
// left ctrl went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d);
kdlctrl = 1;
}
if ((kdlctrl != 0) && ((mf & 1) == 0)) {
// left ctrl went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d);
kdlctrl = 0;
}
// right ctrl
if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) {
// right ctrl went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d);
kdrctrl = 1;
}
if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) {
// right ctrl went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d);
kdrctrl = 0;
}
// left alt
if ((kdlalt == 0) && ((mf & 0x20) != 0)) {
// left alt went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38);
kdlalt = 1;
}
if ((kdlalt != 0) && ((mf & 0x20) == 0)) {
// left alt went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38);
kdlalt = 0;
}
// right alt
if ((kdralt == 0) && ((mf & 0x40) != 0)) {
// right alt went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38);
kdralt = 1;
}
if ((kdralt != 0) && ((mf & 0x40) == 0)) {
// right alt went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38);
kdralt = 0;
}
// left meta
if ((kdlmeta == 0) && ((mf & 0x08) != 0)) {
// left meta went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b);
kdlmeta = 1;
}
if ((kdlmeta != 0) && ((mf & 0x08) == 0)) {
// left meta went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b);
kdlmeta = 0;
}
// right meta
if ((kdrmeta == 0) && ((mf & 0x10) != 0)) {
// right meta went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c);
kdrmeta = 1;
}
if ((kdrmeta != 0) && ((mf & 0x10) == 0)) {
// right meta went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c);
kdrmeta = 0;
}
}
- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID
{
rdp_instance = instance;
context = instance->context;
width = w;
height = h;
savedWindowId = windowID;
NSRect tr = NSMakeRect(0, 0,
[[NSScreen mainScreen] frame].size.width,
[[NSScreen mainScreen] frame].size.height);
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:tr options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveAlways owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
g_mrdpRailView = self;
[self becomeFirstResponder];
[self setAcceptsTouchEvents:YES];
// we want to be notified when window resizes....
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil];
// ...moves
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:nil];
// ...and becomes the key window
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil];
}
- (void) setupBmiRep:(int) frameWidth :(int) frameHeight
{
struct rgba_data
{
char red;
char green;
char blue;
char alpha;
};
if (pixelData)
free(pixelData);
pixelData = (char *) malloc(frameWidth * frameHeight * sizeof(struct rgba_data));
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixelData
pixelsWide:frameWidth
pixelsHigh:frameHeight
bitsPerSample:8
samplesPerPixel:sizeof(struct rgba_data)
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:0
bytesPerRow:frameWidth * sizeof(struct rgba_data)
bitsPerPixel:0];
}
- (void) beginGestureWithEvent:(NSEvent *)event
{
gestureEventInProgress = YES;
}
- (void) endGestureWithEvent:(NSEvent *)event
{
gestureEventInProgress = NO;
}
/**
* called when a bordered window changes size
*/
- (void) windowDidResize:(NSNotification *) notification
{
// if we are not the source of this notification, just return
if ([notification object] != [self mrdpRailWindow])
return;
// let RDP server know that window has moved
RAIL_WINDOW_MOVE_ORDER windowMove;
NSRect r = [[self window] frame];
int diffInHeight = [[self window] frame].size.height - [self frame].size.height;
r.size.height -= diffInHeight;
apple_to_windowMove(&r, &windowMove);
windowMove.windowId = self->savedWindowId;
mac_send_rail_client_event(self->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove);
}
/**
* called when user moves a bordered window
*/
- (void) windowDidMove:(NSNotification *) notification
{
// if we are not the source of this notification, just return
if ([notification object] != [self mrdpRailWindow])
return;
// let RDP server know that window has moved
RAIL_WINDOW_MOVE_ORDER windowMove;
NSRect r = [[self window] frame];
int diffInHeight = [[self window] frame].size.height - [self frame].size.height;
r.size.height -= diffInHeight;
apple_to_windowMove(&r, &windowMove);
windowMove.windowId = self->savedWindowId;
mac_send_rail_client_event(self->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &windowMove);
}
/**
* called when a NSWindow becomes the key window
*/
- (void) windowDidBecomeKey:(NSNotification *) notification
{
// if we are not the source of this notification, just return
if ([notification object] != [self mrdpRailWindow])
return;
if (![self activateWindow])
return;
[[self window] setAcceptsMouseMovedEvents: YES];
//if ([self activateWindow])
mac_rail_send_activate(savedWindowId);
set_current_window(windowIndex);
}
- (void) releaseResources
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
void rail_cvt_from_rect(char *dest, char *src, NSRect destRect, int destWidth, int destHeight, NSRect srcRect)
{
}
/** *********************************************************************
* color space conversion used specifically in RAIL
***********************************************************************/
void rail_convert_color_space(char *destBuf, char * srcBuf,
NSRect * destRect, int width, int height)
{
int i;
int j;
int numRows;
int srcX;
int srcY;
int destX;
int destY;
int pixelsPerRow;
int pixel;
int pixel1;
int pixel2;
int * src32;
int * dest32;
int destWidth = destRect->size.width;
int destHeight = destRect->size.height;
if ((!destBuf) || (!srcBuf)) {
return;
}
numRows = (destRect->origin.y + destHeight > height) ? height - destRect->origin.y : destHeight;
pixelsPerRow = destWidth;
srcX = destRect->origin.x;
srcY = destRect->origin.y;
destX = 0;
destY = 0;
for (i = 0; i < numRows; i++)
{
src32 = (int *) (srcBuf + ((srcY + i) * width + srcX) * 4);
dest32 = (int *) (destBuf + ((destY + i) * destWidth + destX) * 4);
for (j = 0; j < pixelsPerRow; j++)
{
pixel = *src32;
pixel1 = (pixel & 0x00ff0000) >> 16;
pixel2 = (pixel & 0x000000ff) << 16;
pixel = (pixel & 0xff00ff00) | pixel1 | pixel2;
*dest32 = pixel;
src32++;
dest32++;
}
}
destRect->origin.y = destHeight - destRect->origin.y - destRect->size.height;
return;
}
/**
* let RDP server know that window has moved
*/
void rail_MoveWindow(rdpRail * rail, rdpWindow * window)
{
if (g_mrdpRailView->isMoveSizeInProgress) {
return;
}
if (g_mrdpRailView->skipMoveWindowOnce) {
g_mrdpRailView->skipMoveWindowOnce = NO;
return;
}
// this rect is based on Windows co-ordinates...
NSRect r;
r.origin.x = window->windowOffsetX;
r.origin.y = window->windowOffsetY;
r.size.width = window->windowWidth;
r.size.height = window->windowHeight;
windows_to_apple_cords(&r);
[[g_mrdpRailView window] setFrame:r display:YES];
}
void mac_rail_send_activate(int window_id)
{
RAIL_ACTIVATE_ORDER activate;
activate.windowId = window_id;
activate.enabled = 1;
mac_send_rail_client_event(g_mrdpRailView->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate);
}
@end

View File

@ -0,0 +1,13 @@
//
// MRDPRailWindow.h
// Mac
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MRDPRailWindow : NSWindow
@end

View File

@ -0,0 +1,18 @@
//
// MRDPRailWindow.m
// Mac
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "MRDPRailWindow.h"
@implementation MRDPRailWindow
- (BOOL) canBecomeKeyWindow
{
return YES;
}
@end

177
client/Mac/MRDPView.h Normal file
View File

@ -0,0 +1,177 @@
//
// MRDPView.h
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import <Cocoa/Cocoa.h>
typedef int boolean;
#import "MRDPWindow.h"
#import "freerdp/freerdp.h"
#import "freerdp/types.h"
#import "freerdp/channels/channels.h"
#import "freerdp/gdi/gdi.h"
#import "freerdp/graphics.h"
#import "freerdp/utils/event.h"
#import "freerdp/plugins/cliprdr.h"
#import "freerdp/utils/args.h"
#import "freerdp/rail/rail.h"
#import "freerdp/rail.h"
#import "freerdp/utils/rail.h"
@interface MRDPView : NSView
{
CFRunLoopSourceRef run_loop_src;
CFRunLoopSourceRef run_loop_src_channels;
NSBitmapImageRep *bmiRep;
NSMutableArray *cursors;
NSMutableArray *windows;
NSTimer *pasteboard_timer;
NSRect rect;
NSRect prevWinPosition;
freerdp *rdp_instance;
rdpContext *rdp_context;
char *pixel_data;
int width;
int height;
int argc;
int titleBarHeight;
char **argv;
// RAIL stuff
MRDPWindow *currentWindow;
NSPoint savedDragLocation;
boolean mouseInClientArea;
boolean isRemoteApp;
boolean firstCreateWindow;
boolean isMoveSizeInProgress;
boolean skipResizeOnce;
boolean saveInitialDragLoc;
boolean skipMoveWindowOnce;
// store state info for some keys
int kdlshift;
int kdrshift;
int kdlctrl;
int kdrctrl;
int kdlalt;
int kdralt;
int kdlmeta;
int kdrmeta;
int kdcapslock;
@public
NSWindow *ourMainWindow;
NSPasteboard *pasteboard_rd; // for reading from clipboard
NSPasteboard *pasteboard_wr; // for writing to clipboard
int pasteboard_changecount;
int pasteboard_format;
int is_connected; // true when connected to RDP server
}
- (void) rdpConnectEror;
- (void) rdpRemoteAppError;
- (void) saveStateInfo :(freerdp *) instance :(rdpContext *) context;
- (void) onPasteboardTimerFired :(NSTimer *) timer;
- (void) my_draw_rect :(void *) context;
- (void) releaseResources;
- (void) setViewSize : (int) width : (int) height;
@property (assign) int is_connected;
@end
/* Pointer Flags */
#define PTR_FLAGS_WHEEL 0x0200
#define PTR_FLAGS_WHEEL_NEGATIVE 0x0100
#define PTR_FLAGS_MOVE 0x0800
#define PTR_FLAGS_DOWN 0x8000
#define PTR_FLAGS_BUTTON1 0x1000
#define PTR_FLAGS_BUTTON2 0x2000
#define PTR_FLAGS_BUTTON3 0x4000
#define WheelRotationMask 0x01FF
void pointer_new(rdpContext* context, rdpPointer* pointer);
void pointer_free(rdpContext* context, rdpPointer* pointer);
void pointer_set(rdpContext* context, rdpPointer* pointer);
void pointer_setNull(rdpContext* context);
void pointer_setDefault(rdpContext* context);
int rdp_connect();
boolean mac_pre_connect(freerdp *inst);
boolean mac_post_connect(freerdp *inst);
void mac_context_new(freerdp *inst, rdpContext *context);
void mac_context_free(freerdp *inst, rdpContext *context);
void mac_set_bounds(rdpContext *context, rdpBounds *bounds);
void mac_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap);
void mac_begin_paint(rdpContext *context);
void mac_end_paint(rdpContext* context);
void mac_save_state_info(freerdp *inst, rdpContext *context);
void skt_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info);
void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info);
int register_fds(int *fds, int count, void *inst);
int invoke_draw_rect(rdpContext *context);
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
int receive_channel_data(freerdp *inst, int chan_id, uint8 *data, int size, int flags, int total_size);
void process_cliprdr_event(freerdp *inst, RDP_EVENT *event);
void cliprdr_process_cb_format_list_event(freerdp *inst, RDP_CB_FORMAT_LIST_EVENT* event);
void cliprdr_send_data_request(freerdp *inst, uint32 format);
void cliprdr_process_cb_monitor_ready_event(freerdp* inst);
void cliprdr_process_cb_data_response_event(freerdp *inst, RDP_CB_DATA_RESPONSE_EVENT *event);
void cliprdr_process_text(freerdp *inst, uint8 *data, int len);
void cliprdr_send_supported_format_list(freerdp *inst);
int register_channel_fds(int *fds, int count, void *inst);
void mac_process_rail_event(freerdp *inst, RDP_EVENT *event);
void mac_rail_register_callbacks(freerdp *inst, rdpRail *rail);
void mac_rail_CreateWindow(rdpRail *rail, rdpWindow *window);
void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window);
void mac_rail_ShowWindow(rdpRail *rail, rdpWindow *window, uint8 state);
void mac_rail_SetWindowText(rdpRail *rail, rdpWindow *window);
void mac_rail_SetWindowIcon(rdpRail *rail, rdpWindow *window, rdpIcon *icon);
void mac_rail_SetWindowRects(rdpRail *rail, rdpWindow *window);
void mac_rail_SetWindowVisibilityRects(rdpRail *rail, rdpWindow *window);
void mac_rail_DestroyWindow(rdpRail *rail, rdpWindow *window);
void mac_process_rail_get_sysparams_event(rdpChannels *channels, RDP_EVENT *event);
void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param);
void mac_on_free_rail_client_event(RDP_EVENT* event);
void mac_process_rail_server_sysparam_event(rdpChannels* channels, RDP_EVENT* event);
void mac_process_rail_exec_result_event(rdpChannels* channels, RDP_EVENT* event);
void mac_rail_enable_remoteapp_mode();
void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, RDP_EVENT* event);
void mac_process_rail_server_localmovesize_event(freerdp *inst, RDP_EVENT *event);
void apple_center_window(NSRect * r);
void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove);
struct mac_context
{
// *must* have this - do not delete
rdpContext _p;
};
struct cursor
{
rdpPointer *pointer;
uint8 *cursor_data; // bitmapped pixel data
void *bmiRep; // NSBitmapImageRep
void *nsCursor; // NSCursor
void *nsImage; // NSImage
};
struct rgba_data
{
char red;
char green;
char blue;
char alpha;
};
struct kkey
{
int key_code;
int flags;
};

2314
client/Mac/MRDPView.m Normal file

File diff suppressed because it is too large Load Diff

15
client/Mac/MRDPWindow.h Normal file
View File

@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import "MRDPRailView.h"
#import "MRDPRailWindow.h"
@interface MRDPWindow : NSObject
{
}
@property (assign) int windowID;
@property (retain) MRDPRailWindow * window;
@property (retain) MRDPRailView * view;
@end

10
client/Mac/MRDPWindow.m Normal file
View File

@ -0,0 +1,10 @@
#include "MRDPWindow.h"
@implementation MRDPWindow
@synthesize windowID;
@synthesize window;
@synthesize view;
@end

796
client/Mac/MainMenu.xib Executable file
View File

@ -0,0 +1,796 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2177</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">2177</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSView</string>
<string>NSMenu</string>
<string>NSWindowTemplate</string>
<string>NSMenuItem</string>
<string>NSCustomView</string>
<string>IBNSLayoutConstraint</string>
<string>NSCustomObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<object class="NSCustomObject" id="1021">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1050">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSMenu" id="649796088">
<string key="NSTitle">AMainMenu</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="694149608">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">FreeRDP</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<object class="NSCustomResource" key="NSOnImage" id="35465992">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuCheckmark</string>
</object>
<object class="NSCustomResource" key="NSMixedImage" id="502551668">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuMixedState</string>
</object>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="110575045">
<string key="NSTitle">FreeRDP</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="238522557">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">About FreeRDP</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="304266470">
<reference key="NSMenu" ref="110575045"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="755159360">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Hide FreeRDP</string>
<string key="NSKeyEquiv">h</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="342932134">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Hide Others</string>
<string key="NSKeyEquiv">h</string>
<int key="NSKeyEquivModMask">1572864</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="908899353">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Show All</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="1056857174">
<reference key="NSMenu" ref="110575045"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="632727374">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Quit FreeRDP</string>
<string key="NSKeyEquiv">q</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSAppleMenu</string>
</object>
</object>
<object class="NSMenuItem" id="379814623">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">File</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="952259628">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Edit</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="302598603">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Format</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="586577488">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">View</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="713487014">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Window</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="835318025">
<string key="NSTitle">Window</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="1011231497">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Minimize</string>
<string key="NSKeyEquiv">m</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="575023229">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Zoom</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="299356726">
<reference key="NSMenu" ref="835318025"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="625202149">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Bring All to Front</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSWindowsMenu</string>
</object>
</object>
<object class="NSMenuItem" id="448692316">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Help</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="992780483">
<string key="NSTitle">Help</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="105068016">
<reference key="NSMenu" ref="992780483"/>
<string key="NSTitle">Mac Help</string>
<string key="NSKeyEquiv">?</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSHelpMenu</string>
</object>
</object>
</array>
<string key="NSName">_NSMainMenu</string>
</object>
<object class="NSWindowTemplate" id="972006081">
<int key="NSWindowStyleMask">15</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{163, 10}, {1024, 768}}</string>
<int key="NSWTFlags">1954021376</int>
<string key="NSWindowTitle">FreeRDP</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1024, 768}</string>
<string key="NSWindowContentMinSize">{1024, 768}</string>
<object class="NSView" key="NSWindowView" id="439893737">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSCustomView" id="467991374">
<reference key="NSNextResponder" ref="439893737"/>
<int key="NSvFlags">268</int>
<string key="NSFrameSize">{1024, 768}</string>
<reference key="NSSuperview" ref="439893737"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">MRDPView</string>
</object>
</array>
<string key="NSFrameSize">{1024, 768}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="467991374"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1366, 746}}</string>
<string key="NSMinSize">{1024, 790}</string>
<string key="NSMaxSize">{1024, 790}</string>
<int key="NSWindowCollectionBehavior">128</int>
<bool key="NSWindowIsRestorable">YES</bool>
</object>
<object class="NSCustomObject" id="976324537">
<string key="NSClassName">AppDelegate</string>
</object>
<object class="NSCustomObject" id="755631768">
<string key="NSClassName">NSFontManager</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">terminate:</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="632727374"/>
</object>
<int key="connectionID">449</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">orderFrontStandardAboutPanel:</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="238522557"/>
</object>
<int key="connectionID">142</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="976324537"/>
</object>
<int key="connectionID">568</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performMiniaturize:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="1011231497"/>
</object>
<int key="connectionID">37</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">arrangeInFront:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="625202149"/>
</object>
<int key="connectionID">39</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performZoom:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="575023229"/>
</object>
<int key="connectionID">240</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">hide:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="755159360"/>
</object>
<int key="connectionID">367</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">hideOtherApplications:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="342932134"/>
</object>
<int key="connectionID">368</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">unhideAllApplications:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="908899353"/>
</object>
<int key="connectionID">370</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">showHelp:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="105068016"/>
</object>
<int key="connectionID">493</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">mrdpView</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="467991374"/>
</object>
<int key="connectionID">565</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="972006081"/>
</object>
<int key="connectionID">567</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1048"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1021"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1014"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1050"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="649796088"/>
<array class="NSMutableArray" key="children">
<reference ref="713487014"/>
<reference ref="694149608"/>
<reference ref="952259628"/>
<reference ref="379814623"/>
<reference ref="586577488"/>
<reference ref="302598603"/>
<reference ref="448692316"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="713487014"/>
<array class="NSMutableArray" key="children">
<reference ref="835318025"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">56</int>
<reference key="object" ref="694149608"/>
<array class="NSMutableArray" key="children">
<reference ref="110575045"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">217</int>
<reference key="object" ref="952259628"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">83</int>
<reference key="object" ref="379814623"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">57</int>
<reference key="object" ref="110575045"/>
<array class="NSMutableArray" key="children">
<reference ref="238522557"/>
<reference ref="755159360"/>
<reference ref="908899353"/>
<reference ref="632727374"/>
<reference ref="304266470"/>
<reference ref="1056857174"/>
<reference ref="342932134"/>
</array>
<reference key="parent" ref="694149608"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">58</int>
<reference key="object" ref="238522557"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">134</int>
<reference key="object" ref="755159360"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">150</int>
<reference key="object" ref="908899353"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">136</int>
<reference key="object" ref="632727374"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">236</int>
<reference key="object" ref="304266470"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">149</int>
<reference key="object" ref="1056857174"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">145</int>
<reference key="object" ref="342932134"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">24</int>
<reference key="object" ref="835318025"/>
<array class="NSMutableArray" key="children">
<reference ref="299356726"/>
<reference ref="625202149"/>
<reference ref="575023229"/>
<reference ref="1011231497"/>
</array>
<reference key="parent" ref="713487014"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">92</int>
<reference key="object" ref="299356726"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="625202149"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">239</int>
<reference key="object" ref="575023229"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="1011231497"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">295</int>
<reference key="object" ref="586577488"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">371</int>
<reference key="object" ref="972006081"/>
<array class="NSMutableArray" key="children">
<reference ref="439893737"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">372</int>
<reference key="object" ref="439893737"/>
<array class="NSMutableArray" key="children">
<reference ref="467991374"/>
<object class="IBNSLayoutConstraint" id="334327932">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="890641817">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="437142032">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">4</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="934352021">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">3</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
</array>
<reference key="parent" ref="972006081"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">375</int>
<reference key="object" ref="302598603"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">420</int>
<reference key="object" ref="755631768"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">490</int>
<reference key="object" ref="448692316"/>
<array class="NSMutableArray" key="children">
<reference ref="992780483"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">491</int>
<reference key="object" ref="992780483"/>
<array class="NSMutableArray" key="children">
<reference ref="105068016"/>
</array>
<reference key="parent" ref="448692316"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">492</int>
<reference key="object" ref="105068016"/>
<reference key="parent" ref="992780483"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">494</int>
<reference key="object" ref="976324537"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">551</int>
<reference key="object" ref="467991374"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">561</int>
<reference key="object" ref="334327932"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">562</int>
<reference key="object" ref="890641817"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">563</int>
<reference key="object" ref="437142032"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">564</int>
<reference key="object" ref="934352021"/>
<reference key="parent" ref="439893737"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="295.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES" key="371.IBNSWindowAutoPositionCentersHorizontal"/>
<boolean value="YES" key="371.IBNSWindowAutoPositionCentersVertical"/>
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
<integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
<array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
<reference ref="334327932"/>
<reference ref="890641817"/>
<reference ref="437142032"/>
<reference ref="934352021"/>
</array>
<string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="551.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="551.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="561.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="562.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="563.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="564.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">568</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">AppDelegate</string>
<string key="superclassName">NSObject</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="mrdpView">MRDPView</string>
<string key="window">NSWindow</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="mrdpView">
<string key="name">mrdpView</string>
<string key="candidateClassName">MRDPView</string>
</object>
<object class="IBToOneOutletInfo" key="window">
<string key="name">window</string>
<string key="candidateClassName">NSWindow</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MRDPView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MRDPView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSLayoutConstraint</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1070" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NSMenuCheckmark">{11, 11}</string>
<string key="NSMenuMixedState">{10, 3}</string>
</dictionary>
<bool key="IBDocument.UseAutolayout">YES</bool>
</data>
</archive>

140
client/Mac/README.txt Normal file
View File

@ -0,0 +1,140 @@
-------------------------------------------------------------------------
Building FreeRDP on Mac OS X
-------------------------------------------------------------------------
Platform: Lion with Xcode 4.3.2
------------------
installing cmake
------------------
first install macports by googling for it, the run the following command
sudo port install cmake
----------------
installing gcc
----------------
Click on Xcode->Preferences->Downloads
Click on Components
Click on Install Command line tools
You will be prompted for your Apple Developer userid and password
----------------------------------------
download FreeRDP source code using git
----------------------------------------
mkdir ~/projects/A8
cd ~/projects/A8
git clone git://github.com/FreeRDP/FreeRDP.git
------------------
building FreeRDP
------------------
cd ~projects/A8/FreeRDP
cmake -DWITH_MACAUDIO=ON -DCMAKE_INSTALL_PREFIX="</path/to/your/staging/dir>"
make
make install
------------------------
creating Xcode project
------------------------
Start xcode
Select 'Create a new xcode project'
In 'Choose a template for your new project', click on Mac OS X -> application
Click on 'Cocoa Application'
Click on next
I used the following:
Product Name: Mac
Company Identifier: com.freerdp
Check 'Automatic Reference Counting'
Create the project in your directory of choice
-------------------------------
Adding files to your projects
-------------------------------
Add the following files to your project:
cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.h
cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.m
cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.h
cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.m
This is what your AppDelegate.h file should like like
#import <Cocoa/Cocoa.h>
#import "MRDPView.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet MRDPView *mrdpView;
int rdp_connect();
@end
This is what your AppDelegate.m file should like like
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize mrdpView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
rdp_connect();
}
- (void) applicationWillTerminate:(NSNotification *)notification
{
[mrdpView releaseResources];
}
@end
----------------------------------
Modifying your MainMenu.xib file
----------------------------------
In your project select MainMenu.xib and drag a NSView object intot the main window
Name the class MRDPView
In Interface Builder, select the Application Delegate and tie the mrdpview outlet to the NSView
Set the default size of the main window to 1024x768. This is FreeRDP's default resolution
----------------------------
Configuring build settings
----------------------------
In Project Navigator, click on Mac
Click on Targets -> Mac
Click on Build Phases
Click on 'Link Binary With Libraries' and click on the + button, then click on the 'Add Other' button to add the following dynamic libraries
~/projects/A8/FreeRDP/libfreerdp-core/libfreerdp-core.dylib
~/projects/A8/FreeRDP/libfreerdp-channels/libfreerdp-channels.dylilb
~/projects/A8/FreeRDP/libfreerdp-utils/libfreerdp-utils.dylib
~/projects/A8/FreeRDP/libfreerdp-codec/libfreerdp-codec.dylib
~/projects/A8/FreeRDP/libfreerdp-cache/libfreerdp-cache.dylib
~/projects/A8/FreeRDP/libfreerdp-gdi/libfreerdp-gdi.dylib
Click on 'Build Settings'
In 'Search Paths -> Library Search Paths' set the following
Header Search Path Debug: ~/projects/A8/FreeRDP/include
Header Search Path Release: ~/projects/A8/FreeRDP/include
TODO: in build settings, set strip build product to yes when done debugging
---------------------------
To deploy the application
---------------------------
in xcode, click on Product->Archive
Click on Distribute button
Select Export As -> application

14
client/Mac/main.m Normal file
View File

@ -0,0 +1,14 @@
//
// main.m
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}

View File

@ -1,36 +1,48 @@
# FreeRDP: A Remote Desktop Protocol Client # FreeRDP: A Remote Desktop Protocol Client
# FreeRDP Windows cmake build script # FreeRDP Windows cmake build script
# #
# Copyright 2011 O.S. Systems Software Ltda. # Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br> #
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> # Licensed under the Apache License, Version 2.0 (the "License");
# # you may not use this file except in compliance with the License.
# Licensed under the Apache License, Version 2.0 (the "License"); # You may obtain a copy of the License at
# 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
# #
# 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,
# Unless required by applicable law or agreed to in writing, software # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# distributed under the License is distributed on an "AS IS" BASIS, # See the License for the specific language governing permissions and
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # limitations under the License.
# See the License for the specific language governing permissions and
# limitations under the License. set(FREERDP_CLIENT_WINDOWS_SRCS
wf_gdi.c
add_executable(wfreerdp WIN32 wf_gdi.h
wf_gdi.c wf_event.c
wf_gdi.h wf_event.h
wf_event.c wf_graphics.c
wf_event.h wf_graphics.h
wf_graphics.c wf_cliprdr.c
wf_graphics.h wf_cliprdr.h
wfreerdp.c wf_window.c
wfreerdp.h) wf_window.h
wf_rail.c
target_link_libraries(wfreerdp freerdp-core) wf_rail.h
target_link_libraries(wfreerdp freerdp-gdi) wfreerdp.c
target_link_libraries(wfreerdp freerdp-utils) wfreerdp.h)
target_link_libraries(wfreerdp freerdp-codec)
target_link_libraries(wfreerdp freerdp-channels) add_executable(wfreerdp WIN32 ${FREERDP_CLIENT_WINDOWS_SRCS})
install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) if(WITH_MONOLITHIC_BUILD)
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} freerdp)
else()
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS}
freerdp-core
freerdp-gdi
freerdp-codec
freerdp-channels
freerdp-utils)
endif()
target_link_libraries(wfreerdp ${FREERDP_CLIENT_WINDOWS_LIBS})
install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR})

110
client/Windows/wf_cliprdr.c Normal file
View File

@ -0,0 +1,110 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows Clipboard Redirection
*
* Copyright 2012 Jason Champion
*
* 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 <freerdp/utils/event.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/plugins/cliprdr.h>
#include "wf_cliprdr.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman)
{
}
void wf_cliprdr_uninit(wfInfo* wfi)
{
}
static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi)
{
}
static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, RDP_CB_DATA_REQUEST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_format_list_event(wfInfo* wfi, RDP_CB_FORMAT_LIST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event)
{
}
void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event)
{
switch (event->event_type)
{
case RDP_EVENT_TYPE_CB_MONITOR_READY:
wf_cliprdr_process_cb_monitor_ready_event(wfi);
break;
case RDP_EVENT_TYPE_CB_FORMAT_LIST:
wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case RDP_EVENT_TYPE_CB_DATA_REQUEST:
wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case RDP_EVENT_TYPE_CB_DATA_RESPONSE:
wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
default:
break;
}
}
boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
void wf_cliprdr_check_owner(wfInfo* wfi)
{
}

View File

@ -0,0 +1,33 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows Clipboard Redirection
*
* Copyright 2012 Jason Champion
*
* 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 __WF_CLIPRDR_H
#define __WF_CLIPRDR_H
#include "wfreerdp.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman);
void wf_cliprdr_uninit(wfInfo* wfi);
void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event);
boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfInfo* wfi);
#endif /* __WF_CLIPRDR_H */

View File

@ -19,8 +19,14 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include "wfreerdp.h" #include "wfreerdp.h"
#include "wf_event.h" #include "wf_event.h"

View File

@ -19,6 +19,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -237,8 +241,8 @@ void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
COLORREF org_textcolor; COLORREF org_textcolor;
wfInfo* wfi = ((wfContext*) context)->wfi; wfInfo* wfi = ((wfContext*) context)->wfi;
fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, 32, wfi->clrconv); fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, 32, wfi->clrconv); bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp); brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp);
org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE); org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE);
@ -279,7 +283,7 @@ void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
uint32 brush_color; uint32 brush_color;
wfInfo* wfi = ((wfContext*) context)->wfi; wfInfo* wfi = ((wfContext*) context)->wfi;
brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, 24, wfi->clrconv); brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
rect.left = opaque_rect->nLeftRect; rect.left = opaque_rect->nLeftRect;
rect.top = opaque_rect->nTopRect; rect.top = opaque_rect->nTopRect;
@ -306,7 +310,7 @@ void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
{ {
rectangle = &multi_opaque_rect->rectangles[i]; rectangle = &multi_opaque_rect->rectangles[i];
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, 32, wfi->clrconv); brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
rect.left = rectangle->left; rect.left = rectangle->left;
rect.top = rectangle->top; rect.top = rectangle->top;

View File

@ -17,6 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/codec/bitmap.h> #include <freerdp/codec/bitmap.h>
@ -45,12 +49,12 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data,
bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = negHeight; bmi.bmiHeader.biHeight = negHeight;
bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = bpp; bmi.bmiHeader.biBitCount = wfi->dstBpp;
bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biCompression = BI_RGB;
bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0);
if (data != NULL) if (data != NULL)
freerdp_image_convert(data, cdata, width, height, bpp, bpp, wfi->clrconv); freerdp_image_convert(data, cdata, width, height, bpp, wfi->dstBpp, wfi->clrconv);
if (pdata != NULL) if (pdata != NULL)
*pdata = cdata; *pdata = cdata;
@ -157,7 +161,7 @@ void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
} }
void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed) uint8* data, int width, int height, int bpp, int length, boolean compressed, int codec_id)
{ {
uint16 size; uint16 size;

58
client/Windows/wf_rail.c Normal file
View File

@ -0,0 +1,58 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/utils/event.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/rail.h>
#include <freerdp/rail/rail.h>
#include "wf_window.h"
#include "wf_rail.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom)
{
}
void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail)
{
}
void wf_rail_send_client_system_command(wfInfo* wfi, uint32 windowId, uint16 command)
{
}
void wf_rail_send_activate(wfInfo* wfi, HWND window, boolean enabled)
{
}
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, RDP_EVENT* event)
{
}
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window)
{
}
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window)
{
}

Some files were not shown because too many files have changed in this diff Show More