From c35c2bdeb6363b8ad0b9124a1f3235b7b549ebe8 Mon Sep 17 00:00:00 2001 From: Nik Twerdochlib Date: Thu, 7 Nov 2013 11:43:22 -0500 Subject: [PATCH 01/40] Minor optimization in DeviceServiceEntry when setting up to share all drives. Removed the call to strlen() and use the return value from _snprintf --- channels/drive/client/drive_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 12d4d89f7..36f2f08df 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -795,8 +795,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) if (*dev > 'B') { /* Suppress disk drives A and B to avoid pesty messages */ - _snprintf(buf, sizeof(buf) - 4, "%s", drive->Name); - len = strlen(buf); + len = _snprintf(buf, sizeof(buf) - 4, "%s", drive->Name); buf[len] = '_'; buf[len + 1] = dev[0]; buf[len + 2] = 0; From f3bfef8da5bb1d553ba05f90ff2b5b2519b2fc8d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 10:27:16 +0100 Subject: [PATCH 02/40] Resource cleanup fixes. --- channels/client/channels.c | 18 ++++- client/Android/FreeRDPCore/CMakeLists.txt | 2 +- .../Android/FreeRDPCore/jni/android_freerdp.c | 68 +++++++++++++------ .../Android/FreeRDPCore/jni/android_freerdp.h | 5 -- .../presentation/SessionActivity.java | 11 ++- .../aFreeRDP/AndroidManifest.xml.cmake | 1 + client/Android/aFreeRDP/CMakeLists.txt | 2 +- 7 files changed, 77 insertions(+), 30 deletions(-) diff --git a/channels/client/channels.c b/channels/client/channels.c index 520073ce2..0241a17e8 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -335,6 +335,16 @@ int freerdp_channels_global_init(void) int freerdp_channels_global_uninit(void) { + EnterCriticalSection(&g_channels_lock); + DeleteCriticalSection(&g_channels_lock); + + if (g_ChannelsList) + { + ArrayList_Lock(g_ChannelsList); + ArrayList_Free(g_ChannelsList); + g_ChannelsList = NULL; + } + return 0; } @@ -356,7 +366,9 @@ void freerdp_channels_free(rdpChannels* channels) { MessagePipe_Free(channels->MsgPipe); - /* TODO: remove from channels list */ + ArrayList_Lock(g_ChannelsList); + ArrayList_Remove(g_ChannelsList, channels); + ArrayList_Unlock(g_ChannelsList); free(channels); } @@ -496,8 +508,8 @@ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) { int index; char* name; - char* hostname; - int hostnameLength; + char* hostname; + int hostnameLength; CHANNEL_CLIENT_DATA* pChannelClientData; channels->is_connected = 1; diff --git a/client/Android/FreeRDPCore/CMakeLists.txt b/client/Android/FreeRDPCore/CMakeLists.txt index a77e2cfdd..dd5c3212e 100644 --- a/client/Android/FreeRDPCore/CMakeLists.txt +++ b/client/Android/FreeRDPCore/CMakeLists.txt @@ -60,5 +60,5 @@ if(ANDROID_BUILD_JAVA) ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-lib ALL SOURCES "${ANDROIDLIB}") - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin") + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") endif() diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index fbebf8623..d7e7993c0 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include @@ -138,17 +140,24 @@ BOOL android_pre_connect(freerdp* instance) return TRUE; } -BOOL android_post_connect(freerdp* instance) +static BOOL android_post_connect(freerdp* instance) { + rdpSettings *settings = instance->settings; + DEBUG_ANDROID("android_post_connect"); + assert(instance); + assert(settings); + freerdp_callback("OnSettingsChanged", "(IIII)V", instance, - instance->settings->DesktopWidth, instance->settings->DesktopHeight, - instance->settings->ColorDepth); + settings->DesktopWidth, settings->DesktopHeight, + settings->ColorDepth); - instance->context->cache = cache_new(instance->settings); + instance->context->cache = cache_new(settings); - gdi_init(instance, CLRCONV_ALPHA | ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), NULL); + gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | + ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), + NULL); instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; @@ -164,6 +173,13 @@ BOOL android_post_connect(freerdp* instance) return TRUE; } +static void android_post_disconnect(freerdp* instance) +{ + gdi_free(instance); + cache_free(instance->context->cache); + android_cliprdr_uninit(instance); +} + BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain) { DEBUG_ANDROID("Authenticate user:"); @@ -374,7 +390,7 @@ static int android_freerdp_run(freerdp* instance) int rcount; int wcount; int fd_input_event; - HANDLE input_event; + HANDLE input_event = NULL; void* rfds[32]; void* wfds[32]; fd_set rfds_set; @@ -413,7 +429,7 @@ static int android_freerdp_run(freerdp* instance) (LPTHREAD_START_ROUTINE) jni_update_thread, instance, 0, NULL); } - if (async_input) + if (async_input) { input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL); @@ -521,7 +537,7 @@ static int android_freerdp_run(freerdp* instance) break; } } - else + else if (input_event) { if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0) { @@ -555,6 +571,13 @@ static int android_freerdp_run(freerdp* instance) freerdp_channels_close(instance->context->channels, instance); DEBUG_ANDROID("Cleanup threads..."); + + if (async_channels) + { + WaitForSingleObject(channels_thread, INFINITE); + CloseHandle(channels_thread); + } + if (async_update) { wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); @@ -570,19 +593,9 @@ static int android_freerdp_run(freerdp* instance) WaitForSingleObject(input_thread, INFINITE); CloseHandle(input_thread); } - - if (async_channels) - { - WaitForSingleObject(channels_thread, INFINITE); - CloseHandle(channels_thread); - } DEBUG_ANDROID("Disconnecting..."); - freerdp_channels_free(instance->context->channels); freerdp_disconnect(instance); - gdi_free(instance); - cache_free(instance->context->cache); - android_cliprdr_uninit(instance); freerdp_callback("OnDisconnected", "(I)V", instance); DEBUG_ANDROID("Quit."); @@ -615,6 +628,7 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) freerdp* instance; #if defined(WITH_GPROF) + setenv("CPUPROFILE_FREQUENCY", "200", 1); monstartup("libfreerdp-android.so"); #endif @@ -622,6 +636,7 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) instance = freerdp_new(); instance->PreConnect = android_pre_connect; instance->PostConnect = android_post_connect; + instance->PostDisconnect = android_post_disconnect; instance->Authenticate = android_authenticate; instance->VerifyCertificate = android_verify_certificate; instance->VerifyChangedCertificate = android_verify_changed_certificate; @@ -640,6 +655,8 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance) { freerdp* inst = (freerdp*)instance; + + freerdp_context_free(inst); freerdp_free(inst); #if defined(WITH_GPROF) @@ -666,9 +683,18 @@ JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint ins JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint instance) { freerdp* inst = (freerdp*)instance; + androidContext* ctx = (androidContext*)inst->context; ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); + + assert(inst); + assert(ctx); + assert(event); + android_push_event(inst, event); + + pthread_join(ctx->thread, NULL); freerdp_callback("OnDisconnecting", "(I)V", instance); + return (jboolean) JNI_TRUE; } @@ -676,8 +702,12 @@ JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, ji { DEBUG_ANDROID("Cancelling connection ..."); freerdp* inst = (freerdp*)instance; + androidContext* ctx = (androidContext*)inst->context; + ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); android_push_event(inst, event); + + pthread_join(ctx->thread, NULL); freerdp_callback("OnDisconnecting", "(I)V", instance); } @@ -1001,7 +1031,7 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin (*env)->ReleaseStringUTFChars(env, jgatewaydomain, gatewaydomain); } -void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) +static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) { int i, j; int length; diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.h b/client/Android/FreeRDPCore/jni/android_freerdp.h index d9acc6249..6b695df68 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.h +++ b/client/Android/FreeRDPCore/jni/android_freerdp.h @@ -28,11 +28,6 @@ struct android_context }; typedef struct android_context androidContext; - - -void copy_remotefx_tile(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int bpp); -void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp); - JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls); JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance); JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint instance); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java index c69b5ff22..54dec0760 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java @@ -9,6 +9,7 @@ package com.freerdp.freerdpcore.presentation; +import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -530,7 +531,15 @@ public class SessionActivity extends Activity protected void onDestroy() { super.onDestroy(); Log.v(TAG, "Session.onDestroy"); - + + // Cancel running disconnect timers. + GlobalApp.cancelDisconnectTimer(); + + // Disconnect all remaining sessions. + Collection sessions = GlobalApp.getSessions(); + for (SessionState session : sessions) + LibFreeRDP.disconnect(session.getInstance()); + // unregister freerdp events broadcast receiver unregisterReceiver(libFreeRDPBroadcastReceiver); diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index d27c71052..986b4baf8 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -11,6 +11,7 @@ diff --git a/client/Android/aFreeRDP/CMakeLists.txt b/client/Android/aFreeRDP/CMakeLists.txt index b335a6f99..5910bac70 100644 --- a/client/Android/aFreeRDP/CMakeLists.txt +++ b/client/Android/aFreeRDP/CMakeLists.txt @@ -78,5 +78,5 @@ if(ANDROID_BUILD_JAVA) ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-package ALL SOURCES "${APK}") - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin") + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") endif() From 72e33363ff77102d50caee7969ff62ac134ca9db Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 10:27:33 +0100 Subject: [PATCH 03/40] Redirected debugging to logcat if build for android. --- include/freerdp/utils/debug.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h index cc986e16d..394da686c 100644 --- a/include/freerdp/utils/debug.h +++ b/include/freerdp/utils/debug.h @@ -20,17 +20,37 @@ #ifndef FREERDP_UTILS_DEBUG_H #define FREERDP_UTILS_DEBUG_H +#define DEBUG_NULL(fmt, ...) do { } while (0) +#if defined(ANDROID) +#include + +#define APP_NAME "freerdp-debug" + +#define ANDROID_DEBUG_PRINT(_dbg_str, fmt, ...) do { \ + __android_log_print(_dbg_str, fmt, ##__VA_ARGS__); \ + } while( 0 ) + +#define DEBUG_CLASS(_dbg_class, fmt, ...) \ + ANDROID_DEBUG_PRINT(ANDROID_LOG_DEBUG, APP_NAME, \ + "DBG_" #_dbg_class " %s (%s:%d): " \ + fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) + +#define DEBUG_WARN(fmt, ...) \ + ANDROID_DEBUG_PRINT(ANDROID_LOG_WARN, APP_NAME, "Warning %s (%s:%d): " \ + fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) +#else #include -#define DEBUG_NULL(fmt, ...) do { } while (0) #define DEBUG_PRINT(_dbg_str, fmt, ...) do { \ - fprintf(stderr, _dbg_str, __FUNCTION__, __FILE__, __LINE__); \ - fprintf(stderr, fmt, ## __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while( 0 ) + fprintf(stderr, _dbg_str, __FUNCTION__, __FILE__, __LINE__); \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } while( 0 ) + #define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%s:%d): ", fmt, ## __VA_ARGS__) #define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%s:%d): ", fmt, ## __VA_ARGS__) +#endif #ifdef WITH_DEBUG #define DEBUG_MSG(fmt, ...) DEBUG_PRINT("DBG %s (%s:%d): ", fmt, ## __VA_ARGS__) From b34c2d0e1dd6b266c9f3274895152dcda7de4a6b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 10:27:57 +0100 Subject: [PATCH 04/40] Removed unneccessary include , which broke the build. --- winpr/libwinpr/thread/process.c | 1 - 1 file changed, 1 deletion(-) diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index f27567b9a..cac0f73e6 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -66,7 +66,6 @@ #include #include -#include #include #include #include From 9eedf16ef05dff212c27ac35719f84287db3fadf Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:08:06 +0100 Subject: [PATCH 05/40] Added native android build scripts. --- client/Android/FreeRDPCore/jni/Android.mk.cmake | 8 ++++++++ client/Android/FreeRDPCore/jni/Application.mk.cmake | 1 + 2 files changed, 9 insertions(+) create mode 100644 client/Android/FreeRDPCore/jni/Android.mk.cmake create mode 100644 client/Android/FreeRDPCore/jni/Application.mk.cmake diff --git a/client/Android/FreeRDPCore/jni/Android.mk.cmake b/client/Android/FreeRDPCore/jni/Android.mk.cmake new file mode 100644 index 000000000..94452ea92 --- /dev/null +++ b/client/Android/FreeRDPCore/jni/Android.mk.cmake @@ -0,0 +1,8 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := freerdp-android +LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfreerdp-android.so +LOCAL_EXPORT_C_INCLUDES := ../../../../include +include $(PREBUILT_SHARED_LIBRARY) diff --git a/client/Android/FreeRDPCore/jni/Application.mk.cmake b/client/Android/FreeRDPCore/jni/Application.mk.cmake new file mode 100644 index 000000000..6d001458f --- /dev/null +++ b/client/Android/FreeRDPCore/jni/Application.mk.cmake @@ -0,0 +1 @@ +APP_ABI := armeabi-v7a From 017308b796c024563333a6a26542a8920458a28b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:37:38 +0100 Subject: [PATCH 06/40] Added generation of android ndk build scripts. --- client/Android/FreeRDPCore/jni/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/CMakeLists.txt b/client/Android/FreeRDPCore/jni/CMakeLists.txt index 5fa6ec505..305c4d1ad 100644 --- a/client/Android/FreeRDPCore/jni/CMakeLists.txt +++ b/client/Android/FreeRDPCore/jni/CMakeLists.txt @@ -19,10 +19,14 @@ set(MODULE_NAME "freerdp-android") set(MODULE_PREFIX "FREERDP_CLIENT_ANDROID") - include_directories(.) include_directories(generated) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Application.mk.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Application.mk @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Android.mk.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Android.mk @ONLY) + if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-pointer-sign") endif() @@ -68,16 +72,15 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} jnigraphics) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${ANDROID_ABI}") set_target_properties(${MODULE_NAME} - PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ANDROID_BINARY_DIR}/libs/${ANDROID_ABI}") + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${ANDROID_ABI}") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Android") get_property(LIB_ABSNAME TARGET ${MODULE_NAME} PROPERTY LOCATION) -file(MAKE_DIRECTORY ${ANDROID_BINARY_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}) add_custom_command(TARGET ${MODULE_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${LIB_ABSNAME} - ${ANDROID_BINARY_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}/) - + COMMAND ${NDK_COMMAND} NDK_DEBUG=${NDK_DEBUG} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../) From dc055782e85a2b6e64058d73055e5cadce8dd441 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:42:41 +0100 Subject: [PATCH 07/40] Modified ant build target. --- client/Android/FreeRDPCore/CMakeLists.txt | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/client/Android/FreeRDPCore/CMakeLists.txt b/client/Android/FreeRDPCore/CMakeLists.txt index dd5c3212e..f0718b0fc 100644 --- a/client/Android/FreeRDPCore/CMakeLists.txt +++ b/client/Android/FreeRDPCore/CMakeLists.txt @@ -17,7 +17,6 @@ # limitations under the License. set(ANDROID_PACKAGE_NAME "aFreeRDPCore") -file(MAKE_DIRECTORY ${ANDROID_BINARY_DIR}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml @ONLY) @@ -45,20 +44,15 @@ endif() add_subdirectory(jni) - if(ANDROID_BUILD_JAVA) - file(MAKE_DIRECTORY "${ANDROID_BINARY_DIR}/bin") - set(ANDROIDLIB "${ANDROID_BINARY_DIR}/bin/classes.jar") - # command to create the android package - add_custom_command( - OUTPUT "${ANDROIDLIB}" + add_custom_target(android-lib ALL COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} - WORKING_DIRECTORY "${ANDROID_BINARY_DIR}" - MAIN_DEPENDENCY AndroidManifest.xml + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPENDS freerdp-android - ${CMAKE_CURRENT_BINARY_DIR}/local.properties + SOURCES AndroidManifest.xml ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) - add_custom_target(android-lib ALL SOURCES "${ANDROIDLIB}") - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") endif() + +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") + From 97995208032a9754d0eb41ee7466266a0f45cf69 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:44:28 +0100 Subject: [PATCH 08/40] Added ndk-build detection. --- client/Android/CMakeLists.txt | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/client/Android/CMakeLists.txt b/client/Android/CMakeLists.txt index 0930be3f3..bb928baf0 100644 --- a/client/Android/CMakeLists.txt +++ b/client/Android/CMakeLists.txt @@ -15,7 +15,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(ANDROID_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/aFreeRDP") +if (NOT ANDROID_NDK) + message(FATAL_ERROR "ANDROID_NDK not set but required for building android native library.") +endif() + +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, BOTH) +find_program(NDK_COMMAND ndk-build) +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, ONLY) + +if(NDK_COMMAND STREQUAL "ANT_COMMAND-NOTFOUND") + message(FATAL_ERROR "ndk-build not found but required to build native lib") +endif() if(ANDROID_BUILD_JAVA) if (NOT ANDROID_SDK) @@ -30,18 +40,20 @@ if(ANDROID_BUILD_JAVA) if(ANT_COMMAND STREQUAL "ANT_COMMAND-NOTFOUND") message(FATAL_ERROR "ant not found but required to build android java") endif() - - if(ANDROID_BUILD_JAVA_DEBUG) - set(ANDROID_BUILD_TYPE "debug") - else() - set(ANDROID_BUILD_TYPE "release") - endif() endif(ANDROID_BUILD_JAVA) +if(ANDROID_BUILD_JAVA_DEBUG) + set(ANDROID_BUILD_TYPE "debug") +else() + set(ANDROID_BUILD_TYPE "release") +endif() + if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(ANDROID_DEBUG_ENABLE "true") + set(NDK_DEBUG "1") else() set(ANDROID_DEBUG_ENABLE "false") + set(NDK_DEBUG "0") endif() add_subdirectory(FreeRDPCore) From 51041bd1bc83b1771f8581cca99105302d718182 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:46:32 +0100 Subject: [PATCH 09/40] Modified ant build target. --- client/Android/aFreeRDP/CMakeLists.txt | 35 ++++---------------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/client/Android/aFreeRDP/CMakeLists.txt b/client/Android/aFreeRDP/CMakeLists.txt index 5910bac70..99e715791 100644 --- a/client/Android/aFreeRDP/CMakeLists.txt +++ b/client/Android/aFreeRDP/CMakeLists.txt @@ -35,48 +35,23 @@ if (ANDROID_SDK) ${CMAKE_CURRENT_BINARY_DIR}/local.properties @ONLY) endif() -if("${ANDROID_DEBUG_ENABLE}" STREQUAL "true") - # 1. generate Android.mk - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/jni/Android.mk - "APP_ABI := ${ANDROID_NDK_ABI_NAME}\n") - - # 2. generate gdb.setup - get_directory_property(INCLUDE_DIRECTORIES DIRECTORY . INCLUDE_DIRECTORIES) - string(REGEX REPLACE ";" " " INCLUDE_DIRECTORIES "${INCLUDE_DIRECTORIES}") - set(LIB_DIRECTORIES "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}") - file(WRITE ${ANDROID_BINARY_DIR}/libs/${ANDROID_NDK_ABI_NAME}/gdb.setup - "set solib-search-path ${CMAKE_CURRENT_BINARY_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}\n") - file(APPEND ${ANDROID_BINARY_DIR}/libs/${ANDROID_NDK_ABI_NAME}/gdb.setup - "directory ${INCLUDE_DIRECTORIES} ${LIB_DIRECTORIES}\n") - - # 3. copy gdbserver executable - file(COPY ${ANDROID_NDK}/prebuilt/android-${ANDROID_ARCH_NAME}/gdbserver/gdbserver - DESTINATION ${ANDROID_BINARY_DIR}/libs/${ANDROID_NDK_ABI_NAME}/) - - # 4. Convenience target to launch debugger. - add_custom_target(debug-ndk - COMMAND adb install -r bin/aFreeRDP-debug.apk - COMMAND ndk-gdb --start --verbose --force - WORKING_DIRECTORY ${CURRENT_BINARY_DIR} - ) -endif() - if(ANDROID_BUILD_JAVA) if(NOT ANDROID_BUILD_JAVA_DEBUG) - set(APK "${ANDROID_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") + set(APK "${CMAKE_CURRENT_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") else() - set(APK "${ANDROID_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-debug.apk") + set(APK "${CMAKE_CURRENT_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-debug.apk") endif() # command to create the android package add_custom_command( OUTPUT "${APK}" COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} - WORKING_DIRECTORY "${ANDROID_BINARY_DIR}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" MAIN_DEPENDENCY AndroidManifest.xml DEPENDS freerdp-android ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-package ALL SOURCES "${APK}") - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") endif() + +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin;obj;libs") From b40123fdff4db4c98dcbde6b97ba6e427e2df10b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:48:04 +0100 Subject: [PATCH 10/40] Using new library destination path for android. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e05052be..6452847f4 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -294,7 +294,7 @@ if(ANDROID) endif() endif() set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_ANDROID_EXTERNAL_SSL_PATH}) - set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/libs/${ANDROID_ABI}) + set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/jni/${ANDROID_ABI}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake ${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh @ONLY) endif() From 105a8596944815d311b375cb06f56129e5aec6df Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 12:51:01 +0100 Subject: [PATCH 11/40] Setting correct debuggable now depending on configuration. --- client/Android/aFreeRDP/AndroidManifest.xml.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index 986b4baf8..28e351425 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -11,7 +11,7 @@ From f00777876d2c757c5cfd5b90f5585e080c142714 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 13:15:04 +0100 Subject: [PATCH 12/40] Android App version now configurable from cmake. --- .../FreeRDPCore/AndroidManifest.xml.cmake | 16 +++++++++++++--- .../Android/aFreeRDP/AndroidManifest.xml.cmake | 15 ++++++++++++--- cmake/ConfigOptionsAndroid.cmake | 3 ++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake index a9adc61e2..d31735bcf 100644 --- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake +++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake @@ -3,17 +3,27 @@ - + + - + + diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index 28e351425..fb4b8a1ef 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -3,14 +3,23 @@ - - + + + diff --git a/cmake/ConfigOptionsAndroid.cmake b/cmake/ConfigOptionsAndroid.cmake index 49db7c756..f2e8e8bc9 100644 --- a/cmake/ConfigOptionsAndroid.cmake +++ b/cmake/ConfigOptionsAndroid.cmake @@ -25,7 +25,8 @@ option(WITH_ANDROID_DEBUG_MENU "Enable debug output for android jni bindings" ${ option(WITH_OPENSLES "Enable sound and microphone redirection using OpenSLES" ON) option(ANDROID_BUILD_JAVA "Automatically android java code - build type depends on CMAKE_BUILD_TYPE" ON) option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ${JAVA_DEBUG_DEFAULT}) - + +set(ANDROID_APP_VERSION 3 "Application version") set(ANDROID_APP_TARGET_SDK 11 CACHE STRING "Application target android SDK") set(ANDROID_APP_MIN_SDK 9 CACHE STRING "Application minimum android SDK requirement") set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK") From 33c4644c06219dd9b54e5fdd26476f5071da998e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 13:31:04 +0100 Subject: [PATCH 13/40] Fixed invaid setting of android app default version. --- cmake/ConfigOptionsAndroid.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ConfigOptionsAndroid.cmake b/cmake/ConfigOptionsAndroid.cmake index f2e8e8bc9..9bbcb1f20 100644 --- a/cmake/ConfigOptionsAndroid.cmake +++ b/cmake/ConfigOptionsAndroid.cmake @@ -26,7 +26,7 @@ option(WITH_OPENSLES "Enable sound and microphone redirection using OpenSLES" ON option(ANDROID_BUILD_JAVA "Automatically android java code - build type depends on CMAKE_BUILD_TYPE" ON) option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ${JAVA_DEBUG_DEFAULT}) -set(ANDROID_APP_VERSION 3 "Application version") +set(ANDROID_APP_VERSION 3 CACHE STRING "Application version") set(ANDROID_APP_TARGET_SDK 11 CACHE STRING "Application target android SDK") set(ANDROID_APP_MIN_SDK 9 CACHE STRING "Application minimum android SDK requirement") set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK") From 003f1bad3b019ba575091111176de2986025a4ca Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 13:31:29 +0100 Subject: [PATCH 14/40] Added missing include. --- include/freerdp/utils/debug.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h index 394da686c..1d30b9729 100644 --- a/include/freerdp/utils/debug.h +++ b/include/freerdp/utils/debug.h @@ -20,7 +20,14 @@ #ifndef FREERDP_UTILS_DEBUG_H #define FREERDP_UTILS_DEBUG_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define DEBUG_NULL(fmt, ...) do { } while (0) + +/* When building for android redirect all debug messages + * to logcat. */ #if defined(ANDROID) #include @@ -38,7 +45,9 @@ #define DEBUG_WARN(fmt, ...) \ ANDROID_DEBUG_PRINT(ANDROID_LOG_WARN, APP_NAME, "Warning %s (%s:%d): " \ fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) + #else +/* By default all log messages are written to stdout */ #include #define DEBUG_PRINT(_dbg_str, fmt, ...) do { \ From d1bc0d6f3742771425b8206d319823289216f86e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 13:40:05 +0100 Subject: [PATCH 15/40] Enabled native building support. --- client/Android/FreeRDPCore/.project | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/client/Android/FreeRDPCore/.project b/client/Android/FreeRDPCore/.project index 85408c31b..3f28ccc44 100644 --- a/client/Android/FreeRDPCore/.project +++ b/client/Android/FreeRDPCore/.project @@ -5,6 +5,60 @@ + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?children? + ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + ndk-build + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + com.android.ide.eclipse.adt.ResourceManagerBuilder @@ -25,9 +79,19 @@ + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature From ba2c31e9d90332b9d16b9ac47a337487daaa9c03 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 15:16:18 +0100 Subject: [PATCH 16/40] Modified build to allow native debugging with eclipse. --- client/Android/FreeRDPCore/.project | 52 ++----------------- .../FreeRDPCore/AndroidManifest.xml.cmake | 4 +- client/Android/FreeRDPCore/CMakeLists.txt | 10 ---- .../FreeRDPCore/jni/Application.mk.cmake | 2 +- client/Android/FreeRDPCore/jni/CMakeLists.txt | 4 -- 5 files changed, 7 insertions(+), 65 deletions(-) diff --git a/client/Android/FreeRDPCore/.project b/client/Android/FreeRDPCore/.project index 3f28ccc44..bfc09afd1 100644 --- a/client/Android/FreeRDPCore/.project +++ b/client/Android/FreeRDPCore/.project @@ -6,56 +6,12 @@ - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, - ?children? - ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| - - - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.buildArguments - - - - org.eclipse.cdt.make.core.buildCommand - ndk-build - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - true + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake index d31735bcf..d7e944c29 100644 --- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake +++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake @@ -4,7 +4,6 @@ android:installLocation="auto" package="com.freerdp.freerdpcore" android:versionCode="@ANDROID_APP_VERSION@" - android:debuggable="@ANDROID_DEBUG_ENABLE@" android:versionName="@GIT_REVISION@" > - + Date: Fri, 8 Nov 2013 15:19:38 +0100 Subject: [PATCH 17/40] Modified build to allow native debugging with eclipse. --- client/Android/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/client/Android/CMakeLists.txt b/client/Android/CMakeLists.txt index bb928baf0..4e7874a1d 100644 --- a/client/Android/CMakeLists.txt +++ b/client/Android/CMakeLists.txt @@ -27,6 +27,7 @@ if(NDK_COMMAND STREQUAL "ANT_COMMAND-NOTFOUND") message(FATAL_ERROR "ndk-build not found but required to build native lib") endif() +set(NDK_LIB_CFG "${CMAKE_CURRENT_BINARY_DIR}/FreeRDPCore/jni/Android.mk") if(ANDROID_BUILD_JAVA) if (NOT ANDROID_SDK) message(FATAL_ERROR "ANDROID_SDK not set but required for building the java gui (ANDROID_BUILD_JAVA)") From f6236048c56e47d385dee4724ca352709ca9fa11 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 15:20:23 +0100 Subject: [PATCH 18/40] Modified build to allow native debugging with eclipse. --- client/Android/aFreeRDP/.project | 64 +++++++++++++++++++ .../aFreeRDP/AndroidManifest.xml.cmake | 1 - client/Android/aFreeRDP/CMakeLists.txt | 3 + client/Android/aFreeRDP/jni/Android.mk.cmake | 1 + .../Android/aFreeRDP/jni/Application.mk.cmake | 1 + client/Android/aFreeRDP/jni/CMakeLists.txt | 22 +++++++ 6 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 client/Android/aFreeRDP/jni/Android.mk.cmake create mode 100644 client/Android/aFreeRDP/jni/Application.mk.cmake create mode 100644 client/Android/aFreeRDP/jni/CMakeLists.txt diff --git a/client/Android/aFreeRDP/.project b/client/Android/aFreeRDP/.project index 0174cad38..f71736165 100644 --- a/client/Android/aFreeRDP/.project +++ b/client/Android/aFreeRDP/.project @@ -6,6 +6,60 @@ FreeRDPCore + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?children? + ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + ndk-build + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + com.android.ide.eclipse.adt.ResourceManagerBuilder @@ -26,9 +80,19 @@ + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index fb4b8a1ef..8cec9833d 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -19,7 +19,6 @@ diff --git a/client/Android/aFreeRDP/CMakeLists.txt b/client/Android/aFreeRDP/CMakeLists.txt index 99e715791..664f19727 100644 --- a/client/Android/aFreeRDP/CMakeLists.txt +++ b/client/Android/aFreeRDP/CMakeLists.txt @@ -18,6 +18,8 @@ set(ANDROID_PACKAGE_NAME "aFreeRDP") +add_subdirectory(jni) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml @ONLY) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build.xml.cmake @@ -45,6 +47,7 @@ if(ANDROID_BUILD_JAVA) # command to create the android package add_custom_command( OUTPUT "${APK}" + COMMAND ${NDK_COMMAND} NDK_DEBUG=${NDK_DEBUG} COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" MAIN_DEPENDENCY AndroidManifest.xml diff --git a/client/Android/aFreeRDP/jni/Android.mk.cmake b/client/Android/aFreeRDP/jni/Android.mk.cmake new file mode 100644 index 000000000..aa4051d5b --- /dev/null +++ b/client/Android/aFreeRDP/jni/Android.mk.cmake @@ -0,0 +1 @@ +include @NDK_LIB_CFG@ diff --git a/client/Android/aFreeRDP/jni/Application.mk.cmake b/client/Android/aFreeRDP/jni/Application.mk.cmake new file mode 100644 index 000000000..3655c4062 --- /dev/null +++ b/client/Android/aFreeRDP/jni/Application.mk.cmake @@ -0,0 +1 @@ +APP_ABI := @ANDROID_ABI@ diff --git a/client/Android/aFreeRDP/jni/CMakeLists.txt b/client/Android/aFreeRDP/jni/CMakeLists.txt new file mode 100644 index 000000000..7151c0f1b --- /dev/null +++ b/client/Android/aFreeRDP/jni/CMakeLists.txt @@ -0,0 +1,22 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# Android Client +# +# Copyright 2013 Armin Novak +# +# 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. + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Application.mk.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Application.mk @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Android.mk.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Android.mk @ONLY) + From 9aa70d4589de8c4b97ef823dbb8ab995a9915b4b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 16:32:50 +0100 Subject: [PATCH 19/40] Explicitly setting debug format now, as the shipped gdbserver is not compatible with the default options for all toolchains. --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6452847f4..e5d25f131 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,11 @@ endif(APPLE) if(ANDROID) if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") add_definitions(-DNDK_DEBUG=1) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG}") + + # NOTE: Manually add -gdwarf-3, as newer toolchains default to -gdwarf-4, + # which is not supported by the gdbserver binary shipped with + # the android NDK (tested with r9b) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG} -gdwarf-3") endif() set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -llog") if (NOT FREERDP_ANDROID_EXTERNAL_SSL_PATH) From 5a801a39515af12c90f59fce9166d733a7f41a89 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 8 Nov 2013 16:43:33 +0100 Subject: [PATCH 20/40] Updated documentation. --- docs/README.android | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/docs/README.android b/docs/README.android index f7c2b7e33..a0db45320 100644 --- a/docs/README.android +++ b/docs/README.android @@ -52,7 +52,8 @@ to the absolut paths on your machine: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \ -DANDROID_NDK="_your_ndk_path_here_" \ -DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \ --DANDROID_SDK="_your_sdk_path_here_" +-DANDROID_SDK="_your_sdk_path_here_" \ +-DCMAKE_BUILD_TYPE=Debug make After that you should have a client/Android/bin/aFreeRDP-debug.apk. @@ -66,12 +67,13 @@ to the absolut paths on your machine: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \ -DANDROID_NDK="_your_ndk_path_here_" \ -DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \ --DANDROID_SDK="_your_sdk_path_here_" -DANDROID_BUILD_JAVA=OFF +-DANDROID_SDK="_your_sdk_path_here_" -DANDROID_BUILD_JAVA=OFF \ +-DCMAKE_BUILD_TYPE=Debug make Now you can run your favourite ant command in client/Android like this: -cd client/Android +cd client/Android/aFreeRDP ant debug install Using an IDE @@ -83,7 +85,7 @@ the eclipse marketplace). cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \ -DANDROID_NDK="_your_ndk_path_here_" \ -DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \ --DANDROID_BUILD_JAVA=OFF +-DCMAKE_BUILD_TYPE=Debug -DANDROID_BUILD_JAVA=OFF make Open Eclipse and choose: @@ -97,6 +99,14 @@ Side note: If you add -G "Eclipse CDT4 - Unix Makefiles" when running cmake you can also import FreeRDP into Eclipse too. Then you have one Java project and one c/c++ project you can work on. This requires CDT to be installed in Eclipse. +Debugging native code +--------------------- + +All CMake builds created with -DCMAKE_BUILD_TYPE=Debug will be ready to +debug with ndk-gdb. + +Eclipse projects are already configured to allow debugging in either Java +or native code, no extra steps required. cmake variables =============== @@ -133,6 +143,35 @@ ANDROID_BUILD_JAVA (used by client/Android/CMakeLists.txt) ANDROID_SDK (used by client/Android/CMakeLists.txt) * absolute path to the Android SDK to use +ANDROID_NDK +* absolute path to the Android NDK to use. + +WITH_DEBUG_ANDROID_JNI +* enable logcat debug messages for JNI calls. + +WITH_ANDROID_DEBUG_MENU +* activate a debug menu in aFreeRDP to enable / disable runtime settings +* not available in release. + +WITH_OPENSLES +* Enables / disables sound and microphone support for android using OpenSLES + +ANDROID_BUILD_JAVA_DEBUG +* Enable / disable debugging code in the java parts of the application. + +ANDROID_APP_VERSION +* The version the aFreeRDP-release.apk / aFreeRDP-debug.apk will have. + +ANDROID_APP_TARGET_SDK +* The target SDK version of the project. + +ANDROID_APP_MIN_SDK +* The lowest supported SDK version + +ANDROID_NATIVE_API_LEVEL +* The native API level to compile the native code against. +* Should be equal to SDK level. + This is used to generate local.properties needed by ant. Needs to be set if you build manually with ant or do integrated builds. From 0d2fe6997ec003e3e7e11a393a665647350a5ae1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:21:14 +0100 Subject: [PATCH 21/40] Fixed output path for JNI header generation script. --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5d25f131..a11ecb4de 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,8 +299,11 @@ if(ANDROID) endif() set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_ANDROID_EXTERNAL_SSL_PATH}) set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/jni/${ANDROID_ABI}) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake - ${CMAKE_CURRENT_SOURCE_DIR}/scripts/regenerate_jni_headers.sh @ONLY) + CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake + ${CMAKE_BINARY_DIR}/scripts/regenerate_jni_headers.sh @ONLY) + CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/gprof_generate.sh.cmake + ${CMAKE_BINARY_DIR}/scripts/gprof_generate.sh @ONLY) + endif() set(CMAKE_THREAD_PREFER_PTHREAD TRUE) From 343c9ebba5a2618888d4c4ba84ca589d74ec5469 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:21:39 +0100 Subject: [PATCH 22/40] Using absolute paths in generation script now. --- scripts/regenerate_jni_headers.sh.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/regenerate_jni_headers.sh.cmake b/scripts/regenerate_jni_headers.sh.cmake index 6bd709a32..bf54d8963 100755 --- a/scripts/regenerate_jni_headers.sh.cmake +++ b/scripts/regenerate_jni_headers.sh.cmake @@ -1,6 +1,6 @@ #!/bin/bash -cd client/Android/FreeRDPCore/jni/generated/ +cd @CMAKE_SOURCE_DIR@/client/Android/FreeRDPCore/jni/generated/ javah -classpath ../../bin/classes:@ANDROID_SDK@/platforms/android-8/android.jar -jni com.freerdp.freerdpcore.services.LibFreeRDP rm com_freerdp_freerdpcore_services_LibFreeRDP_EventListener.h \ com_freerdp_freerdpcore_services_LibFreeRDP_UIEventListener.h From 23b58456607b1ccab02cdfaa0b1f20d0ad42d1cd Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:22:04 +0100 Subject: [PATCH 23/40] Fixed crash due to duplicate resource cleanup (MessagePipe freed in channel) --- channels/rdpsnd/client/rdpsnd_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 08495c043..1fc4c9e25 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -930,8 +930,6 @@ static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd) { MessagePipe_PostQuit(rdpsnd->MsgPipe, 0); WaitForSingleObject(rdpsnd->thread, INFINITE); - - MessagePipe_Free(rdpsnd->MsgPipe); CloseHandle(rdpsnd->thread); rdpsnd->channelEntryPoints.pVirtualChannelClose(rdpsnd->OpenHandle); From 83053c865adc7551b53380090bcd037340ab0e7e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:22:41 +0100 Subject: [PATCH 24/40] DEBUG_ANDROID now a debug define using default macros. --- client/Android/FreeRDPCore/jni/android_debug.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_debug.h b/client/Android/FreeRDPCore/jni/android_debug.h index 46892fb91..9c2f440c4 100644 --- a/client/Android/FreeRDPCore/jni/android_debug.h +++ b/client/Android/FreeRDPCore/jni/android_debug.h @@ -16,19 +16,15 @@ #include "config.h" #endif -#include - -#define TAG "LibFreeRDP" - -#define DEBUG_ANDROID_NULL(fmt, ...) do { } while (0) -#define DEBUG_ANDROID_PRINT(_dbg_str, fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, _dbg_str fmt "\n" , __FUNCTION__, __LINE__, ## __VA_ARGS__) -#define DEBUG_ANDROID_CLASS(_dbg_class, fmt, ...) DEBUG_ANDROID_PRINT("DBG_" #_dbg_class " %s (%d): ", fmt, ## __VA_ARGS__) +#include #ifdef WITH_DEBUG_ANDROID_JNI -#define DEBUG_ANDROID(fmt, ...) DEBUG_ANDROID_PRINT("DBG %s (%d): ", fmt, ## __VA_ARGS__) +#define DEBUG_ANDROID(fmt, ...) DEBUG_CLASS(JNI, fmt, ## __VA_ARGS__) #else -#define DEBUG_ANDROID(fmt, ...) DEBUG_ANDROID_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_ANDROID(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif + + #endif /* FREERDP_ANDROID_DEBUG_H */ From f93b69320f95ac826cfc6ac50caf98112aea9911 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:23:22 +0100 Subject: [PATCH 25/40] Split ndk-build and ant runs to different targets, ndk-build is now also run, if no ant build is desired. --- client/Android/aFreeRDP/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/Android/aFreeRDP/CMakeLists.txt b/client/Android/aFreeRDP/CMakeLists.txt index 664f19727..597349aac 100644 --- a/client/Android/aFreeRDP/CMakeLists.txt +++ b/client/Android/aFreeRDP/CMakeLists.txt @@ -37,6 +37,13 @@ if (ANDROID_SDK) ${CMAKE_CURRENT_BINARY_DIR}/local.properties @ONLY) endif() +# command to create the android package +add_custom_target( ndk-build ALL + COMMAND ${NDK_COMMAND} NDK_DEBUG=${NDK_DEBUG} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS freerdp-android +) + if(ANDROID_BUILD_JAVA) if(NOT ANDROID_BUILD_JAVA_DEBUG) set(APK "${CMAKE_CURRENT_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") @@ -47,11 +54,10 @@ if(ANDROID_BUILD_JAVA) # command to create the android package add_custom_command( OUTPUT "${APK}" - COMMAND ${NDK_COMMAND} NDK_DEBUG=${NDK_DEBUG} COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" MAIN_DEPENDENCY AndroidManifest.xml - DEPENDS freerdp-android + DEPENDS ndk-build ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-package ALL SOURCES "${APK}") From 2af8efb26b578c29f6761b7dfe5d4ee1a8bb3e29 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:24:13 +0100 Subject: [PATCH 26/40] Fixed resource cleanup, using DEBUG_WARN now for error messages. --- .../FreeRDPCore/jni/android_jni_callback.c | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_jni_callback.c b/client/Android/FreeRDPCore/jni/android_jni_callback.c index 071b3de3f..f862b34ba 100644 --- a/client/Android/FreeRDPCore/jni/android_jni_callback.c +++ b/client/Android/FreeRDPCore/jni/android_jni_callback.c @@ -13,7 +13,6 @@ #endif #include -#include #include "android_jni_callback.h" #include "android_debug.h" @@ -36,24 +35,30 @@ void jni_load_class(JNIEnv *env, const char *path, jobject *objptr) if (!class) { - DEBUG_ANDROID("jni_load_class: failed to find class %s", path); + DEBUG_WARN("jni_load_class: failed to find class %s", path); + goto finish; } method = (*env)->GetMethodID(env, class, "", "()V"); if (!method) { - DEBUG_ANDROID("jni_load_class: failed to find class constructor of %s", path); + DEBUG_WARN("jni_load_class: failed to find class constructor of %s", path); + goto finish; } object = (*env)->NewObject(env, class, method); if (!object) { - DEBUG_ANDROID("jni_load_class: failed create new object of %s", path); + DEBUG_WARN("jni_load_class: failed create new object of %s", path); + goto finish; } (*objptr) = (*env)->NewGlobalRef(env, object); + +finish: + while(0); } jint init_callback_environment(JavaVM* vm) @@ -61,7 +66,7 @@ jint init_callback_environment(JavaVM* vm) JNIEnv* env; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { - DEBUG_ANDROID("JNI_OnLoad: failed to obtain current JNI environment"); + DEBUG_WARN("JNI_OnLoad: failed to obtain current JNI environment"); return -1; } @@ -83,7 +88,7 @@ jboolean jni_attach_thread(JNIEnv** env) if ((*jVM)->GetEnv(jVM, (void**) env, JNI_VERSION_1_4) != JNI_OK) { - DEBUG_ANDROID("android_java_callback: failed to obtain current JNI environment"); + DEBUG_WARN("android_java_callback: failed to obtain current JNI environment"); } return JNI_TRUE; @@ -113,17 +118,20 @@ void java_callback_void(jobject obj, const char * callback, const char* signatur jObjClass = (*env)->GetObjectClass(env, obj); if (!jObjClass) { - DEBUG_ANDROID("android_java_callback: failed to get class reference"); + DEBUG_WARN("android_java_callback: failed to get class reference"); + goto finish; } jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature); if (!jCallback) { - DEBUG_ANDROID("android_java_callback: failed to get method id"); + DEBUG_WARN("android_java_callback: failed to get method id"); + goto finish; } (*env)->CallStaticVoidMethodV(env, jObjClass, jCallback, args); +finish: if(attached == JNI_TRUE) jni_detach_thread(); } @@ -134,6 +142,7 @@ jboolean java_callback_bool(jobject obj, const char * callback, const char* sign jclass jObjClass; jmethodID jCallback; jboolean attached; + jboolean res = JNI_FALSE; JNIEnv *env; DEBUG_ANDROID("java_callback: %s (%s)", callback, signature); @@ -143,17 +152,20 @@ jboolean java_callback_bool(jobject obj, const char * callback, const char* sign jObjClass = (*env)->GetObjectClass(env, obj); if (!jObjClass) { - DEBUG_ANDROID("android_java_callback: failed to get class reference"); + DEBUG_WARN("android_java_callback: failed to get class reference"); + goto finish; } jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature); if (!jCallback) { - DEBUG_ANDROID("android_java_callback: failed to get method id"); + DEBUG_WARN("android_java_callback: failed to get method id"); + goto finish; } - jboolean res = (*env)->CallStaticBooleanMethodV(env, jObjClass, jCallback, args); + res = (*env)->CallStaticBooleanMethodV(env, jObjClass, jCallback, args); +finish: if(attached == JNI_TRUE) jni_detach_thread(); From 3b209b93456bff8c36c07bb7a2c3268724b659ed Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:25:41 +0100 Subject: [PATCH 27/40] Removed pthreads, using winpr now. --- client/Android/FreeRDPCore/jni/android_freerdp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.h b/client/Android/FreeRDPCore/jni/android_freerdp.h index 6b695df68..3c7016aba 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.h +++ b/client/Android/FreeRDPCore/jni/android_freerdp.h @@ -11,7 +11,6 @@ #define __ANDROID_FREERDP_H #include -#include #include #include "android_event.h" @@ -21,7 +20,8 @@ struct android_context rdpContext rdpCtx; ANDROID_EVENT_QUEUE* event_queue; - pthread_t thread; + HANDLE thread; + BOOL is_connected; void* clipboard_context; From 8fa18f1174c5c8e2bf0b23d53aa671be9c447c08 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 10:30:14 +0100 Subject: [PATCH 28/40] Using winpr instead of pthread now. now uses up to date settings for callback now. Improved error handling in Unified disconnect and cancel JNI calls, as they currently do the same. --- .../Android/FreeRDPCore/jni/android_freerdp.c | 80 ++++++++----------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index d7e7993c0..712467cbc 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -44,12 +44,6 @@ #include "jni/prof.h" #endif -struct thread_data -{ - freerdp* instance; -}; - - int android_context_new(freerdp* instance, rdpContext* context) { context->channels = freerdp_channels_new(); @@ -74,28 +68,33 @@ void android_begin_paint(rdpContext* context) void android_end_paint(rdpContext* context) { + androidContext *ctx = (androidContext*)context; + rdpSettings* settings = context->instance->settings; + DEBUG_ANDROID("ui_update"); - rdpGdi *gdi = context->gdi; - if (gdi->primary->hdc->hwnd->invalid->null) - return; + assert(ctx); + assert(settings); + assert(context->instance); - int x = gdi->primary->hdc->hwnd->invalid->x; - int y = gdi->primary->hdc->hwnd->invalid->y; - int w = gdi->primary->hdc->hwnd->invalid->w; - int h = gdi->primary->hdc->hwnd->invalid->h; - - DEBUG_ANDROID("ui_update: x:%d y:%d w:%d h:%d", x, y, w, h); - - freerdp_callback("OnGraphicsUpdate", "(IIIII)V", context->instance, x, y, w, h); + DEBUG_ANDROID("width=%d, height=%d, bpp=%d", settings->DesktopWidth, + settings->DesktopHeight, settings->ColorDepth); + + freerdp_callback("OnGraphicsUpdate", "(IIIII)V", context->instance, + 0, 0, settings->DesktopWidth, settings->DesktopHeight); } void android_desktop_resize(rdpContext* context) { DEBUG_ANDROID("ui_desktop_resize"); - rdpGdi *gdi = context->gdi; - freerdp_callback("OnGraphicsResize", "(IIII)V", context->instance, gdi->width, gdi->height, gdi->dstBpp); + assert(context); + assert(context->settings); + assert(context->instance); + + freerdp_callback("OnGraphicsResize", "(IIII)V", + context->instance, context->settings->DesktopWidth, + context->settings->DesktopHeight, context->settings->ColorDepth); } @@ -330,6 +329,9 @@ static void* jni_input_thread(void* arg) do { DWORD rc = WaitForMultipleObjects(3, event, FALSE, INFINITE); + if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 2)) + continue; + if (rc == WAIT_OBJECT_0 + 2) { wMessage msg; @@ -338,9 +340,6 @@ static void* jni_input_thread(void* arg) if (msg.id == WMQ_QUIT) break; } - if ((rc < WAIT_OBJECT_0) && (rc > WAIT_OBJECT_0 + 1)) - break; - if (android_check_fds(instance) != TRUE) break; } @@ -603,19 +602,15 @@ static int android_freerdp_run(freerdp* instance) return 0; } -void* android_thread_func(void* param) +static void* android_thread_func(void* param) { - struct thread_data* data; - data = (struct thread_data*) param; - - assert(data); - assert(data->instance); + freerdp* instance = param; DEBUG_ANDROID("Start."); - freerdp* instance = data->instance; + assert(instance); + android_freerdp_run(instance); - free(data); DEBUG_ANDROID("Quit."); @@ -667,15 +662,13 @@ JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance) JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint instance) { freerdp* inst = (freerdp*)instance; - struct thread_data* data = (struct thread_data*) malloc(sizeof(struct thread_data)); - data->instance = inst; + androidContext* ctx = (androidContext*)inst->context; assert(inst); - assert(data); - assert(inst->context); + assert(ctx); - androidContext* ctx = (androidContext*)inst->context; - pthread_create(&ctx->thread, 0, android_thread_func, data); + ctx->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)android_thread_func, inst, 0, NULL); return JNI_TRUE; } @@ -692,7 +685,10 @@ JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint android_push_event(inst, event); - pthread_join(ctx->thread, NULL); + WaitForSingleObject(ctx->thread, INFINITE); + CloseHandle(ctx->thread); + ctx->thread = NULL; + freerdp_callback("OnDisconnecting", "(I)V", instance); return (jboolean) JNI_TRUE; @@ -700,15 +696,7 @@ JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance) { - DEBUG_ANDROID("Cancelling connection ..."); - freerdp* inst = (freerdp*)instance; - androidContext* ctx = (androidContext*)inst->context; - - ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); - android_push_event(inst, event); - - pthread_join(ctx->thread, NULL); - freerdp_callback("OnDisconnecting", "(I)V", instance); + jni_freerdp_disconnect(env, cls, instance); } JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory) From 800f94605303a72726c08517c9de64b08b7cbec8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:01:25 +0100 Subject: [PATCH 29/40] Added assertions to spot invalid call sequence for --- libfreerdp/core/freerdp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index b4f208a32..57ea44526 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -208,6 +208,10 @@ BOOL freerdp_check_fds(freerdp* instance) int status; rdpRdp* rdp; + assert(instance); + assert(instance->context); + assert(instance->context->rdp); + rdp = instance->context->rdp; status = rdp_check_fds(rdp); From f46a560e76335f0aee05c487c51406346214fd9b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:02:25 +0100 Subject: [PATCH 30/40] Added message queue custom free handler for input queue. --- libfreerdp/core/input.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 64011b807..fc5b5f4ee 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -486,8 +486,15 @@ int input_process_events(rdpInput* input) return input_message_queue_process_pending_messages(input); } +static void input_free_queued_message(void *obj) +{ + wMessage *msg = (wMessage*)obj; + input_message_queue_free_message(msg); +} + rdpInput* input_new(rdpRdp* rdp) { + const wObject cb = { .fnObjectFree = input_free_queued_message }; rdpInput* input; input = (rdpInput*) malloc(sizeof(rdpInput)); @@ -496,7 +503,7 @@ rdpInput* input_new(rdpRdp* rdp) { ZeroMemory(input, sizeof(rdpInput)); - input->queue = MessageQueue_New(); + input->queue = MessageQueue_New(&cb); } return input; From b6fff6a99204def4e652dc9f561f4d06f13a0542 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:03:07 +0100 Subject: [PATCH 31/40] Split message handling and resource cleanup for input and update messages. --- libfreerdp/core/message.c | 613 ++++++++++++++++++++++++++++++++------ 1 file changed, 522 insertions(+), 91 deletions(-) diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index b810fa1ad..5d6083f22 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "rdp.h" #include "message.h" #include "transport.h" @@ -971,37 +973,30 @@ static void update_message_PointerCached(rdpContext* context, POINTER_CACHED_UPD } /* Message Queue */ - -int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_free_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case Update_BeginPaint: - IFCALL(proxy->BeginPaint, msg->context); break; case Update_EndPaint: - IFCALL(proxy->EndPaint, msg->context); break; case Update_SetBounds: - IFCALL(proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); if (msg->wParam) free(msg->wParam); break; case Update_Synchronize: - IFCALL(proxy->Synchronize, msg->context); break; case Update_DesktopResize: - IFCALL(proxy->DesktopResize, msg->context); break; case Update_BitmapUpdate: - IFCALL(proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); { int index; BITMAP_UPDATE* wParam = (BITMAP_UPDATE*) msg->wParam; @@ -1022,30 +1017,23 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_Palette: - IFCALL(proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); free(msg->wParam); break; case Update_PlaySound: - IFCALL(proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*) msg->wParam); free(msg->wParam); break; case Update_RefreshRect: - IFCALL(proxy->RefreshRect, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); free(msg->lParam); break; case Update_SuppressOutput: - IFCALL(proxy->SuppressOutput, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); if (msg->lParam) free(msg->lParam); break; case Update_SurfaceCommand: - IFCALL(proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); { wStream* s = (wStream*) msg->wParam; Stream_Free(s, TRUE); @@ -1053,7 +1041,6 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_SurfaceBits: - IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); { #ifdef WITH_STREAM_POOL rdpContext* context = (rdpContext*) msg->context; @@ -1068,10 +1055,81 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_SurfaceFrameMarker: - IFCALL(proxy->SurfaceFrameMarker, msg->context, (SURFACE_FRAME_MARKER*) msg->wParam); free(msg->wParam); break; + case Update_SurfaceFrameAcknowledge: + break; + + default: + status = -1; + break; + } + + return status; +} + + +static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case Update_BeginPaint: + IFCALL(proxy->BeginPaint, msg->context); + break; + + case Update_EndPaint: + IFCALL(proxy->EndPaint, msg->context); + break; + + case Update_SetBounds: + IFCALL(proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); + break; + + case Update_Synchronize: + IFCALL(proxy->Synchronize, msg->context); + break; + + case Update_DesktopResize: + IFCALL(proxy->DesktopResize, msg->context); + break; + + case Update_BitmapUpdate: + IFCALL(proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); + break; + + case Update_Palette: + IFCALL(proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); + break; + + case Update_PlaySound: + IFCALL(proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*) msg->wParam); + break; + + case Update_RefreshRect: + IFCALL(proxy->RefreshRect, msg->context, + (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + break; + + case Update_SuppressOutput: + IFCALL(proxy->SuppressOutput, msg->context, + (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + break; + + case Update_SurfaceCommand: + IFCALL(proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); + break; + + case Update_SurfaceBits: + IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); + break; + + case Update_SurfaceFrameMarker: + IFCALL(proxy->SurfaceFrameMarker, msg->context, (SURFACE_FRAME_MARKER*) msg->wParam); + break; + case Update_SurfaceFrameAcknowledge: IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32) (size_t) msg->wParam); break; @@ -1084,69 +1142,57 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in return status; } -int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_free_primary_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case PrimaryUpdate_DstBlt: - IFCALL(proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_PatBlt: - IFCALL(proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_ScrBlt: - IFCALL(proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_OpaqueRect: - IFCALL(proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_DrawNineGrid: - IFCALL(proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiDstBlt: - IFCALL(proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiPatBlt: - IFCALL(proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiScrBlt: - IFCALL(proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiOpaqueRect: - IFCALL(proxy->MultiOpaqueRect, msg->context, (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiDrawNineGrid: - IFCALL(proxy->MultiDrawNineGrid, msg->context, (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_LineTo: - IFCALL(proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_Polyline: - IFCALL(proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); { POLYLINE_ORDER* wParam = (POLYLINE_ORDER*) msg->wParam; @@ -1156,32 +1202,26 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_MemBlt: - IFCALL(proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_Mem3Blt: - IFCALL(proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_SaveBitmap: - IFCALL(proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_GlyphIndex: - IFCALL(proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_FastIndex: - IFCALL(proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_FastGlyph: - IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); { FAST_GLYPH_ORDER* wParam = (FAST_GLYPH_ORDER*) msg->wParam; if (wParam->glyphData.aj) @@ -1191,7 +1231,6 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_PolygonSC: - IFCALL(proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); { POLYGON_SC_ORDER* wParam = (POLYGON_SC_ORDER*) msg->wParam; @@ -1201,7 +1240,6 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_PolygonCB: - IFCALL(proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); { POLYGON_CB_ORDER* wParam = (POLYGON_CB_ORDER*) msg->wParam; @@ -1211,12 +1249,10 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_EllipseSC: - IFCALL(proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_EllipseCB: - IFCALL(proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); free(msg->wParam); break; @@ -1228,14 +1264,116 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case PrimaryUpdate_DstBlt: + IFCALL(proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PatBlt: + IFCALL(proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_ScrBlt: + IFCALL(proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_OpaqueRect: + IFCALL(proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_DrawNineGrid: + IFCALL(proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiDstBlt: + IFCALL(proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiPatBlt: + IFCALL(proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiScrBlt: + IFCALL(proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiOpaqueRect: + IFCALL(proxy->MultiOpaqueRect, msg->context, (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiDrawNineGrid: + IFCALL(proxy->MultiDrawNineGrid, msg->context, (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_LineTo: + IFCALL(proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_Polyline: + IFCALL(proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MemBlt: + IFCALL(proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_Mem3Blt: + IFCALL(proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_SaveBitmap: + IFCALL(proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_GlyphIndex: + IFCALL(proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_FastIndex: + IFCALL(proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_FastGlyph: + IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PolygonSC: + IFCALL(proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PolygonCB: + IFCALL(proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_EllipseSC: + IFCALL(proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_EllipseCB: + IFCALL(proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_secondary_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case SecondaryUpdate_CacheBitmap: - IFCALL(proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); { CACHE_BITMAP_ORDER* wParam = (CACHE_BITMAP_ORDER*) msg->wParam; @@ -1245,7 +1383,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBitmapV2: - IFCALL(proxy->CacheBitmapV2, msg->context, (CACHE_BITMAP_V2_ORDER*) msg->wParam); { CACHE_BITMAP_V2_ORDER* wParam = (CACHE_BITMAP_V2_ORDER*) msg->wParam; @@ -1255,7 +1392,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBitmapV3: - IFCALL(proxy->CacheBitmapV3, msg->context, (CACHE_BITMAP_V3_ORDER*) msg->wParam); { CACHE_BITMAP_V3_ORDER* wParam = (CACHE_BITMAP_V3_ORDER*) msg->wParam; @@ -1265,7 +1401,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheColorTable: - IFCALL(proxy->CacheColorTable, msg->context, (CACHE_COLOR_TABLE_ORDER*) msg->wParam); { CACHE_COLOR_TABLE_ORDER* wParam = (CACHE_COLOR_TABLE_ORDER*) msg->wParam; free(wParam); @@ -1273,7 +1408,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheGlyph: - IFCALL(proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); { CACHE_GLYPH_ORDER* wParam = (CACHE_GLYPH_ORDER*) msg->wParam; free(wParam); @@ -1281,7 +1415,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheGlyphV2: - IFCALL(proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); { CACHE_GLYPH_V2_ORDER* wParam = (CACHE_GLYPH_V2_ORDER*) msg->wParam; free(wParam); @@ -1289,7 +1422,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBrush: - IFCALL(proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); { CACHE_BRUSH_ORDER* wParam = (CACHE_BRUSH_ORDER*) msg->wParam; free(wParam); @@ -1304,14 +1436,56 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag return status; } -int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case SecondaryUpdate_CacheBitmap: + IFCALL(proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBitmapV2: + IFCALL(proxy->CacheBitmapV2, msg->context, (CACHE_BITMAP_V2_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBitmapV3: + IFCALL(proxy->CacheBitmapV3, msg->context, (CACHE_BITMAP_V3_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheColorTable: + IFCALL(proxy->CacheColorTable, msg->context, (CACHE_COLOR_TABLE_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheGlyph: + IFCALL(proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheGlyphV2: + IFCALL(proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBrush: + IFCALL(proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_altsec_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case AltSecUpdate_CreateOffscreenBitmap: - IFCALL(proxy->CreateOffscreenBitmap, msg->context, (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); { CREATE_OFFSCREEN_BITMAP_ORDER* wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam; @@ -1321,57 +1495,46 @@ int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* break; case AltSecUpdate_SwitchSurface: - IFCALL(proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_CreateNineGridBitmap: - IFCALL(proxy->CreateNineGridBitmap, msg->context, (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_FrameMarker: - IFCALL(proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_StreamBitmapFirst: - IFCALL(proxy->StreamBitmapFirst, msg->context, (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_StreamBitmapNext: - IFCALL(proxy->StreamBitmapNext, msg->context, (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusFirst: - IFCALL(proxy->DrawGdiPlusFirst, msg->context, (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusNext: - IFCALL(proxy->DrawGdiPlusNext, msg->context, (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusEnd: - IFCALL(proxy->DrawGdiPlusEnd, msg->context, (DRAW_GDIPLUS_END_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheFirst: - IFCALL(proxy->DrawGdiPlusCacheFirst, msg->context, (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheNext: - IFCALL(proxy->DrawGdiPlusCacheNext, msg->context, (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheEnd: - IFCALL(proxy->DrawGdiPlusCacheEnd, msg->context, (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); free(msg->wParam); break; @@ -1383,22 +1546,81 @@ int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case AltSecUpdate_CreateOffscreenBitmap: + IFCALL(proxy->CreateOffscreenBitmap, msg->context, (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); + break; + + case AltSecUpdate_SwitchSurface: + IFCALL(proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); + break; + + case AltSecUpdate_CreateNineGridBitmap: + IFCALL(proxy->CreateNineGridBitmap, msg->context, (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); + break; + + case AltSecUpdate_FrameMarker: + IFCALL(proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); + break; + + case AltSecUpdate_StreamBitmapFirst: + IFCALL(proxy->StreamBitmapFirst, msg->context, (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_StreamBitmapNext: + IFCALL(proxy->StreamBitmapNext, msg->context, (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusFirst: + IFCALL(proxy->DrawGdiPlusFirst, msg->context, (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusNext: + IFCALL(proxy->DrawGdiPlusNext, msg->context, (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusEnd: + IFCALL(proxy->DrawGdiPlusEnd, msg->context, (DRAW_GDIPLUS_END_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheFirst: + IFCALL(proxy->DrawGdiPlusCacheFirst, msg->context, (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheNext: + IFCALL(proxy->DrawGdiPlusCacheNext, msg->context, (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheEnd: + IFCALL(proxy->DrawGdiPlusCacheEnd, msg->context, (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_window_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case WindowUpdate_WindowCreate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_WindowUpdate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; @@ -1408,8 +1630,6 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*) msg->wParam; WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*) msg->lParam; - IFCALL(proxy->WindowIcon, msg->context, orderInfo, windowIcon); - if (windowIcon->iconInfo->cbBitsColor > 0) { free(windowIcon->iconInfo->bitsColor); @@ -1431,39 +1651,29 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* break; case WindowUpdate_WindowCachedIcon: - IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_CACHED_ICON_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_WindowDelete: - IFCALL(proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; case WindowUpdate_NotifyIconCreate: - IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_NotifyIconUpdate: - IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_NotifyIconDelete: - IFCALL(proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; case WindowUpdate_MonitoredDesktop: - IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (MONITORED_DESKTOP_ORDER*) msg->lParam); { MONITORED_DESKTOP_ORDER* lParam = (MONITORED_DESKTOP_ORDER*) msg->lParam; @@ -1475,7 +1685,6 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* break; case WindowUpdate_NonMonitoredDesktop: - IFCALL(proxy->NonMonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; @@ -1487,24 +1696,85 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { int status = 0; switch (type) { - case PointerUpdate_PointerPosition: - IFCALL(proxy->PointerPosition, msg->context, (POINTER_POSITION_UPDATE*) msg->wParam); - free(msg->wParam); + case WindowUpdate_WindowCreate: + IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); break; + case WindowUpdate_WindowUpdate: + IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); + break; + + case WindowUpdate_WindowIcon: + { + WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*) msg->wParam; + WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*) msg->lParam; + + IFCALL(proxy->WindowIcon, msg->context, orderInfo, windowIcon); + } + break; + + case WindowUpdate_WindowCachedIcon: + IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_CACHED_ICON_ORDER*) msg->lParam); + break; + + case WindowUpdate_WindowDelete: + IFCALL(proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + case WindowUpdate_NotifyIconCreate: + IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + break; + + case WindowUpdate_NotifyIconUpdate: + IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + break; + + case WindowUpdate_NotifyIconDelete: + IFCALL(proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + case WindowUpdate_MonitoredDesktop: + IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (MONITORED_DESKTOP_ORDER*) msg->lParam); + break; + + case WindowUpdate_NonMonitoredDesktop: + IFCALL(proxy->NonMonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +int update_message_free_pointer_update_class(wMessage* msg, int type) +{ + int status = 0; + + switch(type) + { + case PointerUpdate_PointerPosition: case PointerUpdate_PointerSystem: - IFCALL(proxy->PointerSystem, msg->context, (POINTER_SYSTEM_UPDATE*) msg->wParam); + case PointerUpdate_PointerCached: free(msg->wParam); break; case PointerUpdate_PointerColor: - IFCALL(proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); { POINTER_COLOR_UPDATE* wParam = (POINTER_COLOR_UPDATE*) msg->wParam; @@ -1513,9 +1783,8 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* free(wParam); } break; - + case PointerUpdate_PointerNew: - IFCALL(proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); { POINTER_NEW_UPDATE* wParam = (POINTER_NEW_UPDATE*) msg->wParam; @@ -1524,10 +1793,38 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* free(wParam); } break; + default: + status = -1; + break; + } + + return status; +} + +static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case PointerUpdate_PointerPosition: + IFCALL(proxy->PointerPosition, msg->context, (POINTER_POSITION_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerSystem: + IFCALL(proxy->PointerSystem, msg->context, (POINTER_SYSTEM_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerColor: + IFCALL(proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerNew: + IFCALL(proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); + break; case PointerUpdate_PointerCached: IFCALL(proxy->PointerCached, msg->context, (POINTER_CACHED_UPDATE*) msg->wParam); - free(msg->wParam); break; default: @@ -1538,7 +1835,48 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int update_message_free_class(wMessage*msg, int msgClass, int msgType) +{ + int status = 0; + + switch (msgClass) + { + case Update_Class: + status = update_message_free_update_class(msg, msgType); + break; + + case PrimaryUpdate_Class: + status = update_message_free_primary_update_class(msg, msgType); + break; + + case SecondaryUpdate_Class: + status = update_message_free_secondary_update_class(msg, msgType); + break; + + case AltSecUpdate_Class: + status = update_message_free_altsec_update_class(msg, msgType); + break; + + case WindowUpdate_Class: + status = update_message_free_window_update_class(msg, msgType); + break; + + case PointerUpdate_Class: + status = update_message_free_pointer_update_class(msg, msgType); + break; + + default: + status = -1; + break; + } + + if (status < 0) + fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType); + + return status; +} + +static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) { int status = 0; @@ -1592,6 +1930,29 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message) msgType = GetMessageType(message->id); status = update_message_process_class(update->proxy, message, msgClass, msgType); + update_message_free_class(message, msgClass, msgType); + + if (status < 0) + status = -1; + + return 1; +} + +int update_message_queue_free_message(wMessage *message) +{ + int status; + int msgClass; + int msgType; + + assert(message); + + if (message->id == WMQ_QUIT) + return 0; + + msgClass = GetMessageClass(message->id); + msgType = GetMessageType(message->id); + + status = update_message_free_class(message, msgClass, msgType); if (status < 0) status = -1; @@ -1860,8 +2221,36 @@ static void input_message_ExtendedMouseEvent(rdpInput* input, UINT16 flags, UINT } /* Event Queue */ +static int input_message_free_input_class(wMessage* msg, int type) +{ + int status = 0; -int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int type) + switch (type) + { + case Input_SynchronizeEvent: + break; + + case Input_KeyboardEvent: + break; + + case Input_UnicodeKeyboardEvent: + break; + + case Input_MouseEvent: + break; + + case Input_ExtendedMouseEvent: + break; + + default: + status = -1; + break; + } + + return status; +} + +static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int type) { int status = 0; @@ -1913,7 +2302,28 @@ int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int t return status; } -int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int input_message_free_class(wMessage* msg, int msgClass, int msgType) +{ + int status = 0; + + switch (msgClass) + { + case Input_Class: + status = input_message_free_input_class(msg, msgType); + break; + + default: + status = -1; + break; + } + + if (status < 0) + fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType); + + return status; +} + +static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, int msgType) { int status = 0; @@ -1934,6 +2344,26 @@ int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClas return status; } +int input_message_queue_free_message(wMessage* message) +{ + int status; + int msgClass; + int msgType; + + if (message->id == WMQ_QUIT) + return 0; + + msgClass = GetMessageClass(message->id); + msgType = GetMessageType(message->id); + + status = input_message_free_class(message, msgClass, msgType); + + if (status < 0) + return -1; + + return 1; +} + int input_message_queue_process_message(rdpInput* input, wMessage* message) { int status; @@ -1947,6 +2377,7 @@ int input_message_queue_process_message(rdpInput* input, wMessage* message) msgType = GetMessageType(message->id); status = input_message_process_class(input->proxy, message, msgClass, msgType); + input_message_free_class(message, msgClass, msgType); if (status < 0) return -1; From 7ae5c8eeefe148b031591e9c4d34f298ac0de538 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:03:48 +0100 Subject: [PATCH 32/40] Added functions to free input and update queue messages. --- libfreerdp/core/message.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/core/message.h b/libfreerdp/core/message.h index 99d79b9d5..fad0e15ce 100644 --- a/libfreerdp/core/message.h +++ b/libfreerdp/core/message.h @@ -123,6 +123,8 @@ struct rdp_update_proxy }; int update_message_queue_process_message(rdpUpdate* update, wMessage* message); +int update_message_queue_free_message(wMessage* message); + int update_message_queue_process_pending_messages(rdpUpdate* update); rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update); @@ -148,6 +150,7 @@ struct rdp_input_proxy }; int input_message_queue_process_message(rdpInput* input, wMessage* message); +int input_message_queue_free_message(wMessage* message); int input_message_queue_process_pending_messages(rdpInput* input); rdpInputProxy* input_message_proxy_new(rdpInput* input); From 0ac908ba200dfe2479debcdc225500a3b2e38fda Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:04:26 +0100 Subject: [PATCH 33/40] Added assertions to detect invalid call sequences of and . --- libfreerdp/core/transport.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 70ff6c069..f47cf4b59 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -1051,6 +1051,12 @@ void transport_free(rdpTransport* transport) { if (transport) { + if (transport->async) + { + assert(!transport->thread); + assert(!transport->stopEvent); + } + if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); From 7cb0a70fd6c87e373b1484118907367223794175 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:05:15 +0100 Subject: [PATCH 34/40] Added custom message resource free to update message queue. --- libfreerdp/core/update.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 49077aec6..a4cebdf08 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -1544,8 +1544,16 @@ int update_process_messages(rdpUpdate* update) return update_message_queue_process_pending_messages(update); } +static void update_free_queued_message(void *obj) +{ + wMessage *msg = (wMessage*)obj; + + update_message_queue_free_message(msg); +} + rdpUpdate* update_new(rdpRdp* rdp) { + const wObject cb = { .fnObjectFree = update_free_queued_message }; rdpUpdate* update; update = (rdpUpdate*) malloc(sizeof(rdpUpdate)); @@ -1587,7 +1595,7 @@ rdpUpdate* update_new(rdpRdp* rdp) update->initialState = TRUE; - update->queue = MessageQueue_New(); + update->queue = MessageQueue_New(&cb); } return update; From 25e7682e02e99f07d0af9212d6463b882365afd6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:10:08 +0100 Subject: [PATCH 35/40] Added and argument for custom handlers to . --- winpr/include/winpr/collections.h | 40 ++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 91d74e130..f37c4e5da 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -402,6 +402,8 @@ struct _wMessageQueue wMessage* array; CRITICAL_SECTION lock; HANDLE event; + + wObject object; }; typedef struct _wMessageQueue wMessageQueue; @@ -418,7 +420,43 @@ WINPR_API void MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode); WINPR_API int MessageQueue_Get(wMessageQueue* queue, wMessage* message); WINPR_API int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove); -WINPR_API wMessageQueue* MessageQueue_New(void); +/*! \brief Clears all elements in a message queue. + * + * \note If dynamically allocated data is part of the messages, + * a custom cleanup handler must be passed in the 'callback' + * argument for MessageQueue_New. + * + * \param queue The queue to clear. + * + * \return 0 in case of success or a error code otherwise. + */ +WINPR_API int MessageQueue_Clear(wMessageQueue *queue); + +/*! \brief Creates a new message queue. + * If 'callback' is null, no custom cleanup will be done + * on message queue deallocation. + * If the 'callback' argument contains valid uninit or + * free functions those will be called by + * 'MessageQueue_Clear'. + * + * \param callback a pointer to custom initialization / cleanup functions. + * Can be NULL if not used. + * + * \return A pointer to a newly allocated MessageQueue or NULL. + */ +WINPR_API wMessageQueue* MessageQueue_New(const wObject *callback); + +/*! \brief Frees resources allocated by a message queue. + * This function will only free resources allocated + * internally. + * + * \note Empty the queue before calling this function with + * 'MessageQueue_Clear', 'MessageQueue_Get' or + * 'MessageQueue_Peek' to free all resources allocated + * by the message contained. + * + * \param queue A pointer to the queue to be freed. + */ WINPR_API void MessageQueue_Free(wMessageQueue* queue); /* Message Pipe */ From 09d219b8d6b74585ccc71314cf7735206cde80e5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:10:41 +0100 Subject: [PATCH 36/40] Added and custom handler argument to . --- .../libwinpr/utils/collections/MessageQueue.c | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/winpr/libwinpr/utils/collections/MessageQueue.c b/winpr/libwinpr/utils/collections/MessageQueue.c index e7b8a5e84..b4dc6c295 100644 --- a/winpr/libwinpr/utils/collections/MessageQueue.c +++ b/winpr/libwinpr/utils/collections/MessageQueue.c @@ -178,7 +178,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove) * Construction, Destruction */ -wMessageQueue* MessageQueue_New() +wMessageQueue* MessageQueue_New(const wObject *callback) { wMessageQueue* queue = NULL; @@ -196,6 +196,11 @@ wMessageQueue* MessageQueue_New() InitializeCriticalSectionAndSpinCount(&queue->lock, 4000); queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (callback) + queue->object = *callback; + else + ZeroMemory(&queue->object, sizeof(queue->object)); } return queue; @@ -209,3 +214,32 @@ void MessageQueue_Free(wMessageQueue* queue) free(queue->array); free(queue); } + +int MessageQueue_Clear(wMessageQueue *queue) +{ + int status = 0; + + EnterCriticalSection(&queue->lock); + + while(queue->size > 0) + { + wMessage *msg = &(queue->array[queue->head]); + + /* Free resources of message. */ + if (queue->object.fnObjectUninit) + queue->object.fnObjectUninit(msg); + if (queue->object.fnObjectFree) + queue->object.fnObjectFree(msg); + + ZeroMemory(msg, sizeof(wMessage)); + + queue->head = (queue->head + 1) % queue->capacity; + queue->size--; + } + ResetEvent(queue->event); + + LeaveCriticalSection(&queue->lock); + + return status; +} + From 638d26569f82e598dc9dc0455b6196fd34783ae3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:11:39 +0100 Subject: [PATCH 37/40] Updated MessagePipe to new MessageQueue API. --- winpr/libwinpr/utils/collections/MessagePipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/utils/collections/MessagePipe.c b/winpr/libwinpr/utils/collections/MessagePipe.c index 6be37e7ed..a7e0eade9 100644 --- a/winpr/libwinpr/utils/collections/MessagePipe.c +++ b/winpr/libwinpr/utils/collections/MessagePipe.c @@ -54,8 +54,8 @@ wMessagePipe* MessagePipe_New() if (pipe) { - pipe->In = MessageQueue_New(); - pipe->Out = MessageQueue_New(); + pipe->In = MessageQueue_New(NULL); + pipe->Out = MessageQueue_New(NULL); } return pipe; From 04854b292ce364e9dbd0301adbb85ee2beb2482f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:18:18 +0100 Subject: [PATCH 38/40] Using new API for MessageQueue. --- channels/drive/client/drive_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index ab0cd4e39..e81992764 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -661,7 +661,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* drive->files = ListDictionary_New(TRUE); ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free; - drive->IrpQueue = MessageQueue_New(); + drive->IrpQueue = MessageQueue_New(NULL); drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive); From 8d6f49c01a33dda282eaf0eb80593980272c611e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:18:35 +0100 Subject: [PATCH 39/40] Using new API for message queue. --- channels/parallel/client/parallel_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index ae4c5a4dc..59e201c27 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -327,7 +327,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) parallel->path = path; - parallel->queue = MessageQueue_New(); + parallel->queue = MessageQueue_New(NULL); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel); From 4a1e9d2e4ea128851e55724e742930da6ac87b31 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Nov 2013 15:18:45 +0100 Subject: [PATCH 40/40] Using new API for message queue. --- winpr/libwinpr/utils/test/TestMessageQueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/utils/test/TestMessageQueue.c b/winpr/libwinpr/utils/test/TestMessageQueue.c index 2185cab14..10a5942e6 100644 --- a/winpr/libwinpr/utils/test/TestMessageQueue.c +++ b/winpr/libwinpr/utils/test/TestMessageQueue.c @@ -29,7 +29,7 @@ int TestMessageQueue(int argc, char* argv[]) HANDLE thread; wMessageQueue* queue; - queue = MessageQueue_New(); + queue = MessageQueue_New(NULL); thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) message_queue_consumer_thread, (void*) queue, 0, NULL);