Merge pull request #1188 from awakecoding/master

Android Translation, LoadBalanceInfo, StreamPool
This commit is contained in:
Marc-André Moreau 2013-04-12 15:30:14 -07:00
commit b4b0fb0642
37 changed files with 1183 additions and 114 deletions

View File

@ -111,6 +111,10 @@ if(MSVC)
message(STATUS "Random freeing errors are a common sign of runtime issues")
endif()
configure_msvc_runtime()
if(NOT DEFINED CMAKE_SUPPRESS_REGENERATION)
set(CMAKE_SUPPRESS_REGENERATION ON)
endif()
endif()
# Compiler-specific flags

View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<resources>
<!-- Button labels -->
<string name="yes">Si</string>
<string name="no">No</string>
<string name="cancel">Cancelar</string>
<string name="cont">Continuar</string>
<string name="login">Ingresar</string>
<string name="logout">Salir</string>
<!-- Home menu items -->
<string name="menu_exit">Salida</string>
<string name="menu_about">Sobre</string>
<string name="menu_help">Ayuda</string>
<string name="menu_new_bookmark">Nueva conexión</string>
<string name="menu_app_settings">Configuracion</string>
<!-- Bookmark menu items -->
<string name="menu_title_bookmark">Conexión</string>
<string name="menu_connect">Conectar</string>
<string name="menu_edit">Editar</string>
<string name="menu_delete">Borrar</string>
<!-- Session menu items -->
<string name="menu_sys_keyboard">Teclado</string>
<string name="menu_ext_keyboard">Funcion teclado</string>
<string name="menu_touch_pointer">Puntero Tactil</string>
<string name="menu_home">Inicio</string>
<string name="menu_disconnect">desconectart</string>
<!-- List section headers -->
<string name="section_bookmarks">Conexión Manual</string>
<string name="section_active_sessions">Sesiones Activas</string>
<!-- Search strings -->
<string name="search_hint">Connectarse a iWinCloud</string>
<!-- List placeholder labels -->
<string name="list_placeholder_login">Login</string>
<string name="list_placeholder_no_servers">No hay escritorios virtuales</string>
<string name="list_placeholder_connecting">Conectando ...</string>
<string name="list_placeholder_disconnecting">Desconectando ...</string>
<string name="list_placeholder_connection_error">Conexión perdida</string>
<string name="list_placeholder_wrong_password">Contraseña equivocada</string>
<string name="list_placeholder_invalid_username">Usuario Invalido</string>
<string name="list_placeholder_add_bookmark">Agregar escritorio virtual de iWinCloud</string>
<!-- Bookmark settings strings -->
<string name="settings_cat_host">Host</string>
<string name="settings_label">Su nombre</string>
<string name="settings_hostname">IP</string>
<string name="settings_port">Puerto</string>
<string name="settings_cat_credentials">Credenciales de iWinCloud</string>
<string name="settings_credentials">Credenciales</string>
<string name="settings_username">Usuario</string>
<string name="settings_password">Contraseña</string>
<string name="settings_domain">Dominio</string>
<string name="settings_cat_settings">Configuracion</string>
<string name="settings_screen">Pantalla</string>
<string name="settings_cat_screen">Configuracion Pantalla</string>
<string name="settings_colors">Colores</string>
<string-array name="colors_array">
<item>Calidad Normal (16 Bit)</item>
<item>Calidad Optima (24 Bit)</item>
<item>Calidad maxima (32 Bit)</item>
</string-array>
<string-array name="colors_values_array">
<item>16</item>
<item>24</item>
<item>32</item>
</string-array>
<string name="settings_resolution">Resolucion</string>
<string name="resolution_automatic">Automatico</string>
<string name="resolution_custom">Manual</string>
<string-array name="resolutions_array">
<item>Automatico</item>
<item>Manual</item>
<item>640x480</item>
<item>720x480</item>
<item>800x600</item>
<item>1024x768</item>
<item>1280x1024</item>
<item>1440x900</item>
<item>1920x1080</item>
<item>1920x1200</item>
</string-array>
<string-array name="resolutions_values_array">
<item>automatico</item>
<item>manual</item>
<item>640x480</item>
<item>720x480</item>
<item>800x600</item>
<item>1024x768</item>
<item>1280x1024</item>
<item>1440x900</item>
<item>1920x1080</item>
<item>1920x1200</item>
</string-array>
<string name="settings_width">Ancho</string>
<string name="settings_height">Altura</string>
<string name="settings_performance">Rendimiento</string>
<string name="settings_cat_performance">Configuracion Rendimiento</string>
<string name="settings_perf_remotefx">RemoteFX</string>
<string name="settings_perf_wallpaper">Fondo escritorio</string>
<string name="settings_perf_font_smoothing">Fuente suave</string>
<string name="settings_perf_desktop_composition">Composicion escritorio</string>
<string name="settings_perf_full_window_drag">Contenidos de la ventana mientras se arrastra</string>
<string name="settings_perf_menu_animation">Animacion del menu</string>
<string name="settings_perf_theming">Estilo visual</string>
<string name="settings_advanced">Avanzado</string>
<string name="settings_cat_advanced">Configuracion Avanzada</string>
<string name="settings_enable_3g_settings">Configuracion 3G</string>
<string name="settings_screen_3g">Pantalla 3G</string>
<string name="settings_performance_3g">Rendimiento 3G</string>
<string name="settings_security">Seguridad</string>
<string-array name="security_array">
<item>Automatico</item>
<item>RDP</item>
<item>TLS</item>
<item>NLA</item>
</string-array>
<string-array name="security_values_array">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string name="settings_remote_program">Programa Remoto</string>
<string name="settings_work_dir">Directorio de trabajo</string>
<string name="settings_console_mode">Modo Consola</string>
<!-- App settings strings -->
<string name="settings_password_present">*******</string>
<string name="settings_password_empty">no configurado</string>
<string name="settings_cat_ui">Interfaze Usuario</string>
<string name="settings_ui_hide_status_bar">Ocultar barra de estado</string>
<string name="settings_ui_hide_zoom_controls">Ocultar controles de zoom</string>
<string name="settings_ui_swap_mouse_buttons">Intercambiar botones del mouse</string>
<string name="settings_ui_invert_scrolling">invertir desplazamiento</string>
<string name="settings_ui_auto_scroll_touchpointer">Puntero táctil de desplazamiento automático</string>
<string name="settings_ui_ask_on_exit">Mostrar cuadro de diálogo en la salida</string>
<string name="settings_cat_power">Ahorro de energía</string>
<string name="settings_power_disconnect_timeout">Cerrar las conexiones inactivas</string>
<string name="settings_cat_security">Seguridad</string>
<string name="settings_security_accept_certificates">Aceptar todos los certificados</string>
<string name="settings_security_clear_certificate_cache">Borrar el Cache de los certificados</string>
<string name="settings_description_after_minutes">Despues %1$d Minutos</string>
<string name="settings_description_disabled">Desabilitado</string>
<!-- Activity titles -->
<string name="title_bookmark_settings">Configuración de la conexión</string>
<string name="title_application_settings">Configuración</string>
<string name="title_home">iWinCloud - iWinCloud para Android</string>
<string name="title_create_shortcut">Conexiones RDP</string>
<string name="title_help">Ayuda</string>
<string name="title_about">Sobre</string>
<!-- Error message strings -->
<string name="error_bookmark_incomplete_title">Cancelar sin guardar?</string>
<string name="error_bookmark_incomplete">Pulse el botón "Cancelar" para abortar! \ NPulse "Continuar" para especificar los campos obligatorios!</string>
<string name="error_connection_failure">No se pudo establecer una conexión con iWinCloud!</string>
<!-- Info message strings -->
<string name="info_capabilities_changed">Los ajustes de pantalla se han cambiado porque el escritorio virtual no es compatible con la configuración especificada!</string>
<string name="info_reset_success">Eliminado el cache del certificado!</string>
<string name="info_reset_failed">No se pudo borrar el caché del certificado!</string>
<!-- Dialog strings -->
<string name="dlg_title_verify_certificate">verificar el certificado</string>
<string name="dlg_msg_verify_certificate">La identidad de su escritorio de iWinCloud debe ser verificada. ¿Desea conectarse de todos modos?</string>
<string name="dlg_title_credentials">Por favor, introduzca sus credenciales</string>
<string name="dlg_title_create_shortcut">Crear acceso directo</string>
<string name="dlg_msg_create_shortcut">Nombre corto:</string>
<string name="dlg_msg_connecting">Conectando ...</string>
<string name="dlg_msg_logging_in">Ingresando a ...</string>
<string name="dlg_title_about">Sobre iWinCloud</string>
<string name="dlg_msg_about">Version: %1$s\n\u00A9 2012 iWinCloud LLc</string>
<string name="dlg_title_create_bookmark_after_qc">Guardar configuración de conexión?</string>
<string name="dlg_msg_create_bookmark_after_qc">La configuración de conexión no se han guardado! ¿Quieres guardarlos?</string>
<string name="dlg_title_save_bookmark">Guardar Conexión</string>
<string name="dlg_save_bookmark">¿Desea guardar los cambios realizados en la configuración de conexión?</string>
<string name="dlg_dont_show_again">No volver a preguntar</string>
<string name="dlg_title_exit">Salir del programa?</string>
<string name="dlg_msg_exit">Esta seguro que desea salir del programa?</string>
<string name="dlg_title_clear_cert_cache">Borrar Certificados?</string>
<string name="dlg_msg_clear_cert_cache">Esta seguro que desea borrar todos los certificados?</string>
</resources>

