diff --git a/CMakeLists.txt b/CMakeLists.txt index 766d8ac2b..45c9e1baf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,13 +58,23 @@ if (FREERDP_VERSION_SUFFIX) else() set(FREERDP_VERSION_FULL "${FREERDP_VERSION}") endif() + +# Allow to search the host machine for git +if(ANDROID) + SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, BOTH) +endif(ANDROID) include(GetGitRevisionDescription) +if(ANDROID) + SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, ONLY) +endif(ANDROID) + git_describe(GIT_REVISION --match "[0-9]*" --abbrev=4 --tags --always) message(STATUS "Git Revision ${GIT_REVISION}") # Turn on solution folders (2.8.4+) set_property(GLOBAL PROPERTY USE_FOLDERS ON) + # Default to release build type if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") @@ -98,8 +108,10 @@ endif() # Compiler-specific flags if(CMAKE_COMPILER_IS_GNUCC) - if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT ANDROID) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "i686") + if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") + endif() endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") CHECK_C_COMPILER_FLAG (-Wno-unused-result Wno-unused-result) @@ -181,6 +193,15 @@ if(APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4") endif() +# Android +if(ANDROID) + if (NOT FREERDP_ANDROID_EXTERNAL_SSL_PATH) + message(STATUS "FREERDP_ANDROID_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)") + endif() + set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_ANDROID_EXTERNAL_SSL_PATH}) + set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/libs/${ANDROID_ABI}) +endif() + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) if(NOT ANDROID) find_package(Threads REQUIRED) @@ -484,4 +505,13 @@ set(CPACK_COMPONENT_GROUP_RUNTIME_DESCRIPTION "Runtime") set(CPACK_COMPONENT_GROUP_APPLICATIONS_DESCRIPTION "Applications") set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "Development") +# Workaround to remove c++ compiler macros and defines for Eclipse. +# If c++ macros/defines are set __cplusplus is also set which causes +# problems when compiling freerdp/jni. To prevent this problem +# we set the macros to "". +if (ANDROID AND CMAKE_EXTRA_GENERATOR STREQUAL "Eclipse CDT4") + set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "") + message(STATUS "Disabled CXX system defines for eclipse (workaround).") +endif() + include(CPack) diff --git a/client/.gitignore b/client/.gitignore index 0b5b69245..76a6d8d29 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1,2 +1 @@ iOS -Android diff --git a/client/Android/.classpath b/client/Android/.classpath new file mode 100644 index 000000000..a4763d1ee --- /dev/null +++ b/client/Android/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/client/Android/.gitignore b/client/Android/.gitignore new file mode 100644 index 000000000..1eee223a1 --- /dev/null +++ b/client/Android/.gitignore @@ -0,0 +1,10 @@ +# Ignore directories +bin/ +obj/ +gen/ +jni/external/* +!libs +libs/armeabi* +AndroidManifest.xml +local.properties +!.project diff --git a/client/Android/.project b/client/Android/.project new file mode 100644 index 000000000..335291e03 --- /dev/null +++ b/client/Android/.project @@ -0,0 +1,33 @@ + + + aFreeRDP + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/client/Android/AndroidManifest.xml.cmake b/client/Android/AndroidManifest.xml.cmake new file mode 100644 index 000000000..bf9d7ac9b --- /dev/null +++ b/client/Android/AndroidManifest.xml.cmake @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/Android/CMakeLists.txt b/client/Android/CMakeLists.txt new file mode 100644 index 000000000..bf543ed2e --- /dev/null +++ b/client/Android/CMakeLists.txt @@ -0,0 +1,64 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# Android Client +# +# Copyright 2012 Marc-Andre Moreau +# Copyright 2013 Bernhard Miklautz +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(ANDROID_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(ANDROID_PACKAGE_NAME "aFreeRDP") + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml @ONLY) + +if (ANDROID_SDK) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local.properties.cmake ${CMAKE_CURRENT_SOURCE_DIR}/local.properties @ONLY) +endif() + +add_subdirectory(jni) + + +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)") + endif() + + # And isn't shiped with the android ndk/sdk so + # we need to find it on the local machine + SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, BOTH) + find_program(ANT_COMMAND ant) + SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER, ONLY) + + 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") + set(APK "${ANDROID_SOURCE_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") + else() + set(ANDROID_BUILD_TYPE "release") + set(APK "${ANDROID_SOURCE_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_SOURCE_DIR}" + MAIN_DEPENDENCY AndroidManifest.xml + DEPENDS freerdp-android local.properties + ) + add_custom_target(android-package ALL SOURCES "${APK}") + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin") +endif() diff --git a/client/Android/assets/about_page/FreeRDP_Logo.png b/client/Android/assets/about_page/FreeRDP_Logo.png new file mode 100644 index 000000000..3b2d02f1d Binary files /dev/null and b/client/Android/assets/about_page/FreeRDP_Logo.png differ diff --git a/client/Android/assets/about_page/about.html b/client/Android/assets/about_page/about.html new file mode 100644 index 000000000..99d5e1cc5 --- /dev/null +++ b/client/Android/assets/about_page/about.html @@ -0,0 +1,202 @@ + + + + + + + + + + + + + +
+ + +
+

aFreeRDP
Remote Desktop Client

+
+

+

+
+ + aFreeRDP is an open source client + capable of natively using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.
+ + +
+

Version Information

+

+ + + + + +
aFreeRDP Version %1$s
System Version %2$s
Model %3$s
+

+
+
+ +
+

Credits

+
+ + aFreeRDP is a part of FreeRDP + +
+ +
+
+

License

+
+ + This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0. + You can obtain an online version of the License from http://mozilla.org/MPL/2.0/. +

+

+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +

+

+ A copy of the product's source code can be obtained from the FreeRDP GitHub repository at https://github.com/FreeRDP/FreeRDP.
+

+
+ + diff --git a/client/Android/assets/about_page/about_phone.html b/client/Android/assets/about_page/about_phone.html new file mode 100644 index 000000000..3eafceb4e --- /dev/null +++ b/client/Android/assets/about_page/about_phone.html @@ -0,0 +1,200 @@ + + + + + + + + + + + + + +
+ + +
+

aFreeRDP
Remote Desktop Client

+
+

+

+
+ + aFreeRDP is an open source client for Windows Remote Services using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.
+ + +
+

Version Information

+

+ + + + + +
aFreerdp Version %1$s
System Version %2$s
Model %3$s
+

+
+
+ +
+

Credits

+
+ aFreeRDP is part of FreeRDP +
+
+
+

License

+
+ + This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0. + You can obtain an online version of the License from http://mozilla.org/MPL/2.0/. +

+

+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +

+

+ A copy of the product's source code can be obtained from the FreeRDP GitHub repository at https://github.com/FreeRDP/FreeRDP.
+

+
+ + diff --git a/client/Android/assets/about_page/back.jpg b/client/Android/assets/about_page/back.jpg new file mode 100644 index 000000000..3bf3455bf Binary files /dev/null and b/client/Android/assets/about_page/back.jpg differ diff --git a/client/Android/assets/about_page/background_transparent.png b/client/Android/assets/about_page/background_transparent.png new file mode 100644 index 000000000..0eba5b5d2 Binary files /dev/null and b/client/Android/assets/about_page/background_transparent.png differ diff --git a/client/Android/assets/help_page/back.jpg b/client/Android/assets/help_page/back.jpg new file mode 100644 index 000000000..3bf3455bf Binary files /dev/null and b/client/Android/assets/help_page/back.jpg differ diff --git a/client/Android/assets/help_page/gestures.html b/client/Android/assets/help_page/gestures.html new file mode 100644 index 000000000..858387773 --- /dev/null +++ b/client/Android/assets/help_page/gestures.html @@ -0,0 +1,159 @@ + + + + + + + +Help + + + + + + + + +
+
+ + +
+

Gestures

+

+aFreeRDP is designed for touch sensitive devices. +These gestures let you do the most usual operations with your fingers.

+

+ +
+
+ + + diff --git a/client/Android/assets/help_page/gestures.png b/client/Android/assets/help_page/gestures.png new file mode 100644 index 000000000..e49a45b8f Binary files /dev/null and b/client/Android/assets/help_page/gestures.png differ diff --git a/client/Android/assets/help_page/gestures_phone.html b/client/Android/assets/help_page/gestures_phone.html new file mode 100644 index 000000000..156d7c94d --- /dev/null +++ b/client/Android/assets/help_page/gestures_phone.html @@ -0,0 +1,159 @@ + + + + + + + +Help + + + + + + + + + + + +
+
+ + +
+

Gestures

+

+aFreeRDP is designed for touch sensitive devices. +These gestures let you do the most usual operations with your fingers.

+

+ + +
+
+ + + diff --git a/client/Android/assets/help_page/gestures_phone.png b/client/Android/assets/help_page/gestures_phone.png new file mode 100644 index 000000000..1b90a1f65 Binary files /dev/null and b/client/Android/assets/help_page/gestures_phone.png differ diff --git a/client/Android/assets/help_page/nav_gestures.png b/client/Android/assets/help_page/nav_gestures.png new file mode 100644 index 000000000..ab1b36fba Binary files /dev/null and b/client/Android/assets/help_page/nav_gestures.png differ diff --git a/client/Android/assets/help_page/nav_toolbar.png b/client/Android/assets/help_page/nav_toolbar.png new file mode 100644 index 000000000..703c0013a Binary files /dev/null and b/client/Android/assets/help_page/nav_toolbar.png differ diff --git a/client/Android/assets/help_page/nav_touch_pointer.png b/client/Android/assets/help_page/nav_touch_pointer.png new file mode 100644 index 000000000..30e04568e Binary files /dev/null and b/client/Android/assets/help_page/nav_touch_pointer.png differ diff --git a/client/Android/assets/help_page/toolbar.html b/client/Android/assets/help_page/toolbar.html new file mode 100644 index 000000000..e9ea27ab5 --- /dev/null +++ b/client/Android/assets/help_page/toolbar.html @@ -0,0 +1,178 @@ + + + + + + + +Help + + + + + + + + + + + +
+ + +
+ + + + +
+ +