View File

@ -0,0 +1,174 @@
<resources>
<!-- Button labels -->
<string name="yes">"Oui"</string>
<string name="no">"Non"</string>
<string name="cancel">"Annuler"</string>
<string name="cont">"Continuer"</string>
<string name="login">"Se connecter"</string>
<string name="logout">"Déconnexion"</string>
<!-- Home menu items -->
<string name="menu_exit">"Quitter"</string>
<string name="menu_about">"À propos"</string>
<string name="menu_help">"Aide"</string>
<string name="menu_new_bookmark">"Nouvelle connexion"</string>
<string name="menu_app_settings">"Paramètres"</string>
<!-- Bookmark menu items -->
<string name="menu_title_bookmark">"Connexion"</string>
<string name="menu_connect">"Connexion"</string>
<string name="menu_edit">"Éditer"</string>
<string name="menu_delete">"Supprimer"</string>
<!-- Session menu items -->
<string name="menu_sys_keyboard">"Clavier"</string>
<string name="menu_ext_keyboard">"Touches de fonction"</string>
<string name="menu_touch_pointer">"Pointeur tactile"</string>
<string name="menu_home">"Accueil"</string>
<string name="menu_disconnect">"Se déconnecter"</string>
<!-- List section headers -->
<string name="section_bookmarks">"Connexions manuelles"</string>
<string name="section_active_sessions">"Sessions actives"</string>
<!-- Search strings -->
<string name="search_hint">"Connexion à l'ordinateur"</string>
<!-- List placeholder labels -->
<string name="list_placeholder_login">"Se connecter"</string>
<string name="list_placeholder_no_servers">"Pas de connexion"</string>
<string name="list_placeholder_connecting">"Connexion..."</string>
<string name="list_placeholder_disconnecting">"Déconnexion…"</string>
<string name="list_placeholder_connection_error">"Perte de la connexion"</string>
<string name="list_placeholder_wrong_password">"Mot de passe incorrect"</string>
<string name="list_placeholder_invalid_username">"Nom d'utilisateur invalide"</string>
<string name="list_placeholder_add_bookmark">"Ajouter une connexion"</string>
<!-- Bookmark settings strings -->
<string name="settings_cat_host">"Hôte"</string>
<string name="settings_label">"Étiquette"</string>
<string name="settings_hostname">"Hôte"</string>
<string name="settings_port">"Port"</string>
<string name="settings_cat_credentials">"Authentifiant"</string>
<string name="settings_credentials">"Authentifiant"</string>
<string name="settings_username">"Nom d'utilisateur"</string>
<string name="settings_password">"Mot de passe"</string>
<string name="settings_domain">"Nom de domaine"</string>
<string name="settings_cat_settings">"Paramètres"</string>
<string name="settings_screen">"Écran"</string>
<string name="settings_cat_screen">"Paramètres d'écran"</string>
<string name="settings_colors">"Couleurs"</string>
<string-array name="colors_array">
<item>"Hautes couleurs (16 bits)"</item>
<item>"Couleurs vraies (24 bits)"</item>
<item>"Haute qualité (32 bits)"</item>
</string-array>
<string-array name="colors_values_array">
<item>"16"</item>
<item>"24"</item>
<item>"32"</item>
</string-array>
<string name="settings_resolution">"Résolution"</string>
<string name="resolution_automatic">"Automatique"</string>
<string name="resolution_custom">"Personalisé"</string>
<string-array name="resolutions_array">
<item>"Automatique"</item>
<item>"Personalisé"</item>
<item>"640x480"</item>
<item>"720x480"</item>
<item>"800x600"</item>
<item>"1024x768"</item>
<item>"1280x1024"</item>
<item>"1440x900"</item>
<item>"1920x1080"</item>
<item>"1920x1200"</item>
</string-array>
<string-array name="resolutions_values_array">
<item>"Automatique"</item>
<item>"Personalisé"</item>
<item>"640x480"</item>
<item>"720x480"</item>
<item>"800x600"</item>
<item>"1024x768"</item>
<item>"1280x1024"</item>
<item>"1440x900"</item>
<item>"1920x1080"</item>
<item>"1920x1200"</item>
</string-array>
<string name="settings_width">"Largeur"</string>
<string name="settings_height">"Hauteur"</string>
<string name="settings_performance">"Performance"</string>
<string name="settings_cat_performance">"Paramètres de performance"</string>
<string name="settings_perf_remotefx">"RemoteFX"</string>
<string name="settings_perf_wallpaper">"Fond d'écran"</string>
<string name="settings_perf_font_smoothing">"Lissage des polices"</string>
<string name="settings_perf_desktop_composition">"Effets visuels Aero"</string>
<string name="settings_perf_full_window_drag">"Afficher le contenu des fenêtres en mouvement"</string>
<string name="settings_perf_menu_animation">"Animations de menu"</string>
<string name="settings_perf_theming">"Styles visuels"</string>
<string name="settings_advanced">"Avancé"</string>
<string name="settings_cat_advanced">"Paramètres avancés"</string>
<string name="settings_enable_3g_settings">"Paramètres 3G"</string>
<string name="settings_screen_3g">"Écran 3G"</string>
<string name="settings_performance_3g">"Performance 3G"</string>
<string name="settings_security">"Securité"</string>
<string-array name="security_array">
<item>"Automatique"</item>
<item>"RDP"</item>
<item>"TLS"</item>
<item>"NLA"</item>
</string-array>
<string-array name="security_values_array">
<item>"0"</item>
<item>"1"</item>
<item>"2"</item>
<item>"3"</item>
</string-array>
<string name="settings_remote_program">"Lancement de programme"</string>
<string name="settings_work_dir">"Répertoire de travail"</string>
<string name="settings_console_mode">"Mode console"</string>
<!-- App settings strings -->
<string name="settings_password_present">"*******"</string>
<string name="settings_password_empty">"Valeur non définie"</string>
<string name="settings_cat_ui">"Interface utilisateur"</string>
<string name="settings_ui_hide_status_bar">"Masquer la barre d'état"</string>
<string name="settings_ui_hide_zoom_controls">"Masquer les contrôles zoom"</string>
<string name="settings_ui_swap_mouse_buttons">"Inverser les boutons de la souris"</string>
<string name="settings_ui_invert_scrolling">"Inverser le défilement de la souris"</string>
<string name="settings_ui_auto_scroll_touchpointer">"Défilement automatique du pointeur tactile"</string>
<string name="settings_ui_ask_on_exit">"Confirmer au moment de quitter"</string>
<string name="settings_cat_power">"Economie d'énergie"</string>
<string name="settings_power_disconnect_timeout">"Fermer les connexions inactives"</string>
<string name="settings_cat_security">"Securité"</string>
<string name="settings_security_accept_certificates">"Accepter tous les certificats"</string>
<string name="settings_security_clear_certificate_cache">"Vider la cache de certificats"</string>
<string name="settings_description_after_minutes">"Après %1$d minutes"</string>
<string name="settings_description_disabled">"Désactivé"</string>
<!-- Activity titles -->
<string name="title_bookmark_settings">"Paramètres de connexion"</string>
<string name="title_application_settings">"Paramètres"</string>
<string name="title_home">"aFreeRDP - FreeRDP pour Android"</string>
<string name="title_create_shortcut">"Connexions RDP"</string>
<string name="title_help">"Aide"</string>
<string name="title_about">"À propos"</string>
<!-- Error message strings -->
<string name="error_bookmark_incomplete_title">"Annuler sans enregistrer?"</string>
<string name="error_bookmark_incomplete">"Appuyez sur \"Annuler\" pour annuler, ou cliquez sur «Continuer» pour spécifier les champs obligatoires."</string>
<string name="error_connection_failure">"Impossible d'établir une connexion au serveur!"</string>
<!-- Info message strings -->
<string name="info_capabilities_changed">"Les paramètres de l'écran ont changé parce que le serveur ne prend pas en charge les paramètres que vous avez spécifiés!"</string>
<string name="info_reset_success">"La cache de certificats a été supprimée!"</string>
<string name="info_reset_failed">"Impossible de supprimer la cache de certificat!"</string>
<!-- Dialog strings -->
<string name="dlg_title_verify_certificate">"Validation de certificat"</string>
<string name="dlg_msg_verify_certificate">"L'identité de l'ordinateur distant ne peut pas être vérifiée. Voulez-vous poursuivre la connexion?"</string>
<string name="dlg_title_credentials">"Veuillez entrer votre nom d'usager et mot de passe"</string>
<string name="dlg_title_create_shortcut">"Créer un raccourci"</string>
<string name="dlg_msg_create_shortcut">"Nom du raccourci:"</string>
<string name="dlg_msg_connecting">"Connexion..."</string>
<string name="dlg_msg_logging_in">"Connexion..."</string>
<string name="dlg_title_about">"À propos de aFreeRDP"</string>
<string name="dlg_msg_about">"Version: %1$s \ n \ u00A9 2012 Technologies GmbH Thinstuff"</string>
<string name="dlg_title_create_bookmark_after_qc">"Enregistrer les paramètres de connexion?"</string>
<string name="dlg_msg_create_bookmark_after_qc">"Vos paramètres de connexion n'ont pas été sauvegardés! Voulez-vous les enregistrer?"</string>
<string name="dlg_title_save_bookmark">"Enregistrer la connexion?"</string>
<string name="dlg_save_bookmark">"Voulez-vous enregistrer les modifications que vous avez apportées aux paramètres de connexion?"</string>
<string name="dlg_dont_show_again">"Ne plus demander"</string>
<string name="dlg_title_exit">"Quittez l'application?"</string>
<string name="dlg_msg_exit">"Êtes-vous sûr de vouloir quitter l'application?"</string>
<string name="dlg_title_clear_cert_cache">"Êtes-vous sûrs de vouloir supprimer les certificats?"</string>
<string name="dlg_msg_clear_cert_cache">"Êtes-vous sûr de vouloir supprimer tous les certificats mis en cache?"</string>
</resources>

View File

@ -29,5 +29,4 @@
<Preference android:key="security.clear_certificate_cache" android:title="@string/settings_security_clear_certificate_cache" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -12,7 +12,7 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:freerdp="http://schemas.android.com/apk/res-auto" >
<PreferenceCategory android:key="category.host" android:title="@string/settings_cat_host">
<EditTextPreference android:key="bookmark.label" android:title="Label" android:summary="@string/settings_label"/>
<EditTextPreference android:key="bookmark.label" android:title="@string/settings_label" android:summary="@string/settings_label"/>
<EditTextPreference android:key="bookmark.hostname" android:title="@string/settings_hostname" android:summary="Name or address of the target computer"/>
<com.freerdp.freerdpcore.utils.IntEditTextPreference android:key="bookmark.port" android:title="@string/settings_port" android:summary="RDP Port on the target computer" android:numeric="integer" android:inputType="number" freerdp:bounds_min="10" freerdp:bounds_max="65535" freerdp:bounds_default="3389" />
</PreferenceCategory>

View File

@ -11,8 +11,8 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Credentials">
<EditTextPreference android:key="bookmark.username" android:title="Username"/>
<EditTextPreference android:key="bookmark.password" android:title="Password" android:inputType="textPassword" />
<EditTextPreference android:key="bookmark.domain" android:title="Domain" android:summary="Optional"/>
<EditTextPreference android:key="bookmark.username" android:title="@string/settings_username"/>
<EditTextPreference android:key="bookmark.password" android:title="@string/settings_password" android:inputType="textPassword" />
<EditTextPreference android:key="bookmark.domain" android:title="@string/settings_domain" android:summary="Optional"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@ -6,12 +6,10 @@ set(MODULE_PREFIX "FREERDP_CLIENT_MAC")
set(FRAMEWORK_HEADERS_PATH /System/Library/Frameworks/Cocoa.framework/Versions/A/Headers/)
include_directories(${FRAMEWORK_HEADERS_PATH} /System/Library/Frameworks)
# set(CMAKE_OSX_SYSROOT MacOSX10.7.sdk)
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)
find_library(COCOA_LIBRARY Cocoa)
find_library(APPKIT_LIBRARY AppKit)
@ -33,16 +31,32 @@ mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY)
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
set(APP_TYPE MACOSX_BUNDLE)
# OS X Interface Builder files
file(GLOB ${MODULE_NAME}_XIBS *.xib)
set(${MODULE_NAME}_XIBS
MainMenu.xib
PasswordDialog.xib)
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_XIBS} ${MACOSX_BUNDLE_ICON_FILE})
set(${MODULE_NAME}_RESOURCES
${${MODULE_NAME}_XIBS}
${MACOSX_BUNDLE_ICON_FILE})
# Headers
file(GLOB ${MODULE_NAME}_HEADERS *.h)
set(${MODULE_NAME}_HEADERS
AppDelegate.h
MRDPCursor.h
MRDPRailView.h
MRDPRailWindow.h
MRDPView.h
MRDPWindow.h
PasswordDialog.h)
# Source
file(GLOB ${MODULE_NAME}_SOURCES *.m)
set(${MODULE_NAME}_SOURCES
main.m
AppDelegate.m
MRDPCursor.m
MRDPRailView.m
MRDPRailWindow.m
MRDPView.m
MRDPWindow.m
PasswordDialog.m)
add_executable(${MODULE_NAME}
${APP_TYPE}
@ -63,13 +77,6 @@ set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOU
# 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(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
# Set the info plist to the custom instance

View File

@ -37,7 +37,11 @@ set(${MODULE_PREFIX}_SRCS
resource.h)
if(WITH_CLIENT_INTERFACE)
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
if(CLIENT_INTERFACE_SHARED)
add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
else()
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
endif()
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib")
else()
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/wfreerdp.c cli/wfreerdp.h)

View File

@ -37,6 +37,9 @@ static HWND g_focus_hWnd;
#define X_POS(lParam) (lParam & 0xFFFF)
#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop);
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
wfInfo* wfi;
@ -167,6 +170,10 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
switch (Msg)
{
case WM_ERASEBKGND:
/* Say we handled it - prevents flickering */
return (LRESULT) 1;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
@ -175,31 +182,29 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
w = ps.rcPaint.right - ps.rcPaint.left + 1;
h = ps.rcPaint.bottom - ps.rcPaint.top + 1;
//fprintf(stderr, "WM_PAINT: x:%d y:%d w:%d h:%d\n", x, y, w, h);
BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x, y - wfi->offset_y, SRCCOPY);
wf_scale_blt(wfi, hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x, y - wfi->offset_y, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN:
input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfi, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
break;
case WM_LBUTTONUP:
input->MouseEvent(input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
break;
case WM_RBUTTONDOWN:
input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfi, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
break;
case WM_RBUTTONUP:
input->MouseEvent(input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
break;
case WM_MOUSEMOVE:
input->MouseEvent(input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfi, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
break;
case WM_MOUSEWHEEL:
@ -257,3 +262,60 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
return 0;
}
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
if (!wh)
wh = dh;
if (!wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
{
return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY);
}
else
{
SetStretchBltMode(hdc, HALFTONE);
SetBrushOrgEx(hdc, 0, 0, NULL);
return StretchBlt(hdc, x * ww / dw, y * wh / dh, ww, wh, wfi->primary->hdc, x1, y1, dw, dh, SRCCOPY);
}
return TRUE;
}
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
if ((ww == dw) && (wh == dh))
input->MouseEvent(input, flags, x, y);
else
input->MouseEvent(input, flags, x * dw / ww, y * dh / wh);
}

View File

@ -166,14 +166,54 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
return br;
}
void wf_scale_rect(wfInfo* wfi, RECT* source)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
if (!wh)
wh = dh;
if (wfi->instance->settings->SmartSizing && (ww != dw || wh != dh))
{
source->bottom = MIN(dh, MAX(0, source->bottom * wh / dh + 2));
source->top = MIN(dh, MAX(0, source->top * wh / dh - 2));
source->left = MIN(dw, MAX(0, source->left * ww / dw - 2));
source->right = MIN(dw, MAX(0, source->right * ww / dw + 2));
}
}
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height)
{
RECT rect;
wfi->update_rect.left = x + wfi->offset_x;
wfi->update_rect.top = y + wfi->offset_y;
wfi->update_rect.right = wfi->update_rect.left + width;
wfi->update_rect.bottom = wfi->update_rect.top + height;
wf_scale_rect(wfi, &(wfi->update_rect));
InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE);
gdi_InvalidateRegion(wfi->hdc, x, y, width, height);
rect.left = x;
rect.right = width;
rect.top = y;
rect.bottom = height;
wf_scale_rect(wfi, &rect);
gdi_InvalidateRegion(wfi->hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void wf_update_offset(wfInfo* wfi)

View File

@ -534,6 +534,8 @@ DWORD WINAPI wf_thread(LPVOID lpParam)
int index;
int rcount;
int wcount;
int width;
int height;
BOOL msg_ret;
int quit_msg;
void* rfds[32];
@ -626,7 +628,30 @@ DWORD WINAPI wf_thread(LPVOID lpParam)
{
msg_ret = GetMessage(&msg, NULL, 0, 0);
if (msg_ret == 0 || msg_ret == -1)
if (instance->settings->EmbeddedWindow)
{
if ((msg.message == WM_SETFOCUS) && (msg.lParam == 1))
{
PostMessage(((wfContext*) instance->context)->wfi->hwnd, WM_SETFOCUS, 0, 0);
}
else if ((msg.message == WM_KILLFOCUS) && (msg.lParam == 1))
{
PostMessage(((wfContext*) instance->context)->wfi->hwnd, WM_KILLFOCUS, 0, 0);
}
}
if (msg.message == WM_SIZE)
{
width = LOWORD(msg.lParam);
height = HIWORD(msg.lParam);
((wfContext*) instance->context)->wfi->client_width = width;
((wfContext*) instance->context)->wfi->client_height = height;
SetWindowPos(((wfContext*) instance->context)->wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
}
if ((msg_ret == 0) || (msg_ret == -1))
{
quit_msg = TRUE;
break;
@ -721,11 +746,9 @@ int freerdp_client_global_uninit()
wfInfo* freerdp_client_new(int argc, char** argv)
{
int index;
int status;
wfInfo* wfi;
freerdp* instance;
HINSTANCE hInstance;
hInstance = GetModuleHandle(NULL);
instance = freerdp_new();
instance->PreConnect = wf_pre_connect;
@ -745,16 +768,27 @@ wfInfo* freerdp_client_new(int argc, char** argv)
wfi->client = instance->context->client;
instance->context->argc = argc;
instance->context->argv = argv;
instance->context->argv = (char**) malloc(sizeof(char*) * argc);
for (index = 0; index < argc; index++)
{
instance->context->argv[index] = _strdup(argv[index]);
}
wfi->hWndParent = NULL;
status = freerdp_client_parse_command_line_arguments(instance->context->argc, instance->context->argv, instance->settings);
return wfi;
}
int freerdp_client_start(wfInfo* wfi)
{
HWND hWndParent;
HINSTANCE hInstance;
freerdp* instance = wfi->instance;
hInstance = GetModuleHandle(NULL);
hWndParent = (HWND) instance->settings->ParentWindowId;
instance->settings->EmbeddedWindow = (hWndParent) ? TRUE : FALSE;
wfi->hWndParent = hWndParent;
wfi->hInstance = hInstance;
wfi->cursor = LoadCursor(NULL, IDC_ARROW);
wfi->icon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
@ -774,24 +808,14 @@ wfInfo* freerdp_client_new(int argc, char** argv)
wfi->wndClass.hIconSm = wfi->icon;
RegisterClassEx(&(wfi->wndClass));
return wfi;
}
int freerdp_client_start(wfInfo* wfi)
{
int status;
freerdp* instance = wfi->instance;
wfi->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfi, 0, NULL);
if (!wfi->keyboardThread)
return -1;
status = freerdp_client_parse_command_line_arguments(instance->context->argc, instance->context->argv, instance->settings);
freerdp_client_load_addins(instance->context->channels, instance->settings);
wfi->thread = CreateThread(NULL, 0, wf_thread, (void*) instance, 0, NULL);
wfi->thread = CreateThread(NULL, 0, wf_thread, (void*) instance, 0, &wfi->mainThreadId);
if (!wfi->thread)
return -1;
@ -801,6 +825,29 @@ int freerdp_client_start(wfInfo* wfi)
int freerdp_client_stop(wfInfo* wfi)
{
PostThreadMessage(wfi->mainThreadId, WM_QUIT, 0, 0);
return 0;
}
int freerdp_client_focus_in(wfInfo* wfi)
{
PostThreadMessage(wfi->mainThreadId, WM_SETFOCUS, 0, 1);
return 0;
}
int freerdp_client_focus_out(wfInfo* wfi)
{
PostThreadMessage(wfi->mainThreadId, WM_KILLFOCUS, 0, 1);
return 0;
}
int wf_set_window_size(wfInfo* wfi, int width, int height)
{
if ((width != wfi->client_width) || (height != wfi->client_height))
{
PostThreadMessage(wfi->mainThreadId, WM_SIZE, SIZE_RESTORED, ((UINT) height << 16) | (UINT) width);
}
return 0;
}

View File

@ -81,6 +81,8 @@ struct wf_info
int fullscreen;
int percentscreen;
char window_title[64];
int client_width;
int client_height;
HANDLE thread;
HANDLE keyboardThread;
@ -105,8 +107,10 @@ struct wf_info
HBRUSH brush;
HBRUSH org_brush;
RECT update_rect;
RECT scale_update_rect;
wfBitmap* tile;
DWORD mainThreadId;
RFX_CONTEXT* rfx_context;
NSC_CONTEXT* nsc_context;
@ -125,6 +129,11 @@ FREERDP_API int freerdp_client_global_uninit();
FREERDP_API int freerdp_client_start(wfInfo* cfi);
FREERDP_API int freerdp_client_stop(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_in(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_out(wfInfo* cfi);
FREERDP_API int freerdp_client_set_window_size(wfInfo* cfi, int width, int height);
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
FREERDP_API int freerdp_client_free(wfInfo* cfi);

View File

@ -44,7 +44,11 @@ set(${MODULE_PREFIX}_SRCS
xf_interface.h)
if(WITH_CLIENT_INTERFACE)
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
if(CLIENT_INTERFACE_SHARED)
add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
else()
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
endif()
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib")
else()
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c cli/xfreerdp.h)

View File

@ -49,8 +49,7 @@ int main(int argc, char* argv[])
GetExitCodeThread(xfi->thread, &dwExitCode);
freerdp_context_free(instance);
freerdp_free(instance);
freerdp_client_free(xfi);
freerdp_client_global_uninit();

View File

@ -1382,9 +1382,6 @@ void* xf_thread(void* param)
freerdp_channels_free(channels);
freerdp_disconnect(instance);
gdi_free(instance);
freerdp_client_free(xfi);
exit_code = 123;
ExitThread(exit_code);
}
@ -1475,8 +1472,6 @@ xfInfo* freerdp_client_new(int argc, char** argv)
freerdp_context_new(instance);
instance->context->argc = argc;
instance->context->argv = argv;
instance->context->argv = (char**) malloc(sizeof(char*) * argc);
for (index = 0; index < argc; index++)
@ -1544,12 +1539,25 @@ void freerdp_client_free(xfInfo* xfi)
{
if (xfi)
{
int index;
rdpContext* context;
xf_window_free(xfi);
free(xfi->bmp_codec_none);
XCloseDisplay(xfi->display);
context = (rdpContext*) xfi->context;
for (index = 0; index < context->argc; index++)
free(context->argv[index]);
free(context->argv);
freerdp_context_free(xfi->instance);
freerdp_free(xfi->instance);
free(xfi);
}
}

View File

@ -52,6 +52,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Work area" },
{ "t", COMMAND_LINE_VALUE_REQUIRED, "<title>", NULL, NULL, -1, "title", "Window title" },
{ "decorations", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueTrue, -1, NULL, "Window decorations" },
{ "smart-sizing", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Scale remote desktop to window size" },
{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "Addin" },
{ "vc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Static virtual channel" },
{ "dvc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Dynamic virtual channel" },
@ -62,6 +63,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[<domain>\\]<user> or <user>[@<domain>]", NULL, NULL, -1, NULL, "Gateway username" },
{ "gp", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL, "Gateway password" },
{ "gd", COMMAND_LINE_VALUE_REQUIRED, "<domain>", NULL, NULL, -1, NULL, "Gateway domain" },
{ "load-balance-info", COMMAND_LINE_VALUE_REQUIRED, "<info string>", NULL, NULL, -1, NULL, "Load balance info" },
{ "app", COMMAND_LINE_VALUE_REQUIRED, "||<alias> or <executable path>", NULL, NULL, -1, NULL, "Remote application program" },
{ "app-name", COMMAND_LINE_VALUE_REQUIRED, "<app name>", NULL, NULL, -1, NULL, "Remote application name for user interface" },
{ "app-icon", COMMAND_LINE_VALUE_REQUIRED, "<icon path>", NULL, NULL, -1, NULL, "Remote application icon for user interface" },
@ -1090,6 +1092,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
{
settings->Decorations = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "smart-sizing")
{
settings->SmartSizing = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "bpp")
{
settings->ColorDepth = atoi(arg->Value);
@ -1209,6 +1215,11 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
settings->DisableWallpaper = TRUE;
settings->DisableFullWindowDrag = TRUE;
}
CommandLineSwitchCase(arg, "load-balance-info")
{
settings->LoadBalanceInfo = (BYTE*) _strdup(arg->Value);
settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo);
}
CommandLineSwitchCase(arg, "app-name")
{
settings->RemoteApplicationName = _strdup(arg->Value);

View File

@ -308,7 +308,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, BYTE* buffer, siz
line = strtok_s((char*) buffer, "\r\n", &context);
while (line != NULL)
while (line)
{
length = strlen(line);
@ -458,8 +458,7 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
if (file_size < 1)
return FALSE;
buffer = (BYTE*) malloc(file_size);
buffer = (BYTE*) malloc(file_size + 2);
read_size = fread(buffer, file_size, 1, fp);
if (!read_size)
@ -475,6 +474,9 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
return FALSE;
}
buffer[file_size] = '\0';
buffer[file_size + 1] = '\0';
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
}
@ -497,7 +499,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~file->ServerPort)
settings->ServerPort = file->ServerPort;
if (~((size_t) file->FullAddress))
settings->ServerHostname = file->FullAddress;
settings->ServerHostname = _strdup(file->FullAddress);
if (~file->DesktopWidth)
settings->DesktopWidth = file->DesktopWidth;
if (~file->DesktopHeight)
@ -513,10 +515,16 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~file->EnableCredSSPSupport)
settings->NlaSecurity = file->EnableCredSSPSupport;
if (~((size_t) file->AlternateShell))
settings->AlternateShell = file->AlternateShell;
settings->AlternateShell = _strdup(file->AlternateShell);
if (~((size_t) file->ShellWorkingDirectory))
settings->ShellWorkingDirectory = file->ShellWorkingDirectory;
settings->ShellWorkingDirectory = _strdup(file->ShellWorkingDirectory);
if (~((size_t) file->LoadBalanceInfo))
{
settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo);
settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo);
}
if (~file->ConnectionType)
{
freerdp_set_connection_type(settings, file->ConnectionType);
@ -540,7 +548,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
}
if (~((size_t) file->GatewayHostname))
settings->GatewayHostname = file->GatewayHostname;
settings->GatewayHostname = _strdup(file->GatewayHostname);
if (~file->GatewayUsageMethod)
settings->GatewayUsageMethod = TRUE;
if (~file->PromptCredentialOnce)
@ -549,17 +557,17 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~file->RemoteApplicationMode)
settings->RemoteApplicationMode = file->RemoteApplicationMode;
if (~((size_t) file->RemoteApplicationProgram))
settings->RemoteApplicationProgram = file->RemoteApplicationProgram;
settings->RemoteApplicationProgram = _strdup(file->RemoteApplicationProgram);
if (~((size_t) file->RemoteApplicationName))
settings->RemoteApplicationName = file->RemoteApplicationName;
settings->RemoteApplicationName = _strdup(file->RemoteApplicationName);
if (~((size_t) file->RemoteApplicationIcon))
settings->RemoteApplicationIcon = file->RemoteApplicationIcon;
settings->RemoteApplicationIcon = _strdup(file->RemoteApplicationIcon);
if (~((size_t) file->RemoteApplicationFile))
settings->RemoteApplicationFile = file->RemoteApplicationFile;
settings->RemoteApplicationFile = _strdup(file->RemoteApplicationFile);
if (~((size_t) file->RemoteApplicationGuid))
settings->RemoteApplicationGuid = file->RemoteApplicationGuid;
settings->RemoteApplicationGuid = _strdup(file->RemoteApplicationGuid);
if (~((size_t) file->RemoteApplicationCmdLine))
settings->RemoteApplicationCmdLine = file->RemoteApplicationCmdLine;
settings->RemoteApplicationCmdLine = _strdup(file->RemoteApplicationCmdLine);
if (~file->SpanMonitors)
settings->SpanMonitors = file->SpanMonitors;

View File

@ -602,7 +602,11 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_AsyncInput 1544
#define FreeRDP_AsyncUpdate 1545
#define FreeRDP_AsyncChannels 1546
#define FreeRDP_ToggleFullscreen 1547
#define FreeRDP_AsyncTransport 1547
#define FreeRDP_ToggleFullscreen 1548
#define FreeRDP_WmClass 1549
#define FreeRDP_EmbeddedWindow 1550
#define FreeRDP_SmartSizing 1551
#define FreeRDP_SoftwareGdi 1601
#define FreeRDP_LocalConnection 1602
#define FreeRDP_AuthenticationOnly 1603
@ -961,7 +965,9 @@ struct rdp_settings
ALIGN64 BOOL AsyncTransport; /* 1547 */
ALIGN64 BOOL ToggleFullscreen; /* 1548 */
ALIGN64 char* WmClass; /* 1549 */
UINT64 padding1600[1600 - 1550]; /* 1550 */
ALIGN64 BOOL EmbeddedWindow; /* 1550 */
ALIGN64 BOOL SmartSizing; /* 1551 */
UINT64 padding1600[1600 - 1552]; /* 1552 */
/* Miscellaneous */
ALIGN64 BOOL SoftwareGdi; /* 1601 */

View File

@ -202,11 +202,12 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
else
#endif
{
if (stream_get_left(data_in) < y_size+cb_size+cr_size)
if (stream_get_left(data_in) < y_size + cb_size + cr_size)
{
DEBUG_WARN("rfx_decode_rgb: packet too small for y_size+cb_size+cr_size");
return FALSE;
}
rfx_decode_component(context, y_quants, stream_get_tail(data_in), y_size, pSrcDst[0]); /* YData */
stream_seek(data_in, y_size);
@ -230,5 +231,6 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[0] - 16);
BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[1] - 16);
BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[2] - 16);
return TRUE;
}

View File

@ -135,6 +135,9 @@ BOOL rdp_client_connect(rdpRdp* rdp)
nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);
if (settings->LoadBalanceInfo)
nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength);
if (!nego_connect(rdp->nego))
{
fprintf(stderr, "Error: protocol security negotiation or connection failure\n");

View File

@ -169,20 +169,21 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
rdpUpdate* update = fastpath->rdp->update;
rdpContext* context = update->context;
if(stream_get_left(s) < 2)
if (stream_get_left(s) < 2)
return FALSE;
stream_read_UINT16(s, updateType); /* updateType (2 bytes) */
switch (updateType)
{
case UPDATE_TYPE_BITMAP:
if(!update_read_bitmap(update, s, &update->bitmap_update))
if (!update_read_bitmap(update, s, &update->bitmap_update))
return FALSE;
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
break;
case UPDATE_TYPE_PALETTE:
if(!update_read_palette(update, s, &update->palette_update))
if (!update_read_palette(update, s, &update->palette_update))
return FALSE;
IFCALL(update->Palette, context, &update->palette_update);
break;
@ -328,6 +329,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
}
update_stream = NULL;
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
{
totalSize = size;
@ -340,6 +342,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
stream_check_size(fastpath->updateData, size);
stream_copy(fastpath->updateData, comp_stream, size);
if (stream_get_length(fastpath->updateData) > rdp->settings->MultifragMaxRequestSize)
{
fprintf(stderr, "fastpath PDU is bigger than MultifragMaxRequestSize\n");

View File

@ -340,7 +340,7 @@ void freerdp_context_new(freerdp* instance)
*/
void freerdp_context_free(freerdp* instance)
{
if (instance->context == NULL)
if (!instance->context)
return;
IFCALL(instance->ContextFree, instance, instance->context);
@ -348,6 +348,8 @@ void freerdp_context_free(freerdp* instance)
rdp_free(instance->context->rdp);
graphics_free(instance->context->graphics);
free(instance->context->client);
free(instance->context);
instance->context = NULL;
}

View File

@ -21,11 +21,18 @@
#include "config.h"
#endif
#include "rdp.h"
#include "message.h"
#include "transport.h"
#include <freerdp/freerdp.h>
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/collections.h>
//#define WITH_STREAM_POOL 1
/* Update */
static void update_message_BeginPaint(rdpContext* context)
@ -79,13 +86,15 @@ static void update_message_BitmapUpdate(rdpContext* context, BITMAP_UPDATE* bitm
wParam->rectangles = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * wParam->number);
CopyMemory(wParam->rectangles, bitmap->rectangles, sizeof(BITMAP_DATA) * wParam->number);
/* TODO: increment reference count to original stream instead of copying */
for (index = 0; index < wParam->number; index++)
{
#ifdef WITH_STREAM_POOL
StreamPool_AddRef(context->rdp->transport->ReceivePool, bitmap->rectangles[index].bitmapDataStream);
#else
wParam->rectangles[index].bitmapDataStream = (BYTE*) malloc(wParam->rectangles[index].bitmapLength);
CopyMemory(wParam->rectangles[index].bitmapDataStream, bitmap->rectangles[index].bitmapDataStream,
wParam->rectangles[index].bitmapLength);
#endif
}
MessageQueue_Post(context->update->queue, (void*) context,
@ -160,8 +169,12 @@ static void update_message_SurfaceBits(rdpContext* context, SURFACE_BITS_COMMAND
wParam = (SURFACE_BITS_COMMAND*) malloc(sizeof(SURFACE_BITS_COMMAND));
CopyMemory(wParam, surfaceBitsCommand, sizeof(SURFACE_BITS_COMMAND));
#ifdef WITH_STREAM_POOL
StreamPool_AddRef(context->rdp->transport->ReceivePool, surfaceBitsCommand->bitmapData);
#else
wParam->bitmapData = (BYTE*) malloc(wParam->bitmapDataLength);
CopyMemory(wParam->bitmapData, surfaceBitsCommand->bitmapData, wParam->bitmapDataLength);
#endif
MessageQueue_Post(context->update->queue, (void*) context,
MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL);
@ -952,7 +965,14 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in
BITMAP_UPDATE* wParam = (BITMAP_UPDATE*) msg->wParam;
for (index = 0; index < wParam->number; index++)
{
#ifdef WITH_STREAM_POOL
rdpContext* context = (rdpContext*) msg->context;
StreamPool_Release(context->rdp->transport->ReceivePool, wParam->rectangles[index].bitmapDataStream);
#else
free(wParam->rectangles[index].bitmapDataStream);
#endif
}
free(wParam);
}
@ -993,9 +1013,15 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in
case Update_SurfaceBits:
IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam);
{
#ifdef WITH_STREAM_POOL
rdpContext* context = (rdpContext*) msg->context;
SURFACE_BITS_COMMAND* wParam = (SURFACE_BITS_COMMAND*) msg->wParam;
StreamPool_Release(context->rdp->transport->ReceivePool, wParam->bitmapData);
#else
SURFACE_BITS_COMMAND* wParam = (SURFACE_BITS_COMMAND*) msg->wParam;
free(wParam->bitmapData);
free(wParam);
#endif
}
break;

View File

@ -490,7 +490,7 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
if (length == 0)
return -1;
if(!tpdu_read_connection_confirm(s, &li))
if (!tpdu_read_connection_confirm(s, &li))
return -1;
if (li > 6)
@ -563,7 +563,8 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
BYTE type;
tpkt_read_header(s);
if(!tpdu_read_connection_request(s, &li))
if (!tpdu_read_connection_request(s, &li))
return FALSE;
if (li != stream_get_left(s) + 6)
@ -648,12 +649,14 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
stream_get_mark(s, bm);
stream_seek(s, length);
if (nego->RoutingToken != NULL)
if (nego->RoutingToken)
{
stream_write(s, nego->RoutingToken, nego->RoutingTokenLength);
length += nego->RoutingTokenLength;
stream_write_BYTE(s, 0x0D); /* CR */
stream_write_BYTE(s, 0x0A); /* LF */
length += nego->RoutingTokenLength + 2;
}
else if (nego->cookie != NULL)
else if (nego->cookie)
{
cookie_length = strlen(nego->cookie);
@ -669,7 +672,7 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols);
if (nego->requested_protocols > PROTOCOL_RDP)
if ((nego->requested_protocols > PROTOCOL_RDP) || (nego->sendNegoData))
{
/* RDP_NEG_DATA must be present for TLS and NLA */
stream_write_BYTE(s, TYPE_RDP_NEG_REQ);
@ -762,18 +765,24 @@ void nego_process_negotiation_failure(rdpNego* nego, wStream* s)
case SSL_REQUIRED_BY_SERVER:
DEBUG_NEGO("Error: SSL_REQUIRED_BY_SERVER");
break;
case SSL_NOT_ALLOWED_BY_SERVER:
DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER");
break;
case SSL_CERT_NOT_ON_SERVER:
DEBUG_NEGO("Error: SSL_CERT_NOT_ON_SERVER");
nego->sendNegoData = TRUE;
break;
case INCONSISTENT_FLAGS:
DEBUG_NEGO("Error: INCONSISTENT_FLAGS");
break;
case HYBRID_REQUIRED_BY_SERVER:
DEBUG_NEGO("Error: HYBRID_REQUIRED_BY_SERVER");
break;
default:
DEBUG_NEGO("Error: Unknown protocol security error %d", failureCode);
break;

View File

@ -100,6 +100,7 @@ struct rdp_nego
BOOL security_connected;
UINT32 cookie_max_length;
BOOL sendNegoData;
UINT32 selected_protocol;
UINT32 requested_protocols;
BOOL NegotiateSecurityLayer;

View File

@ -454,6 +454,7 @@ void freerdp_settings_free(rdpSettings* settings)
free(settings->ConfigPath);
free(settings->CurrentPath);
free(settings->HomePath);
free(settings->LoadBalanceInfo);
freerdp_device_collection_free(settings);
freerdp_static_channel_collection_free(settings);
freerdp_dynamic_channel_collection_free(settings);

View File

@ -25,7 +25,7 @@
#include "surface.h"
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT32 *length)
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT32* length)
{
int pos;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
@ -50,11 +50,11 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3
pos = stream_get_pos(s) + cmd->bitmapDataLength;
cmd->bitmapData = stream_get_tail(s);
IFCALL(update->SurfaceBits, update->context, cmd);
stream_set_pos(s, pos);
*length = 20 + cmd->bitmapDataLength;
IFCALL(update->SurfaceBits, update->context, cmd);
return 0;
}

View File

@ -703,8 +703,7 @@ int transport_check_fds(rdpTransport** ptransport)
}
received = transport->ReceiveBuffer;
transport->ReceiveBuffer = ObjectPool_Take(transport->ReceivePool);
transport->ReceiveBuffer->pointer = transport->ReceiveBuffer->buffer;
transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
stream_set_pos(received, length);
stream_seal(received);
@ -720,7 +719,7 @@ int transport_check_fds(rdpTransport** ptransport)
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
ObjectPool_Return(transport->ReceivePool, received);
Stream_Release(received);
if (recv_status < 0)
status = -1;
@ -799,16 +798,6 @@ static void* transport_client_thread(void* arg)
return NULL;
}
wStream* transport_receive_buffer_pool_new()
{
wStream* pdu = NULL;
pdu = stream_new(BUFFER_SIZE);
pdu->pointer = pdu->buffer;
return pdu;
}
rdpTransport* transport_new(rdpSettings* settings)
{
rdpTransport* transport;
@ -826,16 +815,14 @@ rdpTransport* transport_new(rdpSettings* settings)
/* a small 0.1ms delay when transport is blocking. */
transport->SleepInterval = 100;
transport->ReceivePool = ObjectPool_New(TRUE);
ObjectPool_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free;
ObjectPool_Object(transport->ReceivePool)->fnObjectNew = (OBJECT_NEW_FN) transport_receive_buffer_pool_new;
transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);
/* receive buffer for non-blocking read. */
transport->ReceiveBuffer = ObjectPool_Take(transport->ReceivePool);
transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
/* buffers for blocking read/write */
transport->ReceiveStream = stream_new(BUFFER_SIZE);
transport->ReceiveStream = StreamPool_Take(transport->ReceivePool, 0);
transport->SendStream = stream_new(BUFFER_SIZE);
transport->blocking = TRUE;
@ -851,11 +838,13 @@ void transport_free(rdpTransport* transport)
if (transport != NULL)
{
if (transport->ReceiveBuffer)
ObjectPool_Return(transport->ReceivePool, transport->ReceiveBuffer);
Stream_Release(transport->ReceiveBuffer);
ObjectPool_Free(transport->ReceivePool);
if (transport->ReceiveStream)
Stream_Release(transport->ReceiveStream);
StreamPool_Free(transport->ReceivePool);
stream_free(transport->ReceiveStream);
stream_free(transport->SendStream);
CloseHandle(transport->ReceiveEvent);

View File

@ -69,7 +69,7 @@ struct rdp_transport
HANDLE GatewayEvent;
BOOL blocking;
BOOL SplitInputOutput;
wObjectPool* ReceivePool;
wStreamPool* ReceivePool;
HANDLE stopEvent;
HANDLE thread;
BOOL async;

View File

@ -28,6 +28,7 @@
#include <winpr/wtypes.h>
#include <winpr/synch.h>
#include <winpr/stream.h>
typedef void* (*OBJECT_NEW_FN)(void);
typedef void (*OBJECT_FREE_FN)(void* obj);

View File

@ -28,12 +28,17 @@
extern "C" {
#endif
typedef struct _wStreamPool wStreamPool;
struct _wStream
{
BYTE* buffer;
BYTE* pointer;
size_t length;
size_t capacity;
DWORD count;
wStreamPool* pool;
};
typedef struct _wStream wStream;
@ -337,6 +342,38 @@ static INLINE BOOL stream_skip(wStream* s, int sz) {
return TRUE;
}
/* StreamPool */
struct _wStreamPool
{
int aSize;
int aCapacity;
wStream** aArray;
int uSize;
int uCapacity;
wStream** uArray;
HANDLE mutex;
BOOL synchronized;
size_t defaultSize;
};
WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
WINPR_API void Stream_AddRef(wStream* s);
WINPR_API void Stream_Release(wStream* s);
WINPR_API wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr);
WINPR_API void StreamPool_AddRef(wStreamPool* pool, BYTE* ptr);
WINPR_API void StreamPool_Release(wStreamPool* pool, BYTE* ptr);
WINPR_API void StreamPool_Clear(wStreamPool* pool);
WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
WINPR_API void StreamPool_Free(wStreamPool* pool);
#ifdef __cplusplus
}
#endif