Toolbar

+

+With the toolbar you'll be able to display and hide the main tools in your session. This allows together with the touch pointer and the gestures an intuitiv workflow for remote computing on touch sensitive screens. +

+

+ +
+
+

Keyboards

+Display/hide the default keyboard as well as an extended keyboard with function keys
+
+

Touch Pointer

+Display/hide the gesture controlled cursor
+
+

Disconnect

+Disconnect your current session. Please be aware that a disconnect is not the same as a log out.
+ +
+ + +
+ + diff --git a/client/Android/assets/help_page/toolbar.png b/client/Android/assets/help_page/toolbar.png new file mode 100644 index 000000000..10c23b62b Binary files /dev/null and b/client/Android/assets/help_page/toolbar.png differ diff --git a/client/Android/assets/help_page/toolbar_phone.html b/client/Android/assets/help_page/toolbar_phone.html new file mode 100644 index 000000000..f810d4b08 --- /dev/null +++ b/client/Android/assets/help_page/toolbar_phone.html @@ -0,0 +1,176 @@ + + + + + + + +Help + + + + + + + + + + + +
+ + +
+ + + + +
+ +

Toolbar

+

+With the toolbar you'll be able to display and hide the main tools in your session. This allows together with the touch pointer and the gestures an intuitiv workflow for remote computing on touch sensitive screens. +

+

+ +
+
+

Keyboards

+Display/hide the default keyboard as well as an extended keyboard with function keys
+
+

Touch Pointer

+Display/hide the gesture controlled cursor
+
+

Disconnect

+Disconnect your current session. Please be aware that a disconnect is not the same as a log out.
+ +
+ + +
+ + diff --git a/client/Android/assets/help_page/toolbar_phone.png b/client/Android/assets/help_page/toolbar_phone.png new file mode 100644 index 000000000..a01279ce0 Binary files /dev/null and b/client/Android/assets/help_page/toolbar_phone.png differ diff --git a/client/Android/assets/help_page/touch_pointer.html b/client/Android/assets/help_page/touch_pointer.html new file mode 100644 index 000000000..8072a1bac --- /dev/null +++ b/client/Android/assets/help_page/touch_pointer.html @@ -0,0 +1,164 @@ + + + + + + + +Help + + + + + + + + + + + +
+ + +
+ + + + +
+ +

Touch Pointer

+

+

+ +
+
+ + + diff --git a/client/Android/assets/help_page/touch_pointer.png b/client/Android/assets/help_page/touch_pointer.png new file mode 100644 index 000000000..f06e3889f Binary files /dev/null and b/client/Android/assets/help_page/touch_pointer.png differ diff --git a/client/Android/assets/help_page/touch_pointer_phone.html b/client/Android/assets/help_page/touch_pointer_phone.html new file mode 100644 index 000000000..89d2e8de0 --- /dev/null +++ b/client/Android/assets/help_page/touch_pointer_phone.html @@ -0,0 +1,161 @@ + + + + + + + +Help + + + + + + + + + + + +
+ + +
+ + + + +
+ +

Touch Pointer

+

+

+
+ +
+
+ + + diff --git a/client/Android/assets/help_page/touch_pointer_phone.png b/client/Android/assets/help_page/touch_pointer_phone.png new file mode 100644 index 000000000..168749fd0 Binary files /dev/null and b/client/Android/assets/help_page/touch_pointer_phone.png differ diff --git a/client/Android/assets/welcome_page/1.png b/client/Android/assets/welcome_page/1.png new file mode 100644 index 000000000..30025d81a Binary files /dev/null and b/client/Android/assets/welcome_page/1.png differ diff --git a/client/Android/assets/welcome_page/2.png b/client/Android/assets/welcome_page/2.png new file mode 100644 index 000000000..43d3a7fe5 Binary files /dev/null and b/client/Android/assets/welcome_page/2.png differ diff --git a/client/Android/assets/welcome_page/back.jpg b/client/Android/assets/welcome_page/back.jpg new file mode 100644 index 000000000..3bf3455bf Binary files /dev/null and b/client/Android/assets/welcome_page/back.jpg differ diff --git a/client/Android/assets/welcome_page/new_connection.png b/client/Android/assets/welcome_page/new_connection.png new file mode 100644 index 000000000..dede2a28a Binary files /dev/null and b/client/Android/assets/welcome_page/new_connection.png differ diff --git a/client/Android/assets/welcome_page/welcome.html b/client/Android/assets/welcome_page/welcome.html new file mode 100644 index 000000000..70df41a14 --- /dev/null +++ b/client/Android/assets/welcome_page/welcome.html @@ -0,0 +1,128 @@ + + + + + + + + +
+
+
+

New Connection

+
+ You can specify your own connection settings - just hit the button below or choose "New Connection" from the application menu.
+
+
+
+
+
+ + diff --git a/client/Android/assets/welcome_page/welcome_phone.html b/client/Android/assets/welcome_page/welcome_phone.html new file mode 100644 index 000000000..fd5ddc434 --- /dev/null +++ b/client/Android/assets/welcome_page/welcome_phone.html @@ -0,0 +1,121 @@ + + + + + + + + +
+
+
+

New Connection