View File

@ -25,6 +25,10 @@
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _WIN32
#define CSTR_LESS_THAN 1
@ -174,4 +178,8 @@ WINPR_API int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteS
WINPR_API int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
#ifdef __cplusplus
}
#endif
#endif /* WINPR_CRT_STRING_H */

View File

@ -236,7 +236,11 @@ LONG InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG
#endif /* _WIN32 */
#if (_WIN32 && (_WIN32_WINNT < 0x0502))
#if defined(_WIN64)
/* InterlockedCompareExchange64 already defined */
#elif (_WIN32 && (_WIN32_WINNT < 0x0502))
static volatile HANDLE mutex = NULL;

View File

@ -29,6 +29,7 @@ set(${MODULE_PREFIX}_COLLECTIONS_SRCS
collections/CountdownEvent.c
collections/BufferPool.c
collections/ObjectPool.c
collections/StreamPool.c
collections/MessageQueue.c
collections/MessagePipe.c)

View File

@ -0,0 +1,323 @@
/**
* WinPR: Windows Portable Runtime
* Object Pool
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/collections.h>
/**
* Methods
*/
void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count)
{
if (count > 0)
{
if (pool->uSize + count > pool->uCapacity)
{
pool->uCapacity *= 2;
pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity);
}
MoveMemory(&pool->uArray[index + count], &pool->uArray[index], (pool->uSize - index) * sizeof(wStream*));
pool->uSize += count;
}
else if (count < 0)
{
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize + count) * sizeof(wStream*));
pool->uSize += count;
}
}
/**
* Adds a used stream to the pool.
*/
void StreamPool_AddUsed(wStreamPool* pool, wStream* s)
{
int index;
if ((pool->uSize + 1) >= pool->uCapacity)
{
pool->uCapacity *= 2;
pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity);
}
pool->uArray[(pool->uSize)++] = s;
}
/**
* Removes a used stream from the pool.
*/
void StreamPool_RemoveUsed(wStreamPool* pool, wStream* s)
{
int index;
BOOL found = FALSE;
for (index = 0; index < pool->uSize; index++)
{
if (pool->uArray[index] == s)
{
found = TRUE;
break;
}
}
if (found)
StreamPool_ShiftUsed(pool, index, -1);
}
/**
* Gets a stream from the pool.
*/
wStream* StreamPool_Take(wStreamPool* pool, size_t size)
{
wStream* s = NULL;
if (pool->synchronized)
WaitForSingleObject(pool->mutex, INFINITE);
if (pool->aSize > 0)
s = pool->aArray[--(pool->aSize)];
if (size == 0)
size = pool->defaultSize;
if (!s)
{
s = Stream_New(NULL, size);
}
else
{
Stream_EnsureCapacity(s, size);
Stream_Pointer(s) = Stream_Buffer(s);
}
s->pool = pool;
s->count = 1;
StreamPool_AddUsed(pool, s);
if (pool->synchronized)
ReleaseMutex(pool->mutex);
return s;
}
/**
* Returns an object to the pool.
*/
void StreamPool_Return(wStreamPool* pool, wStream* s)
{
if (pool->synchronized)
WaitForSingleObject(pool->mutex, INFINITE);
if ((pool->aSize + 1) >= pool->aCapacity)
{
pool->aCapacity *= 2;
pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity);
}
pool->aArray[(pool->aSize)++] = s;
StreamPool_RemoveUsed(pool, s);
if (pool->synchronized)
ReleaseMutex(pool->mutex);
}
/**
* Lock the stream pool
*/
void StreamPool_Lock(wStreamPool* pool)
{
WaitForSingleObject(pool->mutex, INFINITE);
}
/**
* Unlock the stream pool
*/
void StreamPool_Unlock(wStreamPool* pool)
{
ReleaseMutex(pool->mutex);
}
/**
* Increment stream reference count
*/
void Stream_AddRef(wStream* s)
{
if (s->pool)
{
StreamPool_Lock(s->pool);
s->count++;
StreamPool_Unlock(s->pool);
}
}
/**
* Decrement stream reference count
*/
void Stream_Release(wStream* s)
{
DWORD count;
if (s->pool)
{
StreamPool_Lock(s->pool);
count = --(s->count);
StreamPool_Unlock(s->pool);
if (count == 0)
StreamPool_Return(s->pool, s);
}
}
/**
* Find stream in pool using pointer inside buffer
*/
wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
{
int index;
wStream* s = NULL;
BOOL found = FALSE;
WaitForSingleObject(pool->mutex, INFINITE);
for (index = 0; index < pool->uSize; index++)
{
s = pool->uArray[index];
if ((ptr >= s->buffer) && (ptr < (s->buffer + s->capacity)))
{
found = TRUE;
break;
}
}
ReleaseMutex(pool->mutex);
return (found) ? s : NULL;
}
/**
* Find stream in pool and increment reference count
*/
void StreamPool_AddRef(wStreamPool* pool, BYTE* ptr)
{
wStream* s;
s = StreamPool_Find(pool, ptr);
if (s)
Stream_AddRef(s);
}
/**
* Find stream in pool and decrement reference count
*/
void StreamPool_Release(wStreamPool* pool, BYTE* ptr)
{
wStream* s;
s = StreamPool_Find(pool, ptr);
if (s)
Stream_Release(s);
}
/**
* Releases the streams currently cached in the pool.
*/
void StreamPool_Clear(wStreamPool* pool)
{
if (pool->synchronized)
WaitForSingleObject(pool->mutex, INFINITE);
while (pool->aSize > 0)
{
(pool->aSize)--;
Stream_Free(pool->aArray[pool->aSize], TRUE);
}
if (pool->synchronized)
ReleaseMutex(pool->mutex);
}
/**
* Construction, Destruction
*/
wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize)
{
wStreamPool* pool = NULL;
pool = (wStreamPool*) malloc(sizeof(wStreamPool));
if (pool)
{
ZeroMemory(pool, sizeof(wStreamPool));
pool->synchronized = synchronized;
pool->defaultSize = defaultSize;
if (pool->synchronized)
pool->mutex = CreateMutex(NULL, FALSE, NULL);
pool->aSize = 0;
pool->aCapacity = 32;
pool->aArray = (wStream**) malloc(sizeof(wStream*) * pool->aCapacity);
pool->uSize = 0;
pool->uCapacity = 32;
pool->uArray = (wStream**) malloc(sizeof(wStream*) * pool->uCapacity);
}
return pool;
}
void StreamPool_Free(wStreamPool* pool)
{
if (pool)
{
StreamPool_Clear(pool);
if (pool->synchronized)
CloseHandle(pool->mutex);
free(pool->aArray);
free(pool->uArray);
free(pool);
}
}

View File

@ -9,6 +9,7 @@ set(${MODULE_PREFIX}_TESTS
TestPrint.c
TestArrayList.c
TestCmdLine.c
TestStreamPool.c
TestMessageQueue.c
TestMessagePipe.c)

View File

@ -0,0 +1,101 @@
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/collections.h>
#define BUFFER_SIZE 16384
int TestStreamPool(int argc, char* argv[])
{
wStream* s[5];
wStreamPool* pool;
pool = StreamPool_New(TRUE, BUFFER_SIZE);
s[0] = StreamPool_Take(pool, 0);
s[1] = StreamPool_Take(pool, 0);
s[2] = StreamPool_Take(pool, 0);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
Stream_Release(s[0]);
Stream_Release(s[1]);
Stream_Release(s[2]);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
s[3] = StreamPool_Take(pool, 0);
s[4] = StreamPool_Take(pool, 0);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
Stream_Release(s[3]);
Stream_Release(s[4]);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
s[2] = StreamPool_Take(pool, 0);
s[3] = StreamPool_Take(pool, 0);
s[4] = StreamPool_Take(pool, 0);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
Stream_AddRef(s[2]);
Stream_AddRef(s[3]);
Stream_AddRef(s[3]);
Stream_AddRef(s[4]);
Stream_AddRef(s[4]);
Stream_AddRef(s[4]);
Stream_Release(s[2]);
Stream_Release(s[2]);
Stream_Release(s[3]);
Stream_Release(s[3]);
Stream_Release(s[3]);
Stream_Release(s[4]);
Stream_Release(s[4]);
Stream_Release(s[4]);
Stream_Release(s[4]);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
s[2] = StreamPool_Take(pool, 0);
s[3] = StreamPool_Take(pool, 0);
s[4] = StreamPool_Take(pool, 0);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
StreamPool_AddRef(pool, s[2]->buffer + 1024);
StreamPool_AddRef(pool, s[3]->buffer + 1024);
StreamPool_AddRef(pool, s[3]->buffer + 1024 * 2);
StreamPool_AddRef(pool, s[4]->buffer + 1024);
StreamPool_AddRef(pool, s[4]->buffer + 1024 * 2);
StreamPool_AddRef(pool, s[4]->buffer + 1024 * 3);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
StreamPool_Release(pool, s[2]->buffer + 2048);
StreamPool_Release(pool, s[2]->buffer + 2048 * 2);
StreamPool_Release(pool, s[3]->buffer + 2048);
StreamPool_Release(pool, s[3]->buffer + 2048 * 2);
StreamPool_Release(pool, s[3]->buffer + 2048 * 3);
StreamPool_Release(pool, s[4]->buffer + 2048);
StreamPool_Release(pool, s[4]->buffer + 2048 * 2);
StreamPool_Release(pool, s[4]->buffer + 2048 * 3);
StreamPool_Release(pool, s[4]->buffer + 2048 * 4);
printf("StreamPool: aSize: %d uSize: %d\n", pool->aSize, pool->uSize);
StreamPool_Free(pool);
return 0;
}