+
+ You can specify your own connection settings - just hit the button below or choose "New Connection" from the application menu.
+
+
+
+
+
+ + diff --git a/client/Android/build.xml b/client/Android/build.xml new file mode 100644 index 000000000..1a230ae00 --- /dev/null +++ b/client/Android/build.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/Android/jni/CMakeLists.txt b/client/Android/jni/CMakeLists.txt new file mode 100644 index 000000000..58d96f6c7 --- /dev/null +++ b/client/Android/jni/CMakeLists.txt @@ -0,0 +1,65 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# Android Client +# +# Copyright 2012 Marc-Andre Moreau +# Copyright 2013 Bernhard Miklautz +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "freerdp-android") +set(MODULE_PREFIX "FREERDP_CLIENT_ANDROID") + + +include_directories(.) +include_directories(generated) + +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-pointer-sign") +endif() + +set(${MODULE_PREFIX}_SRCS + android_debug.h + android_event.c + android_event.h + android_freerdp.c + android_freerdp.h + android_jni_callback.c + android_jni_callback.h) + +set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} + generated/android_freerdp_jni.c + generated/android_freerdp_jni.h) + +add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS}) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-core freerdp-gdi freerdp-utils) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-synch) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} dl) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} log) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} jnigraphics) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ANDROID_SOURCE_DIR}/libs/${ANDROID_ABI}") + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Android") diff --git a/client/Android/jni/android_debug.h b/client/Android/jni/android_debug.h new file mode 100644 index 000000000..46892fb91 --- /dev/null +++ b/client/Android/jni/android_debug.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Debug Interface + * + * Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef FREERDP_ANDROID_DEBUG_H +#define FREERDP_ANDROID_DEBUG_H + +#ifdef HAVE_CONFIG_H +#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__) + +#ifdef WITH_DEBUG_ANDROID_JNI +#define DEBUG_ANDROID(fmt, ...) DEBUG_ANDROID_PRINT("DBG %s (%d): ", fmt, ## __VA_ARGS__) +#else +#define DEBUG_ANDROID(fmt, ...) DEBUG_ANDROID_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* FREERDP_ANDROID_DEBUG_H */ + diff --git a/client/Android/jni/android_event.c b/client/Android/jni/android_event.c new file mode 100644 index 000000000..bb0f55bb1 --- /dev/null +++ b/client/Android/jni/android_event.c @@ -0,0 +1,289 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Event System + * + * Copyright 2010-2012 Marc-Andre Moreau + * Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "android_freerdp.h" + +int android_is_event_set(ANDROID_EVENT_QUEUE * queue) +{ + fd_set rfds; + int num_set; + struct timeval time; + + FD_ZERO(&rfds); + FD_SET(queue->pipe_fd[0], &rfds); + memset(&time, 0, sizeof(time)); + num_set = select(queue->pipe_fd[0] + 1, &rfds, 0, 0, &time); + + return (num_set == 1); +} + +void android_set_event(ANDROID_EVENT_QUEUE * queue) +{ + int length; + + length = write(queue->pipe_fd[1], "sig", 4); + + if (length != 4) + printf("android_set_event: error\n"); +} + + +void android_clear_event(ANDROID_EVENT_QUEUE * queue) +{ + int length; + + while (android_is_event_set(queue)) + { + length = read(queue->pipe_fd[0], &length, 4); + + if (length != 4) + printf("android_clear_event: error\n"); + } +} + +void android_push_event(freerdp * inst, ANDROID_EVENT* event) +{ + + androidContext* aCtx = (androidContext*)inst->context; + if (aCtx->event_queue->count >= aCtx->event_queue->size) + { + aCtx->event_queue->size = aCtx->event_queue->size * 2; + aCtx->event_queue->events = realloc((void*) aCtx->event_queue->events, aCtx->event_queue->size); + } + + aCtx->event_queue->events[(aCtx->event_queue->count)++] = event; + + android_set_event(aCtx->event_queue); +} + +ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue) +{ + ANDROID_EVENT* event; + + if (queue->count < 1) + return NULL; + + event = queue->events[0]; + + return event; +} + +ANDROID_EVENT* android_pop_event(ANDROID_EVENT_QUEUE * queue) +{ + int i; + ANDROID_EVENT* event; + + if (queue->count < 1) + return NULL; + + event = queue->events[0]; + (queue->count)--; + + for (i = 0; i < queue->count; i++) + { + queue->events[i] = queue->events[i + 1]; + } + + return event; +} + +int android_process_event(ANDROID_EVENT_QUEUE * queue, freerdp * inst) +{ + ANDROID_EVENT* event; + + while (android_peek_event(queue) != NULL) + { + event = android_pop_event(queue); + + if (event->type == EVENT_TYPE_KEY) + { + ANDROID_EVENT_KEY* key_event = (ANDROID_EVENT_KEY*) event; + inst->input->KeyboardEvent(inst->input, key_event->flags, key_event->scancode); + android_event_key_free(key_event); + } + else if (event->type == EVENT_TYPE_KEY_UNICODE) + { + ANDROID_EVENT_KEY* key_event = (ANDROID_EVENT_KEY*) event; + inst->input->UnicodeKeyboardEvent(inst->input, key_event->flags, key_event->scancode); + android_event_key_free(key_event); + } + else if (event->type == EVENT_TYPE_CURSOR) + { + ANDROID_EVENT_CURSOR* cursor_event = (ANDROID_EVENT_CURSOR*) event; + inst->input->MouseEvent(inst->input, cursor_event->flags, cursor_event->x, cursor_event->y); + android_event_cursor_free(cursor_event); + } + else if (event->type == EVENT_TYPE_DISCONNECT) + { + android_event_disconnect_free(event); + return 1; + } + } + + return 0; +} + +BOOL android_get_fds(freerdp * inst, void ** read_fds, + int * read_count, void ** write_fds, int * write_count) +{ + androidContext* aCtx = (androidContext*)inst->context; + if (aCtx->event_queue->pipe_fd[0] == -1) + return TRUE; + + read_fds[*read_count] = (void *)(long) aCtx->event_queue->pipe_fd[0]; + + (*read_count)++; + return TRUE; +} + +BOOL android_check_fds(freerdp * inst) +{ + androidContext* aCtx = (androidContext*)inst->context; + + if (aCtx->event_queue->pipe_fd[0] == -1) + return TRUE; + + if (android_is_event_set(aCtx->event_queue)) + { + android_clear_event(aCtx->event_queue); + if(android_process_event(aCtx->event_queue, inst) != 0) + return FALSE; + } + + return TRUE; +} + +ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode) +{ + ANDROID_EVENT_KEY* event; + + event = (ANDROID_EVENT_KEY*) malloc(sizeof(ANDROID_EVENT_KEY)); + memset(event, 0, sizeof(ANDROID_EVENT_KEY)); + + event->type = EVENT_TYPE_KEY; + event->flags = flags; + event->scancode = scancode; + + return event; +} + +void android_event_key_free(ANDROID_EVENT_KEY* event) +{ + if (event != NULL) + free(event); +} + +ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key) +{ + ANDROID_EVENT_KEY* event; + + event = (ANDROID_EVENT_KEY*) malloc(sizeof(ANDROID_EVENT_KEY)); + memset(event, 0, sizeof(ANDROID_EVENT_KEY)); + + event->type = EVENT_TYPE_KEY_UNICODE; + event->scancode = key; + + return event; +} + +void android_event_unicodekey_free(ANDROID_EVENT_KEY* event) +{ + if (event != NULL) + free(event); +} + +ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y) +{ + ANDROID_EVENT_CURSOR* event; + + event = (ANDROID_EVENT_CURSOR*) malloc(sizeof(ANDROID_EVENT_CURSOR)); + memset(event, 0, sizeof(ANDROID_EVENT_CURSOR)); + + event->type = EVENT_TYPE_CURSOR; + event->x = x; + event->y = y; + event->flags = flags; + + return event; +} + +void android_event_cursor_free(ANDROID_EVENT_CURSOR* event) +{ + if (event != NULL) + free(event); +} + +ANDROID_EVENT* android_event_disconnect_new() +{ + ANDROID_EVENT* event; + + event = (ANDROID_EVENT*) malloc(sizeof(ANDROID_EVENT)); + memset(event, 0, sizeof(ANDROID_EVENT)); + + event->type = EVENT_TYPE_DISCONNECT; + return event; +} + +void android_event_disconnect_free(ANDROID_EVENT* event) +{ + if (event != NULL) + free(event); +} + +void android_event_queue_init(freerdp * inst) +{ + androidContext* aCtx = (androidContext*)inst->context; + + aCtx->event_queue = (ANDROID_EVENT_QUEUE*) malloc(sizeof(ANDROID_EVENT_QUEUE)); + memset(aCtx->event_queue, 0, sizeof(ANDROID_EVENT_QUEUE)); + + aCtx->event_queue->pipe_fd[0] = -1; + aCtx->event_queue->pipe_fd[1] = -1; + + aCtx->event_queue->size = 16; + aCtx->event_queue->count = 0; + aCtx->event_queue->events = (ANDROID_EVENT**) malloc(sizeof(ANDROID_EVENT*) * aCtx->event_queue->size); + + if (pipe(aCtx->event_queue->pipe_fd) < 0) + printf("android_pre_connect: pipe failed\n"); +} + +void android_event_queue_uninit(freerdp * inst) +{ + androidContext* aCtx = (androidContext*)inst->context; + + if (aCtx->event_queue->pipe_fd[0] != -1) + { + close(aCtx->event_queue->pipe_fd[0]); + aCtx->event_queue->pipe_fd[0] = -1; + } + if (aCtx->event_queue->pipe_fd[1] != -1) + { + close(aCtx->event_queue->pipe_fd[1]); + aCtx->event_queue->pipe_fd[1] = -1; + } +} diff --git a/client/Android/jni/android_event.h b/client/Android/jni/android_event.h new file mode 100644 index 000000000..f0a373652 --- /dev/null +++ b/client/Android/jni/android_event.h @@ -0,0 +1,74 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android Event System + * + * Copyright 2010-2012 Marc-Andre Moreau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef FREERDP_ANDROID_EVENT_H +#define FREERDP_ANDROID_EVENT_H +#include + +#define EVENT_TYPE_KEY 1 +#define EVENT_TYPE_CURSOR 2 +#define EVENT_TYPE_DISCONNECT 3 +#define EVENT_TYPE_KEY_UNICODE 4 + +struct _ANDROID_EVENT +{ + int type; +}; +typedef struct _ANDROID_EVENT ANDROID_EVENT; + +struct _ANDROID_EVENT_KEY +{ + int type; + int flags; + UINT16 scancode; +}; +typedef struct _ANDROID_EVENT_KEY ANDROID_EVENT_KEY; + +struct _ANDROID_EVENT_CURSOR +{ + int type; + UINT16 flags; + UINT16 x; + UINT16 y; +}; +typedef struct _ANDROID_EVENT_CURSOR ANDROID_EVENT_CURSOR; + +struct _ANDROID_EVENT_QUEUE +{ + int size; + int count; + int pipe_fd[2]; + ANDROID_EVENT **events; +}; +typedef struct _ANDROID_EVENT_QUEUE ANDROID_EVENT_QUEUE; + +int android_is_event_set(ANDROID_EVENT_QUEUE * queue); +void android_set_event(ANDROID_EVENT_QUEUE * queue); +void android_clear_event(ANDROID_EVENT_QUEUE * queue); +void android_push_event(freerdp * inst, ANDROID_EVENT* event); +ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue); +ANDROID_EVENT* android_pop_event(ANDROID_EVENT_QUEUE * queue); +int android_process_event(ANDROID_EVENT_QUEUE * queue, freerdp * inst); +BOOL android_get_fds(freerdp * inst, void ** read_fds, + int * read_count, void ** write_fds, int * write_count); +BOOL android_check_fds(freerdp * inst); +ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode); +ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key); +ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y); +ANDROID_EVENT* android_event_disconnect_new(); +void android_event_key_free(ANDROID_EVENT_KEY* event); +void android_event_unicodekey_free(ANDROID_EVENT_KEY* event); +void android_event_cursor_free(ANDROID_EVENT_CURSOR* event); +void android_event_disconnect_free(ANDROID_EVENT* event); +void android_event_queue_init(freerdp * inst); +void android_event_queue_uninit(freerdp * inst); + +#endif /* FREERDP_ANDROID_EVENT_H */ diff --git a/client/Android/jni/android_freerdp.c b/client/Android/jni/android_freerdp.c new file mode 100644 index 000000000..6a31ebc0e --- /dev/null +++ b/client/Android/jni/android_freerdp.c @@ -0,0 +1,841 @@ +/* + Android JNI Client Layer + + Copyright 2010-2012 Marc-Andre Moreau + Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "android_freerdp.h" +#include "android_jni_callback.h" +#include "android_debug.h" + +struct thread_data +{ + freerdp* instance; +}; + + +void android_context_new(freerdp* instance, rdpContext* context) +{ + context->channels = freerdp_channels_new(); + android_event_queue_init(instance); +} + +void android_context_free(freerdp* instance, rdpContext* context) +{ + freerdp_channels_free(context->channels); + android_event_queue_uninit(instance); +} + + +void android_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->ninvalid = 0; +} + + +void android_end_paint(rdpContext* context) +{ + DEBUG_ANDROID("ui_update"); + + rdpGdi *gdi = context->gdi; + if (gdi->primary->hdc->hwnd->invalid->null) + return; + + 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); +} + +void android_desktop_resize(rdpContext* context) +{ + DEBUG_ANDROID("ui_desktop_resize"); + + rdpGdi *gdi = context->gdi; + rdpSettings* settings = context->instance->settings; + + gdi_resize(gdi, settings->DesktopWidth, settings->DesktopHeight); + freerdp_callback("OnGraphicsResize", "(III)V", context->instance, settings->DesktopWidth, settings->DesktopHeight); +} + + +BOOL android_pre_connect(freerdp* instance) +{ + DEBUG_ANDROID("android_pre_connect"); + + rdpSettings* settings = instance->settings; + BOOL bitmap_cache = settings->BitmapCacheEnabled; + settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; + settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; + settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; + settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; + settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache; + settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; + settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache; + settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; + settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; + settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; + settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; + settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; + settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; + + settings->FrameAcknowledge = 10; + + freerdp_channels_load_plugin(instance->context->channels, instance->settings, "tsxlc", NULL); + + freerdp_channels_pre_connect(instance->context->channels, instance); + + return TRUE; +} + +BOOL android_post_connect(freerdp* instance) +{ + DEBUG_ANDROID("android_post_connect"); + + freerdp_callback("OnSettingsChanged", "(IIII)V", instance, instance->settings->DesktopWidth, instance->settings->DesktopHeight, instance->settings->ColorDepth); + + instance->context->cache = cache_new(instance->settings); + + gdi_init(instance, CLRCONV_ALPHA | ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), NULL); + + instance->update->BeginPaint = android_begin_paint; + instance->update->EndPaint = android_end_paint; + instance->update->DesktopResize = android_desktop_resize; + + //ai->rail = rail_new(instance->settings); + //instance->update->rail = (void*) ai->rail; + //rail_register_update_callbacks(xfi->rail, instance->update); + //android_rail_register_callbacks(xfi, xfi->rail); + + freerdp_channels_post_connect(instance->context->channels, instance); + + // send notifications + freerdp_callback("OnConnectionSuccess", "(I)V", instance); + + return TRUE; +} + +jobject create_string_builder(JNIEnv *env, char* initialStr) +{ + jclass cls; + jmethodID methodId; + jobject obj; + + // get class + cls = (*env)->FindClass(env, "java/lang/StringBuilder"); + if(!cls) + return NULL; + + if(initialStr) + { + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "", "(Ljava/lang/String;)V"); + if(!methodId) + return NULL; + + // create string that holds our initial string + jstring jstr = (*env)->NewStringUTF(env, initialStr); + + // construct new StringBuilder + obj = (*env)->NewObject(env, cls, methodId, jstr); + } + else + { + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "", "()V"); + if(!methodId) + return NULL; + + // construct new StringBuilder + obj = (*env)->NewObject(env, cls, methodId); + } + + return obj; +} + +char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder) +{ + jclass cls; + jmethodID methodId; + jstring strObj; + const jbyte* native_str; + char* result; + + // get class + cls = (*env)->FindClass(env, "java/lang/StringBuilder"); + if(!cls) + return NULL; + + // get method id for constructor + methodId = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;"); + if(!methodId) + return NULL; + + // get jstring representation of our buffer + strObj = (*env)->CallObjectMethod(env, strBuilder, methodId); + + // read string + native_str = (*env)->GetStringUTFChars(env, strObj, NULL); + result = strdup(native_str); + (*env)->ReleaseStringUTFChars(env, strObj, native_str); + + return result; +} + + +BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain) +{ + DEBUG_ANDROID("Authenticate user:"); + DEBUG_ANDROID(" Username: %s", *username); + DEBUG_ANDROID(" Domain: %s", *domain); + + JNIEnv* env; + jboolean attached = jni_attach_thread(&env); + jobject jstr1 = create_string_builder(env, *username); + jobject jstr2 = create_string_builder(env, *domain); + jobject jstr3 = create_string_builder(env, *password); + + jboolean res = freerdp_callback_bool_result("OnAuthenticate", "(ILjava/lang/StringBuilder;Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;)Z", instance, jstr1, jstr2, jstr3); + if(res == JNI_TRUE) + { + // read back string values + if(*username != NULL) + free(*username); + + *username = get_string_from_string_builder(env, jstr1); + + if(*domain != NULL) + free(*domain); + + *domain = get_string_from_string_builder(env, jstr2); + + if(*password == NULL) + free(*password); + + *password = get_string_from_string_builder(env, jstr3); + } + + if(attached == JNI_TRUE) + jni_detach_thread(); + + return ((res == JNI_TRUE) ? TRUE : FALSE); +} + +BOOL android_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +{ + DEBUG_ANDROID("Certificate details:"); + DEBUG_ANDROID("\tSubject: %s", subject); + DEBUG_ANDROID("\tIssuer: %s", issuer); + DEBUG_ANDROID("\tThumbprint: %s", fingerprint); + DEBUG_ANDROID("The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired." + "Please look at the documentation on how to create local certificate store for a private CA.\n"); + + JNIEnv* env; + jboolean attached = jni_attach_thread(&env); + jstring jstr1 = (*env)->NewStringUTF(env, subject); + jstring jstr2 = (*env)->NewStringUTF(env, issuer); + jstring jstr3 = (*env)->NewStringUTF(env, fingerprint); + + jboolean res = freerdp_callback_bool_result("OnVerifyCertificate", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", instance, jstr1, jstr2, jstr3); + + if(attached == JNI_TRUE) + jni_detach_thread(); + + return ((res == JNI_TRUE) ? TRUE : FALSE); +} + +BOOL android_verify_changed_certificate(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint) +{ + return android_verify_certificate(instance, subject, issuer, new_fingerprint); +} + + +/* +int xf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChanMan* chanman = (rdpChanMan*) user_data; + + printf("loading plugin %s\n", name); + freerdp_chanman_load_plugin(chanman, settings, name, plugin_data); + + return 1; +} +*/ + +int android_receive_channel_data(freerdp* instance, int channelId, UINT8* data, int size, int flags, int total_size) +{ + return freerdp_channels_data(instance, channelId, data, size, flags, total_size); +} + +void android_process_channel_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + + event = freerdp_channels_pop_event(channels); + + if (event) + { +/* switch (event->event_class) + { + case RDP_EVENT_CLASS_RAIL: + xf_process_rail_event(ai, chanman, event); + break; + + default: + break; + } + + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_SYNC: + android_process_cb_sync_event(chanman, instance); + break; + default: + break; + } +*/ + freerdp_event_free(event); + } +} + +int android_freerdp_run(freerdp* instance) +{ + int i; + int fds; + int max_fds; + int rcount; + int wcount; + void* rfds[32]; + void* wfds[32]; + fd_set rfds_set; + fd_set wfds_set; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); + + if (!freerdp_connect(instance)) + { + freerdp_callback("OnConnectionFailure", "(I)V", instance); + return 0; + } + + ((androidContext*)instance->context)->is_connected = TRUE; + while (1) + { + rcount = 0; + wcount = 0; + + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n"); + break; + } + if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get channel manager file descriptor\n"); + break; + } + if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get android file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + DEBUG_ANDROID("android_run: select failed\n"); + break; + } + } + + if (freerdp_check_fds(instance) != TRUE) + { + DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n"); + break; + } + if (android_check_fds(instance) != TRUE) + { + DEBUG_ANDROID("Failed to check android file descriptor\n"); + break; + } + if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE) + { + DEBUG_ANDROID("Failed to check channel manager file descriptor\n"); + break; + } + android_process_channel_event(instance->context->channels, instance); + } + + // issue another OnDisconnecting here in case the disconnect was initiated by the sever and not our client + freerdp_callback("OnDisconnecting", "(I)V", instance); + freerdp_channels_close(instance->context->channels, instance); + freerdp_disconnect(instance); + gdi_free(instance); + cache_free(instance->context->cache); + freerdp_callback("OnDisconnected", "(I)V", instance); + + return 0; +} + +void* android_thread_func(void* param) +{ + struct thread_data* data; + data = (struct thread_data*) param; + + freerdp* instance = data->instance; + android_freerdp_run(instance); + free(data); + + pthread_detach(pthread_self()); + + return NULL; +} + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + + DEBUG_ANDROID("JNI_OnLoad"); + + jint res = init_callback_environment(vm); + + setlocale(LC_ALL, ""); + + freerdp_channels_global_init(); + + return res; +} + +JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) +{ + freerdp* instance; + + // create instance + instance = freerdp_new(); + instance->PreConnect = android_pre_connect; + instance->PostConnect = android_post_connect; + instance->Authenticate = android_authenticate; + instance->VerifyCertificate = android_verify_certificate; + instance->VerifyChangedCertificate = android_verify_changed_certificate; + instance->ReceiveChannelData = android_receive_channel_data; + + + // create context + instance->context_size = sizeof(androidContext); + instance->ContextNew = android_context_new; + instance->ContextFree = android_context_free; + freerdp_context_new(instance); + + return (jint) instance; +} + +JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance) +{ + freerdp* inst = (freerdp*)instance; + freerdp_free(inst); +} + +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; + pthread_create(&ctx->thread, 0, android_thread_func, data); + + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint instance) +{ + freerdp* inst = (freerdp*)instance; + ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); + android_push_event(inst, event); + freerdp_callback("OnDisconnecting", "(I)V", instance); + return (jboolean) JNI_TRUE; +} + +JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance) +{ + DEBUG_ANDROID("Cancelling connection ..."); + freerdp* inst = (freerdp*)instance; + ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); + android_push_event(inst, event); + freerdp_callback("OnDisconnecting", "(I)V", instance); +} + +JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + const jbyte *directory = (*env)->GetStringUTFChars(env, jdirectory, NULL); + free(settings->HomePath); + settings->HomePath = strdup(directory); + (*env)->ReleaseStringUTFChars(env, jdirectory, directory); +} + +JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance, + jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, + jint color_depth, jint port, jboolean console, jint security, jstring jcertname) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + const jbyte *hostname = (*env)->GetStringUTFChars(env, jhostname, NULL); + const jbyte *username = (*env)->GetStringUTFChars(env, jusername, NULL); + const jbyte *password = (*env)->GetStringUTFChars(env, jpassword, NULL); + const jbyte *domain = (*env)->GetStringUTFChars(env, jdomain, NULL); + const jbyte *certname = (*env)->GetStringUTFChars(env, jcertname, NULL); + + DEBUG_ANDROID("hostname: %s", (char*) hostname); + DEBUG_ANDROID("username: %s", (char*) username); + DEBUG_ANDROID("password: %s", (char*) password); + DEBUG_ANDROID("domain: %s", (char*) domain); + DEBUG_ANDROID("width: %d", width); + DEBUG_ANDROID("height: %d", height); + DEBUG_ANDROID("color depth: %d", color_depth); + DEBUG_ANDROID("port: %d", port); + DEBUG_ANDROID("security: %d", security); + + settings->DesktopWidth = width; + settings->DesktopHeight = height; + settings->ColorDepth = color_depth; + settings->ServerPort = port; + + // Hack for 16 bit RDVH connections: + // In this case we get screen corruptions when we have an odd screen resolution width ... need to investigate what is causing this... + if (color_depth <= 16) + settings->DesktopWidth &= (~1); + + settings->ServerHostname = strdup(hostname); + + if(username && strlen(username) > 0) + settings->Username = strdup(username); + + if(password && strlen(password) > 0) + { + settings->Password = strdup(password); + settings->AutoLogonEnabled = TRUE; + } + + settings->Domain = strdup(domain); + + if(certname && strlen(certname) > 0) + settings->CertificateName = strdup(certname); + + settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE; + + settings->SoftwareGdi = TRUE; + + /* enable NSCodec */ + settings->NSCodec = TRUE; + + switch ((int) security) + { + case 1: + /* Standard RDP */ + settings->RdpSecurity = TRUE; + settings->TlsSecurity = FALSE; + settings->NlaSecurity = FALSE; + settings->ExtSecurity = FALSE; + settings->DisableEncryption = TRUE; + settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + break; + + case 2: + /* TLS */ + settings->NlaSecurity = FALSE; + settings->TlsSecurity = TRUE; + settings->RdpSecurity = FALSE; + settings->ExtSecurity = FALSE; + break; + + case 3: + /* NLA */ + settings->NlaSecurity = TRUE; + settings->TlsSecurity = FALSE; + settings->RdpSecurity = FALSE; + settings->ExtSecurity = FALSE; + break; + + default: + break; + } + + // set US keyboard layout + settings->KeyboardLayout = 0x0409; + + (*env)->ReleaseStringUTFChars(env, jhostname, hostname); + (*env)->ReleaseStringUTFChars(env, jusername, username); + (*env)->ReleaseStringUTFChars(env, jpassword, password); + (*env)->ReleaseStringUTFChars(env, jdomain, domain); + (*env)->ReleaseStringUTFChars(env, jcertname, certname); + + return; +} + +JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( + JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, + jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + DEBUG_ANDROID("remotefx: %d", (remotefx == JNI_TRUE) ? 1 : 0); + if (remotefx == JNI_TRUE) + { + settings->RemoteFxCodec = TRUE; + settings->FastPathOutput = TRUE; + settings->ColorDepth = 32; + settings->LargePointerFlag = TRUE; + settings->PerformanceFlags = PERF_FLAG_NONE; + settings->FrameMarkerCommandEnabled = TRUE; + } + + /* store performance settings */ + if (disableWallpaper == JNI_TRUE) + settings->DisableWallpaper = TRUE; + + if (disableFullWindowDrag == JNI_TRUE) + settings->DisableFullWindowDrag = TRUE; + + if (disableMenuAnimations == JNI_TRUE) + settings->DisableMenuAnims = TRUE; + + if (disableTheming == JNI_TRUE) + settings->DisableThemes = TRUE; + + if (enableFontSmoothing == JNI_TRUE) + settings->AllowFontSmoothing = TRUE; + + if(enableDesktopComposition == JNI_TRUE) + settings->AllowDesktopComposition = TRUE; + + + /* Create performance flags from settings */ + if (settings->AllowFontSmoothing) + settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; + + if (settings->AllowDesktopComposition) + settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; + + if (settings->DisableWallpaper) + settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; + + if (settings->DisableFullWindowDrag) + settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; + + if (settings->DisableMenuAnims) + settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; + + if (settings->DisableThemes) + settings->PerformanceFlags |= PERF_DISABLE_THEMING; + + DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); +} + +JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir) +{ + freerdp* inst = (freerdp*)instance; + rdpSettings * settings = inst->settings; + + const jbyte *remote_program = (*env)->GetStringUTFChars(env, jRemoteProgram, NULL); + const jbyte *work_dir = (*env)->GetStringUTFChars(env, jWorkDir, NULL); + + DEBUG_ANDROID("Remote Program: %s", (char*) remote_program); + DEBUG_ANDROID("Work Dir: %s", (char*) work_dir); + + if(remote_program && strlen(remote_program) > 0) + settings->AlternateShell = strdup(remote_program); + + if(work_dir && strlen(work_dir) > 0) + settings->ShellWorkingDirectory = strdup(work_dir); + + (*env)->ReleaseStringUTFChars(env, jRemoteProgram, remote_program); + (*env)->ReleaseStringUTFChars(env, jWorkDir, work_dir); +} + +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; + int scanline; + UINT8 *dstp, *srcp; + + length = width * bpp; + scanline = wBuf * bpp; + + srcp = (UINT8*) &srcBuf[(scanline * y) + (x * bpp)]; + dstp = (UINT8*) &dstBuf[(scanline * y) + (x * bpp)]; + + if (bpp == 4) + { + for (i = 0; i < height; i++) + { + for (j = 0; j < width * 4; j += 4) + { + // ARGB <-> ABGR + dstp[j + 0] = srcp[j + 2]; + dstp[j + 1] = srcp[j + 1]; + dstp[j + 2] = srcp[j + 0]; + dstp[j + 3] = srcp[j + 3]; + } + + srcp += scanline; + dstp += scanline; + } + } + else + { + for (i = 0; i < height; i++) + { + memcpy(dstp, srcp, length); + srcp += scanline; + dstp += scanline; + } + } +} + +JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics( + JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height) +{ + + int ret; + void* pixels; + AndroidBitmapInfo info; + freerdp* inst = (freerdp*)instance; + rdpGdi *gdi = inst->context->gdi; + + if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) + { + DEBUG_ANDROID("AndroidBitmap_getInfo() failed ! error=%d", ret); + return JNI_FALSE; + } + + if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) + { + DEBUG_ANDROID("AndroidBitmap_lockPixels() failed ! error=%d", ret); + return JNI_FALSE; + } + + copy_pixel_buffer(pixels, gdi->primary_buffer, x, y, width, height, gdi->width, gdi->height, gdi->bytesPerPixel); + + AndroidBitmap_unlockPixels(env, bitmap); + + return JNI_TRUE; +} + +JNIEXPORT void JNICALL jni_freerdp_send_key_event( + JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down) +{ + RDP_SCANCODE scancode; + ANDROID_EVENT* event; + + freerdp* inst = (freerdp*)instance; + + scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(keycode); + int flags = (down == JNI_TRUE) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; + flags |= (RDP_SCANCODE_EXTENDED(scancode)) ? KBD_FLAGS_EXTENDED : 0; + event = (ANDROID_EVENT*) android_event_key_new(flags, RDP_SCANCODE_CODE(scancode)); + + android_push_event(inst, event); + + DEBUG_ANDROID("send_key_event: %d, %d", scancode, flags); +} + +JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event( + JNIEnv *env, jclass cls, jint instance, jint keycode) +{ + ANDROID_EVENT* event; + + freerdp* inst = (freerdp*)instance; + event = (ANDROID_EVENT*) android_event_unicodekey_new(keycode); + android_push_event(inst, event); + + DEBUG_ANDROID("send_unicodekey_event: %d", keycode); +} + +JNIEXPORT void JNICALL jni_freerdp_send_cursor_event( + JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) +{ + ANDROID_EVENT* event; + + freerdp* inst = (freerdp*)instance; + event = (ANDROID_EVENT*) android_event_cursor_new(flags, x, y); + android_push_event(inst, event); + + DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags); +} + +JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls) +{ + return (*env)->NewStringUTF(env, GIT_REVISION); +} + diff --git a/client/Android/jni/android_freerdp.h b/client/Android/jni/android_freerdp.h new file mode 100644 index 000000000..e932220d0 --- /dev/null +++ b/client/Android/jni/android_freerdp.h @@ -0,0 +1,53 @@ +/* + Android JNI Client Layer + + Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifndef __ANDROID_FREERDP_H +#define __ANDROID_FREERDP_H + +#include +#include +#include + +#include "android_event.h" + +struct android_context +{ + rdpContext rdpCtx; + + ANDROID_EVENT_QUEUE* event_queue; + pthread_t thread; + BOOL is_connected; +}; +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); +JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint instance); +JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance); +JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance, + jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, + jint height, jint color_depth, jint port, jboolean console, jint security, jstring jcertname); +JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, + jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition); +JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir); +JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory); +JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics(JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height); +JNIEXPORT void JNICALL jni_freerdp_send_cursor_event(JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags); +JNIEXPORT void JNICALL jni_freerdp_send_key_event(JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down); +JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event(JNIEnv *env, jclass cls, jint instance, jint keycode); +JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls); + +#endif /* __ANDROID_FREERDP_H */ + diff --git a/client/Android/jni/android_jni_callback.c b/client/Android/jni/android_jni_callback.c new file mode 100644 index 000000000..071b3de3f --- /dev/null +++ b/client/Android/jni/android_jni_callback.c @@ -0,0 +1,179 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android JNI Callback Helpers + * + * Copyright 2011-2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "android_jni_callback.h" +#include "android_debug.h" +#include "android_freerdp_jni.h" + +JavaVM *jVM; +jobject jLibFreeRDPObject; + +const char *jLibFreeRDPPath = JAVA_LIBFREERDP_CLASS; + +void jni_load_class(JNIEnv *env, const char *path, jobject *objptr) +{ + jclass class; + jmethodID method; + jobject object; + + DEBUG_ANDROID("jni_load_class: %s", path); + + class = (*env)->FindClass(env, path); + + if (!class) + { + DEBUG_ANDROID("jni_load_class: failed to find class %s", path); + } + + method = (*env)->GetMethodID(env, class, "", "()V"); + + if (!method) + { + DEBUG_ANDROID("jni_load_class: failed to find class constructor of %s", path); + } + + object = (*env)->NewObject(env, class, method); + + if (!object) + { + DEBUG_ANDROID("jni_load_class: failed create new object of %s", path); + } + + (*objptr) = (*env)->NewGlobalRef(env, object); +} + +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"); + return -1; + } + + jVM = vm; + + jni_load_class(env, jLibFreeRDPPath, &jLibFreeRDPObject); + + return JNI_VERSION_1_4; +} + +/* attach current thread to jvm */ +jboolean jni_attach_thread(JNIEnv** env) +{ + if ((*jVM)->GetEnv(jVM, (void**) env, JNI_VERSION_1_4) != JNI_OK) + { + DEBUG_ANDROID("android_java_callback: attaching current thread"); + + (*jVM)->AttachCurrentThread(jVM, env, NULL); + + if ((*jVM)->GetEnv(jVM, (void**) env, JNI_VERSION_1_4) != JNI_OK) + { + DEBUG_ANDROID("android_java_callback: failed to obtain current JNI environment"); + } + + return JNI_TRUE; + } + + return JNI_FALSE; +} + +/* attach current thread to JVM */ +void jni_detach_thread() +{ + (*jVM)->DetachCurrentThread(jVM); +} + +/* callback with void result */ +void java_callback_void(jobject obj, const char * callback, const char* signature, va_list args) +{ + jclass jObjClass; + jmethodID jCallback; + jboolean attached; + JNIEnv *env; + + DEBUG_ANDROID("java_callback: %s (%s)", callback, signature); + + attached = jni_attach_thread(&env); + + jObjClass = (*env)->GetObjectClass(env, obj); + + if (!jObjClass) { + DEBUG_ANDROID("android_java_callback: failed to get class reference"); + } + + jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature); + + if (!jCallback) { + DEBUG_ANDROID("android_java_callback: failed to get method id"); + } + + (*env)->CallStaticVoidMethodV(env, jObjClass, jCallback, args); + + if(attached == JNI_TRUE) + jni_detach_thread(); +} + +/* callback with bool result */ +jboolean java_callback_bool(jobject obj, const char * callback, const char* signature, va_list args) +{ + jclass jObjClass; + jmethodID jCallback; + jboolean attached; + JNIEnv *env; + + DEBUG_ANDROID("java_callback: %s (%s)", callback, signature); + + attached = jni_attach_thread(&env); + + jObjClass = (*env)->GetObjectClass(env, obj); + + if (!jObjClass) { + DEBUG_ANDROID("android_java_callback: failed to get class reference"); + } + + jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature); + + if (!jCallback) { + DEBUG_ANDROID("android_java_callback: failed to get method id"); + } + + jboolean res = (*env)->CallStaticBooleanMethodV(env, jObjClass, jCallback, args); + + if(attached == JNI_TRUE) + jni_detach_thread(); + + return res; +} + +/* callback to freerdp class */ +void freerdp_callback(const char * callback, const char * signature, ...) +{ + va_list vl; + va_start(vl, signature); + java_callback_void(jLibFreeRDPObject, callback, signature, vl); + va_end(vl); +} + +jboolean freerdp_callback_bool_result(const char * callback, const char * signature, ...) +{ + va_list vl; + va_start(vl, signature); + jboolean res = java_callback_bool(jLibFreeRDPObject, callback, signature, vl); + va_end(vl); + return res; +} diff --git a/client/Android/jni/android_jni_callback.h b/client/Android/jni/android_jni_callback.h new file mode 100644 index 000000000..106fc326b --- /dev/null +++ b/client/Android/jni/android_jni_callback.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Android JNI Callback Helpers + * + * Copyright 2010-2012 Marc-Andre Moreau + * Copyright 2011-2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef FREERDP_ANDROID_JNI_CALLBACK_H +#define FREERDP_ANDROID_JNI_CALLBACK_H + +#include +#include + +jint init_callback_environment(JavaVM* vm); +jboolean jni_attach_thread(JNIEnv** env); +void jni_detach_thread(); +void freerdp_callback(const char * callback, const char * signature, ...); +jboolean freerdp_callback_bool_result(const char * callback, const char * signature, ...); +void tsxconnect_callback(const char * callback, const char * signature, ...); + +#endif /* FREERDP_ANDROID_JNI_CALLBACK_H */ + diff --git a/client/Android/jni/generated/android_freerdp_jni.c b/client/Android/jni/generated/android_freerdp_jni.c new file mode 100644 index 000000000..8d64e094c --- /dev/null +++ b/client/Android/jni/generated/android_freerdp_jni.c @@ -0,0 +1,101 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + Android JNI Bindings and Native Code + + Copyright 2010 Marc-Andre Moreau + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "android_freerdp.h" +#include "android_freerdp_jni.h" + +JNIEXPORT jint JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1new(JNIEnv *env, jclass cls) +{ + return jni_freerdp_new(env, cls); +} + +JNIEXPORT void JNICALL JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1free(JNIEnv *env, jclass cls, jint instance) +{ + jni_freerdp_free(env, cls, instance); +} + +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1connect(JNIEnv *env, jclass cls, jint instance) +{ + return jni_freerdp_connect(env, cls, instance); +} + +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1disconnect(JNIEnv *env, jclass cls, jint instance) +{ + return jni_freerdp_disconnect(env, cls, instance); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1cancel_1connection(JNIEnv *env, jclass cls, jint instance) +{ + jni_freerdp_cancel_connection(env, cls, instance); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1connection_1info(JNIEnv *env, jclass cls, jint instance, + jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, jint color_depth, jint port, + jboolean console, jint security, jstring certname) +{ + jni_freerdp_set_connection_info(env, cls, instance, jhostname, jusername, jpassword, jdomain, + width, height, color_depth, port, console, security, certname); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1advanced_1settings(JNIEnv *env, jclass cls, jint instance, jstring remote_program, jstring work_dir) +{ + jni_freerdp_set_advanced_settings(env, cls, instance, remote_program, work_dir); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1data_1directory(JNIEnv *env, jclass cls, jint instance, jstring directory) +{ + jni_freerdp_set_data_directory(env, cls, instance, directory); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1performance_1flags( + JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, + jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition) +{ + jni_freerdp_set_performance_flags(env, cls, instance, remotefx, disableWallpaper, disableFullWindowDrag, disableMenuAnimations, disableTheming, enableFontSmoothing, enableDesktopComposition); +} + +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1update_1graphics( + JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height) +{ + return jni_freerdp_update_graphics(env, cls, instance, bitmap, x, y, width, height); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1cursor_1event( + JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) +{ + jni_freerdp_send_cursor_event(env, cls, instance, x, y, flags); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1key_1event( + JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down) +{ + jni_freerdp_send_key_event(env, cls, instance, keycode, down); +} + +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1unicodekey_1event + (JNIEnv *env, jclass cls, jint instance, jint keycode) +{ + jni_freerdp_send_unicodekey_event(env, cls, instance, keycode); +} + +JNIEXPORT jstring JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1get_1version(JNIEnv *env, jclass cls) +{ + return jni_freerdp_get_version(env, cls); +} + diff --git a/client/Android/jni/generated/android_freerdp_jni.h b/client/Android/jni/generated/android_freerdp_jni.h new file mode 100644 index 000000000..a10d17cc6 --- /dev/null +++ b/client/Android/jni/generated/android_freerdp_jni.h @@ -0,0 +1,28 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + Android FreeRDP JNI Definitions + + Copyright 2010 Marc-Andre Moreau + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __ANDROID_FREERDP_JNI_H +#define __ANDROID_FREERDP_JNI_H + +#include "com_freerdp_afreerdp_services_LibFreeRDP.h" + +#define JAVA_LIBFREERDP_CLASS "com/freerdp/afreerdp/services/LibFreeRDP" + +#endif /* __ANDROID_FREERDP_JNI_H */ + diff --git a/client/Android/jni/generated/com_freerdp_afreerdp_services_LibFreeRDP.h b/client/Android/jni/generated/com_freerdp_afreerdp_services_LibFreeRDP.h new file mode 100644 index 000000000..cfe8d65f5 --- /dev/null +++ b/client/Android/jni/generated/com_freerdp_afreerdp_services_LibFreeRDP.h @@ -0,0 +1,125 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_freerdp_afreerdp_services_LibFreeRDP */ + +#ifndef _Included_com_freerdp_afreerdp_services_LibFreeRDP +#define _Included_com_freerdp_afreerdp_services_LibFreeRDP +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_new + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1new + (JNIEnv *, jclass); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_free + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1free + (JNIEnv *, jclass, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_connect + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1connect + (JNIEnv *, jclass, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_disconnect + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1disconnect + (JNIEnv *, jclass, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_cancel_connection + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1cancel_1connection + (JNIEnv *, jclass, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_set_connection_info + * Signature: (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIZILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1connection_1info + (JNIEnv *, jclass, jint, jstring, jstring, jstring, jstring, jint, jint, jint, jint, jboolean, jint, jstring); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_set_performance_flags + * Signature: (IZZZZZZZ)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1performance_1flags + (JNIEnv *, jclass, jint, jboolean, jboolean, jboolean, jboolean, jboolean, jboolean, jboolean); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_set_advanced_settings + * Signature: (ILjava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1advanced_1settings + (JNIEnv *, jclass, jint, jstring, jstring); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_set_data_directory + * Signature: (ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1set_1data_1directory + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_update_graphics + * Signature: (ILandroid/graphics/Bitmap;IIII)Z + */ +JNIEXPORT jboolean JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1update_1graphics + (JNIEnv *, jclass, jint, jobject, jint, jint, jint, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_send_cursor_event + * Signature: (IIII)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1cursor_1event + (JNIEnv *, jclass, jint, jint, jint, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_send_key_event + * Signature: (IIZ)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1key_1event + (JNIEnv *, jclass, jint, jint, jboolean); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_send_unicodekey_event + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1send_1unicodekey_1event + (JNIEnv *, jclass, jint, jint); + +/* + * Class: com_freerdp_afreerdp_services_LibFreeRDP + * Method: freerdp_get_version + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_freerdp_afreerdp_services_LibFreeRDP_freerdp_1get_1version + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/client/Android/local.properties.cmake b/client/Android/local.properties.cmake new file mode 100644 index 000000000..159126370 --- /dev/null +++ b/client/Android/local.properties.cmake @@ -0,0 +1,2 @@ +# This file is automatically generated by cmake. +sdk.dir=@ANDROID_SDK@ diff --git a/client/Android/project.properties b/client/Android/project.properties new file mode 100644 index 000000000..ea89160e0 --- /dev/null +++ b/client/Android/project.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-8 diff --git a/client/Android/res/drawable-hdpi/icon_button_add.png b/client/Android/res/drawable-hdpi/icon_button_add.png new file mode 100644 index 000000000..6e028b20b Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_button_add.png differ diff --git a/client/Android/res/drawable-hdpi/icon_edittext_clear.png b/client/Android/res/drawable-hdpi/icon_edittext_clear.png new file mode 100644 index 000000000..90db01b5b Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_edittext_clear.png differ diff --git a/client/Android/res/drawable-hdpi/icon_edittext_search.png b/client/Android/res/drawable-hdpi/icon_edittext_search.png new file mode 100644 index 000000000..0a91eabcc Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_edittext_search.png differ diff --git a/client/Android/res/drawable-hdpi/icon_launcher_freerdp.png b/client/Android/res/drawable-hdpi/icon_launcher_freerdp.png new file mode 100644 index 000000000..45ed86123 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_about.png b/client/Android/res/drawable-hdpi/icon_menu_about.png new file mode 100644 index 000000000..6b3f7fd15 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_about.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_add.png b/client/Android/res/drawable-hdpi/icon_menu_add.png new file mode 100644 index 000000000..7b0dfc5e1 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_add.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_close.png b/client/Android/res/drawable-hdpi/icon_menu_close.png new file mode 100644 index 000000000..4683f6193 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_close.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_disconnect.png b/client/Android/res/drawable-hdpi/icon_menu_disconnect.png new file mode 100644 index 000000000..172ae5f3d Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_disconnect.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_ext_keyboard.png b/client/Android/res/drawable-hdpi/icon_menu_ext_keyboard.png new file mode 100644 index 000000000..53319e291 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_help.png b/client/Android/res/drawable-hdpi/icon_menu_help.png new file mode 100644 index 000000000..a5b4a2f60 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_help.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_preferences.png b/client/Android/res/drawable-hdpi/icon_menu_preferences.png new file mode 100644 index 000000000..039c72174 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_preferences.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_settings.png b/client/Android/res/drawable-hdpi/icon_menu_settings.png new file mode 100644 index 000000000..c08e64f91 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_settings.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_sys_keyboard.png b/client/Android/res/drawable-hdpi/icon_menu_sys_keyboard.png new file mode 100644 index 000000000..5b14130e3 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/res/drawable-hdpi/icon_menu_touch_pointer.png b/client/Android/res/drawable-hdpi/icon_menu_touch_pointer.png new file mode 100644 index 000000000..3f5142012 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/res/drawable-hdpi/icon_star_off.png b/client/Android/res/drawable-hdpi/icon_star_off.png new file mode 100644 index 000000000..4be0f5df2 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_star_off.png differ diff --git a/client/Android/res/drawable-hdpi/icon_star_on.png b/client/Android/res/drawable-hdpi/icon_star_on.png new file mode 100644 index 000000000..421305087 Binary files /dev/null and b/client/Android/res/drawable-hdpi/icon_star_on.png differ diff --git a/client/Android/res/drawable-hdpi/search_plate.9.png b/client/Android/res/drawable-hdpi/search_plate.9.png new file mode 100644 index 000000000..32c6dc370 Binary files /dev/null and b/client/Android/res/drawable-hdpi/search_plate.9.png differ diff --git a/client/Android/res/drawable-hdpi/sym_keyboard_delete.png b/client/Android/res/drawable-hdpi/sym_keyboard_delete.png new file mode 100755 index 000000000..59d78bec0 Binary files /dev/null and b/client/Android/res/drawable-hdpi/sym_keyboard_delete.png differ diff --git a/client/Android/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/client/Android/res/drawable-hdpi/sym_keyboard_feedback_delete.png new file mode 100755 index 000000000..ca7637552 Binary files /dev/null and b/client/Android/res/drawable-hdpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/res/drawable-hdpi/sym_keyboard_feedback_return.png b/client/Android/res/drawable-hdpi/sym_keyboard_feedback_return.png new file mode 100755 index 000000000..ae57299e4 Binary files /dev/null and b/client/Android/res/drawable-hdpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/res/drawable-hdpi/sym_keyboard_return.png b/client/Android/res/drawable-hdpi/sym_keyboard_return.png new file mode 100755 index 000000000..58505c5e0 Binary files /dev/null and b/client/Android/res/drawable-hdpi/sym_keyboard_return.png differ diff --git a/client/Android/res/drawable-ldpi/icon_button_add.png b/client/Android/res/drawable-ldpi/icon_button_add.png new file mode 100644 index 000000000..7afaeded1 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_button_add.png differ diff --git a/client/Android/res/drawable-ldpi/icon_edittext_search.png b/client/Android/res/drawable-ldpi/icon_edittext_search.png new file mode 100644 index 000000000..bdefbf5c6 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_edittext_search.png differ diff --git a/client/Android/res/drawable-ldpi/icon_launcher_freerdp.png b/client/Android/res/drawable-ldpi/icon_launcher_freerdp.png new file mode 100644 index 000000000..b57651bed Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_launcher_freerdp.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_about.png b/client/Android/res/drawable-ldpi/icon_menu_about.png new file mode 100644 index 000000000..55c57d5c5 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_about.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_add.png b/client/Android/res/drawable-ldpi/icon_menu_add.png new file mode 100644 index 000000000..89620af8c Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_add.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_disconnect.png b/client/Android/res/drawable-ldpi/icon_menu_disconnect.png new file mode 100644 index 000000000..606cce4a7 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_disconnect.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_exit.png b/client/Android/res/drawable-ldpi/icon_menu_exit.png new file mode 100644 index 000000000..760b9254d Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_exit.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_ext_keyboard.png b/client/Android/res/drawable-ldpi/icon_menu_ext_keyboard.png new file mode 100644 index 000000000..425d904ca Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_help.png b/client/Android/res/drawable-ldpi/icon_menu_help.png new file mode 100644 index 000000000..f93a4e640 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_help.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_preferences.png b/client/Android/res/drawable-ldpi/icon_menu_preferences.png new file mode 100644 index 000000000..efc2f3e45 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_preferences.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_settings.png b/client/Android/res/drawable-ldpi/icon_menu_settings.png new file mode 100644 index 000000000..b137b8c6e Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_settings.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_sys_keyboard.png b/client/Android/res/drawable-ldpi/icon_menu_sys_keyboard.png new file mode 100644 index 000000000..49837f290 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/res/drawable-ldpi/icon_menu_touch_pointer.png b/client/Android/res/drawable-ldpi/icon_menu_touch_pointer.png new file mode 100644 index 000000000..4e3b7d7a6 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/res/drawable-ldpi/icon_star_off.png b/client/Android/res/drawable-ldpi/icon_star_off.png new file mode 100644 index 000000000..f0f1eb845 Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_star_off.png differ diff --git a/client/Android/res/drawable-ldpi/icon_star_on.png b/client/Android/res/drawable-ldpi/icon_star_on.png new file mode 100644 index 000000000..cf5ed353b Binary files /dev/null and b/client/Android/res/drawable-ldpi/icon_star_on.png differ diff --git a/client/Android/res/drawable-ldpi/search_plate.9.png b/client/Android/res/drawable-ldpi/search_plate.9.png new file mode 100644 index 000000000..2fa21299f Binary files /dev/null and b/client/Android/res/drawable-ldpi/search_plate.9.png differ diff --git a/client/Android/res/drawable-ldpi/sym_keyboard_delete.png b/client/Android/res/drawable-ldpi/sym_keyboard_delete.png new file mode 100644 index 000000000..d9d565391 Binary files /dev/null and b/client/Android/res/drawable-ldpi/sym_keyboard_delete.png differ diff --git a/client/Android/res/drawable-ldpi/sym_keyboard_feedback_delete.png b/client/Android/res/drawable-ldpi/sym_keyboard_feedback_delete.png new file mode 100644 index 000000000..8922bf92c Binary files /dev/null and b/client/Android/res/drawable-ldpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/res/drawable-ldpi/sym_keyboard_feedback_return.png b/client/Android/res/drawable-ldpi/sym_keyboard_feedback_return.png new file mode 100644 index 000000000..c5f324752 Binary files /dev/null and b/client/Android/res/drawable-ldpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/res/drawable-ldpi/sym_keyboard_return.png b/client/Android/res/drawable-ldpi/sym_keyboard_return.png new file mode 100644 index 000000000..1c7c58d5d Binary files /dev/null and b/client/Android/res/drawable-ldpi/sym_keyboard_return.png differ diff --git a/client/Android/res/drawable-mdpi/icon_button_add.png b/client/Android/res/drawable-mdpi/icon_button_add.png new file mode 100644 index 000000000..af637b3be Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_button_add.png differ diff --git a/client/Android/res/drawable-mdpi/icon_edittext_clear.png b/client/Android/res/drawable-mdpi/icon_edittext_clear.png new file mode 100644 index 000000000..90db01b5b Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_edittext_clear.png differ diff --git a/client/Android/res/drawable-mdpi/icon_edittext_search.png b/client/Android/res/drawable-mdpi/icon_edittext_search.png new file mode 100644 index 000000000..3f8913e2a Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_edittext_search.png differ diff --git a/client/Android/res/drawable-mdpi/icon_launcher_freerdp.png b/client/Android/res/drawable-mdpi/icon_launcher_freerdp.png new file mode 100644 index 000000000..55335c869 Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_about.png b/client/Android/res/drawable-mdpi/icon_menu_about.png new file mode 100644 index 000000000..1f8a7cd47 Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_about.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_add.png b/client/Android/res/drawable-mdpi/icon_menu_add.png new file mode 100644 index 000000000..57a4099bb Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_add.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_disconnect.png b/client/Android/res/drawable-mdpi/icon_menu_disconnect.png new file mode 100644 index 000000000..c1aa860da Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_disconnect.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_exit.png b/client/Android/res/drawable-mdpi/icon_menu_exit.png new file mode 100644 index 000000000..04a76b589 Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_exit.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_ext_keyboard.png b/client/Android/res/drawable-mdpi/icon_menu_ext_keyboard.png new file mode 100644 index 000000000..9ae25ff2e Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_help.png b/client/Android/res/drawable-mdpi/icon_menu_help.png new file mode 100644 index 000000000..4f65a619d Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_help.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_preferences.png b/client/Android/res/drawable-mdpi/icon_menu_preferences.png new file mode 100644 index 000000000..2f34c7695 Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_preferences.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_settings.png b/client/Android/res/drawable-mdpi/icon_menu_settings.png new file mode 100644 index 000000000..a96bb0c4c Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_settings.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_sys_keyboard.png b/client/Android/res/drawable-mdpi/icon_menu_sys_keyboard.png new file mode 100644 index 000000000..bcd3eba42 Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/res/drawable-mdpi/icon_menu_touch_pointer.png b/client/Android/res/drawable-mdpi/icon_menu_touch_pointer.png new file mode 100644 index 000000000..e37e1dbbe Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/res/drawable-mdpi/icon_star_off.png b/client/Android/res/drawable-mdpi/icon_star_off.png new file mode 100755 index 000000000..7e9342b5c Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_star_off.png differ diff --git a/client/Android/res/drawable-mdpi/icon_star_on.png b/client/Android/res/drawable-mdpi/icon_star_on.png new file mode 100755 index 000000000..a9bdb052a Binary files /dev/null and b/client/Android/res/drawable-mdpi/icon_star_on.png differ diff --git a/client/Android/res/drawable-mdpi/search_plate.9.png b/client/Android/res/drawable-mdpi/search_plate.9.png new file mode 100644 index 000000000..1cad9020d Binary files /dev/null and b/client/Android/res/drawable-mdpi/search_plate.9.png differ diff --git a/client/Android/res/drawable-mdpi/sym_keyboard_delete.png b/client/Android/res/drawable-mdpi/sym_keyboard_delete.png new file mode 100644 index 000000000..43a033ead Binary files /dev/null and b/client/Android/res/drawable-mdpi/sym_keyboard_delete.png differ diff --git a/client/Android/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/client/Android/res/drawable-mdpi/sym_keyboard_feedback_delete.png new file mode 100644 index 000000000..1edb10b4e Binary files /dev/null and b/client/Android/res/drawable-mdpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/res/drawable-mdpi/sym_keyboard_feedback_return.png b/client/Android/res/drawable-mdpi/sym_keyboard_feedback_return.png new file mode 100644 index 000000000..03d9c9b2d Binary files /dev/null and b/client/Android/res/drawable-mdpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/res/drawable-mdpi/sym_keyboard_return.png b/client/Android/res/drawable-mdpi/sym_keyboard_return.png new file mode 100644 index 000000000..17f257439 Binary files /dev/null and b/client/Android/res/drawable-mdpi/sym_keyboard_return.png differ diff --git a/client/Android/res/drawable/button_background.xml b/client/Android/res/drawable/button_background.xml new file mode 100644 index 000000000..9fdf3096d --- /dev/null +++ b/client/Android/res/drawable/button_background.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/Android/res/drawable/icon_button_cancel.png b/client/Android/res/drawable/icon_button_cancel.png new file mode 100644 index 000000000..606cce4a7 Binary files /dev/null and b/client/Android/res/drawable/icon_button_cancel.png differ diff --git a/client/Android/res/drawable/icon_launcher_freerdp.png b/client/Android/res/drawable/icon_launcher_freerdp.png new file mode 100644 index 000000000..ad325d46e Binary files /dev/null and b/client/Android/res/drawable/icon_launcher_freerdp.png differ diff --git a/client/Android/res/drawable/separator_background.xml b/client/Android/res/drawable/separator_background.xml new file mode 100644 index 000000000..61c7b8925 --- /dev/null +++ b/client/Android/res/drawable/separator_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/client/Android/res/drawable/sym_keyboard_arrows.png b/client/Android/res/drawable/sym_keyboard_arrows.png new file mode 100755 index 000000000..3ad31caba Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_arrows.png differ diff --git a/client/Android/res/drawable/sym_keyboard_arrows_black.png b/client/Android/res/drawable/sym_keyboard_arrows_black.png new file mode 100755 index 000000000..3e9168240 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_arrows_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_down_arrow.png b/client/Android/res/drawable/sym_keyboard_down_arrow.png new file mode 100755 index 000000000..9039b78e9 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_down_arrow.png differ diff --git a/client/Android/res/drawable/sym_keyboard_down_arrow_black.png b/client/Android/res/drawable/sym_keyboard_down_arrow_black.png new file mode 100755 index 000000000..c01ef09ed Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_down_arrow_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_left_arrow.png b/client/Android/res/drawable/sym_keyboard_left_arrow.png new file mode 100755 index 000000000..471e42171 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_left_arrow.png differ diff --git a/client/Android/res/drawable/sym_keyboard_left_arrow_black.png b/client/Android/res/drawable/sym_keyboard_left_arrow_black.png new file mode 100755 index 000000000..b43956dd5 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_left_arrow_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_menu.png b/client/Android/res/drawable/sym_keyboard_menu.png new file mode 100755 index 000000000..c92d6f225 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_menu.png differ diff --git a/client/Android/res/drawable/sym_keyboard_menu_black.png b/client/Android/res/drawable/sym_keyboard_menu_black.png new file mode 100755 index 000000000..a24081b1c Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_menu_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_right_arrow.png b/client/Android/res/drawable/sym_keyboard_right_arrow.png new file mode 100755 index 000000000..c82f696a6 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_right_arrow.png differ diff --git a/client/Android/res/drawable/sym_keyboard_right_arrow_black.png b/client/Android/res/drawable/sym_keyboard_right_arrow_black.png new file mode 100755 index 000000000..19208ec0f Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_right_arrow_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_up_arrow.png b/client/Android/res/drawable/sym_keyboard_up_arrow.png new file mode 100755 index 000000000..ca187b5ca Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_up_arrow.png differ diff --git a/client/Android/res/drawable/sym_keyboard_up_arrow_black.png b/client/Android/res/drawable/sym_keyboard_up_arrow_black.png new file mode 100755 index 000000000..4240b5928 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_up_arrow_black.png differ diff --git a/client/Android/res/drawable/sym_keyboard_winkey.png b/client/Android/res/drawable/sym_keyboard_winkey.png new file mode 100755 index 000000000..6196b7246 Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_winkey.png differ diff --git a/client/Android/res/drawable/sym_keyboard_winkey_black.png b/client/Android/res/drawable/sym_keyboard_winkey_black.png new file mode 100755 index 000000000..8173d5c9c Binary files /dev/null and b/client/Android/res/drawable/sym_keyboard_winkey_black.png differ diff --git a/client/Android/res/drawable/touch_pointer_active.png b/client/Android/res/drawable/touch_pointer_active.png new file mode 100755 index 000000000..9f91b2465 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_active.png differ diff --git a/client/Android/res/drawable/touch_pointer_default.png b/client/Android/res/drawable/touch_pointer_default.png new file mode 100644 index 000000000..273e21114 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_default.png differ diff --git a/client/Android/res/drawable/touch_pointer_extkeyboard.png b/client/Android/res/drawable/touch_pointer_extkeyboard.png new file mode 100644 index 000000000..c82bdea37 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_extkeyboard.png differ diff --git a/client/Android/res/drawable/touch_pointer_keyboard.png b/client/Android/res/drawable/touch_pointer_keyboard.png new file mode 100644 index 000000000..cd58c87ee Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_keyboard.png differ diff --git a/client/Android/res/drawable/touch_pointer_lclick.png b/client/Android/res/drawable/touch_pointer_lclick.png new file mode 100644 index 000000000..f0a7afa93 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_lclick.png differ diff --git a/client/Android/res/drawable/touch_pointer_rclick.png b/client/Android/res/drawable/touch_pointer_rclick.png new file mode 100644 index 000000000..2129a1f33 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_rclick.png differ diff --git a/client/Android/res/drawable/touch_pointer_reset.png b/client/Android/res/drawable/touch_pointer_reset.png new file mode 100644 index 000000000..3c1289474 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_reset.png differ diff --git a/client/Android/res/drawable/touch_pointer_scroll.png b/client/Android/res/drawable/touch_pointer_scroll.png new file mode 100644 index 000000000..b6205da61 Binary files /dev/null and b/client/Android/res/drawable/touch_pointer_scroll.png differ diff --git a/client/Android/res/layout/bookmark_list_item.xml b/client/Android/res/layout/bookmark_list_item.xml new file mode 100644 index 000000000..8903355aa --- /dev/null +++ b/client/Android/res/layout/bookmark_list_item.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/client/Android/res/layout/button_preference.xml b/client/Android/res/layout/button_preference.xml new file mode 100644 index 000000000..dcf913933 --- /dev/null +++ b/client/Android/res/layout/button_preference.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + +