mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -37,6 +37,9 @@ external/*
|
||||
# Documentation
|
||||
docs/api
|
||||
client/X11/xfreerdp.1
|
||||
client/X11/xfreerdp.1.xml
|
||||
client/X11/xfreerdp-channels.1.xml
|
||||
client/X11/xfreerdp-examples.1.xml
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
||||
@@ -142,7 +142,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
|
||||
@@ -160,10 +160,10 @@ endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ob2")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W2")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MD")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ob2")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W2")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_")
|
||||
else()
|
||||
@@ -171,6 +171,13 @@ if(MSVC)
|
||||
endif()
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Zi")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@@ -220,21 +227,24 @@ if(APPLE)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH})
|
||||
set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES)
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
|
||||
if(NOT DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES i386 x86_64)
|
||||
endif()
|
||||
|
||||
if(IS_DIRECTORY /opt/local/include)
|
||||
include_directories(/opt/local/include)
|
||||
link_directories(/opt/local/lib)
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.5")
|
||||
endif()
|
||||
|
||||
if(WITH_CLANG)
|
||||
set(CMAKE_C_COMPILER "clang")
|
||||
endif()
|
||||
|
||||
if (WITH_VERBOSE)
|
||||
# Support for automatic reference counting requires non-fragile abi.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v")
|
||||
|
||||
# Tell the compiler where to look for the FreeRDP framework
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v")
|
||||
endif()
|
||||
endif()
|
||||
@@ -261,6 +271,7 @@ endif()
|
||||
|
||||
if(UNIX OR CYGWIN)
|
||||
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
|
||||
check_include_files(sys/timerfd.h HAVE_TIMERFD_H)
|
||||
set(X11_FEATURE_TYPE "RECOMMENDED")
|
||||
else()
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
@@ -313,6 +324,10 @@ set(NPP_FEATURE_TYPE "OPTIONAL")
|
||||
set(NPP_FEATURE_PURPOSE "performance")
|
||||
set(NPP_FEATURE_DESCRIPTION "NVIDIA Performance Primitives library")
|
||||
|
||||
set(JPEG_FEATURE_TYPE "OPTIONAL")
|
||||
set(JPEG_FEATURE_PURPOSE "codec")
|
||||
set(JPEG_FEATURE_DESCRIPTION "use JPEG library")
|
||||
|
||||
if(WIN32)
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(ZLIB_FEATURE_TYPE "DISABLED")
|
||||
@@ -329,8 +344,9 @@ if(APPLE)
|
||||
set(DIRECTFB_FEATURE_TYPE "DISABLED")
|
||||
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
|
||||
set(GSTREAMER_FEATURE_TYPE "OPTIONAL")
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(X11_FEATURE_TYPE "OPTIONAL")
|
||||
if(IOS)
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(ALSA_FEATURE_TYPE "DISABLED")
|
||||
set(PULSE_FEATURE_TYPE "DISABLED")
|
||||
set(CUPS_FEATURE_TYPE "DISABLED")
|
||||
@@ -353,6 +369,11 @@ endif()
|
||||
|
||||
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
|
||||
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
|
||||
if (${WITH_DIRECTFB})
|
||||
message(WARNING "
|
||||
DIRECTFB is orphaned and not maintained see docs/README.directfb for details
|
||||
")
|
||||
endif()
|
||||
|
||||
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
|
||||
find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION})
|
||||
@@ -366,6 +387,8 @@ find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DE
|
||||
find_feature(FFmpeg ${FFMPEG_FEATURE_TYPE} ${FFMPEG_FEATURE_PURPOSE} ${FFMPEG_FEATURE_DESCRIPTION})
|
||||
find_feature(Gstreamer ${GSTREAMER_FEATURE_TYPE} ${GSTREAMER_FEATURE_PURPOSE} ${GSTREAMER_FEATURE_DESCRIPTION})
|
||||
|
||||
find_feature(JPEG ${JPEG_FEATURE_TYPE} ${JPEG_FEATURE_PURPOSE} ${JPEG_FEATURE_DESCRIPTION})
|
||||
|
||||
if(TARGET_ARCH MATCHES "x86|x64")
|
||||
if (NOT APPLE)
|
||||
# Intel Performance Primitives
|
||||
@@ -394,12 +417,12 @@ set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
|
||||
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions")
|
||||
|
||||
# Include directories
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# Configure files
|
||||
add_definitions("-DHAVE_CONFIG_H")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
# RPATH configuration
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
@@ -424,8 +447,8 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
|
||||
# WinPR
|
||||
set(WINPR_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/winpr/include")
|
||||
include_directories(${WINPR_INCLUDE_DIR})
|
||||
include_directories("${CMAKE_SOURCE_DIR}/winpr/include")
|
||||
include_directories("${CMAKE_BINARY_DIR}/winpr/include")
|
||||
|
||||
add_subdirectory(winpr)
|
||||
|
||||
@@ -449,7 +472,9 @@ if(WITH_THIRD_PARTY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(include)
|
||||
if (NOT WITH_WAYK)
|
||||
add_subdirectory(include)
|
||||
endif()
|
||||
|
||||
add_subdirectory(libfreerdp)
|
||||
|
||||
@@ -474,6 +499,8 @@ endif()
|
||||
|
||||
SET(CPACK_BINARY_ZIP "ON")
|
||||
|
||||
if(NOT WITH_WAYK)
|
||||
|
||||
set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt")
|
||||
|
||||
if(NOT WIN32)
|
||||
@@ -529,9 +556,12 @@ if(MSVC)
|
||||
if(MSVC_RUNTIME STREQUAL "dynamic")
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
if(NOT WITH_WAYK)
|
||||
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT libraries)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(EXTRA_DATA_DIR "extra/")
|
||||
@@ -577,3 +607,4 @@ endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>FreeRDP</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>FreeRDP.Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string></string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string></string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -290,6 +290,17 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
|
||||
BYTE* encoded_data;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) userdata;
|
||||
|
||||
/* There is a race condition here where we may receive this callback
|
||||
* before the buffer has been set up in the main code. It's probably
|
||||
* possible to fix with additional locking, but it's easier just to
|
||||
* ignore input until the buffer is ready.
|
||||
*/
|
||||
if (pulse->buffer == NULL)
|
||||
{
|
||||
/* fprintf(stderr, "%s: ignoring input, pulse buffer not ready.\n", __func__); */
|
||||
return;
|
||||
}
|
||||
|
||||
pa_stream_peek(stream, &data, &length);
|
||||
frames = length / pulse->bytes_per_frame;
|
||||
|
||||
@@ -373,6 +384,7 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
pulse->buffer = NULL;
|
||||
pulse->receive = receive;
|
||||
pulse->user_data = user_data;
|
||||
|
||||
|
||||
@@ -19,16 +19,16 @@ set(MODULE_NAME "freerdp-channels-client")
|
||||
set(MODULE_PREFIX "FREERDP_CHANNELS_CLIENT")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
tables.c
|
||||
tables.h
|
||||
addin.c
|
||||
addin.h
|
||||
init.c
|
||||
init.h
|
||||
open.c
|
||||
open.h
|
||||
channels.c
|
||||
channels.h)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tables.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tables.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.h)
|
||||
|
||||
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
|
||||
|
||||
@@ -96,7 +96,7 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
|
||||
endforeach()
|
||||
set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};")
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_SOURCE_DIR}/tables.c)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_BINARY_DIR}/tables.c)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
||||
@@ -441,10 +441,14 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface)
|
||||
{
|
||||
int status = 0;
|
||||
ChannelConnectedEventArgs e;
|
||||
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||
freerdp* instance = channels->instance;
|
||||
|
||||
IFCALLRET(instance->OnChannelConnected, status, instance, name, pInterface);
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pInterface;
|
||||
PubSub_OnChannelConnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -452,10 +456,14 @@ int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const ch
|
||||
int freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, const char* name, void* pInterface)
|
||||
{
|
||||
int status = 0;
|
||||
ChannelDisconnectedEventArgs e;
|
||||
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||
freerdp* instance = channels->instance;
|
||||
|
||||
IFCALLRET(instance->OnChannelDisconnected, status, instance, name, pInterface);
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pInterface;
|
||||
PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -87,14 +87,15 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS
|
||||
if (!cliprdr->use_long_format_names)
|
||||
name_length = 32;
|
||||
|
||||
Stream_EnsureRemainingCapacity(body, Stream_Capacity(body) + 4 + name_length);
|
||||
Stream_EnsureRemainingCapacity(body, 4 + name_length);
|
||||
|
||||
Stream_Write_UINT32(body, cb_event->formats[i]);
|
||||
Stream_Write(body, name, name_length);
|
||||
}
|
||||
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Capacity(body));
|
||||
Stream_Write(s, Stream_Buffer(body), Stream_Capacity(body));
|
||||
Stream_SealLength(body);
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Length(body));
|
||||
Stream_Write(s, Stream_Buffer(body), Stream_Length(body));
|
||||
Stream_Free(body, TRUE);
|
||||
}
|
||||
|
||||
@@ -290,16 +291,16 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
|
||||
|
||||
void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
|
||||
{
|
||||
/* where is this documented? */
|
||||
#if 0
|
||||
/* http://msdn.microsoft.com/en-us/library/hh872154.aspx */
|
||||
wMessage* event;
|
||||
|
||||
if ((msgFlags & CB_RESPONSE_FAIL) != 0)
|
||||
{
|
||||
event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL);
|
||||
/* In case of an error the clipboard will not be synchronized with the server.
|
||||
* Post this event to restart format negociation and data transfer. */
|
||||
event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
|
||||
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
|
||||
|
||||
22
channels/disp/CMakeLists.txt
Normal file
22
channels/disp/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel("disp")
|
||||
|
||||
if(WITH_CLIENT_CHANNELS)
|
||||
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
||||
12
channels/disp/ChannelOptions.cmake
Normal file
12
channels/disp/ChannelOptions.cmake
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
set(OPTION_DEFAULT OFF)
|
||||
set(OPTION_CLIENT_DEFAULT ON)
|
||||
set(OPTION_SERVER_DEFAULT OFF)
|
||||
|
||||
define_channel_options(NAME "disp" TYPE "dynamic"
|
||||
DESCRIPTION "Display Update Virtual Channel Extension"
|
||||
SPECIFICATIONS "[MS-RDPEDISP]"
|
||||
DEFAULT ${OPTION_DEFAULT})
|
||||
|
||||
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
|
||||
define_channel_server_options(${OPTION_SERVER_DEFAULT})
|
||||
47
channels/disp/client/CMakeLists.txt
Normal file
47
channels/disp/client/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel_client("disp")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
disp_main.c
|
||||
disp_main.h)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-common freerdp-utils)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-sysinfo)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
341
channels/disp/client/disp_main.c
Normal file
341
channels/disp/client/disp_main.c
Normal file
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include "disp_main.h"
|
||||
|
||||
struct _DISP_CHANNEL_CALLBACK
|
||||
{
|
||||
IWTSVirtualChannelCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
IWTSVirtualChannel* channel;
|
||||
};
|
||||
typedef struct _DISP_CHANNEL_CALLBACK DISP_CHANNEL_CALLBACK;
|
||||
|
||||
struct _DISP_LISTENER_CALLBACK
|
||||
{
|
||||
IWTSListenerCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
DISP_CHANNEL_CALLBACK* channel_callback;
|
||||
};
|
||||
typedef struct _DISP_LISTENER_CALLBACK DISP_LISTENER_CALLBACK;
|
||||
|
||||
struct _DISP_PLUGIN
|
||||
{
|
||||
IWTSPlugin iface;
|
||||
|
||||
IWTSListener* listener;
|
||||
DISP_LISTENER_CALLBACK* listener_callback;
|
||||
|
||||
UINT32 MaxNumMonitors;
|
||||
UINT32 MaxMonitorWidth;
|
||||
UINT32 MaxMonitorHeight;
|
||||
};
|
||||
typedef struct _DISP_PLUGIN DISP_PLUGIN;
|
||||
|
||||
int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||
{
|
||||
int index;
|
||||
int status;
|
||||
wStream* s;
|
||||
UINT32 type;
|
||||
UINT32 length;
|
||||
DISP_PLUGIN* disp;
|
||||
UINT32 MonitorLayoutSize;
|
||||
|
||||
disp = (DISP_PLUGIN*) callback->plugin;
|
||||
|
||||
#ifdef DISP_PREVIEW
|
||||
MonitorLayoutSize = 32;
|
||||
#else
|
||||
MonitorLayoutSize = 40;
|
||||
#endif
|
||||
|
||||
length = 8 + 8 + (NumMonitors * MonitorLayoutSize);
|
||||
|
||||
type = DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
Stream_Write_UINT32(s, type); /* Type (4 bytes) */
|
||||
Stream_Write_UINT32(s, length); /* Length (4 bytes) */
|
||||
|
||||
if (NumMonitors > disp->MaxNumMonitors)
|
||||
NumMonitors = disp->MaxNumMonitors;
|
||||
|
||||
#ifdef DISP_PREVIEW
|
||||
Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */
|
||||
#else
|
||||
Stream_Write_UINT32(s, MonitorLayoutSize); /* MonitorLayoutSize (4 bytes) */
|
||||
#endif
|
||||
|
||||
Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "NumMonitors: %d\n", NumMonitors);
|
||||
|
||||
for (index = 0; index < NumMonitors; index++)
|
||||
{
|
||||
Monitors[index].Width -= (Monitors[index].Width % 2);
|
||||
|
||||
if (Monitors[index].Width < 200)
|
||||
Monitors[index].Width = 200;
|
||||
|
||||
if (Monitors[index].Width > disp->MaxMonitorWidth)
|
||||
Monitors[index].Width = disp->MaxMonitorWidth;
|
||||
|
||||
if (Monitors[index].Height < 200)
|
||||
Monitors[index].Height = 200;
|
||||
|
||||
if (Monitors[index].Height > disp->MaxMonitorHeight)
|
||||
Monitors[index].Height = disp->MaxMonitorHeight;
|
||||
|
||||
Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Width); /* Width (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Height); /* Height (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags);
|
||||
fprintf(stderr, "\t: Left: %d\n", Monitors[index].Left);
|
||||
fprintf(stderr, "\t: Top: %d\n", Monitors[index].Top);
|
||||
fprintf(stderr, "\t: Width: %d\n", Monitors[index].Width);
|
||||
fprintf(stderr, "\t: Height: %d\n", Monitors[index].Height);
|
||||
fprintf(stderr, "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth);
|
||||
fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight);
|
||||
fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation);
|
||||
#endif
|
||||
|
||||
#ifndef DISP_PREVIEW
|
||||
Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */
|
||||
#endif
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
DISP_PLUGIN* disp;
|
||||
|
||||
disp = (DISP_PLUGIN*) callback->plugin;
|
||||
|
||||
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
|
||||
Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */
|
||||
Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n",
|
||||
// disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
UINT32 type;
|
||||
UINT32 length;
|
||||
|
||||
Stream_Read_UINT32(s, type); /* Type (4 bytes) */
|
||||
Stream_Read_UINT32(s, length); /* Length (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "Type: %d Length: %d\n", type, length);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DISPLAY_CONTROL_PDU_TYPE_CAPS:
|
||||
disp_recv_display_control_caps_pdu(callback, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer)
|
||||
{
|
||||
wStream* s;
|
||||
int status = 0;
|
||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
s = Stream_New(pBuffer, cbSize);
|
||||
|
||||
status = disp_recv_pdu(callback, s);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int disp_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
if (callback)
|
||||
{
|
||||
free(callback);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
||||
IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept,
|
||||
IWTSVirtualChannelCallback** ppCallback)
|
||||
{
|
||||
DISP_CHANNEL_CALLBACK* callback;
|
||||
DISP_LISTENER_CALLBACK* listener_callback = (DISP_LISTENER_CALLBACK*) pListenerCallback;
|
||||
|
||||
callback = (DISP_CHANNEL_CALLBACK*) malloc(sizeof(DISP_CHANNEL_CALLBACK));
|
||||
ZeroMemory(callback, sizeof(DISP_CHANNEL_CALLBACK));
|
||||
|
||||
callback->iface.OnDataReceived = disp_on_data_received;
|
||||
callback->iface.OnClose = disp_on_close;
|
||||
callback->plugin = listener_callback->plugin;
|
||||
callback->channel_mgr = listener_callback->channel_mgr;
|
||||
callback->channel = pChannel;
|
||||
listener_callback->channel_callback = callback;
|
||||
|
||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
int status;
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
||||
|
||||
disp->listener_callback = (DISP_LISTENER_CALLBACK*) malloc(sizeof(DISP_LISTENER_CALLBACK));
|
||||
ZeroMemory(disp->listener_callback, sizeof(DISP_LISTENER_CALLBACK));
|
||||
|
||||
disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection;
|
||||
disp->listener_callback->plugin = pPlugin;
|
||||
disp->listener_callback->channel_mgr = pChannelMgr;
|
||||
|
||||
status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0,
|
||||
(IWTSListenerCallback*) disp->listener_callback, &(disp->listener));
|
||||
|
||||
disp->listener->pInterface = disp->iface.pInterface;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int disp_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
||||
|
||||
if (disp)
|
||||
{
|
||||
free(disp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel Client Interface
|
||||
*/
|
||||
|
||||
int disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||
{
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) context->handle;
|
||||
DISP_CHANNEL_CALLBACK* callback = disp->listener_callback->channel_callback;
|
||||
|
||||
disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry disp_DVCPluginEntry
|
||||
#endif
|
||||
|
||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
int error = 0;
|
||||
DISP_PLUGIN* disp;
|
||||
DispClientContext* context;
|
||||
|
||||
disp = (DISP_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "disp");
|
||||
|
||||
if (disp == NULL)
|
||||
{
|
||||
disp = (DISP_PLUGIN*) malloc(sizeof(DISP_PLUGIN));
|
||||
|
||||
if (disp)
|
||||
{
|
||||
ZeroMemory(disp, sizeof(DISP_PLUGIN));
|
||||
|
||||
disp->iface.Initialize = disp_plugin_initialize;
|
||||
disp->iface.Connected = NULL;
|
||||
disp->iface.Disconnected = NULL;
|
||||
disp->iface.Terminated = disp_plugin_terminated;
|
||||
|
||||
context = (DispClientContext*) malloc(sizeof(DispClientContext));
|
||||
|
||||
context->handle = (void*) disp;
|
||||
|
||||
context->SendMonitorLayout = disp_send_monitor_layout;
|
||||
|
||||
disp->iface.pInterface = (void*) context;
|
||||
|
||||
disp->MaxNumMonitors = 16;
|
||||
disp->MaxMonitorWidth = 8192;
|
||||
disp->MaxMonitorHeight = 8192;
|
||||
|
||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
40
channels/disp/client/disp_main.h
Normal file
40
channels/disp/client/disp_main.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_DISP_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_DISP_CLIENT_MAIN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
|
||||
#include <freerdp/client/disp.h>
|
||||
|
||||
#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000003
|
||||
|
||||
#define DISP_PREVIEW 1
|
||||
|
||||
#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */
|
||||
|
||||
@@ -376,16 +376,13 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
|
||||
{
|
||||
DEBUG_WARN("channel rejected by plugin");
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,7 @@ static void parallel_free(DEVICE* device)
|
||||
MessageQueue_PostQuit(parallel->queue, 0);
|
||||
WaitForSingleObject(parallel->thread, INFINITE);
|
||||
|
||||
Stream_Free(parallel->device.data, TRUE);
|
||||
MessageQueue_Free(parallel->queue);
|
||||
CloseHandle(parallel->thread);
|
||||
|
||||
|
||||
@@ -179,13 +179,16 @@ static void* printer_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg;
|
||||
HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(printer_dev->event, INFINITE);
|
||||
DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(printer_dev->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (rc == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
else if( rc != WAIT_OBJECT_0 )
|
||||
continue;
|
||||
|
||||
ResetEvent(printer_dev->event);
|
||||
|
||||
|
||||
@@ -96,9 +96,10 @@ struct _RDPEI_PLUGIN
|
||||
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
|
||||
RDPINPUT_CONTACT_POINT* contactPoints;
|
||||
|
||||
HANDLE mutex;
|
||||
HANDLE event;
|
||||
HANDLE thread;
|
||||
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
|
||||
|
||||
@@ -160,7 +161,7 @@ static void* rdpei_schedule_thread(void* arg)
|
||||
{
|
||||
status = WaitForSingleObject(rdpei->event, 20);
|
||||
|
||||
WaitForSingleObject(rdpei->mutex, INFINITE);
|
||||
EnterCriticalSection(&rdpei->lock);
|
||||
|
||||
rdpei_add_frame(context);
|
||||
|
||||
@@ -170,7 +171,7 @@ static void* rdpei_schedule_thread(void* arg)
|
||||
if (status == WAIT_OBJECT_0)
|
||||
ResetEvent(rdpei->event);
|
||||
|
||||
ReleaseMutex(rdpei->mutex);
|
||||
LeaveCriticalSection(&rdpei->lock);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -212,14 +213,14 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||
|
||||
Stream_Write_UINT32(s, flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V1); /* protocolVersion (4 bytes) */
|
||||
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V10); /* protocolVersion (4 bytes) */
|
||||
Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
if (!rdpei->thread)
|
||||
{
|
||||
rdpei->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&rdpei->lock);
|
||||
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL);
|
||||
}
|
||||
@@ -249,6 +250,7 @@ void rdpei_print_contact_flags(UINT32 contactFlags)
|
||||
int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
{
|
||||
int index;
|
||||
int rectSize = 2;
|
||||
RDPINPUT_CONTACT_DATA* contact;
|
||||
|
||||
#ifdef WITH_DEBUG_RDPEI
|
||||
@@ -264,12 +266,18 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
*/
|
||||
rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
|
||||
Stream_EnsureRemainingCapacity(s, frame->contactCount * 64);
|
||||
|
||||
for (index = 0; index < frame->contactCount; index++)
|
||||
{
|
||||
contact = &frame->contacts[index];
|
||||
|
||||
contact->fieldsPresent |= CONTACT_DATA_CONTACTRECT_PRESENT;
|
||||
contact->contactRectLeft = contact->x - rectSize;
|
||||
contact->contactRectTop = contact->y - rectSize;
|
||||
contact->contactRectRight = contact->x + rectSize;
|
||||
contact->contactRectBottom = contact->y + rectSize;
|
||||
|
||||
#ifdef WITH_DEBUG_RDPEI
|
||||
printf("contact[%d].contactId: %d\n", index, contact->contactId);
|
||||
printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent);
|
||||
@@ -325,7 +333,7 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
|
||||
wStream* s;
|
||||
UINT32 pduLength;
|
||||
|
||||
pduLength = 64 + (frame->contactCount * 32);
|
||||
pduLength = 64 + (frame->contactCount * 64);
|
||||
|
||||
s = Stream_New(NULL, pduLength);
|
||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||
@@ -355,11 +363,13 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
|
||||
Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */
|
||||
|
||||
if (protocolVersion != RDPINPUT_PROTOCOL_V1)
|
||||
#if 0
|
||||
if (protocolVersion != RDPINPUT_PROTOCOL_V10)
|
||||
{
|
||||
fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -533,7 +543,7 @@ int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contac
|
||||
RDPINPUT_CONTACT_POINT* contactPoint;
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
|
||||
WaitForSingleObject(rdpei->mutex, INFINITE);
|
||||
EnterCriticalSection(&rdpei->lock);
|
||||
|
||||
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId];
|
||||
CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||
@@ -541,7 +551,7 @@ int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contac
|
||||
|
||||
SetEvent(rdpei->event);
|
||||
|
||||
ReleaseMutex(rdpei->mutex);
|
||||
LeaveCriticalSection(&rdpei->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
|
||||
/* Protocol Version */
|
||||
|
||||
#define RDPINPUT_PROTOCOL_V1 0x00010000
|
||||
#define RDPINPUT_PROTOCOL_V10 0x00010000
|
||||
#define RDPINPUT_PROTOCOL_V101 0x00010001
|
||||
|
||||
/* Client Ready Flags */
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ struct _SERIAL_DEVICE
|
||||
|
||||
wQueue* queue;
|
||||
LIST* pending_irps;
|
||||
HANDLE in_event;
|
||||
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
@@ -324,35 +323,31 @@ static void* serial_thread_func(void* arg)
|
||||
IRP* irp;
|
||||
DWORD status;
|
||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||
HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue)};
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
status = WaitForMultipleObjects(2, ev, FALSE, 1);
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(serial->queue), 10) == WAIT_OBJECT_0)
|
||||
if (WAIT_OBJECT_0 == status)
|
||||
break;
|
||||
|
||||
serial->nfds = 1;
|
||||
FD_ZERO(&serial->read_fds);
|
||||
FD_ZERO(&serial->write_fds);
|
||||
|
||||
serial->tv.tv_sec = 1;
|
||||
serial->tv.tv_sec = 0;
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
irp = (IRP*) Queue_Dequeue(serial->queue);
|
||||
|
||||
if (irp)
|
||||
serial_process_irp(serial, irp);
|
||||
|
||||
status = WaitForSingleObject(serial->in_event, 0);
|
||||
|
||||
if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT))
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
if (serial_check_fds(serial))
|
||||
ResetEvent(serial->in_event);
|
||||
if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
|
||||
serial_process_irp(serial, irp);
|
||||
continue;
|
||||
}
|
||||
|
||||
serial_check_fds(serial);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -371,10 +366,18 @@ static void serial_free(DEVICE* device)
|
||||
|
||||
DEBUG_SVC("freeing device");
|
||||
|
||||
/* Stop thread */
|
||||
SetEvent(serial->stopEvent);
|
||||
WaitForSingleObject(serial->thread, INFINITE);
|
||||
|
||||
/* TODO: free lists */
|
||||
serial_tty_free(serial->tty);
|
||||
|
||||
/* Clean up resources */
|
||||
Stream_Free(serial->device.data, TRUE);
|
||||
Queue_Free(serial->queue);
|
||||
list_free(serial->pending_irps);
|
||||
CloseHandle(serial->stopEvent);
|
||||
CloseHandle(serial->thread);
|
||||
free(serial);
|
||||
}
|
||||
|
||||
@@ -387,6 +390,11 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (abort_io)
|
||||
{
|
||||
@@ -423,7 +431,6 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
|
||||
Stream_Write_UINT32(irp->output, 0);
|
||||
irp->Complete(irp);
|
||||
|
||||
SetEvent(serial->in_event);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -438,6 +445,11 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
|
||||
SERIAL_TTY* tty;
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
@@ -460,8 +472,6 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
|
||||
prev = irp;
|
||||
irp = (IRP*) list_next(serial->pending_irps, irp);
|
||||
list_remove(serial->pending_irps, prev);
|
||||
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,6 +495,11 @@ void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, UINT32* timeout, UINT3
|
||||
DEBUG_SVC("length read %u", Length);
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
*timeout = (tty->read_total_timeout_multiplier * Length) + tty->read_total_timeout_constant;
|
||||
*interval_timeout = tty->read_interval_timeout;
|
||||
@@ -499,6 +514,11 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
|
||||
SERIAL_TTY* tty;
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (irp->MajorFunction)
|
||||
{
|
||||
@@ -537,7 +557,6 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
|
||||
|
||||
irp->IoStatus = STATUS_PENDING;
|
||||
list_enqueue(serial->pending_irps, irp);
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
|
||||
static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
@@ -550,6 +569,11 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
|
||||
ZeroMemory(&serial->tv, sizeof(struct timeval));
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
/* scan every pending */
|
||||
irp = list_peek(serial->pending_irps);
|
||||
@@ -599,10 +623,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
irp = (IRP*) list_next(serial->pending_irps, irp);
|
||||
|
||||
if (irp_completed || (prev->IoStatus == STATUS_SUCCESS))
|
||||
{
|
||||
list_remove(serial->pending_irps, prev);
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,6 +636,11 @@ static void serial_set_fds(SERIAL_DEVICE* serial)
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
irp = (IRP*) list_peek(serial->pending_irps);
|
||||
|
||||
while (irp)
|
||||
@@ -692,7 +718,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
name = device->Name;
|
||||
path = device->Path;
|
||||
|
||||
if (name[0] && path[0])
|
||||
if ((name && name[0]) && (path && path[0]))
|
||||
{
|
||||
serial = (SERIAL_DEVICE*) malloc(sizeof(SERIAL_DEVICE));
|
||||
ZeroMemory(serial, sizeof(SERIAL_DEVICE));
|
||||
@@ -711,13 +737,13 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
serial->path = path;
|
||||
serial->queue = Queue_New(TRUE, -1, -1);
|
||||
serial->pending_irps = list_new();
|
||||
serial->in_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
serial->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial);
|
||||
|
||||
serial->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
|
||||
serial->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -412,7 +412,11 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
|
||||
status = read(tty->fd, buffer, *Length);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
DEBUG_WARN("failed with %zd, errno=[%d] %s\n",
|
||||
status, errno, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tty->event_txempty = status;
|
||||
*Length = status;
|
||||
@@ -456,6 +460,9 @@ void serial_tty_free(SERIAL_TTY* tty)
|
||||
{
|
||||
DEBUG_SVC("in");
|
||||
|
||||
if(!tty)
|
||||
return;
|
||||
|
||||
if (tty->fd >= 0)
|
||||
{
|
||||
if (tty->pold_termios)
|
||||
|
||||
@@ -40,7 +40,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked)
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked winpr-error)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
||||
@@ -44,8 +44,7 @@ static void smartcard_free(DEVICE* dev)
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev;
|
||||
|
||||
SetEvent(smartcard->stopEvent);
|
||||
CloseHandle(smartcard->thread);
|
||||
CloseHandle(smartcard->irpEvent);
|
||||
WaitForSingleObject(smartcard->thread, INFINITE);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
@@ -55,8 +54,14 @@ static void smartcard_free(DEVICE* dev)
|
||||
/* Begin TS Client defect workaround. */
|
||||
|
||||
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL)
|
||||
free(CompletionIdInfo);
|
||||
free(CompletionIdInfo);
|
||||
|
||||
CloseHandle(smartcard->thread);
|
||||
CloseHandle(smartcard->irpEvent);
|
||||
CloseHandle(smartcard->stopEvent);
|
||||
CloseHandle(smartcard->CompletionIdsMutex);
|
||||
|
||||
Stream_Free(smartcard->device.data, TRUE);
|
||||
list_free(smartcard->CompletionIds);
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
@@ -119,13 +124,16 @@ static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
|
||||
static void* smartcard_thread_func(void* arg)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
|
||||
HANDLE ev[] = {smartcard->irpEvent, smartcard->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(smartcard->irpEvent, INFINITE);
|
||||
DWORD status = WaitForSingleObject(2, ev, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
else if(status != WAIT_OBJECT_0)
|
||||
continue;
|
||||
|
||||
ResetEvent(smartcard->irpEvent);
|
||||
smartcard_process_irp_list(smartcard);
|
||||
|
||||
@@ -669,7 +669,6 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder * decoder, TS_AM_MEDIA_TYPE *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1133,12 +1132,12 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEX_AUDIO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_AUDIO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
|
||||
@@ -1176,7 +1175,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
*/
|
||||
if (start_time > (mdecoder->last_sample_end_time + 10000000) || (end_time + 10000000) < mdecoder->last_sample_end_time)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%llu] > last_sample_end_time=[%llu]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_end_time=[%"PRIu64"]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: Stream seek detected - flushing element.");
|
||||
tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL);
|
||||
gst_object_unref(mdecoder->pipe);
|
||||
@@ -1205,7 +1204,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (fout)
|
||||
{
|
||||
fprintf(fout, "%"PRIu64"\n", (long unsigned int) start_time);
|
||||
fprintf(fout, "%"PRIu64"\n", start_time);
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
@@ -1231,7 +1230,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 AStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &AStartTime);
|
||||
fscanf(fin, "%"PRIu64, &AStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > AStartTime)
|
||||
{
|
||||
@@ -1265,7 +1264,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 VStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &VStartTime);
|
||||
fscanf(fin, "%"PRIu64, &VStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > VStartTime)
|
||||
{
|
||||
@@ -1283,7 +1282,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
pthread_mutex_unlock(&mdecoder->gst_mutex);
|
||||
DEBUG_WARN("tsmf_gstreamer_decodeEx: gst_buffer_try_new_and_alloc(%d) failed.", data_size);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
gst_buffer_set_caps(gst_buf, mdecoder->gst_caps);
|
||||
memcpy(GST_BUFFER_MALLOCDATA(gst_buf), data, data_size);
|
||||
GST_BUFFER_TIMESTAMP(gst_buf) = tsmf_gstreamer_timestamp_ms_to_gst(start_time);
|
||||
@@ -1325,20 +1324,21 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder * decoder, UINT32 newVolum
|
||||
if (mdecoder->shutdown)
|
||||
return;
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
return;
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
return;
|
||||
|
||||
if (!G_IS_OBJECT(mdecoder->aVolume))
|
||||
return;
|
||||
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
g_object_set(mdecoder->aVolume, "mute", mdecoder->gstMuted, NULL);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
g_object_set(mdecoder->aVolume, "volume", mdecoder->gstVolume, NULL);
|
||||
}
|
||||
|
||||
@@ -1482,7 +1482,7 @@ static UINT64 tsmf_gstreamer_get_running_time(ITSMFDecoder * decoder)
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
gint64 pos = 0;
|
||||
gst_element_query_position (mdecoder->outsink, &fmt, &pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%llu]", pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%"PRIu64"]", pos);
|
||||
return pos/100;
|
||||
}
|
||||
|
||||
@@ -1524,13 +1524,14 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
{
|
||||
if (info->noutput > 0)
|
||||
{
|
||||
if (info->outputs[0] == primary_output)
|
||||
if (info->outputs[0] == primary_output || i == 0)
|
||||
{
|
||||
mdecoder->xOffset = info->x;
|
||||
mdecoder->yOffset = info->y;
|
||||
}
|
||||
DEBUG_DVC("output %d ID: %lu (x,y): (%d,%d) (w,h): (%d,%d) primary: %d", i, info->outputs[0], info->x, info->y, info->width, info->height, (info->outputs[0] == primary_output));
|
||||
}
|
||||
XRRFreeCrtcInfo(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1545,7 +1546,12 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
if(mdecoder->subwin)
|
||||
{
|
||||
XMoveWindow(mdecoder->disp, mdecoder->subwin, anewX, anewY);
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
|
||||
if(newWidth > 0 && newHeight > 0) {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
|
||||
} else {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, 1, 1);
|
||||
}
|
||||
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
XShapeCombineRectangles (mdecoder->disp, mdecoder->subwin, ShapeBounding, 0, 0,(XRectangle*) rectangles, numRectangles, ShapeSet, Unsorted);
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
@@ -1599,7 +1605,7 @@ ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
|
||||
decoder->xOffset = 0;
|
||||
decoder->yOffset = 0;
|
||||
decoder->offsetObtained = FALSE;
|
||||
decoder->gstVolume = 1.0;
|
||||
decoder->gstVolume = 0.5;
|
||||
decoder->gstMuted = FALSE;
|
||||
decoder->state = GST_STATE_VOID_PENDING; /* No real state yet */
|
||||
pthread_mutex_init(&decoder->gst_mutex, NULL);
|
||||
|
||||
@@ -127,8 +127,6 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static TSMF_PRESENTATION* pexisted = 0;
|
||||
|
||||
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
{
|
||||
int status = 0;
|
||||
@@ -136,15 +134,16 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
if (pexisted)
|
||||
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
|
||||
if (presentation)
|
||||
{
|
||||
DEBUG_DVC("Presentation already exists");
|
||||
ifman->output_pending = FALSE;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
|
||||
pexisted = presentation;
|
||||
|
||||
if (presentation == NULL)
|
||||
status = 1;
|
||||
@@ -283,8 +282,8 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
if (presentation)
|
||||
tsmf_presentation_free(presentation);
|
||||
|
||||
pexisted = 0;
|
||||
else
|
||||
DEBUG_WARN("unknown presentation id");
|
||||
|
||||
Stream_EnsureRemainingCapacity(ifman->output, 4);
|
||||
Stream_Write_UINT32(ifman->output, 0); /* Result */
|
||||
|
||||
@@ -84,6 +84,9 @@ struct _TSMF_PRESENTATION
|
||||
UINT64 audio_start_time;
|
||||
UINT64 audio_end_time;
|
||||
|
||||
UINT32 volume;
|
||||
UINT32 muted;
|
||||
|
||||
HANDLE mutex;
|
||||
HANDLE thread;
|
||||
|
||||
@@ -282,6 +285,9 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
|
||||
memcpy(presentation->presentation_id, guid, GUID_SIZE);
|
||||
presentation->channel_callback = pChannelCallback;
|
||||
|
||||
presentation->volume = 5000; /* 50% */
|
||||
presentation->muted = 0;
|
||||
|
||||
presentation->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
presentation->stream_list = list_new();
|
||||
|
||||
@@ -786,6 +792,9 @@ void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 ne
|
||||
LIST_ITEM* item;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
presentation->volume = newVolume;
|
||||
presentation->muted = muted;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
@@ -964,7 +973,10 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
|
||||
stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
|
||||
|
||||
stream->sample_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_list->object.fnObjectFree = free;
|
||||
|
||||
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_ack_list->object.fnObjectFree = free;
|
||||
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_enqueue(presentation->stream_list, stream);
|
||||
@@ -1026,6 +1038,7 @@ void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s)
|
||||
stream->width = mediatype.Width;
|
||||
stream->height = mediatype.Height;
|
||||
stream->decoder = tsmf_load_decoder(name, &mediatype);
|
||||
tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted);
|
||||
}
|
||||
|
||||
void tsmf_stream_end(TSMF_STREAM* stream)
|
||||
|
||||
@@ -31,6 +31,10 @@ set(${MODULE_PREFIX}_SRCS
|
||||
|
||||
include_directories(..)
|
||||
|
||||
find_package(UDev REQUIRED)
|
||||
find_package(UUID REQUIRED)
|
||||
find_package(DbusGlib REQUIRED)
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
@@ -38,9 +42,9 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
#set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS
|
||||
dbus-glib-1
|
||||
udev
|
||||
uuid)
|
||||
${DBUS_GLIB_LIBRARIES}
|
||||
${UDEV_LIBRARIES}
|
||||
${UUID_LIBRARIES})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
||||
@@ -27,6 +27,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
|
||||
include_directories(..)
|
||||
|
||||
find_package(libusb-1.0 REQUIRED)
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
@@ -35,9 +37,10 @@ set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
dbus-glib-1
|
||||
usb-1.0
|
||||
udev)
|
||||
${DBUS_GLIB_LIBRARIES}
|
||||
${UUID_LIBRARIES}
|
||||
${LIBUSB_1_LIBRARIES}
|
||||
)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
||||
@@ -686,7 +686,8 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin
|
||||
settings->GatewayUsername = strdup(gatewayusername);
|
||||
settings->GatewayPassword = strdup(gatewaypassword);
|
||||
settings->GatewayDomain = strdup(gatewaydomain);
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
settings->GatewayUseSameCredentials = FALSE;
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname);
|
||||
|
||||
@@ -248,6 +248,9 @@ public class SessionActivity extends Activity
|
||||
{
|
||||
Log.v(TAG, "OnConnectionFailure");
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@@ -264,7 +267,10 @@ public class SessionActivity extends Activity
|
||||
private void OnDisconnected(Context context)
|
||||
{
|
||||
Log.v(TAG, "OnDisconnected");
|
||||
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@@ -434,6 +440,7 @@ public class SessionActivity extends Activity
|
||||
|
||||
keyboardMapper = new KeyboardMapper();
|
||||
keyboardMapper.init(this);
|
||||
keyboardMapper.reset(this);
|
||||
|
||||
modifiersKeyboard = new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
|
||||
specialkeysKeyboard = new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);
|
||||
|
||||
@@ -65,7 +65,9 @@ public abstract class ClipboardManagerProxy {
|
||||
String data = null;
|
||||
|
||||
if (clip != null && clip.getItemCount() > 0) {
|
||||
data = clip.getItemAt(0).getText().toString();
|
||||
CharSequence cs = clip.getItemAt(0).getText();
|
||||
if (cs != null)
|
||||
data = cs.toString();
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onClipboardChanged(data);
|
||||
|
||||
@@ -57,4 +57,4 @@ endif()
|
||||
|
||||
if (WITH_DOTNET)
|
||||
add_subdirectory(DotNetClient)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
project(MacFreeRDP-library)
|
||||
|
||||
set(MODULE_NAME "MacFreeRDP-library")
|
||||
set(MODULE_OUTPUT_NAME "MacFreeRDP")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_MAC-LIB")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_MAC_LIBRARY")
|
||||
|
||||
# Import frameworks
|
||||
find_library(FOUNDATION_LIBRARY Foundation)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
@@ -21,53 +21,57 @@ set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0)
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0)
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013. All Rights Reserved.")
|
||||
|
||||
set(${MODULE_NAME}_RESOURCES "en.lproj/InfoPlist.strings")
|
||||
set(${MODULE_PREFIX}_XIBS PasswordDialog.xib)
|
||||
|
||||
# OS X Interface Builder files
|
||||
file(GLOB ${MODULE_NAME}_XIBS *.xib)
|
||||
set(${MODULE_PREFIX}_SOURCES "")
|
||||
|
||||
# source files
|
||||
file(GLOB ${MODULE_NAME}_SRC *.c *.m)
|
||||
set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
|
||||
main.m
|
||||
mf_client.m
|
||||
MRDPCursor.m
|
||||
MRDPView.m
|
||||
PasswordDialog.m)
|
||||
|
||||
# header files
|
||||
file(GLOB ${MODULE_NAME}_HEADERS *.h)
|
||||
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
|
||||
|
||||
set(${MODULE_PREFIX}_HEADERS
|
||||
mfreerdp.h
|
||||
mf_client.h
|
||||
MRDPCursor.h
|
||||
MRDPView.h
|
||||
PasswordDialog.h)
|
||||
|
||||
set(${MODULE_PREFIX}_RESOURCES "en.lproj/InfoPlist.strings")
|
||||
|
||||
# Include XIB file in Xcode resources.
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
|
||||
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
|
||||
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS})
|
||||
set(${MODULE_PREFIX}_RESOURCES ${${MODULE_PREFIX}_RESOURCES} ${${MODULE_PREFIX}_XIBS})
|
||||
endif()
|
||||
|
||||
add_library(${MODULE_NAME}
|
||||
SHARED
|
||||
../common/client.c
|
||||
${${MODULE_NAME}_SRC}
|
||||
${${MODULE_NAME}_HEADERS}
|
||||
${${MODULE_NAME}_RESOURCES})
|
||||
${${MODULE_PREFIX}_SOURCES}
|
||||
${${MODULE_PREFIX}_HEADERS}
|
||||
${${MODULE_PREFIX}_RESOURCES})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
|
||||
|
||||
# configures the framework to always be looked for in the application bundle in the Frameworks sub-folder.
|
||||
SET_TARGET_PROPERTIES(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/)
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
# Support for automatic reference counting requires non-fragile abi.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
|
||||
|
||||
set(MODULE_VERSION, 1.1.0)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
MACOSX_FRAMEWORK_IDENTIFIER com.awakecoding.${MODULE_NAME}
|
||||
FRAMEWORK_VERSION 1.1.0
|
||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING 1.1.0
|
||||
MACOSX_FRAMEWORK_BUNDLE_VERSION 1.1.0
|
||||
INSTALL_NAME_DIR "@executable_path/../../Frameworks"
|
||||
MACOSX_FRAMEWORK_BUNDLE_BUNDLE_VERSION 1.1.0
|
||||
INSTALL_NAME_DIR "@executable_path/../Frameworks"
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
|
||||
BUILD_WITH_INSTALL_RPATH 1)
|
||||
|
||||
@@ -106,15 +110,15 @@ if (${BUILD_SHARED_LIBS})
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
COMMENT "Copying ${LIB} to output directory"
|
||||
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}"
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}"
|
||||
COMMENT Setting install name for ${LIB}
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}")
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}")
|
||||
endforeach()
|
||||
|
||||
# Call install_name_tool to reassign the library install names in dependent libraries
|
||||
@@ -123,8 +127,8 @@ if (${BUILD_SHARED_LIBS})
|
||||
# message("adding post-build dependency: ${LIB}")
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
COMMENT Setting install name for ${LIB} in module ${DEST})
|
||||
endforeach()
|
||||
endforeach()
|
||||
@@ -132,7 +136,7 @@ if (${BUILD_SHARED_LIBS})
|
||||
endif()
|
||||
|
||||
# Add post-build NIB file generation in unix makefiles. XCode handles this implicitly.
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
# if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
message(STATUS "Adding post-build NIB file generation event for ${MODULE_NAME}")
|
||||
|
||||
# Make sure we can find the 'ibtool' program. If we can NOT find it we
|
||||
@@ -145,7 +149,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
|
||||
# Make sure the 'Resources' Directory is correctly created before we build
|
||||
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources)
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources)
|
||||
|
||||
# Compile the .xib files using the 'ibtool' program with the destination being the app package
|
||||
foreach(xib ${${MODULE_NAME}_XIBS})
|
||||
@@ -153,22 +157,23 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
|
||||
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources/${XIB_WE}.nib ${CMAKE_CURRENT_SOURCE_DIR}/${xib}
|
||||
COMMENT "Compiling ${xib}")
|
||||
endforeach()
|
||||
endif()
|
||||
# endif()
|
||||
|
||||
# Copy the public header files into the framework
|
||||
foreach(HEADER ${${MODULE_NAME}_HEADERS})
|
||||
foreach(HEADER ${${MODULE_PREFIX}_HEADERS})
|
||||
# message("adding post-build dependency: ${LIB}")
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/
|
||||
COMMAND ditto ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/
|
||||
COMMENT Copying public header files to ${MODULE_NAME})
|
||||
endforeach()
|
||||
|
||||
# Copy the FreeRDP header files into the framework
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/freerdp
|
||||
COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/freerdp
|
||||
COMMAND ditto ${CMAKE_SOURCE_DIR}/winpr/include/winpr ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/winpr
|
||||
COMMENT Copying FreeRDP header files to ${MODULE_NAME})
|
||||
|
||||
add_subdirectory(cli)
|
||||
|
||||
@@ -41,14 +41,11 @@
|
||||
|
||||
@interface MRDPView : NSView
|
||||
{
|
||||
CFRunLoopSourceRef run_loop_src_channels;
|
||||
CFRunLoopSourceRef run_loop_src_update;
|
||||
CFRunLoopSourceRef run_loop_src_input;
|
||||
|
||||
NSBitmapImageRep* bmiRep;
|
||||
NSMutableArray* cursors;
|
||||
NSMutableArray* windows;
|
||||
NSTimer* pasteboard_timer;
|
||||
NSCursor* currentCursor;
|
||||
NSRect prevWinPosition;
|
||||
int titleBarHeight;
|
||||
freerdp* instance;
|
||||
@@ -61,7 +58,6 @@
|
||||
char** argv;
|
||||
|
||||
NSPoint savedDragLocation;
|
||||
BOOL mouseInClientArea;
|
||||
BOOL firstCreateWindow;
|
||||
BOOL isMoveSizeInProgress;
|
||||
BOOL skipResizeOnce;
|
||||
@@ -78,6 +74,10 @@
|
||||
int kdlmeta;
|
||||
int kdrmeta;
|
||||
int kdcapslock;
|
||||
|
||||
BOOL initialized;
|
||||
|
||||
NSImageView* imageView;
|
||||
|
||||
@public
|
||||
NSPasteboard* pasteboard_rd; /* for reading from clipboard */
|
||||
@@ -88,11 +88,11 @@
|
||||
}
|
||||
|
||||
- (int) rdpStart :(rdpContext*) rdp_context;
|
||||
- (void) rdpConnectError;
|
||||
- (void) rdpRemoteAppError;
|
||||
- (void) setCursor: (NSCursor*) cursor;
|
||||
|
||||
- (void) onPasteboardTimerFired :(NSTimer *) timer;
|
||||
- (void) releaseResources;
|
||||
- (void) setViewSize : (int) width : (int) height;
|
||||
- (void) setViewSize : (int) w : (int) h;
|
||||
|
||||
@property (assign) int is_connected;
|
||||
|
||||
@@ -107,3 +107,9 @@
|
||||
#define PTR_FLAGS_BUTTON2 0x2000
|
||||
#define PTR_FLAGS_BUTTON3 0x4000
|
||||
#define WheelRotationMask 0x01FF
|
||||
|
||||
BOOL mac_pre_connect(freerdp* instance);
|
||||
BOOL mac_post_connect(freerdp* instance);
|
||||
BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
int mac_receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
|
||||
DWORD mac_client_thread(void* param);
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
* -
|
||||
*/
|
||||
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include "mf_client.h"
|
||||
#import "mfreerdp.h"
|
||||
#import "MRDPView.h"
|
||||
@@ -63,7 +65,6 @@
|
||||
#import "freerdp/client/file.h"
|
||||
#import "freerdp/client/cmdline.h"
|
||||
|
||||
|
||||
/******************************************
|
||||
Forward declarations
|
||||
******************************************/
|
||||
@@ -75,19 +76,14 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer);
|
||||
void mf_Pointer_SetNull(rdpContext* context);
|
||||
void mf_Pointer_SetDefault(rdpContext* context);
|
||||
// int rdp_connect(void);
|
||||
BOOL mac_pre_connect(freerdp* instance);
|
||||
BOOL mac_post_connect(freerdp* instance);
|
||||
BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
void mac_set_bounds(rdpContext* context, rdpBounds* bounds);
|
||||
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap);
|
||||
void mac_begin_paint(rdpContext* context);
|
||||
void mac_end_paint(rdpContext* context);
|
||||
void mac_save_state_info(freerdp* instance, rdpContext* context);
|
||||
static void update_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info);
|
||||
static void input_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info);
|
||||
static void channel_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info);
|
||||
int register_update_fds(freerdp* instance);
|
||||
int register_input_fds(freerdp* instance);
|
||||
static void update_activity_cb(freerdp* instance);
|
||||
static void input_activity_cb(freerdp* instance);
|
||||
static void channel_activity_cb(freerdp* instance);
|
||||
int invoke_draw_rect(rdpContext* context);
|
||||
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
|
||||
int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
|
||||
@@ -101,6 +97,9 @@ void cliprdr_process_text(freerdp* instance, BYTE* data, int len);
|
||||
void cliprdr_send_supported_format_list(freerdp* instance);
|
||||
int register_channel_fds(int* fds, int count, freerdp* instance);
|
||||
|
||||
|
||||
DWORD mac_client_thread(void* param);
|
||||
|
||||
struct cursor
|
||||
{
|
||||
rdpPointer* pointer;
|
||||
@@ -124,57 +123,112 @@ struct rgba_data
|
||||
|
||||
- (int) rdpStart:(rdpContext*) rdp_context
|
||||
{
|
||||
int status;
|
||||
mfContext* mfc;
|
||||
rdpSettings* settings;
|
||||
EmbedWindowEventArgs e;
|
||||
|
||||
[self initializeView];
|
||||
|
||||
context = rdp_context;
|
||||
mfc = (mfContext*) rdp_context;
|
||||
instance = context->instance;
|
||||
settings = context->settings;
|
||||
mfc->view = self;
|
||||
|
||||
EventArgsInit(&e, "mfreerdp");
|
||||
e.embed = TRUE;
|
||||
e.handle = (void*) self;
|
||||
PubSub_OnEmbedWindow(context->pubSub, context, &e);
|
||||
[self setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight];
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
// TODO
|
||||
// instance->Authenticate = mf_authenticate;
|
||||
// instance->VerifyCertificate = mf_verify_certificate;
|
||||
// instance->LogonErrorInfo = mf_logon_error_info;
|
||||
|
||||
status = freerdp_connect(context->instance);
|
||||
mfc->thread = CreateThread(NULL, 0, mac_client_thread, (void*) context, 0, &mfc->mainThreadId);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
[self setIs_connected:0];
|
||||
[self rdpConnectError];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* register update message queue with the RunLoop */
|
||||
register_update_fds(context->instance);
|
||||
|
||||
/* register update message queue with the RunLoop */
|
||||
register_input_fds(context->instance);
|
||||
|
||||
/* register channel events with the RunLoop */
|
||||
register_channels_fds(context->instance);
|
||||
|
||||
freerdp_check_fds(context->instance);
|
||||
|
||||
[self setIs_connected:1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD mac_client_thread(void* param)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
int status;
|
||||
HANDLE events[4];
|
||||
HANDLE input_event;
|
||||
HANDLE update_event;
|
||||
HANDLE channels_event;
|
||||
|
||||
DWORD nCount;
|
||||
rdpContext* context = (rdpContext*) param;
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
freerdp* instance = context->instance;
|
||||
MRDPView* view = mfc->view;
|
||||
|
||||
status = freerdp_connect(context->instance);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
[view setIs_connected:0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
[view setIs_connected:1];
|
||||
|
||||
nCount = 0;
|
||||
|
||||
events[nCount++] = mfc->stopEvent;
|
||||
|
||||
if (instance->settings->AsyncUpdate)
|
||||
{
|
||||
events[nCount++] = update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncInput)
|
||||
{
|
||||
events[nCount++] = input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncChannels)
|
||||
{
|
||||
events[nCount++] = channels_event = freerdp_channels_get_event_handle(instance);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(mfc->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncUpdate)
|
||||
{
|
||||
if (WaitForSingleObject(update_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
update_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncInput)
|
||||
{
|
||||
if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
input_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->settings->AsyncChannels)
|
||||
{
|
||||
if (WaitForSingleObject(channels_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
channel_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
methods we override
|
||||
************************************************************************/
|
||||
@@ -185,7 +239,7 @@ struct rgba_data
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
@@ -201,24 +255,50 @@ struct rgba_data
|
||||
|
||||
//TODO - Expose this code as a public method, because awakeFromNib
|
||||
// won't be called if the view is created dynamically
|
||||
- (void) awakeFromNib
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
height = [self frame].size.height;
|
||||
titleBarHeight = 22;
|
||||
|
||||
[[self window] becomeFirstResponder];
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
[self initializeView];
|
||||
}
|
||||
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
mouseInClientArea = YES;
|
||||
- (void) initializeView
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
height = [self frame].size.height;
|
||||
titleBarHeight = 22;
|
||||
|
||||
[[self window] becomeFirstResponder];
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
// Set the default cursor
|
||||
currentCursor = [NSCursor arrowCursor];
|
||||
|
||||
initialized = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setCursor: (NSCursor*) cursor
|
||||
{
|
||||
self->currentCursor = cursor;
|
||||
[[self window] invalidateCursorRectsForView:self];
|
||||
|
||||
[imageView setImage:[currentCursor image]];
|
||||
}
|
||||
|
||||
|
||||
// Set the current cursor
|
||||
- (void) resetCursorRects
|
||||
{
|
||||
[self addCursorRect:[self visibleRect] cursor:currentCursor];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@@ -596,7 +676,8 @@ struct rgba_data
|
||||
- (void) releaseResources
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
@@ -610,20 +691,6 @@ struct rgba_data
|
||||
|
||||
if (pixel_data)
|
||||
free(pixel_data);
|
||||
|
||||
if (run_loop_src_update != 0)
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_update, kCFRunLoopDefaultMode);
|
||||
|
||||
if (run_loop_src_input != 0)
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_input, kCFRunLoopDefaultMode);
|
||||
|
||||
if (run_loop_src_channels != 0)
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_channels, kCFRunLoopDefaultMode);
|
||||
|
||||
freerdp_client_stop(self->context);
|
||||
|
||||
freerdp_client_context_free(self->context);
|
||||
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@@ -657,94 +724,6 @@ struct rgba_data
|
||||
instance methods
|
||||
************************************************************************/
|
||||
|
||||
/** *********************************************************************
|
||||
* double check that a mouse event occurred in our client view
|
||||
***********************************************************************/
|
||||
|
||||
- (BOOL) eventIsInClientArea :(NSEvent *) event :(int *) xptr :(int *) yptr
|
||||
{
|
||||
NSPoint loc = [event locationInWindow];
|
||||
int x = (int) loc.x;
|
||||
int y = (int) loc.y;
|
||||
|
||||
if ((x < 0) || (y < 0))
|
||||
{
|
||||
if (mouseInClientArea)
|
||||
{
|
||||
// set default cursor before leaving client area
|
||||
mouseInClientArea = NO;
|
||||
NSCursor *cur = [NSCursor arrowCursor];
|
||||
[cur set];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ((x > width) || (y > height))
|
||||
{
|
||||
if (mouseInClientArea)
|
||||
{
|
||||
// set default cursor before leaving client area
|
||||
mouseInClientArea = NO;
|
||||
NSCursor *cur = [NSCursor arrowCursor];
|
||||
[cur set];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
// on Mac origin is at lower left, but we want it on upper left
|
||||
y = height - y;
|
||||
|
||||
*xptr = x;
|
||||
*yptr = y;
|
||||
mouseInClientArea = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when we fail to connect to a RDP server
|
||||
***********************************************************************/
|
||||
|
||||
- (void) rdpConnectError
|
||||
{
|
||||
NSString* message = @"Error connecting to server";
|
||||
if (connectErrorCode == AUTHENTICATIONERROR)
|
||||
{
|
||||
message = [NSString stringWithFormat:@"%@:\n%@", message, @"Authentication failure, check credentials."];
|
||||
}
|
||||
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:message];
|
||||
[alert beginSheetModalForWindow:[self window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when we fail to launch remote app on RDP server
|
||||
***********************************************************************/
|
||||
|
||||
- (void) rdpRemoteAppError
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:@"Error starting remote app on specified server"];
|
||||
[alert beginSheetModalForWindow:[self window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* just a terminate selector for above call
|
||||
***********************************************************************/
|
||||
|
||||
- (void) alertDidEnd:(NSAlert *)a returnCode:(NSInteger)rc contextInfo:(void *)ci
|
||||
{
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
||||
- (void) onPasteboardTimerFired :(NSTimer*) timer
|
||||
{
|
||||
int i;
|
||||
@@ -782,8 +761,17 @@ struct rgba_data
|
||||
outerRect.size.height = h + heightDiff;
|
||||
[[self window] setMaxSize:outerRect.size];
|
||||
[[self window] setMinSize:outerRect.size];
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
|
||||
|
||||
@try
|
||||
{
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
}
|
||||
@catch (NSException * e) {
|
||||
NSLog(@"Exception: %@", e);
|
||||
}
|
||||
@finally {
|
||||
}
|
||||
|
||||
// set client area to specified dimensions
|
||||
innerRect.size.width = w;
|
||||
innerRect.size.height = h;
|
||||
@@ -815,9 +803,6 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
instance->update->EndPaint = mac_end_paint;
|
||||
instance->update->SetBounds = mac_set_bounds;
|
||||
//instance->update->BitmapUpdate = mac_bitmap_update;
|
||||
|
||||
mfContext *mfc = (mfContext*) instance->context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
@@ -868,8 +853,6 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
|
||||
[view setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight];
|
||||
|
||||
freerdp_channels_pre_connect(instance->context->channels, instance);
|
||||
|
||||
return TRUE;
|
||||
@@ -888,13 +871,7 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
|
||||
BOOL mac_post_connect(freerdp* instance)
|
||||
{
|
||||
int index;
|
||||
int fds[32];
|
||||
UINT32 flags;
|
||||
int rd_count = 0;
|
||||
int wr_count = 0;
|
||||
void* rd_fds[32];
|
||||
void* wr_fds[32];
|
||||
rdpPointer rdp_pointer;
|
||||
mfContext *mfc = (mfContext*) instance->context;
|
||||
|
||||
@@ -908,7 +885,7 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
rdp_pointer.SetNull = mf_Pointer_SetNull;
|
||||
rdp_pointer.SetDefault = mf_Pointer_SetDefault;
|
||||
|
||||
flags = CLRBUF_32BPP;
|
||||
flags = CLRBUF_32BPP | CLRCONV_ALPHA;
|
||||
gdi_init(instance, flags, NULL);
|
||||
|
||||
rdpGdi* gdi = instance->context->gdi;
|
||||
@@ -927,9 +904,6 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
view->pasteboard_rd = [NSPasteboard generalPasteboard];
|
||||
view->pasteboard_changecount = (int) [view->pasteboard_rd changeCount];
|
||||
view->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:mfc->view selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES];
|
||||
|
||||
/* we want to be notified when window resizes */
|
||||
[[NSNotificationCenter defaultCenter] addObserver:mfc->view selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -992,6 +966,11 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
cursor_data = (BYTE*) malloc(rect.size.width * rect.size.height * 4);
|
||||
mrdpCursor->cursor_data = cursor_data;
|
||||
|
||||
if (pointer->xorBpp > 24)
|
||||
{
|
||||
freerdp_image_swap_color_order(pointer->xorMaskData, pointer->width, pointer->height);
|
||||
}
|
||||
|
||||
freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData,
|
||||
pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv);
|
||||
|
||||
@@ -1066,19 +1045,16 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
|
||||
NSMutableArray* ma = view->cursors;
|
||||
|
||||
return; /* disable pointer until it is fixed */
|
||||
|
||||
if (!view->mouseInClientArea)
|
||||
return;
|
||||
|
||||
for (MRDPCursor* cursor in ma)
|
||||
{
|
||||
if (cursor->pointer == pointer)
|
||||
{
|
||||
[cursor->nsCursor set];
|
||||
[view setCursor:cursor->nsCursor];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"Cursor not found");
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@@ -1096,7 +1072,9 @@ void mf_Pointer_SetNull(rdpContext* context)
|
||||
|
||||
void mf_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view setCursor:[NSCursor arrowCursor]];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@@ -1152,10 +1130,10 @@ void mac_end_paint(rdpContext* context)
|
||||
|
||||
for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++)
|
||||
{
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h;
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x - 1;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y - 1;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w + 1;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h + 1;
|
||||
windows_to_apple_cords(mfc->view, &drawRect);
|
||||
[view setNeedsDisplayInRect:drawRect];
|
||||
}
|
||||
@@ -1168,16 +1146,15 @@ void mac_end_paint(rdpContext* context)
|
||||
* called when update data is available
|
||||
***********************************************************************/
|
||||
|
||||
static void update_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info)
|
||||
static void update_activity_cb(freerdp* instance)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
freerdp* instance = (freerdp*) info;
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
|
||||
|
||||
if (queue)
|
||||
{
|
||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||
@@ -1188,21 +1165,21 @@ static void update_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBack
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(fdref);
|
||||
register_update_fds(instance);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "update_activity_cb: No queue!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when input data is available
|
||||
***********************************************************************/
|
||||
|
||||
static void input_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info)
|
||||
static void input_activity_cb(freerdp* instance)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
freerdp* instance = (freerdp*) info;
|
||||
wMessageQueue* queue;
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
@@ -1211,33 +1188,32 @@ static void input_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackT
|
||||
{
|
||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||
{
|
||||
fprintf(stderr, "input_activity_cb: message %d\n", message.id);
|
||||
|
||||
status = freerdp_message_queue_process_message(instance, FREERDP_INPUT_MESSAGE_QUEUE, &message);
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(fdref);
|
||||
register_input_fds(instance);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "input_activity_cb: No queue!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when data is available on a virtual channel
|
||||
***********************************************************************/
|
||||
|
||||
static void channel_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info)
|
||||
static void channel_activity_cb(freerdp* instance)
|
||||
{
|
||||
wMessage* event;
|
||||
freerdp* instance = (freerdp*) info;
|
||||
wMessage* event;
|
||||
|
||||
freerdp_channels_process_pending_messages(instance);
|
||||
event = freerdp_channels_pop_event(instance->context->channels);
|
||||
if (event)
|
||||
{
|
||||
switch (GetMessageClass(event->id))
|
||||
fprintf(stderr, "channel_activity_cb: message %d\n", event->id);
|
||||
switch (GetMessageClass(event->id))
|
||||
{
|
||||
case CliprdrChannel_Class:
|
||||
process_cliprdr_event(instance, event);
|
||||
@@ -1246,90 +1222,6 @@ static void channel_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBac
|
||||
|
||||
freerdp_event_free(event);
|
||||
}
|
||||
|
||||
CFRelease(fdref);
|
||||
register_channels_fds(instance);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* setup callbacks for data availability on update message queue
|
||||
***********************************************************************/
|
||||
|
||||
int register_update_fds(freerdp* instance)
|
||||
{
|
||||
int fd_update_event;
|
||||
HANDLE update_event;
|
||||
CFFileDescriptorRef fdref;
|
||||
CFFileDescriptorContext fd_context = { 0, instance, NULL, NULL, NULL };
|
||||
mfContext* mfc = (mfContext*) instance->context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
if (instance->settings->AsyncUpdate)
|
||||
{
|
||||
update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
fd_update_event = GetEventFileDescriptor(update_event);
|
||||
|
||||
fdref = CFFileDescriptorCreate(kCFAllocatorDefault, fd_update_event, true, update_activity_cb, &fd_context);
|
||||
CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
|
||||
view->run_loop_src_update = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), view->run_loop_src_update, kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* setup callbacks for data availability on input message queue
|
||||
***********************************************************************/
|
||||
|
||||
int register_input_fds(freerdp* instance)
|
||||
{
|
||||
int fd_input_event;
|
||||
HANDLE input_event;
|
||||
CFFileDescriptorRef fdref;
|
||||
CFFileDescriptorContext fd_context = { 0, instance, NULL, NULL, NULL };
|
||||
mfContext* mfc = (mfContext*) instance->context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
if (instance->settings->AsyncInput)
|
||||
{
|
||||
input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
fd_input_event = GetEventFileDescriptor(input_event);
|
||||
|
||||
fdref = CFFileDescriptorCreate(kCFAllocatorDefault, fd_input_event, true, input_activity_cb, &fd_context);
|
||||
CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
|
||||
view->run_loop_src_input = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), view->run_loop_src_input, kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* setup callbacks for data availability on channels
|
||||
***********************************************************************/
|
||||
|
||||
int register_channels_fds(freerdp* instance)
|
||||
{
|
||||
int fd_channel_event;
|
||||
HANDLE channel_event;
|
||||
CFFileDescriptorRef fdref;
|
||||
CFFileDescriptorContext fd_context = { 0, instance, NULL, NULL, NULL };
|
||||
mfContext* mfc = (mfContext*) instance->context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
if (instance->settings->AsyncChannels)
|
||||
{
|
||||
channel_event = freerdp_channels_get_event_handle(instance);
|
||||
fd_channel_event = GetEventFileDescriptor(channel_event);
|
||||
|
||||
fdref = CFFileDescriptorCreate(kCFAllocatorDefault, fd_channel_event, true, channel_activity_cb, &fd_context);
|
||||
CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
|
||||
view->run_loop_src_channels = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), view->run_loop_src_channels, kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@@ -1567,20 +1459,12 @@ void cliprdr_send_supported_format_list(freerdp* instance)
|
||||
freerdp_channels_send_event(instance->context->channels, (wMessage*) event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* given a rect with 0,0 at the bottom left (apple cords)
|
||||
* convert it to a rect with 0,0 at the top left (windows cords)
|
||||
*/
|
||||
|
||||
void apple_to_windows_cords(MRDPView* view, NSRect* r)
|
||||
{
|
||||
r->origin.y = view->height - (r->origin.y + r->size.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* given a rect with 0,0 at the top left (windows cords)
|
||||
* convert it to a rect with 0,0 at the bottom left (apple cords)
|
||||
*
|
||||
* Note: the formula works for conversions in both directions.
|
||||
*
|
||||
*/
|
||||
|
||||
void windows_to_apple_cords(MRDPView* view, NSRect* r)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <MacFreeRDP-library/MRDPView.h>
|
||||
#import <MacFreeRDP-library/mfreerdp.h>
|
||||
#import <MacFreeRDP/MRDPView.h>
|
||||
#import <MacFreeRDP/mfreerdp.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
@@ -18,8 +18,9 @@
|
||||
MRDPView* mrdpView;
|
||||
}
|
||||
|
||||
- (void) rdpConnectError: (NSString*) customMessage;
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
@property (assign) rdpContext *context;
|
||||
@property (assign) IBOutlet MRDPView *mrdpView;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "MacFreeRDP-library/mfreerdp.h"
|
||||
#import "MacFreeRDP-library/mf_client.h"
|
||||
#import "MacFreeRDP/mfreerdp.h"
|
||||
#import "MacFreeRDP/mf_client.h"
|
||||
|
||||
static AppDelegate* _singleDelegate = nil;
|
||||
void AppDelegate_EmbedWindowEventHandler(void* context, EmbedWindowEventArgs* e);
|
||||
void AppDelegate_ConnectionResultEventHandler(void* context, ConnectionResultEventArgs* e);
|
||||
void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e);
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@@ -19,7 +24,6 @@
|
||||
|
||||
@synthesize window = window;
|
||||
|
||||
@synthesize mrdpView = mrdpView;
|
||||
|
||||
@synthesize context = context;
|
||||
|
||||
@@ -28,6 +32,7 @@
|
||||
int status;
|
||||
mfContext* mfc;
|
||||
|
||||
_singleDelegate = self;
|
||||
[self CreateContext];
|
||||
|
||||
status = [self ParseCommandLineArguments];
|
||||
@@ -41,6 +46,10 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
PubSub_SubscribeConnectionResult(context->pubSub, AppDelegate_ConnectionResultEventHandler);
|
||||
PubSub_SubscribeErrorInfo(context->pubSub, AppDelegate_ErrorInfoEventHandler);
|
||||
PubSub_SubscribeEmbedWindow(context->pubSub, AppDelegate_EmbedWindowEventHandler);
|
||||
|
||||
freerdp_client_start(context);
|
||||
}
|
||||
}
|
||||
@@ -48,6 +57,7 @@
|
||||
- (void) applicationWillTerminate:(NSNotification*)notification
|
||||
{
|
||||
[mrdpView releaseResources];
|
||||
_singleDelegate = nil;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
@@ -103,4 +113,92 @@
|
||||
context = nil;
|
||||
}
|
||||
|
||||
|
||||
/** *********************************************************************
|
||||
* called when we fail to connect to a RDP server - Make sure this is called from the main thread.
|
||||
***********************************************************************/
|
||||
|
||||
- (void) rdpConnectError : (NSString*) withMessage
|
||||
{
|
||||
NSString* message = withMessage ? withMessage : @"Error connecting to server";
|
||||
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:message];
|
||||
[alert beginSheetModalForWindow:[self window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
/** *********************************************************************
|
||||
* just a terminate selector for above call
|
||||
***********************************************************************/
|
||||
|
||||
- (void) alertDidEnd:(NSAlert *)a returnCode:(NSInteger)rc contextInfo:(void *)ci
|
||||
{
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
void AppDelegate_EmbedWindowEventHandler(void* ctx, EmbedWindowEventArgs* e)
|
||||
{
|
||||
rdpContext* context = (rdpContext*) ctx;
|
||||
|
||||
if (_singleDelegate)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
_singleDelegate->mrdpView = mfc->view;
|
||||
|
||||
if (_singleDelegate->window)
|
||||
{
|
||||
[[_singleDelegate->window contentView] addSubview:mfc->view];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* On connection error, display message and quit application
|
||||
***********************************************************************/
|
||||
|
||||
void AppDelegate_ConnectionResultEventHandler(void* ctx, ConnectionResultEventArgs* e)
|
||||
{
|
||||
NSLog(@"ConnectionResult event result:%d\n", e->result);
|
||||
if (_singleDelegate)
|
||||
{
|
||||
if (e->result != 0)
|
||||
{
|
||||
NSString* message = nil;
|
||||
if (connectErrorCode == AUTHENTICATIONERROR)
|
||||
{
|
||||
message = [NSString stringWithFormat:@"%@:\n%@", message, @"Authentication failure, check credentials."];
|
||||
}
|
||||
|
||||
|
||||
// Making sure this should be invoked on the main UI thread.
|
||||
[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:) withObject:message waitUntilDone:FALSE];
|
||||
[message release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e)
|
||||
{
|
||||
NSLog(@"ErrorInfo event code:%d\n", e->code);
|
||||
if (_singleDelegate)
|
||||
{
|
||||
// Retrieve error message associated with error code
|
||||
NSString* message = nil;
|
||||
if (e->code != ERRINFO_NONE)
|
||||
{
|
||||
const char* errorMessage = freerdp_get_error_info_string(e->code);
|
||||
message = [[NSString alloc] initWithUTF8String:errorMessage];
|
||||
}
|
||||
|
||||
// Making sure this should be invoked on the main UI thread.
|
||||
[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:) withObject:message waitUntilDone:TRUE];
|
||||
[message release];
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
project(MacFreeRDP-client)
|
||||
|
||||
project(MacFreeRDP)
|
||||
|
||||
set(MODULE_NAME "MacFreeRDP")
|
||||
set(MODULE_OUTPUT_NAME "MacFreeRDP")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_MAC_CLIENT")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.5")
|
||||
|
||||
# Import libraries
|
||||
find_library(FOUNDATION_LIBRARY Foundation)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
#find_library(FREERDP_LIBRARY NAMES MacFreeRDP PATHS ${CMAKE_CURRENT_BINARY_DIR}/../${CONFIGURATION})
|
||||
|
||||
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns")
|
||||
@@ -27,28 +26,32 @@ set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
|
||||
mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY)
|
||||
set(APP_TYPE MACOSX_BUNDLE)
|
||||
|
||||
# OS X Interface Builder files
|
||||
file(GLOB ${MODULE_NAME}_XIBS *.xib)
|
||||
set(${MODULE_PREFIX}_XIBS MainMenu.xib)
|
||||
|
||||
set(${MODULE_NAME}_RESOURCES ${MACOSX_BUNDLE_ICON_FILE})
|
||||
set(${MODULE_PREFIX}_SOURCES "")
|
||||
|
||||
set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
|
||||
main.m
|
||||
AppDelegate.m)
|
||||
|
||||
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
|
||||
|
||||
set(${MODULE_PREFIX}_HEADERS
|
||||
AppDelegate.h)
|
||||
|
||||
set(${MODULE_PREFIX}_RESOURCES ${MACOSX_BUNDLE_ICON_FILE})
|
||||
|
||||
# Include XIB file in Xcode resources.
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
|
||||
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
|
||||
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS})
|
||||
endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
|
||||
|
||||
# Headers
|
||||
file(GLOB ${MODULE_NAME}_HEADERS *.h)
|
||||
|
||||
# Source
|
||||
file(GLOB ${MODULE_NAME}_SOURCES *.m)
|
||||
set(${MODULE_PREFIX}_RESOURCES ${${MODULE_PREFIX}_RESOURCES} ${${MODULE_PREFIX}_XIBS})
|
||||
endif()
|
||||
|
||||
add_executable(${MODULE_NAME}
|
||||
${APP_TYPE}
|
||||
${${MODULE_NAME}_HEADERS}
|
||||
${${MODULE_NAME}_SOURCES}
|
||||
${${MODULE_NAME}_RESOURCES})
|
||||
${${MODULE_PREFIX}_HEADERS}
|
||||
${${MODULE_PREFIX}_SOURCES}
|
||||
${${MODULE_PREFIX}_RESOURCES})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
|
||||
|
||||
@@ -56,14 +59,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAM
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
|
||||
|
||||
# This allows for automatic xib to nib ibitool
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOURCES}")
|
||||
|
||||
# Automatic ref counting
|
||||
# temporary turn off for x86_64 build issue
|
||||
# set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
|
||||
|
||||
# Support for automatic reference counting requires non-fragile abi.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_PREFIX}_RESOURCES}")
|
||||
|
||||
# Tell the compiler where to look for the FreeRDP framework
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F../")
|
||||
@@ -72,8 +68,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F../")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS
|
||||
"${XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS} ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
|
||||
|
||||
# Set the info plist to the custom instance
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
|
||||
|
||||
@@ -86,7 +80,7 @@ set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Mac")
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND mkdir ARGS -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/Frameworks
|
||||
COMMAND ditto ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)/MacFreeRDP.framework ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/Frameworks/MacFreeRDP.framework
|
||||
COMMAND install_name_tool -change "@executable_path/../../Frameworks/MacFreeRDP.framework/Versions/1.1.0/MacFreeRDP"
|
||||
COMMAND install_name_tool -change "@executable_path/../Frameworks/MacFreeRDP.framework/Versions/${MAC_OS_X_BUNDLE_BUNDLE_VERSION}/MacFreeRDP"
|
||||
"@executable_path/../Frameworks/MacFreeRDP.framework/Versions/Current/MacFreeRDP"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/MacOS/${MODULE_NAME}"
|
||||
COMMENT Setting install name for MacFreeRDP)
|
||||
@@ -106,13 +100,13 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources)
|
||||
|
||||
# Compile the .xib files using the 'ibtool' program with the destination being the app package
|
||||
foreach(xib ${${MODULE_NAME}_XIBS})
|
||||
foreach(xib ${${MODULE_PREFIX}_XIBS})
|
||||
get_filename_component(XIB_WE ${xib} NAME_WE)
|
||||
|
||||
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources/${XIB_WE}.nib ${CMAKE_CURRENT_SOURCE_DIR}/${xib}
|
||||
COMMENT "Compiling ${xib}")
|
||||
endforeach()
|
||||
|
||||
endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
endif()
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1070</int>
|
||||
<string key="IBDocument.SystemVersion">12D78</string>
|
||||
<string key="IBDocument.SystemVersion">12E55</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.37</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.39</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="NS.object.0">3084</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBNSLayoutConstraint</string>
|
||||
<string>NSCustomObject</string>
|
||||
<string>NSCustomView</string>
|
||||
<string>NSMenu</string>
|
||||
<string>NSMenuItem</string>
|
||||
<string>NSView</string>
|
||||
@@ -257,24 +255,12 @@
|
||||
<object class="NSView" key="NSWindowView" id="439893737">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSCustomView" id="467991374">
|
||||
<reference key="NSNextResponder" ref="439893737"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrameSize">{1024, 768}</string>
|
||||
<reference key="NSSuperview" ref="439893737"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<string key="NSClassName">MRDPView</string>
|
||||
</object>
|
||||
</array>
|
||||
<array class="NSMutableArray" key="NSSubviews"/>
|
||||
<string key="NSFrameSize">{1024, 768}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="467991374"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
||||
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
|
||||
<string key="NSMinSize">{1024, 790}</string>
|
||||
<string key="NSMaxSize">{1024, 790}</string>
|
||||
<int key="NSWindowCollectionBehavior">128</int>
|
||||
@@ -369,14 +355,6 @@
|
||||
</object>
|
||||
<int key="connectionID">493</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">mrdpView</string>
|
||||
<reference key="source" ref="976324537"/>
|
||||
<reference key="destination" ref="467991374"/>
|
||||
</object>
|
||||
<int key="connectionID">569</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">window</string>
|
||||
@@ -551,73 +529,7 @@
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">372</int>
|
||||
<reference key="object" ref="439893737"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="467991374"/>
|
||||
<object class="IBNSLayoutConstraint" id="334327932">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">6</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">6</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="890641817">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">5</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">5</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="437142032">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">4</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">4</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="934352021">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">3</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">3</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
</array>
|
||||
<array class="NSMutableArray" key="children"/>
|
||||
<reference key="parent" ref="972006081"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
@@ -657,31 +569,6 @@
|
||||
<reference key="object" ref="976324537"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">551</int>
|
||||
<reference key="object" ref="467991374"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">561</int>
|
||||
<reference key="object" ref="334327932"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">562</int>
|
||||
<reference key="object" ref="890641817"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">563</int>
|
||||
<reference key="object" ref="437142032"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">564</int>
|
||||
<reference key="object" ref="934352021"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
@@ -706,12 +593,6 @@
|
||||
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
|
||||
<integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
|
||||
<array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
|
||||
<reference ref="334327932"/>
|
||||
<reference ref="890641817"/>
|
||||
<reference ref="437142032"/>
|
||||
<reference ref="934352021"/>
|
||||
</array>
|
||||
<string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
@@ -720,13 +601,7 @@
|
||||
<string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<boolean value="NO" key="551.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||
<string key="551.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="561.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="562.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="563.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="564.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
@@ -738,48 +613,7 @@
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">570</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">AppDelegate</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="mrdpView">MRDPView</string>
|
||||
<string key="window">NSWindow</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="mrdpView">
|
||||
<string key="name">mrdpView</string>
|
||||
<string key="candidateClassName">MRDPView</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="window">
|
||||
<string key="name">window</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/AppDelegate.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">MRDPView</string>
|
||||
<string key="superclassName">NSView</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/MRDPView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSLayoutConstraint</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/signal.h>
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#import "MRDPView.h"
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
@@ -46,6 +47,13 @@ int mfreerdp_client_start(rdpContext* context)
|
||||
MRDPView* view;
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
|
||||
if (mfc->view == NULL)
|
||||
{
|
||||
// view not specified beforehand. Create view dynamically
|
||||
mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)];
|
||||
mfc->view_ownership = TRUE;
|
||||
}
|
||||
|
||||
view = (MRDPView*) mfc->view;
|
||||
[view rdpStart:context];
|
||||
|
||||
@@ -60,19 +68,40 @@ int mfreerdp_client_stop(rdpContext* context)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (context->settings->AsyncInput)
|
||||
else if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mfc->disconnect = TRUE;
|
||||
}
|
||||
|
||||
if (mfc->thread)
|
||||
{
|
||||
SetEvent(mfc->stopEvent);
|
||||
WaitForSingleObject(mfc->thread, INFINITE);
|
||||
CloseHandle(mfc->thread);
|
||||
mfc->thread = NULL;
|
||||
}
|
||||
|
||||
if (mfc->view_ownership)
|
||||
{
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view releaseResources];
|
||||
[view release];
|
||||
mfc->view = nil;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,12 +113,19 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
mfc = (mfContext*) instance->context;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
mfc->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
settings->AsyncUpdate = TRUE;
|
||||
// TODO settings->AsyncInput = TRUE;
|
||||
settings->AsyncUpdate = TRUE;
|
||||
settings->AsyncInput = TRUE;
|
||||
settings->AsyncChannels = TRUE;
|
||||
settings->AsyncTransport = TRUE;
|
||||
settings->RedirectClipboard = TRUE;
|
||||
|
||||
@@ -28,6 +28,7 @@ struct mf_context
|
||||
DEFINE_RDP_CLIENT_COMMON();
|
||||
|
||||
void* view;
|
||||
BOOL view_ownership; // TRUE indicates that the window was created and should be freed by the API.
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@@ -43,6 +44,7 @@ struct mf_context
|
||||
int client_height;
|
||||
|
||||
HANDLE keyboardThread;
|
||||
HANDLE stopEvent;
|
||||
|
||||
HGDI_DC hdc;
|
||||
UINT16 srcBpp;
|
||||
|
||||
@@ -63,8 +63,10 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(WITH_CLIENT_INTERFACE)
|
||||
if (NOT WITH_WAYK)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
add_subdirectory(cli)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
|
||||
endif()
|
||||
|
||||
@@ -575,14 +575,14 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
|
||||
|
||||
/* blit each tile */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
for (i = 0; i < message->numTiles; i++)
|
||||
{
|
||||
tx = message->tiles[i]->x + surface_bits_command->destLeft;
|
||||
ty = message->tiles[i]->y + surface_bits_command->destTop;
|
||||
|
||||
freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);
|
||||
|
||||
for (j = 0; j < message->num_rects; j++)
|
||||
for (j = 0; j < message->numRects; j++)
|
||||
{
|
||||
wf_set_clip_rgn(wfc,
|
||||
surface_bits_command->destLeft + message->rects[j].x,
|
||||
@@ -596,7 +596,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
wf_set_null_clip_rgn(wfc);
|
||||
|
||||
/* invalidate regions */
|
||||
for (i = 0; i < message->num_rects; i++)
|
||||
for (i = 0; i < message->numRects; i++)
|
||||
{
|
||||
tx = surface_bits_command->destLeft + message->rects[i].x;
|
||||
ty = surface_bits_command->destTop + message->rects[i].y;
|
||||
@@ -618,7 +618,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
bitmap_info.bmiHeader.biCompression = BI_RGB;
|
||||
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
|
||||
nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS);
|
||||
nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS);
|
||||
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
surface_bits_command->width, surface_bits_command->height);
|
||||
}
|
||||
@@ -664,8 +664,8 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
{
|
||||
rdpPrimaryUpdate* primary = update->primary;
|
||||
|
||||
update->Palette = wf_gdi_palette_update;
|
||||
update->SetBounds = wf_gdi_set_bounds;
|
||||
update->Palette = (pPalette) wf_gdi_palette_update;
|
||||
update->SetBounds = (pSetBounds) wf_gdi_set_bounds;
|
||||
|
||||
primary->DstBlt = (pDstBlt) wf_gdi_dstblt;
|
||||
primary->PatBlt = (pPatBlt) wf_gdi_patblt;
|
||||
@@ -690,8 +690,8 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
primary->EllipseSC = NULL;
|
||||
primary->EllipseCB = NULL;
|
||||
|
||||
update->SurfaceBits = wf_gdi_surface_bits;
|
||||
update->SurfaceFrameMarker = wf_gdi_surface_frame_marker;
|
||||
update->SurfaceBits = (pSurfaceBits) wf_gdi_surface_bits;
|
||||
update->SurfaceFrameMarker = (pSurfaceFrameMarker) wf_gdi_surface_frame_marker;
|
||||
}
|
||||
|
||||
void wf_update_canvas_diff(wfContext* wfc)
|
||||
|
||||
2
client/X11/.gitignore
vendored
Normal file
2
client/X11/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.xml
|
||||
generate_argument_docbook
|
||||
@@ -2,6 +2,7 @@
|
||||
# FreeRDP X11 Client
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +19,7 @@
|
||||
set(MODULE_NAME "xfreerdp-client")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_X11_CONTROL")
|
||||
|
||||
include(FindXmlto)
|
||||
include(FindDocBookXSL)
|
||||
include_directories(${X11_INCLUDE_DIRS})
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
@@ -28,6 +29,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
xf_rail.h
|
||||
xf_tsmf.c
|
||||
xf_tsmf.h
|
||||
xf_input.c
|
||||
xf_input.h
|
||||
xf_event.c
|
||||
xf_event.h
|
||||
xf_input.c
|
||||
@@ -65,18 +68,55 @@ set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_DL_LIBS})
|
||||
|
||||
if(WITH_MANPAGES)
|
||||
if(XMLTO_FOUND)
|
||||
find_program( XSLTPROC_EXECUTABLE NAMES xsltproc)
|
||||
|
||||
if(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
|
||||
|
||||
# We need the variable ${MAN_TODAY} to contain the current date in ISO
|
||||
# format to replace it in the configure_file step.
|
||||
include(today)
|
||||
|
||||
TODAY(MAN_TODAY)
|
||||
|
||||
configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY IMMEDIATE)
|
||||
|
||||
add_executable(generate_argument_docbook generate_argument_docbook.c)
|
||||
|
||||
set(GAD_LIBS freerdp-client)
|
||||
|
||||
set_complex_link_libraries(VARIABLE GAD_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-utils)
|
||||
|
||||
set_complex_link_libraries(VARIABLE GAD_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-core freerdp-utils)
|
||||
|
||||
message(WARNING "GAD_LIBS: ${GAD_LIBS}")
|
||||
|
||||
target_link_libraries(generate_argument_docbook ${GAD_LIBS})
|
||||
|
||||
add_custom_command(OUTPUT xfreerdp.1
|
||||
COMMAND ${XMLTO_EXECUTABLE} man ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml
|
||||
DEPENDS xfreerdp.1.xml)
|
||||
COMMAND generate_argument_docbook
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml
|
||||
generate_argument_docbook)
|
||||
|
||||
add_custom_target(xfreerdp.manpage ALL
|
||||
DEPENDS xfreerdp.1)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION share/man/man1)
|
||||
else(XMLTO_FOUND)
|
||||
message(WARNING "WITH_MANPAGES was set, but xmlto was not found. man-pages will not be installed")
|
||||
endif(XMLTO_FOUND)
|
||||
else()
|
||||
message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed")
|
||||
endif()
|
||||
endif(WITH_MANPAGES)
|
||||
|
||||
set(XSHM_FEATURE_TYPE "REQUIRED")
|
||||
@@ -101,11 +141,11 @@ set(XV_FEATURE_DESCRIPTION "X11 video extension")
|
||||
|
||||
set(XI_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XI_FEATURE_PURPOSE "input")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
|
||||
set(XRENDER_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XRENDER_FEATURE_PURPOSE "rendering")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
|
||||
find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
|
||||
find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
|
||||
|
||||
177
client/X11/generate_argument_docbook.c
Normal file
177
client/X11/generate_argument_docbook.c
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
/* We need to include the command line c file to get access to
|
||||
* the argument struct. */
|
||||
#include "../common/cmdline.c"
|
||||
|
||||
LPSTR tmp = NULL;
|
||||
|
||||
LPCSTR tr_esc_str(LPCSTR arg)
|
||||
{
|
||||
size_t cs = 0, x, ds;
|
||||
size_t s;
|
||||
|
||||
if( NULL == arg )
|
||||
return NULL;
|
||||
|
||||
s = strlen(arg);
|
||||
|
||||
/* Find trailing whitespaces */
|
||||
while( (s > 0) && isspace(arg[s-1]))
|
||||
s--;
|
||||
|
||||
/* Prepare a initial buffer with the size of the result string. */
|
||||
tmp = malloc(s * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not allocate string buffer.");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
/* Copy character for character and check, if it is necessary to escape. */
|
||||
ds = s + 1;
|
||||
for(x=0; x<s; x++)
|
||||
{
|
||||
switch(arg[x])
|
||||
{
|
||||
case '<':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-3);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'l';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '>':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-4);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'g';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '\'':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-5);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 's';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '"':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-6);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'q';
|
||||
tmp[cs++] = 'u';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '&':
|
||||
ds += 4;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-7);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'm';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
default:
|
||||
tmp[cs++] = arg[x];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assure, the string is '\0' terminated. */
|
||||
tmp[ds-1] = '\0';
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
size_t elements = sizeof(args)/sizeof(args[0]);
|
||||
size_t x;
|
||||
const char *fname = "xfreerdp-argument.1.xml";
|
||||
FILE *fp = NULL;
|
||||
|
||||
/* Open output file for writing, truncate if existing. */
|
||||
fp = fopen(fname, "w");
|
||||
if( NULL == fp )
|
||||
{
|
||||
fprintf(stderr, "Could not open '%s' for writing.", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The tag used as header in the manpage */
|
||||
fprintf(fp, "<refsect1>\n");
|
||||
fprintf(fp, "\t<title>Options</title>\n");
|
||||
fprintf(fp, "\t\t<variablelist>\n");
|
||||
|
||||
/* Iterate over argument struct and write data to docbook 4.5
|
||||
* compatible XML */
|
||||
if( elements < 2 )
|
||||
{
|
||||
fprintf(stderr, "The argument array 'args' is empty, writing an empty file.");
|
||||
elements = 1;
|
||||
}
|
||||
|
||||
for(x=0; x<elements - 1; x++)
|
||||
{
|
||||
const COMMAND_LINE_ARGUMENT_A *arg = &args[x];
|
||||
|
||||
fprintf(fp, "\t\t\t<varlistentry>\n");
|
||||
if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags )
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option> <replaceable>%s</replaceable></term>\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) );
|
||||
else
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option></term>\n", tr_esc_str(arg->Name) );
|
||||
fprintf(fp, "\t\t\t\t<listitem>\n");
|
||||
fprintf(fp, "\t\t\t\t\t<para>%s</para>\n", tr_esc_str(arg->Text));
|
||||
|
||||
fprintf(fp, "\t\t\t\t</listitem>\n");
|
||||
fprintf(fp, "\t\t\t</varlistentry>\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t</variablelist>\n");
|
||||
fprintf(fp, "\t</refsect1>\n");
|
||||
fclose(fp);
|
||||
|
||||
if(NULL != tmp)
|
||||
free(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,19 +26,17 @@
|
||||
#include "xf_client.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)
|
||||
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xfc->rdpei = (RdpeiClientContext*) pInterface;
|
||||
xfc->rdpei = (RdpeiClientContext*) e->pInterface;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface)
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,4 +27,7 @@
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface);
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e);
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* X11 Client Interface
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +25,14 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
@@ -73,6 +82,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
#include "xf_rail.h"
|
||||
@@ -83,14 +93,51 @@
|
||||
#include "xf_monitor.h"
|
||||
#include "xf_graphics.h"
|
||||
#include "xf_keyboard.h"
|
||||
#include "xf_input.h"
|
||||
#include "xf_channels.h"
|
||||
|
||||
#include "xfreerdp.h"
|
||||
|
||||
static long xv_port = 0;
|
||||
static const size_t password_size = 512;
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc)
|
||||
void xf_transform_window(xfContext* xfc)
|
||||
{
|
||||
int ret;
|
||||
int w;
|
||||
int h;
|
||||
long supplied;
|
||||
Atom hints_atom;
|
||||
XSizeHints* size_hints = NULL;
|
||||
|
||||
hints_atom = XInternAtom(xfc->display, "WM_SIZE_HINTS", 1);
|
||||
|
||||
ret = XGetWMSizeHints(xfc->display, xfc->window->handle, size_hints, &supplied, hints_atom);
|
||||
|
||||
if(ret == 0)
|
||||
size_hints = XAllocSizeHints();
|
||||
|
||||
w = (xfc->originalWidth * xfc->settings->ScalingFactor) + xfc->offset_x;
|
||||
h = (xfc->originalHeight * xfc->settings->ScalingFactor) + xfc->offset_y;
|
||||
|
||||
if(w < 1)
|
||||
w = 1;
|
||||
|
||||
if(h < 1)
|
||||
h = 1;
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->flags |= PMinSize | PMaxSize;
|
||||
size_hints->min_width = size_hints->max_width = w;
|
||||
size_hints->min_height = size_hints->max_height = h;
|
||||
XSetWMNormalHints(xfc->display, xfc->window->handle, size_hints);
|
||||
XResizeWindow(xfc->display, xfc->window->handle, w, h);
|
||||
|
||||
XFree(size_hints);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale)
|
||||
{
|
||||
#ifdef WITH_XRENDER
|
||||
XTransform transform;
|
||||
@@ -98,6 +145,7 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
Picture primaryPicture;
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat* picFormat;
|
||||
XRectangle xr;
|
||||
|
||||
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
@@ -114,11 +162,38 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
|
||||
transform.matrix[2][0] = XDoubleToFixed(0);
|
||||
transform.matrix[2][1] = XDoubleToFixed(0);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->scale);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor);
|
||||
|
||||
if( (w != 0) && (h != 0) )
|
||||
{
|
||||
|
||||
if(scale == TRUE)
|
||||
{
|
||||
xr.x = x * xfc->settings->ScalingFactor;
|
||||
xr.y = y * xfc->settings->ScalingFactor;
|
||||
xr.width = (w+1) * xfc->settings->ScalingFactor;
|
||||
xr.height = (h+1) * xfc->settings->ScalingFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
xr.x = x;
|
||||
xr.y = y;
|
||||
xr.width = w;
|
||||
xr.height = h;
|
||||
}
|
||||
|
||||
XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1);
|
||||
}
|
||||
|
||||
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderFreePicture(xfc->display, primaryPicture);
|
||||
XRenderFreePicture(xfc->display, windowPicture);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void xf_sw_begin_paint(rdpContext* context)
|
||||
@@ -153,9 +228,9 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -184,12 +259,13 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
|
||||
//combine xfc->primary with xfc->image
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -271,12 +347,12 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = xfc->hdc->hwnd->invalid->y;
|
||||
w = xfc->hdc->hwnd->invalid->w;
|
||||
h = xfc->hdc->hwnd->invalid->h;
|
||||
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -305,10 +381,10 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -666,8 +742,11 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
settings = instance->settings;
|
||||
channels = instance->context->channels;
|
||||
|
||||
instance->OnChannelConnected = xf_on_channel_connected;
|
||||
instance->OnChannelDisconnected = xf_on_channel_disconnected;
|
||||
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
||||
(pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler);
|
||||
|
||||
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
|
||||
(pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler);
|
||||
|
||||
freerdp_client_load_addins(channels, instance->settings);
|
||||
|
||||
@@ -829,7 +908,10 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
xfc->originalHeight = settings->DesktopHeight;
|
||||
xfc->currentWidth = xfc->originalWidth;
|
||||
xfc->currentHeight = xfc->originalWidth;
|
||||
xfc->scale = 1.0;
|
||||
xfc->settings->ScalingFactor = 1.0;
|
||||
|
||||
xfc->offset_x = 0;
|
||||
xfc->offset_y = 0;
|
||||
|
||||
xfc->width = settings->DesktopWidth;
|
||||
xfc->height = settings->DesktopHeight;
|
||||
@@ -1480,6 +1562,8 @@ void* xf_thread(void* param)
|
||||
gdi_free(instance);
|
||||
|
||||
ExitThread(exit_code);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason)
|
||||
@@ -1520,6 +1604,66 @@ void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e)
|
||||
}
|
||||
}
|
||||
|
||||
void xf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e)
|
||||
{
|
||||
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
switch (e->id)
|
||||
{
|
||||
case FreeRDP_ScalingFactor:
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->settings->ScalingFactor += e->ScalingFactor;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
@@ -1573,28 +1717,6 @@ int xfreerdp_client_stop(rdpContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
double freerdp_client_get_scale(rdpContext* context)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
return xfc->scale;
|
||||
}
|
||||
|
||||
void freerdp_client_reset_scale(rdpContext* context)
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->scale = 1.0;
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
xfContext* xfc;
|
||||
@@ -1643,6 +1765,9 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
|
||||
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
|
||||
PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler);
|
||||
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ extern "C" {
|
||||
* Client Interface
|
||||
*/
|
||||
|
||||
|
||||
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "xf_input.h"
|
||||
|
||||
#include "xf_event.h"
|
||||
#include "xf_input.h"
|
||||
|
||||
const char* const X11_EVENT_STRINGS[] =
|
||||
{
|
||||
@@ -88,22 +89,24 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
|
||||
x = event->xexpose.x;
|
||||
y = event->xexpose.y;
|
||||
w = event->xexpose.width;
|
||||
h = event->xexpose.height;
|
||||
|
||||
|
||||
if (!app)
|
||||
{
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x - xfc->offset_x,
|
||||
y - xfc->offset_y, w, h, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfc->display, xfc->primary,
|
||||
xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
||||
xfc->window->handle, xfc->gc, x, y, w,
|
||||
h, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -111,16 +114,17 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||
xfWindow* xfw;
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
|
||||
|
||||
if (window != NULL)
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list,
|
||||
(void*) event->xexpose.window);
|
||||
|
||||
if (window)
|
||||
{
|
||||
xfw = (xfWindow*) window->extra;
|
||||
xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -156,12 +160,12 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
/* Take scaling in to consideration */
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int)((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
y = (int)((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
}
|
||||
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
@@ -176,6 +180,9 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
|
||||
static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
|
||||
event->xmotion.state, event->xmotion.window, app);
|
||||
}
|
||||
@@ -257,13 +264,16 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
||||
XTranslateCoordinates(xfc->display, window,
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x)
|
||||
|| (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@@ -278,6 +288,9 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
||||
|
||||
static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y,
|
||||
event->xbutton.button, event->xbutton.window, app);
|
||||
}
|
||||
@@ -290,6 +303,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
rdpInput* input;
|
||||
Window childWindow;
|
||||
|
||||
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
@@ -343,11 +357,11 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@@ -361,6 +375,9 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
|
||||
static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y,
|
||||
event->xbutton.button, event->xbutton.window, app);
|
||||
}
|
||||
@@ -542,15 +559,18 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
|
||||
/* This is for resizing the window by dragging the border
|
||||
|
||||
if (xfc->width != event->xconfigure.width)
|
||||
{
|
||||
xfc->scale = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->settings->ScalingFactor = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->currentWidth = event->xconfigure.width;
|
||||
xfc->currentHeight = event->xconfigure.width;
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
*/
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
|
||||
|
||||
if (window != NULL)
|
||||
@@ -568,6 +588,9 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
0, 0, &xfw->left, &xfw->top, &childWindow);
|
||||
|
||||
|
||||
|
||||
|
||||
xfw->width = event->xconfigure.width;
|
||||
xfw->height = event->xconfigure.height;
|
||||
xfw->right = xfw->left + xfw->width - 1;
|
||||
@@ -926,7 +949,6 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case MotionNotify:
|
||||
status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
@@ -1003,6 +1025,7 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case PropertyNotify:
|
||||
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
xf_input_handle_event(xfc, event);
|
||||
|
||||
@@ -950,10 +950,10 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
|
||||
|
||||
XSetClipRectangles(xfc->display, xfc->gc,
|
||||
surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
(XRectangle*) message->rects, message->num_rects, YXBanded);
|
||||
(XRectangle*) message->rects, message->numRects, YXBanded);
|
||||
|
||||
/* Draw the tiles to primary surface, each is 64x64. */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
for (i = 0; i < message->numTiles; i++)
|
||||
{
|
||||
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
|
||||
(char*) message->tiles[i]->data, 64, 64, 32, 0);
|
||||
@@ -966,7 +966,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
|
||||
}
|
||||
|
||||
/* Copy the updated region from backstore to the window. */
|
||||
for (i = 0; i < message->num_rects; i++)
|
||||
for (i = 0; i < message->numRects; i++)
|
||||
{
|
||||
tx = message->rects[i].x + surface_bits_command->destLeft;
|
||||
ty = message->rects[i].y + surface_bits_command->destTop;
|
||||
@@ -988,7 +988,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
|
||||
xfc->bmp_codec_nsc = (BYTE*) realloc(xfc->bmp_codec_nsc,
|
||||
surface_bits_command->width * surface_bits_command->height * 4);
|
||||
|
||||
freerdp_image_flip(nsc_context->bmpdata, xfc->bmp_codec_nsc,
|
||||
freerdp_image_flip(nsc_context->BitmapData, xfc->bmp_codec_nsc,
|
||||
surface_bits_command->width, surface_bits_command->height, 32);
|
||||
|
||||
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
|
||||
|
||||
@@ -131,7 +131,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
RFX_MESSAGE* msg;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
size = width * height * ((bpp + 7) / 8);
|
||||
|
||||
if (bitmap->data == NULL)
|
||||
bitmap->data = (BYTE*) malloc(size);
|
||||
@@ -255,7 +255,7 @@ void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (((xfPointer*) pointer)->cursor != 0)
|
||||
if (((xfPointer*) pointer)->cursor)
|
||||
XFreeCursor(xfc->display, ((xfPointer*) pointer)->cursor);
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
@@ -269,10 +269,12 @@ void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
xfc->pointer = (xfPointer*) pointer;
|
||||
|
||||
/* in RemoteApp mode, window can be null if none has had focus */
|
||||
|
||||
if (xfc->window != NULL)
|
||||
XDefineCursor(xfc->display, xfc->window->handle, ((xfPointer*) pointer)->cursor);
|
||||
if (xfc->window)
|
||||
XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
#endif
|
||||
@@ -299,7 +301,9 @@ void xf_Pointer_SetNull(rdpContext* context)
|
||||
nullcursor = XcursorImageLoadCursor(xfc->display, &ci);
|
||||
}
|
||||
|
||||
if (xfc->window != NULL && nullcursor != None)
|
||||
xfc->pointer = NULL;
|
||||
|
||||
if ((xfc->window) && (nullcursor != None))
|
||||
XDefineCursor(xfc->display, xfc->window->handle, nullcursor);
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
@@ -313,7 +317,9 @@ void xf_Pointer_SetDefault(rdpContext* context)
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (xfc->window != NULL)
|
||||
xfc->pointer = NULL;
|
||||
|
||||
if (xfc->window)
|
||||
XUndefineCursor(xfc->display, xfc->window->handle);
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
|
||||
@@ -21,6 +21,13 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef WITH_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -28,13 +35,17 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "xf_event.h"
|
||||
|
||||
#include "xf_input.h"
|
||||
|
||||
#ifdef WITH_XI
|
||||
|
||||
#define MAX_CONTACTS 2
|
||||
|
||||
#define PAN_THRESHOLD 50
|
||||
#define ZOOM_THRESHOLD 10
|
||||
|
||||
#define MIN_FINGER_DIST 5
|
||||
|
||||
typedef struct touch_contact
|
||||
{
|
||||
int id;
|
||||
@@ -43,16 +54,21 @@ typedef struct touch_contact
|
||||
double pos_y;
|
||||
double last_x;
|
||||
double last_y;
|
||||
|
||||
|
||||
} touchContact;
|
||||
|
||||
touchContact contacts[MAX_CONTACTS];
|
||||
|
||||
int active_contacts;
|
||||
int lastEvType;
|
||||
XIDeviceEvent lastEvent;
|
||||
double firstDist = -1.0;
|
||||
double lastDist;
|
||||
|
||||
double z_vector;
|
||||
double px_vector;
|
||||
double py_vector;
|
||||
|
||||
int xinput_opcode;
|
||||
int scale_cnt;
|
||||
|
||||
@@ -68,10 +84,11 @@ const char* xf_input_get_class_string(int class)
|
||||
return "XIScrollClass";
|
||||
else if (class == XITouchClass)
|
||||
return "XITouchClass";
|
||||
|
||||
|
||||
return "XIUnknownClass";
|
||||
}
|
||||
|
||||
|
||||
int xf_input_init(xfContext* xfc, Window window)
|
||||
{
|
||||
int i, j;
|
||||
@@ -84,87 +101,94 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
XIEventMask evmasks[64];
|
||||
int opcode, event, error;
|
||||
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
|
||||
nmasks = 0;
|
||||
ndevices = 0;
|
||||
active_contacts = 0;
|
||||
ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS);
|
||||
|
||||
|
||||
if (!XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error))
|
||||
{
|
||||
printf("XInput extension not available.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
xfc->XInputOpcode = opcode;
|
||||
|
||||
|
||||
XIQueryVersion(xfc->display, &major, &minor);
|
||||
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
{
|
||||
printf("Server does not support XI 2.2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
xfc->use_xinput = TRUE;
|
||||
|
||||
|
||||
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
||||
|
||||
|
||||
for (i = 0; i < ndevices; i++)
|
||||
{
|
||||
BOOL touch = FALSE;
|
||||
XIDeviceInfo* dev = &info[i];
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
touch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s (%d) \"%s\" id: %d\n",
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
}
|
||||
|
||||
|
||||
evmasks[nmasks].mask = masks[nmasks];
|
||||
evmasks[nmasks].mask_len = sizeof(masks[0]);
|
||||
ZeroMemory(masks[nmasks], sizeof(masks[0]));
|
||||
evmasks[nmasks].deviceid = dev->deviceid;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
}
|
||||
|
||||
|
||||
XISetMask(masks[nmasks], XI_TouchBegin);
|
||||
XISetMask(masks[nmasks], XI_TouchUpdate);
|
||||
XISetMask(masks[nmasks], XI_TouchEnd);
|
||||
nmasks++;
|
||||
}
|
||||
|
||||
|
||||
if (xfc->use_xinput)
|
||||
{
|
||||
if (!touch && (class->type == XIButtonClass))
|
||||
if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer"))
|
||||
{
|
||||
printf("%s button device (id: %d, mode: %d)\n",
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
XISetMask(masks[nmasks], XI_ButtonPress);
|
||||
XISetMask(masks[nmasks], XI_ButtonRelease);
|
||||
XISetMask(masks[nmasks], XI_Motion);
|
||||
@@ -173,51 +197,181 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nmasks > 0)
|
||||
xstatus = XISelectEvents(xfc->display, window, evmasks, nmasks);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_input_is_duplicate(XIDeviceEvent* event)
|
||||
BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
|
||||
if ( (lastEvent.time == event->time) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
(lastEvType == cookie->evtype) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void xf_input_save_last_event(XIDeviceEvent* event)
|
||||
void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
lastEvType = cookie->evtype;
|
||||
|
||||
lastEvent.time = event->time;
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
lastEvent.event_y = event->event_y;
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
double dx[2];
|
||||
double dy[2];
|
||||
|
||||
double px;
|
||||
double py;
|
||||
|
||||
double dist_x;
|
||||
double dist_y;
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dx[0] = contacts[0].pos_x - contacts[0].last_x;
|
||||
dx[1] = contacts[1].pos_x - contacts[1].last_x;
|
||||
|
||||
dy[0] = contacts[0].pos_y - contacts[0].last_y;
|
||||
dy[1] = contacts[1].pos_y - contacts[1].last_y;
|
||||
|
||||
px = fabs(dx[0]) < fabs(dx[1]) ? dx[0] : dx[1];
|
||||
py = fabs(dy[0]) < fabs(dy[1]) ? dy[0] : dy[1];
|
||||
|
||||
px_vector += px;
|
||||
py_vector += py;
|
||||
|
||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||
|
||||
|
||||
//only pan in x if dist_y is greater than something
|
||||
if(dist_y > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(px_vector > PAN_THRESHOLD)
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(px_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(dist_x > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(py_vector > PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(py_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
|
||||
double delta;
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
firstDist = -1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* first calculate the distance */
|
||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
/* if this is the first 2pt touch */
|
||||
if (firstDist <= 0)
|
||||
{
|
||||
@@ -225,50 +379,69 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = lastDist - dist;
|
||||
|
||||
|
||||
if(delta > 1.0)
|
||||
delta = 1.0;
|
||||
if(delta < -1.0)
|
||||
delta = -1.0;
|
||||
|
||||
/* compare the current distance to the first one */
|
||||
zoom = (dist / firstDist);
|
||||
|
||||
|
||||
z_vector += delta;
|
||||
//printf("d: %.2f\n", delta);
|
||||
|
||||
|
||||
|
||||
lastDist = dist;
|
||||
|
||||
if (z_vector > 10)
|
||||
|
||||
if (z_vector > ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale -= 0.05;
|
||||
|
||||
if (xfc->scale < 0.5)
|
||||
xfc->scale = 0.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor -= 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
if (z_vector < -10)
|
||||
|
||||
if (z_vector < -ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale += 0.05;
|
||||
|
||||
if (xfc->scale > 1.5)
|
||||
xfc->scale = 1.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor += 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +450,9 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(active_contacts == MAX_CONTACTS)
|
||||
printf("Houston, we have a problem!\n\n");
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == 0)
|
||||
@@ -286,7 +461,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 1;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
active_contacts++;
|
||||
break;
|
||||
}
|
||||
@@ -296,7 +471,6 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@@ -306,9 +480,10 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].last_y = contacts[i].pos_y;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
xf_input_detect_pinch(xfc);
|
||||
|
||||
xf_input_detect_pan(xfc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -317,7 +492,6 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@@ -326,7 +500,7 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 0;
|
||||
//contacts[i].pos_x = (int)event->event_x;
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
|
||||
active_contacts--;
|
||||
break;printf("TouchBegin\n");
|
||||
}
|
||||
@@ -336,39 +510,39 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_begin(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_update(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_end(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("unhandled xi type= %d\n", cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -384,73 +558,126 @@ char* xf_input_touch_state_string(DWORD flags)
|
||||
return "TouchUnknown";
|
||||
}
|
||||
|
||||
void xf_input_hide_cursor(xfContext* xfc)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
if (!xfc->cursorHidden)
|
||||
{
|
||||
XcursorImage ci;
|
||||
XcursorPixel xp = 0;
|
||||
static Cursor nullcursor = None;
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
ZeroMemory(&ci, sizeof(ci));
|
||||
ci.version = XCURSOR_IMAGE_VERSION;
|
||||
ci.size = sizeof(ci);
|
||||
ci.width = ci.height = 1;
|
||||
ci.xhot = ci.yhot = 0;
|
||||
ci.pixels = &xp;
|
||||
nullcursor = XcursorImageLoadCursor(xfc->display, &ci);
|
||||
|
||||
if ((xfc->window) && (nullcursor != None))
|
||||
XDefineCursor(xfc->display, xfc->window->handle, nullcursor);
|
||||
|
||||
xfc->cursorHidden = TRUE;
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void xf_input_show_cursor(xfContext* xfc)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (xfc->cursorHidden)
|
||||
{
|
||||
if (xfc->window)
|
||||
{
|
||||
if (!xfc->pointer)
|
||||
XUndefineCursor(xfc->display, xfc->window->handle);
|
||||
else
|
||||
XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
|
||||
}
|
||||
|
||||
xfc->cursorHidden = FALSE;
|
||||
}
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
int x, y;
|
||||
int touchId;
|
||||
int contactId;
|
||||
RdpeiClientContext* rdpei = xfc->rdpei;
|
||||
|
||||
|
||||
if (!rdpei)
|
||||
return 0;
|
||||
|
||||
xf_input_hide_cursor(xfc);
|
||||
|
||||
touchId = event->detail;
|
||||
x = (int) event->event_x;
|
||||
y = (int) event->event_y;
|
||||
|
||||
|
||||
if (evtype == XI_TouchBegin)
|
||||
{
|
||||
//printf("TouchBegin: %d\n", touchId);
|
||||
printf("TouchBegin: %d\n", touchId);
|
||||
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchUpdate)
|
||||
{
|
||||
//printf("TouchUpdate: %d\n", touchId);
|
||||
printf("TouchUpdate: %d\n", touchId);
|
||||
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchEnd)
|
||||
{
|
||||
//printf("TouchEnd: %d\n", touchId);
|
||||
printf("TouchEnd: %d\n", touchId);
|
||||
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
return TRUE;
|
||||
xf_input_show_cursor(xfc);
|
||||
|
||||
switch (evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
printf("ButtonPress\n");
|
||||
|
||||
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
|
||||
case XI_ButtonRelease:
|
||||
printf("ButtonRelease\n");
|
||||
|
||||
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
|
||||
case XI_Motion:
|
||||
printf("Motion\n");
|
||||
|
||||
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
@@ -458,23 +685,23 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
case XI_TouchBegin:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchBegin);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchUpdate);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchEnd);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
xf_input_event(xfc, cookie->data, cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -493,10 +720,10 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
{
|
||||
case RdpeiChannel_ServerReady:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_SuspendTouch:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_ResumeTouch:
|
||||
break;
|
||||
}
|
||||
@@ -505,14 +732,16 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
//printf("m:%d g:%d\n", (xfc->settings->MultiTouchInput), (xfc->settings->MultiTouchGestures) );
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
return xf_input_handle_event_remote(xfc, event);
|
||||
}
|
||||
|
||||
if (xfc->enableScaling)
|
||||
|
||||
if (xfc->settings->MultiTouchGestures)
|
||||
return xf_input_handle_event_local(xfc, event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,160 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysym == XK_period)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//Zoom in (scale larger)
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
s += 0.1;
|
||||
if (s > 2.0)
|
||||
s = 2.0;
|
||||
|
||||
xfc->settings->ScalingFactor = s;
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * s;
|
||||
xfc->currentHeight = xfc->originalHeight * s;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_comma)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//Zoom out (scale smaller)
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
s -= 0.1;
|
||||
if (s < 0.5)
|
||||
s = 0.5;
|
||||
|
||||
xfc->settings->ScalingFactor = s;
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * s;
|
||||
xfc->currentHeight = xfc->originalHeight * s;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_4)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_6)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_8)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_2)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include "xf_input.h"
|
||||
#endif
|
||||
|
||||
#include "xf_input.h"
|
||||
|
||||
0
client/X11/xfreerdp-channels.1.xml
Normal file
0
client/X11/xfreerdp-channels.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp connection.rdp /p:Pwd123! /f</command></term>
|
||||
<listitem>
|
||||
<para>Connect in fullscreen mode using a stored configuration <replaceable>connection.rdp</replaceable> and the password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>rdp.contoso.com</replaceable> with user <replaceable>CONTOSO\\JohnDoe</replaceable> and password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>192.168.1.100</replaceable> on port <replaceable>4489</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable>. The screen width is set to <replaceable>1366</replaceable> and the height to <replaceable>768</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100</command></term>
|
||||
<listitem>
|
||||
<para>Establish a connection to host <replaceable>192.168.1.100</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable> and connect to Hyper-V console (use port 2179, disable negotiation) with VMID <replaceable>C824F53E-95D2-46C6-9A18-23A5BB403532</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>+clipboard</command></term>
|
||||
<listitem>
|
||||
<para>Activate clipboard redirection</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/drive:home,/home/user</command></term>
|
||||
<listitem>
|
||||
<para>Activate drive redirection of <replaceable>/home/user</replaceable> as home drive</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/smartcard:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate smartcard redirection for device <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/printer:<device>,<driver></command></term>
|
||||
<listitem>
|
||||
<para>Activate printer redirection for printer <replaceable>device</replaceable> using driver <replaceable>driver</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/serial:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate serial port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/parallel:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate parallel port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/sound:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio output redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/microphone:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio input redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/multimedia:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate multimedia redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/usb:id,dev:054c:0268</command></term>
|
||||
<listitem>
|
||||
<para>Activate USB device redirection for the device identified by <replaceable>054c:0268</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
@@ -1,571 +0,0 @@
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>2011-08-27</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>2011-08-27</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [options] server[:port] [[options] server[:port] …]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>2011-08-27</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-0</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Attach to the admin console of the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-a <replaceable class="parameter">bpp</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the color depth for the connection to <replaceable class="parameter">bpp</replaceable> bits per pixel.
|
||||
Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="WorkingDir">
|
||||
<term>-c <replaceable class="parameter">dir</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the working-dir to <replaceable class="parameter">dir</replaceable>.
|
||||
This parameter is only used when an AlternateShell (<xref linkend="AlternateShell"/>) is requested.
|
||||
<replaceable class="parameter">dir</replaceable> should contain the executable file specified in the AlternateShell.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Removes the windows decorations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Domain used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-f</term>
|
||||
<listitem>
|
||||
<para>
|
||||
start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-T <replaceable class="parameter">text</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the window title to <replaceable class="parameter">text</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-g <replaceable class="parameter">geometry</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the size of the FreeRDP window (and of the remote desktop, when establishing a new connection).
|
||||
<replaceable class="parameter">geometry</replaceable> can have one of the following forms:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> -
|
||||
in this case the resulting window will be of
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> pixels.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">P</replaceable>% -
|
||||
in this case the resulting window will be <replaceable class="parameter">P</replaceable>%
|
||||
of your screen.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The special keyword <emphasis>workarea</emphasis> -
|
||||
in this case the resulting window will be of the same size as your workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print help.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the keyboard-layout-id to <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-K</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not interfere with window manager bindings. Normally, xfreerdp captures all keystrokes while its window is focused.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">hostname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the reported client hostname to <replaceable class="parameter">hostname</replaceable>.
|
||||
Default is to automatically detect the hostname.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-o</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Play audio on the console instead of redirecting to the client.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-p <replaceable class="parameter">password</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Password used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="AlternateShell">
|
||||
<term>-s <replaceable class="parameter">shell</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the startup-shell to <replaceable class="parameter">shell</replaceable>.
|
||||
This parameter should contain a complete path to the alternate shell.
|
||||
If the alternete shell requires a different working directory use <xref linkend="WorkingDir"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-t <replaceable class="parameter">port</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Connect to <replaceable class="parameter">port</replaceable>, instead of the default 3389.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-u <replaceable class="parameter">username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Username used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-x <replaceable class="parameter">flag</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the experience performance flags.
|
||||
<replaceable class="parameter">flag</replaceable> can be one of:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
m - (modem): Equivalent to 15.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
b - (broadband): Equivalent to 1.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
l - (lan): Equivalent to 0.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">num</replaceable> - A hexadecimal number that
|
||||
represents a bit-mask, were numbers mean the following
|
||||
<footnote><para>Taken from <ulink url="http://msdn.microsoft.com/en-us/library/cc240476%28v=prot.10%29.aspx">
|
||||
MS-RDPBCGR Section 2.2.1.11.1.1.1 - Extended Info Packet</ulink></para></footnote>:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>1: Disable desktop wallpaper.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>2: Disable full-window drag (only the window outline is displayed when the window is moved).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>4: Disable menu animations.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>8: Disable user interface themes.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>20: Disable mouse cursor shadows.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>40: Disable cursor blinking.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>80: Enable font smoothing.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>100: Enable Desktop Composition.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-X <replaceable class="parameter">xid</replaceable></term>
|
||||
<listitem>
|
||||
<para>embed xfreerdp into window with <replaceable class="parameter">xid</replaceable>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable compression.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--app</term>
|
||||
<listitem>
|
||||
<para>
|
||||
initialize a RemoteApp connection. This implies -g workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-auth</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--authonly</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Only authenticates. This is useful to test your credentials (username and password).
|
||||
Returns status code 0 if the client can connect, 1 otherwise. Requires a username,
|
||||
password and connection host at the command line.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--bcv3 <replaceable class="parameter">codec</replaceable></term>
|
||||
<listitem>
|
||||
<para>Use <replaceable class="parameter">codec</replaceable> for bitmap cache v3
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-bmp-cache</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable bitmap cache.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--certificate-name <replaceable class="parameter">name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
use <replaceable class="parameter">name</replaceable> for the logon certificate, instead of the server name
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--composition</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable composition (RDVH only, not to be confused with remote composition).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ext <replaceable class="parameter">extname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load extension <replaceable class="parameter">extname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-fastpath</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disables fast-path. Use slow-path packets instead, which have larger headers.
|
||||
It might be good for debugging certain issues when you suspect it might be
|
||||
linked to the parsing of one of the two header types.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--from-stdin</term>
|
||||
<listitem>
|
||||
<para>Prompts for unspecified arguments -u username, -p
|
||||
password, -d domain and connection host. This is useful to
|
||||
hide arguments from ps. Also useful for scripts that will
|
||||
feed these arguments to the client via (what else?) stdin.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-full-window-drag</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable full window drag.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--gdi <replaceable class="parameter">backend</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
GDI (Graphics Device Interface) rendering backend. <replaceable class="parameter">backend</replaceable> can be either sw (software) or hw (hardware).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ignore-certificate</term>
|
||||
<listitem>
|
||||
<para>
|
||||
ignore verification of logon certificate.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--kbd-list</term>
|
||||
<listitem>
|
||||
<para>
|
||||
list all keyboard layout ids used by -k
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-menu-animations</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable menu animations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-motion</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Don't send mouse motion events.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nego</term>
|
||||
<listitem>
|
||||
<para>disable negotiation of security layer and enforce highest enabled security protocol.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nla</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable network level authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--nsc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable NSCodec.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-osb</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable off screen bitmaps.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcb <replaceable class="parameter">blob</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">blob</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcid <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--plugin <replaceable class="parameter">pluginname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load <replaceable class="parameter">pluginname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-rdp</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable RemoteFX.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx-mode</term>
|
||||
<listitem>
|
||||
<para>
|
||||
RemoteFX operational flags. <replaceable class="parameter">flags</replaceable> can be either v[ideo], i[mage]), default is video.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-salted-checksum</term>
|
||||
<listitem>
|
||||
<para>
|
||||
disable salted checksums with Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ntlm</term>
|
||||
<listitem>
|
||||
<para>
|
||||
force NTLM protocol version. <replaceable class="parameter">version</replaceable> can be one of 1 or 2.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--sec <replaceable class="parameter">proto</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
force protocol security. <replaceable class="parameter">proto</replaceable> can be one of rdp, tls or nla.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-theming</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable theming.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-tls</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable TLS encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--tsg
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable> </term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use Terminal Server Gateway with
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print version information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-wallpaper</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable wallpaper.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
60
client/X11/xfreerdp.1.xml.in
Normal file
60
client/X11/xfreerdp.1.xml.in
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE refentry
|
||||
PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY syntax SYSTEM "xfreerdp-argument.1.xml">
|
||||
<!ENTITY channels SYSTEM "xfreerdp-channels.1.xml">
|
||||
<!ENTITY examples SYSTEM "xfreerdp-examples.1.xml">
|
||||
]
|
||||
>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [file] [options] [/v:server[:port]]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
&syntax;
|
||||
|
||||
&channels;
|
||||
|
||||
&examples;
|
||||
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
@@ -89,6 +89,7 @@ struct xf_context
|
||||
BOOL unobscured;
|
||||
BOOL debug;
|
||||
xfWindow* window;
|
||||
xfPointer* pointer;
|
||||
xfWorkArea workArea;
|
||||
int current_desktop;
|
||||
BOOL remote_app;
|
||||
@@ -96,6 +97,7 @@ struct xf_context
|
||||
HCLRCONV clrconv;
|
||||
HANDLE mutex;
|
||||
BOOL UseXThreads;
|
||||
BOOL cursorHidden;
|
||||
|
||||
HGDI_DC hdc;
|
||||
BYTE* primary_buffer;
|
||||
@@ -106,7 +108,6 @@ struct xf_context
|
||||
UINT16 frame_x2;
|
||||
UINT16 frame_y2;
|
||||
|
||||
double scale;
|
||||
int originalWidth;
|
||||
int originalHeight;
|
||||
int currentWidth;
|
||||
@@ -114,6 +115,9 @@ struct xf_context
|
||||
int XInputOpcode;
|
||||
BOOL enableScaling;
|
||||
|
||||
int offset_x;
|
||||
int offset_y;
|
||||
|
||||
BOOL focused;
|
||||
BOOL use_xinput;
|
||||
BOOL mouse_active;
|
||||
@@ -208,7 +212,8 @@ enum XF_EXIT_CODE
|
||||
void xf_lock_x11(xfContext* xfc, BOOL display);
|
||||
void xf_unlock_x11(xfContext* xfc, BOOL display);
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc);
|
||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale);
|
||||
void xf_transform_window(xfContext* xfc);
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@ set(${MODULE_PREFIX}_SRCS
|
||||
compatibility.h
|
||||
file.c)
|
||||
|
||||
set(FREERDP_CHANNELS_CLIENT_PATH "../../channels/client")
|
||||
foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS})
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_PATH}/${FREERDP_CHANNELS_CLIENT_SRC}")
|
||||
get_filename_component(NINC ${FREERDP_CHANNELS_CLIENT_SRC} PATH)
|
||||
include_directories(${NINC})
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_SRC}")
|
||||
endforeach()
|
||||
|
||||
if(MSVC)
|
||||
@@ -53,7 +54,9 @@ target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
if (NOT WITH_WAYK)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries)
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common")
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
freerdp_context_new(instance);
|
||||
|
||||
context = instance->context;
|
||||
context->instance = instance;
|
||||
context->settings = instance->settings;
|
||||
context->instance = instance;
|
||||
context->settings = instance->settings;
|
||||
|
||||
return context;
|
||||
}
|
||||
@@ -112,16 +112,13 @@ int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv
|
||||
|
||||
if (settings->ConnectionFile)
|
||||
{
|
||||
rdpFile* file = freerdp_client_rdp_file_new();
|
||||
freerdp_client_parse_rdp_file(file, settings->ConnectionFile);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, settings);
|
||||
freerdp_client_rdp_file_free(file);
|
||||
return freerdp_client_parse_connection_file(context, settings->ConnectionFile);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_connection_file(rdpContext* context, char* filename)
|
||||
int freerdp_client_parse_connection_file(rdpContext* context, const char* filename)
|
||||
{
|
||||
rdpFile* file;
|
||||
|
||||
@@ -136,11 +133,35 @@ int freerdp_client_parse_connection_file(rdpContext* context, char* filename)
|
||||
int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
freerdp_client_parse_rdp_file_buffer(file, buffer, size);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, context->settings);
|
||||
if (freerdp_client_parse_rdp_file_buffer(file, buffer, size)
|
||||
&& freerdp_client_populate_settings_from_rdp_file(file, context->settings))
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
freerdp_client_rdp_file_free(file);
|
||||
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
if (freerdp_client_populate_rdp_file_from_settings(file, context->settings))
|
||||
{
|
||||
if (freerdp_client_write_rdp_file(file, filename, unicode))
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
freerdp_client_rdp_file_free(file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" },
|
||||
{ "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" },
|
||||
{ "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" },
|
||||
{ "gestures", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Consume multitouch input locally" },
|
||||
{ "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" },
|
||||
{ "disp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Display control" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" },
|
||||
{ "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" },
|
||||
{ "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Full window drag" },
|
||||
@@ -134,6 +136,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "wm-class", COMMAND_LINE_VALUE_REQUIRED, "<class name>", NULL, NULL, -1, NULL, "set the WM_CLASS hint for the window instance" },
|
||||
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" },
|
||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
|
||||
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
||||
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -595,6 +599,11 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
|
||||
p[0] = "rdpei";
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gestures")
|
||||
{
|
||||
printf("gestures\n");
|
||||
settings->MultiTouchGestures = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "echo")
|
||||
{
|
||||
char* p[1];
|
||||
@@ -605,6 +614,16 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
|
||||
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "disp")
|
||||
{
|
||||
char* p[1];
|
||||
int count;
|
||||
|
||||
count = 1;
|
||||
p[0] = "disp";
|
||||
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "sound")
|
||||
{
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
@@ -863,13 +882,10 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int*
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
if (detect_status == 0)
|
||||
{
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
}
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
|
||||
return 0;
|
||||
return detect_status;
|
||||
}
|
||||
|
||||
int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* count)
|
||||
@@ -899,13 +915,10 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
if (detect_status == 0)
|
||||
{
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
}
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
|
||||
return 0;
|
||||
return detect_status;
|
||||
}
|
||||
|
||||
BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
|
||||
@@ -1032,6 +1045,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
|
||||
}
|
||||
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "v");
|
||||
|
||||
arg = args;
|
||||
@@ -1241,8 +1255,9 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
settings->GatewayHostname = _strdup(settings->ServerHostname);
|
||||
}
|
||||
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayUseSameCredentials = TRUE;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gu")
|
||||
{
|
||||
@@ -1426,6 +1441,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
CommandLineSwitchCase(arg, "nsc")
|
||||
{
|
||||
settings->NSCodec = TRUE;
|
||||
settings->ColorDepth = 32;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "jpeg")
|
||||
{
|
||||
@@ -1597,6 +1613,15 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
{
|
||||
settings->WmClass = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "play-rfx")
|
||||
{
|
||||
settings->PlayRemoteFxFile = _strdup(arg->Value);
|
||||
settings->PlayRemoteFx = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "auth-only")
|
||||
{
|
||||
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
@@ -1626,7 +1651,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
if (settings->DisableThemes)
|
||||
settings->PerformanceFlags |= PERF_DISABLE_THEMING;
|
||||
|
||||
if (settings->GatewayUsageMethod)
|
||||
if (settings->GatewayEnabled)
|
||||
{
|
||||
if (settings->GatewayUseSameCredentials)
|
||||
{
|
||||
@@ -1655,7 +1680,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
FillMemory(arg->Value, strlen(arg->Value), '*');
|
||||
}
|
||||
|
||||
return 1;
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings* settings, char* name, void* data)
|
||||
|
||||
@@ -473,7 +473,9 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
||||
CommandLineSwitchCase(arg, "p")
|
||||
{
|
||||
settings->Password = _strdup(arg->Value);
|
||||
fprintf(stderr, "-p %s -> /p:%s\n", arg->Value, arg->Value);
|
||||
fprintf(stderr, "-p ****** -> /p:******\n");
|
||||
/* Hide the value from 'ps'. */
|
||||
FillMemory(arg->Value, strlen(arg->Value), '*');
|
||||
}
|
||||
CommandLineSwitchCase(arg, "s")
|
||||
{
|
||||
|
||||
@@ -439,7 +439,7 @@ BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t si
|
||||
return freerdp_client_parse_rdp_file_buffer_ascii(file, buffer, size);
|
||||
}
|
||||
|
||||
BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
|
||||
BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
|
||||
{
|
||||
BYTE* buffer;
|
||||
FILE* fp = NULL;
|
||||
@@ -480,7 +480,8 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
|
||||
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
|
||||
}
|
||||
|
||||
#define SETTING_MODIFIED(_settings, _field) (_settings->settings_modified[FreeRDP_##_field])
|
||||
#define WRITE_ALL_SETTINGS FALSE
|
||||
#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->settings_modified[FreeRDP_##_field])
|
||||
#define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field
|
||||
|
||||
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings)
|
||||
@@ -529,9 +530,9 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings*
|
||||
}
|
||||
|
||||
|
||||
BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
|
||||
BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
int rc = 0;
|
||||
char* buffer;
|
||||
int len, len2;
|
||||
FILE* fp = NULL;
|
||||
@@ -559,22 +560,22 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
|
||||
fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp);
|
||||
fwrite(unicodestr, 2, len, fp);
|
||||
|
||||
free(unicodestr);
|
||||
free(unicodestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(buffer, 1, len, fp);
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
rc = fflush(fp);
|
||||
rc = fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
|
||||
return success;
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
#define WRITE_RDP_FILE_DECLARE(_file, _buffer, _size) \
|
||||
@@ -604,7 +605,6 @@ if (~__rdpFile->_field) \
|
||||
#define WRITE_RDP_FILE_VALUE_RETURN \
|
||||
return __required_size;
|
||||
|
||||
// TODO: Optimize by only writing the fields that have a value i.e ~((size_t) file->FieldName) != 0
|
||||
size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size)
|
||||
{
|
||||
WRITE_RDP_FILE_DECLARE(file, buffer, size)
|
||||
@@ -731,11 +731,19 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
|
||||
if (~((size_t) file->GatewayHostname))
|
||||
freerdp_set_param_string(settings, FreeRDP_GatewayHostname, file->GatewayHostname);
|
||||
|
||||
if (~file->GatewayUsageMethod)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
{
|
||||
freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
|
||||
if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
||||
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
||||
}
|
||||
|
||||
if (~file->PromptCredentialOnce)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
settings->GatewayUseSameCredentials = TRUE;
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUseSameCredentials, TRUE);
|
||||
|
||||
if (~file->RemoteApplicationMode)
|
||||
freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode);
|
||||
|
||||
@@ -175,7 +175,8 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
|
||||
settings->GatewayUsername = strdup([_params UTF8StringForKey:@"tsg_username"]);
|
||||
settings->GatewayPassword = strdup([_params UTF8StringForKey:@"tsg_password"]);
|
||||
settings->GatewayDomain = strdup([_params UTF8StringForKey:@"tsg_domain"]);
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
settings->GatewayUseSameCredentials = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2010-2011, Ethan Rublee
|
||||
# Copyright (c) 2011-2012, Andrey Kamaev
|
||||
# Copyright (c) 2011-2013, Andrey Kamaev
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,7 +35,6 @@
|
||||
#
|
||||
# The file is mantained by the OpenCV project. The latest version can be get at
|
||||
# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake
|
||||
# Git commit: 084b1c796900b0825fc4e0593ab3143da3f3a90e
|
||||
#
|
||||
# Usage Linux:
|
||||
# $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
|
||||
@@ -282,8 +281,19 @@
|
||||
# [+] updated for NDK r8c
|
||||
# [+] added support for clang compiler
|
||||
# - December 2012
|
||||
# [+] suppress warning about unused CMAKE_TOOLCHAIN_FILE variable
|
||||
# [+] adjust API level to closest compatible as NDK does
|
||||
# [~] fixed ccache full path search
|
||||
# [+] updated for NDK r8d
|
||||
# [~] compiler options are aligned with NDK r8d
|
||||
# - March 2013
|
||||
# [+] updated for NDK r8e (x86 version)
|
||||
# [+] support x86_64 version of NDK
|
||||
# - April 2013
|
||||
# [+] support non-release NDK layouts (from Linaro git and Android git)
|
||||
# [~] automatically detect if explicit link to crtbegin_*.o is needed
|
||||
# - June 2013
|
||||
# [~] fixed stl include path for standalone toolchain made by NDK >= r8c
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required( VERSION 2.6.3 )
|
||||
@@ -293,6 +303,10 @@ if( DEFINED CMAKE_CROSSCOMPILING )
|
||||
return()
|
||||
endif()
|
||||
|
||||
if( CMAKE_TOOLCHAIN_FILE )
|
||||
# touch toolchain variable only to suppress "unused variable" warning
|
||||
endif()
|
||||
|
||||
get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
|
||||
if( _CMAKE_IN_TRY_COMPILE )
|
||||
include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
|
||||
@@ -312,7 +326,7 @@ endif()
|
||||
# rpath makes low sence for Android
|
||||
set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
|
||||
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS)
|
||||
if( CMAKE_HOST_WIN32 )
|
||||
file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
|
||||
@@ -456,19 +470,32 @@ if( ANDROID_FORBID_SYGWIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# detect current host platform
|
||||
if( NOT DEFINED ANDROID_NDK_HOST_X64 AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64")
|
||||
set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" )
|
||||
mark_as_advanced( ANDROID_NDK_HOST_X64 )
|
||||
endif()
|
||||
|
||||
set( TOOL_OS_SUFFIX "" )
|
||||
if( CMAKE_HOST_APPLE )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" )
|
||||
elseif( CMAKE_HOST_WIN32 )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "windows" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" )
|
||||
set( TOOL_OS_SUFFIX ".exe" )
|
||||
elseif( CMAKE_HOST_UNIX )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" )
|
||||
else()
|
||||
message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
|
||||
endif()
|
||||
|
||||
if( NOT ANDROID_NDK_HOST_X64 )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} )
|
||||
endif()
|
||||
|
||||
# see if we have path to Android NDK
|
||||
__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
|
||||
if( NOT ANDROID_NDK )
|
||||
@@ -500,35 +527,19 @@ if( NOT ANDROID_NDK )
|
||||
endif( ANDROID_NDK )
|
||||
endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
|
||||
endif( NOT ANDROID_NDK )
|
||||
|
||||
# remember found paths
|
||||
if( ANDROID_NDK )
|
||||
get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
|
||||
# try to detect change
|
||||
if( CMAKE_AR )
|
||||
string( LENGTH "${ANDROID_NDK}" __length )
|
||||
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
|
||||
if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK )
|
||||
message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
|
||||
" )
|
||||
endif()
|
||||
unset( __androidNdkPreviousPath )
|
||||
unset( __length )
|
||||
endif()
|
||||
set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE )
|
||||
set( BUILD_WITH_ANDROID_NDK True )
|
||||
file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_TXT LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? )
|
||||
|
||||
if(${ANDROID_NDK_RELEASE_TXT} MATCHES "^r[0-9]+[a-z] \([^ ]+\)$")
|
||||
string( REGEX REPLACE "^(r[0-9]+[a-z]) \(([^ ]+)\)$" "\\1" ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
string( REGEX REPLACE "^(r[0-9]+[a-z]) \(([^ ]+)\)$" "\\2" ANDROID_NDK_RELEASE_EXTRA "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
|
||||
set( ANDROID_NDK_64BIT True)
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "${ANDROID_NDK_HOST_SYSTEM_NAME}_64" )
|
||||
|
||||
if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" )
|
||||
file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? )
|
||||
string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" )
|
||||
else()
|
||||
set( ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
set( ANDROID_NDK_RELEASE "r1x" )
|
||||
set( ANDROID_NDK_RELEASE_FULL "unreleased" )
|
||||
endif()
|
||||
|
||||
elseif( ANDROID_STANDALONE_TOOLCHAIN )
|
||||
get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
|
||||
# try to detect change
|
||||
@@ -555,6 +566,51 @@ else()
|
||||
sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
|
||||
endif()
|
||||
|
||||
# android NDK layout
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
if( NOT DEFINED ANDROID_NDK_LAYOUT )
|
||||
# try to automatically detect the layout
|
||||
if( EXISTS "${ANDROID_NDK}/RELEASE.TXT")
|
||||
set( ANDROID_NDK_LAYOUT "RELEASE" )
|
||||
elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" )
|
||||
set( ANDROID_NDK_LAYOUT "LINARO" )
|
||||
elseif( EXISTS "${ANDROID_NDK}/../../gcc/" )
|
||||
set( ANDROID_NDK_LAYOUT "ANDROID" )
|
||||
endif()
|
||||
endif()
|
||||
set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" )
|
||||
mark_as_advanced( ANDROID_NDK_LAYOUT )
|
||||
if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
|
||||
elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
|
||||
else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE"
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" )
|
||||
endif()
|
||||
get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE )
|
||||
|
||||
# try to detect change of NDK
|
||||
if( CMAKE_AR )
|
||||
string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length )
|
||||
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
|
||||
if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH )
|
||||
message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
|
||||
" )
|
||||
endif()
|
||||
unset( __androidNdkPreviousPath )
|
||||
unset( __length )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# get all the details about standalone toolchain
|
||||
if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
__DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
|
||||
@@ -582,22 +638,27 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar )
|
||||
foreach( __toolchain ${${__availableToolchainsVar}} )
|
||||
if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" )
|
||||
macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath )
|
||||
foreach( __toolchain ${${__availableToolchainsLst}} )
|
||||
if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" )
|
||||
string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
|
||||
else()
|
||||
set( __gcc_toolchain "${__toolchain}" )
|
||||
endif()
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" )
|
||||
if( __machine )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" )
|
||||
string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" )
|
||||
if( __machine MATCHES i686 )
|
||||
set( __arch "x86" )
|
||||
elseif( __machine MATCHES arm )
|
||||
set( __arch "arm" )
|
||||
elseif( __machine MATCHES mipsel )
|
||||
set( __arch "mipsel" )
|
||||
endif()
|
||||
list( APPEND __availableToolchainMachines "${__machine}" )
|
||||
list( APPEND __availableToolchainArchs "${__arch}" )
|
||||
list( APPEND __availableToolchainCompilerVersions "${__version}" )
|
||||
else()
|
||||
list( REMOVE_ITEM ${__availableToolchainsVar} "${__toolchain}" )
|
||||
list( APPEND ${__availableToolchainsVar} "${__toolchain}" )
|
||||
endif()
|
||||
unset( __gcc_toolchain )
|
||||
endforeach()
|
||||
@@ -611,19 +672,31 @@ if( BUILD_WITH_ANDROID_NDK )
|
||||
set( __availableToolchainMachines "" )
|
||||
set( __availableToolchainArchs "" )
|
||||
set( __availableToolchainCompilerVersions "" )
|
||||
if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" )
|
||||
if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" )
|
||||
# do not go through all toolchains if we know the name
|
||||
set( __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
|
||||
if( __availableToolchains )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" )
|
||||
file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
|
||||
if( __availableToolchains )
|
||||
list(SORT __availableToolchains) # we need clang to go after gcc
|
||||
list(SORT __availableToolchainsLst) # we need clang to go after gcc
|
||||
endif()
|
||||
__LIST_FILTER( __availableToolchainsLst "^[.]" )
|
||||
__LIST_FILTER( __availableToolchainsLst "llvm" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
|
||||
if( __availableToolchains )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
|
||||
endif()
|
||||
endif()
|
||||
__LIST_FILTER( __availableToolchains "^[.]" )
|
||||
__LIST_FILTER( __availableToolchains "llvm" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
|
||||
@@ -636,11 +709,11 @@ set( __uniqToolchainArchNames ${__availableToolchainArchs} )
|
||||
list( REMOVE_DUPLICATES __uniqToolchainArchNames )
|
||||
list( SORT __uniqToolchainArchNames )
|
||||
foreach( __arch ${__uniqToolchainArchNames} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
endforeach()
|
||||
unset( __uniqToolchainArchNames )
|
||||
if( NOT ANDROID_SUPPORTED_ABIS )
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
endif()
|
||||
|
||||
# choose target ABI
|
||||
@@ -752,6 +825,7 @@ else()
|
||||
list( GET __availableToolchainArchs ${__idx} __toolchainArch )
|
||||
if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
|
||||
list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
|
||||
string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}")
|
||||
if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
|
||||
set( __toolchainMaxVersion "${__toolchainVersion}" )
|
||||
set( __toolchainIdx ${__idx} )
|
||||
@@ -779,11 +853,22 @@ unset( __availableToolchainCompilerVersions )
|
||||
# choose native API level
|
||||
__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
|
||||
string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
|
||||
# TODO: filter out unsupported levels
|
||||
# adjust API level
|
||||
set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} )
|
||||
foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
|
||||
if( NOT __level GREATER ANDROID_NATIVE_API_LEVEL AND NOT __level LESS __real_api_level )
|
||||
set( __real_api_level ${__level} )
|
||||
endif()
|
||||
endforeach()
|
||||
if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL EQUAL __real_api_level )
|
||||
message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'")
|
||||
set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} )
|
||||
endif()
|
||||
unset(__real_api_level)
|
||||
# validate
|
||||
list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
|
||||
if( __levelIdx EQUAL -1 )
|
||||
message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." )
|
||||
message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." )
|
||||
else()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
__DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
|
||||
@@ -893,7 +978,11 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
|
||||
|
||||
if( NOT ANDROID_STL STREQUAL "none" )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" )
|
||||
# old location ( pre r8c )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
endif()
|
||||
if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" )
|
||||
list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" )
|
||||
elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" )
|
||||
@@ -944,11 +1033,11 @@ if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
|
||||
elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
|
||||
string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
|
||||
string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
message( FATAL_ERROR "Could not find the " )
|
||||
if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
message( FATAL_ERROR "Could not find the Clang compiler driver" )
|
||||
endif()
|
||||
set( ANDROID_COMPILER_IS_CLANG 1 )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
else()
|
||||
set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
unset( ANDROID_COMPILER_IS_CLANG CACHE )
|
||||
@@ -962,7 +1051,7 @@ endif()
|
||||
|
||||
# setup paths and STL for NDK
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
|
||||
|
||||
if( ANDROID_STL STREQUAL "none" )
|
||||
@@ -1021,11 +1110,11 @@ if( BUILD_WITH_ANDROID_NDK )
|
||||
endif()
|
||||
# find libsupc++.a - rtti & exceptions
|
||||
if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
|
||||
if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b")
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
else( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer
|
||||
if( NOT EXISTS "${__libsupcxx}" )
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8
|
||||
endif()
|
||||
if( NOT EXISTS "${__libsupcxx}" ) # before r7
|
||||
if( ARMEABI_V7A )
|
||||
if( ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
|
||||
@@ -1075,7 +1164,7 @@ unset( _ndk_ccache )
|
||||
|
||||
# setup the cross-compiler
|
||||
if( NOT CMAKE_C_COMPILER )
|
||||
if( NDK_CCACHE )
|
||||
if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
|
||||
set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
@@ -1147,11 +1236,25 @@ set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
|
||||
remove_definitions( -DANDROID )
|
||||
add_definitions( -DANDROID )
|
||||
|
||||
if(ANDROID_SYSROOT MATCHES "[ ;\"]")
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
|
||||
if( ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
if( CMAKE_HOST_WIN32 )
|
||||
# try to convert path to 8.3 form
|
||||
file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" )
|
||||
execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}"
|
||||
OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE __result ERROR_QUIET )
|
||||
if( __result EQUAL 0 )
|
||||
file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT )
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" )
|
||||
endif()
|
||||
if( NOT _CMAKE_IN_TRY_COMPILE )
|
||||
# quotes will break try_compile and compiler identification
|
||||
message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.")
|
||||
# quotes can break try_compile and compiler identification
|
||||
message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n")
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
|
||||
@@ -1159,38 +1262,52 @@ endif()
|
||||
|
||||
# NDK flags
|
||||
if( ARMEABI OR ARMEABI_V7A )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables" )
|
||||
if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
|
||||
# It is recommended to use the -mthumb compiler flag to force the generation
|
||||
# of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-mthumb" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -finline-limit=64" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" )
|
||||
endif()
|
||||
else()
|
||||
# always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
|
||||
# O3 instead of O2/Os in release mode - like cmake sets for desktop gcc
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-marm" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -finline-limit=300" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
|
||||
endif()
|
||||
endif()
|
||||
elseif( X86 )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-finline-limit=300" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fPIC" )
|
||||
endif()
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
elseif( MIPS )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -frename-registers" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-finline-limit=300 -fno-strict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-finline-functions -fgcse-after-reload -frerun-cse-after-loop" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
|
||||
endif()
|
||||
elseif()
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "" )
|
||||
endif()
|
||||
|
||||
if( NOT X86 )
|
||||
set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
|
||||
|
||||
if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -fomit-frame-pointer" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer" )
|
||||
if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/
|
||||
endif()
|
||||
|
||||
# ABI-specific flags
|
||||
if( ARMEABI_V7A )
|
||||
@@ -1208,22 +1325,18 @@ elseif( ARMEABI )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
|
||||
endif()
|
||||
|
||||
if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
else()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
endif()
|
||||
|
||||
# STL
|
||||
if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
|
||||
if( ANDROID_STL MATCHES "gnustl" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
else()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
endif()
|
||||
if ( X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" )
|
||||
# workaround "undefined reference to `__dso_handle'" problem
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
endif()
|
||||
if( EXISTS "${__libstl}" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" )
|
||||
@@ -1242,9 +1355,12 @@ if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
|
||||
set( CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
|
||||
endif()
|
||||
if( ANDROID_STL MATCHES "gnustl" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} -lm" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} -lm" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lm" )
|
||||
if( NOT EXISTS "${ANDROID_LIBM_PATH}" )
|
||||
set( ANDROID_LIBM_PATH -lm )
|
||||
endif()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1280,7 +1396,14 @@ if( ARMEABI_V7A )
|
||||
endif()
|
||||
|
||||
if( ANDROID_NO_UNDEFINED )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
|
||||
if( MIPS )
|
||||
# there is some sysroot-related problem in mips linker...
|
||||
if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" )
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( ANDROID_SO_UNDEFINED )
|
||||
@@ -1327,9 +1450,6 @@ if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
if(ANDROID_ARCH_NAME STREQUAL "arm" )
|
||||
set( ANDROID_CXX_FLAGS "-isystem ${ANDROID_CLANG_TOOLCHAIN_ROOT}/lib/clang/${ANDROID_CLANG_VERSION}/include ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
endif()
|
||||
@@ -1345,6 +1465,12 @@ set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "shared li
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "module linker flags" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "executable linker flags" )
|
||||
|
||||
# put flags to cache (for debug purpose only)
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Android specific c/c++ flags" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG}" CACHE INTERNAL "Android specific c/c++ Debug flags" )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android specific c/c++ linker flags" )
|
||||
|
||||
# finish flags
|
||||
set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
|
||||
set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
|
||||
@@ -1357,9 +1483,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL
|
||||
set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
|
||||
if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
endif()
|
||||
|
||||
# configure rtti
|
||||
@@ -1386,6 +1512,43 @@ endif()
|
||||
include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
|
||||
link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
|
||||
|
||||
# detect if need link crtbegin_so.o explicitly
|
||||
if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK )
|
||||
set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" )
|
||||
string( REPLACE "<CMAKE_CXX_COMPILER>" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_CXX_FLAGS>" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LANGUAGE_COMPILE_FLAGS>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LINK_FLAGS>" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>" "-shared" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<TARGET_SONAME>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<TARGET>" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" )
|
||||
string( REPLACE "<OBJECTS>" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LINK_LIBRARIES>" "" __cmd "${__cmd}" )
|
||||
separate_arguments( __cmd )
|
||||
foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN )
|
||||
if( ${__var} )
|
||||
set( __tmp "${${__var}}" )
|
||||
separate_arguments( __tmp )
|
||||
string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}")
|
||||
endif()
|
||||
endforeach()
|
||||
string( REPLACE "'" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "\"" "" __cmd "${__cmd}" )
|
||||
execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET )
|
||||
if( __cmd_result EQUAL 0 )
|
||||
set( ANDROID_EXPLICIT_CRT_LINK ON )
|
||||
else()
|
||||
set( ANDROID_EXPLICIT_CRT_LINK OFF )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( ANDROID_EXPLICIT_CRT_LINK )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
endif()
|
||||
|
||||
# setup output directories
|
||||
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
|
||||
set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
|
||||
@@ -1475,7 +1638,9 @@ endmacro()
|
||||
if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
|
||||
set( __toolchain_config "")
|
||||
foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN ANDROID_SET_OBSOLETE_VARIABLES
|
||||
ANDROID_NDK_HOST_X64
|
||||
ANDROID_NDK
|
||||
ANDROID_NDK_LAYOUT
|
||||
ANDROID_STANDALONE_TOOLCHAIN
|
||||
ANDROID_TOOLCHAIN_NAME
|
||||
ANDROID_ABI
|
||||
@@ -1489,6 +1654,8 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
|
||||
ANDROID_GOLD_LINKER
|
||||
ANDROID_NOEXECSTACK
|
||||
ANDROID_RELRO
|
||||
ANDROID_LIBM_PATH
|
||||
ANDROID_EXPLICIT_CRT_LINK
|
||||
)
|
||||
if( DEFINED ${__var} )
|
||||
if( "${__var}" MATCHES " ")
|
||||
@@ -1531,6 +1698,8 @@ endif()
|
||||
# ANDROID_NDK
|
||||
# ANDROID_STANDALONE_TOOLCHAIN
|
||||
# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
|
||||
# ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
|
||||
# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
|
||||
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
|
||||
# NDK_CCACHE : <path to your ccache executable>
|
||||
# Obsolete:
|
||||
@@ -1553,7 +1722,7 @@ endif()
|
||||
# BUILD_ANDROID : always TRUE
|
||||
# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
|
||||
# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
|
||||
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86", "linux-x86_64" or "darwin-x86" depending on host platform
|
||||
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
|
||||
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI
|
||||
# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d, r8e; set only for NDK
|
||||
# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI
|
||||
@@ -1576,6 +1745,7 @@ endif()
|
||||
# ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
|
||||
# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
|
||||
# ANDROID_CLANG_VERSION : version of clang compiler if clang is used
|
||||
# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
|
||||
#
|
||||
# Defaults:
|
||||
# ANDROID_DEFAULT_NDK_API_LEVEL
|
||||
|
||||
73
cmake/FindDBus.cmake
Normal file
73
cmake/FindDBus.cmake
Normal file
@@ -0,0 +1,73 @@
|
||||
# - Try to find the low-level D-Bus library
|
||||
# Once done this will define
|
||||
#
|
||||
# DBUS_FOUND - system has D-Bus
|
||||
# DBUS_INCLUDE_DIR - the D-Bus include directory
|
||||
# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory
|
||||
# DBUS_LIBRARIES - the libraries needed to use D-Bus
|
||||
|
||||
# Copyright (c) 2008, Kevin Kofler, <kevin.kofler@chello.at>
|
||||
# modeled after FindLibArt.cmake:
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
# in cache already
|
||||
SET(DBUS_FOUND TRUE)
|
||||
|
||||
else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
IF (PKG_CONFIG_FOUND)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
pkg_check_modules(_DBUS_PC QUIET dbus-1)
|
||||
ENDIF (PKG_CONFIG_FOUND)
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/include/dbus-1.0
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/lib${LIB_SUFFIX}/include
|
||||
/usr/lib${LIB_SUFFIX}/dbus-1.0/include
|
||||
/usr/lib64/include
|
||||
/usr/lib64/dbus-1.0/include
|
||||
/usr/lib/include
|
||||
/usr/lib/dbus-1.0/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus
|
||||
PATHS
|
||||
${_DBUS_PC_LIBDIR}
|
||||
)
|
||||
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
set(DBUS_FOUND TRUE)
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
|
||||
if (DBUS_FOUND)
|
||||
if (NOT DBus_FIND_QUIETLY)
|
||||
message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}")
|
||||
endif (NOT DBus_FIND_QUIETLY)
|
||||
else (DBUS_FOUND)
|
||||
if (DBus_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find D-Bus")
|
||||
endif (DBus_FIND_REQUIRED)
|
||||
endif (DBUS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES)
|
||||
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
38
cmake/FindDbusGlib.cmake
Normal file
38
cmake/FindDbusGlib.cmake
Normal file
@@ -0,0 +1,38 @@
|
||||
# DbusGlib library detection
|
||||
#
|
||||
# Copyright 2013 Thinstuff Technologies GmbH
|
||||
# Copyright 2013 Armin Novak <anovak@thinstuff.at>
|
||||
#
|
||||
# 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.
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_DBUS_GLIB QUIET dbus-glib-1)
|
||||
set(DBUS_GLIB_DEFINITIONS ${PC_DBUS_GLIB_CFLAGS_OTHER})
|
||||
|
||||
find_path(DBUS_GLIB_INCLUDE_DIR dbus/dbus-glib.h
|
||||
HINTS ${PC_DBUS_GLIB_INCLUDEDIR} ${PC_DBUS_GLIB_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES dbus-glib-1 )
|
||||
|
||||
find_library(DBUS_GLIB_LIBRARY NAMES dbus-glib-1 dbus-glib
|
||||
HINTS ${PC_DBUS_GLIB_LIBDIR} ${PC_DBUS_GLIB_LIBRARY_DIRS} )
|
||||
|
||||
set(DBUS_GLIB_LIBRARIES ${DBUS_GLIB_LIBRARY} )
|
||||
set(DBUS_GLIB_INCLUDE_DIRS ${DBUS_GLIB_INCLUDE_DIR} )
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set DBUS_GLIB_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(dbus-glib DEFAULT_MSG
|
||||
DBUS_GLIB_LIBRARY DBUS_GLIB_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(DBUS_GLIB_INCLUDE_DIR DBUS_GLIB_LIBRARY )
|
||||
52
cmake/FindDocBookXSL.cmake
Normal file
52
cmake/FindDocBookXSL.cmake
Normal file
@@ -0,0 +1,52 @@
|
||||
# Try to find DocBook XSL stylesheet
|
||||
# Once done, it will define:
|
||||
#
|
||||
# DOCBOOKXSL_FOUND - system has the required DocBook XML DTDs
|
||||
# DOCBOOKXSL_DIR - the directory containing the stylesheets
|
||||
# used to process DocBook XML
|
||||
|
||||
# Copyright (c) 2010, Luigi Toscano, <luigi.toscano@tiscali.it>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
set (STYLESHEET_PATH_LIST
|
||||
share/xml/docbook/stylesheet/docbook-xsl
|
||||
share/xml/docbook/xsl-stylesheets
|
||||
share/sgml/docbook/xsl-stylesheets
|
||||
share/xml/docbook/stylesheet/nwalsh/current
|
||||
share/xml/docbook/stylesheet/nwalsh
|
||||
share/xsl/docbook
|
||||
share/xsl/docbook-xsl
|
||||
)
|
||||
|
||||
find_path (DOCBOOKXSL_DIR lib/lib.xsl
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
|
||||
if (NOT DOCBOOKXSL_DIR)
|
||||
# hacks for systems that put the version in the stylesheet dirs
|
||||
set (STYLESHEET_PATH_LIST)
|
||||
foreach (STYLESHEET_PREFIX_ITER ${CMAKE_SYSTEM_PREFIX_PATH})
|
||||
file(GLOB STYLESHEET_SUFFIX_ITER RELATIVE ${STYLESHEET_PREFIX_ITER}
|
||||
${STYLESHEET_PREFIX_ITER}/share/xml/docbook/xsl-stylesheets-*
|
||||
)
|
||||
if (STYLESHEET_SUFFIX_ITER)
|
||||
list (APPEND STYLESHEET_PATH_LIST ${STYLESHEET_SUFFIX_ITER})
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
find_path (DOCBOOKXSL_DIR VERSION
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
endif (NOT DOCBOOKXSL_DIR)
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (DocBookXSL
|
||||
"Could NOT find DocBook XSL stylesheets"
|
||||
DOCBOOKXSL_DIR)
|
||||
|
||||
mark_as_advanced (DOCBOOKXSL_DIR)
|
||||
237
cmake/FindImageMagick.cmake
Normal file
237
cmake/FindImageMagick.cmake
Normal file
@@ -0,0 +1,237 @@
|
||||
# - Find the ImageMagick binary suite.
|
||||
# This module will search for a set of ImageMagick tools specified
|
||||
# as components in the FIND_PACKAGE call. Typical components include,
|
||||
# but are not limited to (future versions of ImageMagick might have
|
||||
# additional components not listed here):
|
||||
#
|
||||
# animate
|
||||
# compare
|
||||
# composite
|
||||
# conjure
|
||||
# convert
|
||||
# display
|
||||
# identify
|
||||
# import
|
||||
# mogrify
|
||||
# montage
|
||||
# stream
|
||||
#
|
||||
# If no component is specified in the FIND_PACKAGE call, then it only
|
||||
# searches for the ImageMagick executable directory. This code defines
|
||||
# the following variables:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_EXECUTABLE_DIR - Full path to executables directory.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
|
||||
# ImageMagick_VERSION_STRING - the version of ImageMagick found
|
||||
# (since CMake 2.8.8)
|
||||
#
|
||||
# ImageMagick_VERSION_STRING will not work for old versions like 5.2.3.
|
||||
#
|
||||
# There are also components for the following ImageMagick APIs:
|
||||
#
|
||||
# Magick++
|
||||
# MagickWand
|
||||
# MagickCore
|
||||
#
|
||||
# For these components the following variables are set:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_INCLUDE_DIRS - Full paths to all include dirs.
|
||||
# ImageMagick_LIBRARIES - Full paths to all libraries.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
|
||||
# ImageMagick_<component>_LIBRARIES - Full path to <component> libraries.
|
||||
#
|
||||
# Example Usages:
|
||||
# find_package(ImageMagick)
|
||||
# find_package(ImageMagick COMPONENTS convert)
|
||||
# find_package(ImageMagick COMPONENTS convert mogrify display)
|
||||
# find_package(ImageMagick COMPONENTS Magick++)
|
||||
# find_package(ImageMagick COMPONENTS Magick++ convert)
|
||||
#
|
||||
# Note that the standard FIND_PACKAGE features are supported
|
||||
# (i.e., QUIET, REQUIRED, etc.).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2007-2008 Miguel A. Figueroa-Villanueva <miguelf at ieee dot org>
|
||||
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Helper functions
|
||||
#---------------------------------------------------------------------
|
||||
function(FIND_IMAGEMAGICK_API component header)
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
|
||||
find_path(ImageMagick_${component}_INCLUDE_DIR
|
||||
NAMES ${header}
|
||||
PATHS
|
||||
${ImageMagick_INCLUDE_DIRS}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
|
||||
PATH_SUFFIXES
|
||||
ImageMagick
|
||||
DOC "Path to the ImageMagick include dir."
|
||||
)
|
||||
find_library(ImageMagick_${component}_LIBRARY
|
||||
NAMES ${ARGN}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
|
||||
DOC "Path to the ImageMagick Magick++ library."
|
||||
)
|
||||
|
||||
if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_INCLUDE_DIRS
|
||||
${ImageMagick_${component}_INCLUDE_DIR}
|
||||
)
|
||||
list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_LIBRARIES
|
||||
${ImageMagick_${component}_LIBRARY}
|
||||
)
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(FIND_IMAGEMAGICK_EXE component)
|
||||
set(_IMAGEMAGICK_EXECUTABLE
|
||||
${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
|
||||
if(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
|
||||
set(ImageMagick_${component}_EXECUTABLE
|
||||
${_IMAGEMAGICK_EXECUTABLE}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Start Actual Work
|
||||
#---------------------------------------------------------------------
|
||||
# Try to find a ImageMagick installation binary path.
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
|
||||
DOC "Path to the ImageMagick binary directory."
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
)
|
||||
|
||||
# Find each component. Search for all tools in same dir
|
||||
# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
|
||||
# independently and not in a cohesive module such as this one.
|
||||
unset(ImageMagick_REQUIRED_VARS)
|
||||
unset(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
foreach(component ${ImageMagick_FIND_COMPONENTS}
|
||||
# DEPRECATED: forced components for backward compatibility
|
||||
convert mogrify import montage composite
|
||||
)
|
||||
if(component STREQUAL "Magick++")
|
||||
FIND_IMAGEMAGICK_API(Magick++ Magick++.h
|
||||
Magick++ CORE_RL_Magick++_ Magick++-Q16 Magick++-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
|
||||
elseif(component STREQUAL "MagickWand")
|
||||
FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
|
||||
Wand MagickWand CORE_RL_wand_ MagickWand-Q16 MagickWand-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
|
||||
elseif(component STREQUAL "MagickCore")
|
||||
FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
|
||||
Magick MagickCore CORE_RL_magick_ MagickCore-6 MagickCore-Q16 MagickCore-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
|
||||
else()
|
||||
if(ImageMagick_EXECUTABLE_DIR)
|
||||
FIND_IMAGEMAGICK_EXE(${component})
|
||||
endif()
|
||||
|
||||
if(ImageMagick_FIND_COMPONENTS)
|
||||
list(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
|
||||
if(is_requested GREATER -1)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
elseif(ImageMagick_${component}_EXECUTABLE)
|
||||
# if no components were requested explicitly put all (default) executables
|
||||
# in the list
|
||||
list(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
|
||||
# No components were requested, and none of the default components were
|
||||
# found. Just insert mogrify into the list of the default components to
|
||||
# find so FPHSA below has something to check
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
|
||||
elseif(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
|
||||
|
||||
if(ImageMagick_mogrify_EXECUTABLE)
|
||||
execute_process(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
|
||||
OUTPUT_VARIABLE imagemagick_version
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(imagemagick_version MATCHES "^Version: ImageMagick [0-9]")
|
||||
string(REGEX REPLACE "^Version: ImageMagick ([-0-9\\.]+).*" "\\1" ImageMagick_VERSION_STRING "${imagemagick_version}")
|
||||
endif()
|
||||
unset(imagemagick_version)
|
||||
endif()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Standard Package Output
|
||||
#---------------------------------------------------------------------
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ImageMagick
|
||||
REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
|
||||
VERSION_VAR ImageMagick_VERSION_STRING
|
||||
)
|
||||
# Maintain consistency with all other variables.
|
||||
set(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# DEPRECATED: Setting variables for backward compatibility.
|
||||
#---------------------------------------------------------------------
|
||||
set(IMAGEMAGICK_BINARY_PATH ${ImageMagick_EXECUTABLE_DIR}
|
||||
CACHE PATH "Path to the ImageMagick binary directory.")
|
||||
set(IMAGEMAGICK_CONVERT_EXECUTABLE ${ImageMagick_convert_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's convert executable.")
|
||||
set(IMAGEMAGICK_MOGRIFY_EXECUTABLE ${ImageMagick_mogrify_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
|
||||
set(IMAGEMAGICK_IMPORT_EXECUTABLE ${ImageMagick_import_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's import executable.")
|
||||
set(IMAGEMAGICK_MONTAGE_EXECUTABLE ${ImageMagick_montage_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's montage executable.")
|
||||
set(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's composite executable.")
|
||||
mark_as_advanced(
|
||||
IMAGEMAGICK_BINARY_PATH
|
||||
IMAGEMAGICK_CONVERT_EXECUTABLE
|
||||
IMAGEMAGICK_MOGRIFY_EXECUTABLE
|
||||
IMAGEMAGICK_IMPORT_EXECUTABLE
|
||||
IMAGEMAGICK_MONTAGE_EXECUTABLE
|
||||
IMAGEMAGICK_COMPOSITE_EXECUTABLE
|
||||
)
|
||||
40
cmake/FindPixman.cmake
Normal file
40
cmake/FindPixman.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - Find Pixman
|
||||
# Find the Pixman libraries
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# PIXMAN_FOUND - true if PIXMAN_INCLUDE_DIR & PIXMAN_LIBRARY are found
|
||||
# PIXMAN_LIBRARIES - Set when PIXMAN_LIBRARY is found
|
||||
# PIXMAN_INCLUDE_DIRS - Set when PIXMAN_INCLUDE_DIR is found
|
||||
#
|
||||
# PIXMAN_INCLUDE_DIR - where to find pixman.h, etc.
|
||||
# PIXMAN_LIBRARY - the Pixman library
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#=============================================================================
|
||||
|
||||
find_path(PIXMAN_INCLUDE_DIR NAMES pixman.h PATH_SUFFIXES pixman-1)
|
||||
|
||||
find_library(PIXMAN_LIBRARY NAMES pixman-1)
|
||||
|
||||
find_package_handle_standard_args(pixman-1 DEFAULT_MSG PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
|
||||
|
||||
if(PIXMAN-1_FOUND)
|
||||
set(PIXMAN_LIBRARIES ${PIXMAN_LIBRARY})
|
||||
set(PIXMAN_INCLUDE_DIRS ${PIXMAN_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(PIXMAN_INCLUDE_DIR PIXMAN_LIBRARY)
|
||||
53
cmake/FindUDev.cmake
Normal file
53
cmake/FindUDev.cmake
Normal file
@@ -0,0 +1,53 @@
|
||||
# razor-de: Configure libudev environment
|
||||
#
|
||||
# UDEV_FOUND - system has a libudev
|
||||
# UDEV_INCLUDE_DIR - where to find header files
|
||||
# UDEV_LIBRARIES - the libraries to link against udev
|
||||
# UDEV_STABLE - it's true when is the version greater or equals to 143 - version when the libudev was stabilized in its API
|
||||
#
|
||||
# copyright (c) 2011 Petr Vanek <petr@scribus.info>
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
#
|
||||
|
||||
FIND_PATH(
|
||||
UDEV_INCLUDE_DIR
|
||||
libudev.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
${UDEV_PATH_INCLUDES}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
UDEV_LIBRARIES
|
||||
NAMES udev libudev
|
||||
PATHS
|
||||
/usr/lib${LIB_SUFFIX}
|
||||
/usr/local/lib${LIB_SUFFIX}
|
||||
${UDEV_PATH_LIB}
|
||||
)
|
||||
|
||||
IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
||||
SET(UDEV_FOUND "YES")
|
||||
execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE)
|
||||
# retvale is 0 of the condition is "true" so we need to negate the value...
|
||||
if (UDEV_STABLE)
|
||||
set(UDEV_STABLE 0)
|
||||
else (UDEV_STABLE)
|
||||
set(UDEV_STABLE 1)
|
||||
endif (UDEV_STABLE)
|
||||
message(STATUS "libudev stable: ${UDEV_STABLE}")
|
||||
ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
||||
|
||||
IF (UDEV_FOUND)
|
||||
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
|
||||
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
|
||||
ELSE (UDEV_FOUND)
|
||||
MESSAGE(STATUS "UDev not found.")
|
||||
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
|
||||
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
|
||||
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
|
||||
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
|
||||
IF (UDev_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find UDev library")
|
||||
ENDIF (UDev_FIND_REQUIRED)
|
||||
ENDIF (UDEV_FOUND)
|
||||
113
cmake/FindUUID.cmake
Normal file
113
cmake/FindUUID.cmake
Normal file
@@ -0,0 +1,113 @@
|
||||
# - Try to find UUID
|
||||
# Once done this will define
|
||||
#
|
||||
# UUID_FOUND - system has UUID
|
||||
# UUID_INCLUDE_DIRS - the UUID include directory
|
||||
# UUID_LIBRARIES - Link these to use UUID
|
||||
# UUID_DEFINITIONS - Compiler switches required for using UUID
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(UUID_FOUND TRUE)
|
||||
else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
||||
find_path(UUID_INCLUDE_DIR
|
||||
NAMES
|
||||
uuid/uuid.h
|
||||
PATHS
|
||||
${UUID_DIR}/include
|
||||
$ENV{UUID_DIR}/include
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/inc
|
||||
$ENV{DELTA_ROOT}/ext/inc
|
||||
$ENV{DELTA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/usr/include/gdal
|
||||
/sw/include # Fink
|
||||
/opt/local/include # DarwinPorts
|
||||
/opt/csw/include # Blastwave
|
||||
/opt/include
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]/include
|
||||
/usr/freeware/include
|
||||
|
||||
)
|
||||
|
||||
find_library(UUID_LIBRARY
|
||||
NAMES
|
||||
uuid
|
||||
PATHS
|
||||
${UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/lib
|
||||
$ENV{DELTA_ROOT}/ext/lib
|
||||
$ENV{DELTA_ROOT}
|
||||
$ENV{OSG_ROOT}/lib
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
/usr/freeware/lib64
|
||||
)
|
||||
|
||||
find_library(UUID_LIBRARY_DEBUG
|
||||
NAMES
|
||||
uuidd
|
||||
PATHS
|
||||
${UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/lib
|
||||
$ENV{DELTA_ROOT}/ext/lib
|
||||
$ENV{DELTA_ROOT}
|
||||
$ENV{OSG_ROOT}/lib
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
/usr/freeware/lib64
|
||||
)
|
||||
|
||||
set(UUID_INCLUDE_DIRS
|
||||
${UUID_INCLUDE_DIR}
|
||||
)
|
||||
set(UUID_LIBRARIES
|
||||
${UUID_LIBRARY}
|
||||
)
|
||||
|
||||
if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
|
||||
set(UUID_FOUND TRUE)
|
||||
endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
|
||||
|
||||
if (UUID_FOUND)
|
||||
if (NOT UUID_FIND_QUIETLY)
|
||||
message(STATUS "Found UUID: ${UUID_LIBRARIES}")
|
||||
endif (NOT UUID_FIND_QUIETLY)
|
||||
else (UUID_FOUND)
|
||||
if (UUID_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find UUID")
|
||||
endif (UUID_FIND_REQUIRED)
|
||||
endif (UUID_FOUND)
|
||||
|
||||
# show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(UUID_INCLUDE_DIRS UUID_LIBRARIES)
|
||||
|
||||
endif (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
||||
@@ -14,6 +14,7 @@
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# - Find Xrender
|
||||
# Find the Xrender libraries
|
||||
# - Find XRender
|
||||
# Find the XRender libraries
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# Xrender_FOUND - true if Xrender_INCLUDE_DIR & Xrender_LIBRARY are found
|
||||
# Xrender_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# Xrender_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
# XRENDER_FOUND - true if XRENDER_INCLUDE_DIR & XRENDER_LIBRARY are found
|
||||
# XRENDER_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# XRENDER_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
#
|
||||
# Xrender_INCLUDE_DIR - where to find Xrendernput2.h, etc.
|
||||
# Xrender_LIBRARY - the Xrender library
|
||||
# XRENDER_INCLUDE_DIR - where to find Xrender.h, etc.
|
||||
# XRENDER_LIBRARY - the Xrender library
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
@@ -36,9 +36,10 @@ include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR)
|
||||
|
||||
if(XRENDER_FOUND)
|
||||
|
||||
set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
|
||||
set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
|
||||
|
||||
endif()
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIRS XRENDER_LIBRARIES)
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIR XRENDER_LIBRARY)
|
||||
|
||||
98
cmake/Findlibusb-1.0.cmake
Normal file
98
cmake/Findlibusb-1.0.cmake
Normal file
@@ -0,0 +1,98 @@
|
||||
# - Try to find libusb-1.0
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBUSB_1_FOUND - system has libusb
|
||||
# LIBUSB_1_INCLUDE_DIRS - the libusb include directory
|
||||
# LIBUSB_1_LIBRARIES - Link these to use libusb
|
||||
# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb
|
||||
#
|
||||
# Adapted from cmake-modules Google Code project
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# (Changes for libusb) Copyright (c) 2008 Kyle Machulis <kyle@nonpolynomial.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||
#
|
||||
# CMake-Modules Project New BSD License
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the CMake-Modules Project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
|
||||
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBUSB_FOUND TRUE)
|
||||
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
find_path(LIBUSB_1_INCLUDE_DIR
|
||||
NAMES
|
||||
libusb.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES
|
||||
libusb-1.0
|
||||
)
|
||||
|
||||
find_library(LIBUSB_1_LIBRARY
|
||||
NAMES
|
||||
usb-1.0 usb
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(LIBUSB_1_INCLUDE_DIRS
|
||||
${LIBUSB_1_INCLUDE_DIR}
|
||||
)
|
||||
set(LIBUSB_1_LIBRARIES
|
||||
${LIBUSB_1_LIBRARY}
|
||||
)
|
||||
|
||||
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
set(LIBUSB_1_FOUND TRUE)
|
||||
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
|
||||
if (LIBUSB_1_FOUND)
|
||||
if (NOT libusb_1_FIND_QUIETLY)
|
||||
message(STATUS "Found libusb-1.0:")
|
||||
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
||||
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
||||
endif (NOT libusb_1_FIND_QUIETLY)
|
||||
else (LIBUSB_1_FOUND)
|
||||
if (libusb_1_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find libusb")
|
||||
endif (libusb_1_FIND_REQUIRED)
|
||||
endif (LIBUSB_1_FOUND)
|
||||
|
||||
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
||||
|
||||
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
@@ -5,17 +5,20 @@ macro(configure_msvc_runtime)
|
||||
if("${MSVC_RUNTIME}" STREQUAL "")
|
||||
set(MSVC_RUNTIME "dynamic")
|
||||
endif()
|
||||
|
||||
# Set compiler options.
|
||||
set(variables
|
||||
CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
)
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
|
||||
if(${MSVC_RUNTIME} STREQUAL "static")
|
||||
message(STATUS "MSVC: using statically-linked runtime (/MT and /MTd).")
|
||||
foreach(variable ${variables})
|
||||
@@ -31,6 +34,25 @@ macro(configure_msvc_runtime)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
foreach(variable ${variables})
|
||||
if(${variable} MATCHES "/Ob0")
|
||||
string(REGEX REPLACE "/Ob0" "/Ob2" ${variable} "${${variable}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(variable ${variables})
|
||||
if(${variable} MATCHES "/W3")
|
||||
string(REGEX REPLACE "/W3" "/W2" ${variable} "${${variable}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
|
||||
foreach(variable ${variables})
|
||||
set(${variable} "${${variable}}" CACHE STRING "MSVC_${variable}" FORCE)
|
||||
endforeach()
|
||||
|
||||
130
cmake/MergeStaticLibs.cmake
Normal file
130
cmake/MergeStaticLibs.cmake
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
# Copyright (C) 2012 Modelon AB
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the BSD style license.
|
||||
|
||||
# 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. See the
|
||||
# FMILIB_License.txt file for more details.
|
||||
|
||||
# You should have received a copy of the FMILIB_License.txt file
|
||||
# along with this program. If not, contact Modelon AB <http://www.modelon.com>.
|
||||
|
||||
# Merge_static_libs(outlib lib1 lib2 ... libn) merges a number of static
|
||||
# libs into a single static library
|
||||
function(merge_static_libs outlib)
|
||||
set(libs ${ARGV})
|
||||
list(REMOVE_AT libs 0)
|
||||
# Create a dummy file that the target will depend on
|
||||
set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/${outlib}_dummy.c)
|
||||
file(WRITE ${dummyfile} "const char * dummy = \"${dummyfile}\";")
|
||||
|
||||
add_library(${outlib} STATIC ${dummyfile})
|
||||
|
||||
if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
|
||||
set(multiconfig FALSE)
|
||||
else()
|
||||
set(multiconfig TRUE)
|
||||
endif()
|
||||
|
||||
# First get the file names of the libraries to be merged
|
||||
foreach(lib ${libs})
|
||||
get_target_property(libtype ${lib} TYPE)
|
||||
if(NOT libtype STREQUAL "STATIC_LIBRARY")
|
||||
message(FATAL_ERROR "Merge_static_libs can only process static libraries")
|
||||
endif()
|
||||
if(multiconfig)
|
||||
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
|
||||
get_target_property("libfile_${CONFIG_TYPE}" ${lib} "LOCATION_${CONFIG_TYPE}")
|
||||
list(APPEND libfiles_${CONFIG_TYPE} ${libfile_${CONFIG_TYPE}})
|
||||
endforeach()
|
||||
else()
|
||||
get_target_property(libfile ${lib} LOCATION)
|
||||
list(APPEND libfiles "${libfile}")
|
||||
endif(multiconfig)
|
||||
endforeach()
|
||||
#message(STATUS "will be merging ${libfiles}")
|
||||
# Just to be sure: cleanup from duplicates
|
||||
if(multiconfig)
|
||||
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
|
||||
list(REMOVE_DUPLICATES libfiles_${CONFIG_TYPE})
|
||||
set(libfiles ${libfiles} ${libfiles_${CONFIG_TYPE}})
|
||||
endforeach()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES libfiles)
|
||||
|
||||
# Now the easy part for MSVC and for MAC
|
||||
if(MSVC)
|
||||
# lib.exe does the merging of libraries just need to conver the list into string
|
||||
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
|
||||
set(flags "")
|
||||
foreach(lib ${libfiles_${CONFIG_TYPE}})
|
||||
set(flags "${flags} ${lib}")
|
||||
endforeach()
|
||||
string(TOUPPER "STATIC_LIBRARY_FLAGS_${CONFIG_TYPE}" PROPNAME)
|
||||
set_target_properties(${outlib} PROPERTIES ${PROPNAME} "${flags}")
|
||||
endforeach()
|
||||
|
||||
elseif(APPLE)
|
||||
# Use OSX's libtool to merge archives
|
||||
if(multiconfig)
|
||||
message(FATAL_ERROR "Multiple configurations are not supported")
|
||||
endif()
|
||||
get_target_property(outfile ${outlib} LOCATION)
|
||||
add_custom_command(TARGET ${outlib} POST_BUILD
|
||||
COMMAND rm ${outfile}
|
||||
COMMAND /usr/bin/libtool -static -o ${outfile}
|
||||
${libfiles}
|
||||
)
|
||||
else()
|
||||
# general UNIX - need to "ar -x" and then "ar -ru"
|
||||
if(multiconfig)
|
||||
message(FATAL_ERROR "Multiple configurations are not supported")
|
||||
endif()
|
||||
get_target_property(outfile ${outlib} LOCATION)
|
||||
message(STATUS "outfile location is ${outfile}")
|
||||
foreach(lib ${libfiles})
|
||||
# objlistfile will contain the list of object files for the library
|
||||
set(objlistfile ${lib}.objlist)
|
||||
set(objdir ${lib}.objdir)
|
||||
set(objlistcmake ${objlistfile}.cmake)
|
||||
# we only need to extract files once
|
||||
if(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache IS_NEWER_THAN ${objlistcmake})
|
||||
#---------------------------------
|
||||
FILE(WRITE ${objlistcmake}
|
||||
"# Extract object files from the library
|
||||
message(STATUS \"Extracting object files from ${lib}\")
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_AR} -x ${lib}
|
||||
WORKING_DIRECTORY ${objdir})
|
||||
# save the list of object files
|
||||
EXECUTE_PROCESS(COMMAND ls .
|
||||
OUTPUT_FILE ${objlistfile}
|
||||
WORKING_DIRECTORY ${objdir})")
|
||||
#---------------------------------
|
||||
file(MAKE_DIRECTORY ${objdir})
|
||||
add_custom_command(
|
||||
OUTPUT ${objlistfile}
|
||||
COMMAND ${CMAKE_COMMAND} -P ${objlistcmake}
|
||||
DEPENDS ${lib})
|
||||
endif()
|
||||
list(APPEND extrafiles "${objlistfile}")
|
||||
# relative path is needed by ar under MSYS
|
||||
file(RELATIVE_PATH objlistfilerpath ${objdir} ${objlistfile})
|
||||
add_custom_command(TARGET ${outlib} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_AR} ru ${outfile} @${objlistfilerpath}"
|
||||
COMMAND ${CMAKE_AR} ru "${outfile}" @"${objlistfilerpath}"
|
||||
WORKING_DIRECTORY ${objdir})
|
||||
endforeach()
|
||||
add_custom_command(TARGET ${outlib} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_RANLIB} ${outfile}"
|
||||
COMMAND ${CMAKE_RANLIB} ${outfile})
|
||||
endif()
|
||||
file(WRITE ${dummyfile}.base "const char* ${outlib}_sublibs=\"${libs}\";")
|
||||
add_custom_command(
|
||||
OUTPUT ${dummyfile}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${dummyfile}.base ${dummyfile}
|
||||
DEPENDS ${libs} ${extrafiles})
|
||||
|
||||
endfunction()
|
||||
16
cmake/today.cmake
Normal file
16
cmake/today.cmake
Normal file
@@ -0,0 +1,16 @@
|
||||
# This script returns the current date in ISO format
|
||||
#
|
||||
# YYYY-MM-DD
|
||||
#
|
||||
MACRO (TODAY RESULT)
|
||||
IF (WIN32)
|
||||
EXECUTE_PROCESS(COMMAND "cmd" " /C date +%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSEIF(UNIX)
|
||||
EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSE (WIN32)
|
||||
MESSAGE(SEND_ERROR "date not implemented")
|
||||
SET(${RESULT} 000000)
|
||||
ENDIF (WIN32)
|
||||
ENDMACRO (TODAY)
|
||||
@@ -30,6 +30,7 @@
|
||||
#cmakedefine HAVE_SYS_SELECT_H
|
||||
#cmakedefine HAVE_SYS_STRTIO_H
|
||||
#cmakedefine HAVE_EVENTFD_H
|
||||
#cmakedefine HAVE_TIMERFD_H
|
||||
#cmakedefine HAVE_TM_GMTOFF
|
||||
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ void test_message(void)
|
||||
message = rfx_process_message(context, s->pointer, s->capacity);
|
||||
if (i == 0)
|
||||
{
|
||||
for (j = 0; j < message->num_tiles; j++)
|
||||
for (j = 0; j < message->numTiles; j++)
|
||||
{
|
||||
dump_ppm_image(message->tiles[j]->data);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ However, any other static build should work as well.
|
||||
|
||||
To build openssl:
|
||||
|
||||
git clone git@github.com:bmiklautz/Android-external-openssl-ndk-static.git
|
||||
cd Android-external-openssl-ndk-static
|
||||
git clone git@github.com:bmiklautz/android-external-openssl-ndk-static.git
|
||||
cd android-external-openssl-ndk-static
|
||||
ndk-build # found in the Android NDK
|
||||
|
||||
|
||||
|
||||
3
docs/README.directfb
Normal file
3
docs/README.directfb
Normal file
@@ -0,0 +1,3 @@
|
||||
The dfreerdp FreeRDP client is currently orphaned and unmaintained so please don't expect it to build and work without problems.
|
||||
|
||||
If you are interested to update and maintain the dfreerdp client please let us know.
|
||||
@@ -138,17 +138,7 @@ enum FILE_CREATE_OPTION
|
||||
#define FILE_WRITE_ATTRIBUTES 0x00000100
|
||||
#endif
|
||||
|
||||
#define DELETE 0x00010000
|
||||
#define READ_CONTROL 0x00020000
|
||||
#define WRITE_DAC 0x00040000
|
||||
#define WRITE_OWNER 0x00080000
|
||||
#define SYNCHRONIZE 0x00100000
|
||||
#define ACCESS_SYSTEM_SECURITY 0x01000000
|
||||
#define MAXIMUM_ALLOWED 0x02000000
|
||||
#define GENERIC_ALL 0x10000000
|
||||
#define GENERIC_EXECUTE 0x20000000
|
||||
#define GENERIC_WRITE 0x40000000
|
||||
#define GENERIC_READ 0x80000000
|
||||
#include <winpr/io.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -84,8 +84,9 @@ FREERDP_API freerdp* freerdp_client_get_instance(rdpContext* context);
|
||||
FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context);
|
||||
|
||||
FREERDP_API int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv);
|
||||
FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, char* filename);
|
||||
FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, const char* filename);
|
||||
FREERDP_API int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size);
|
||||
FREERDP_API int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
64
include/freerdp/client/disp.h
Normal file
64
include/freerdp/client/disp.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_CLIENT_DISP_H
|
||||
#define FREERDP_CHANNEL_CLIENT_DISP_H
|
||||
|
||||
#define ORIENTATION_LANDSCAPE 0
|
||||
#define ORIENTATION_PORTRAIT 90
|
||||
#define ORIENTATION_LANDSCAPE_FLIPPED 180
|
||||
#define ORIENTATION_PORTRAIT_FLIPPED 270
|
||||
|
||||
#define DISPLAY_CONTROL_MONITOR_PRIMARY 0x00000001
|
||||
|
||||
struct _DISPLAY_CONTROL_MONITOR_LAYOUT
|
||||
{
|
||||
UINT32 Flags;
|
||||
INT32 Left;
|
||||
INT32 Top;
|
||||
UINT32 Width;
|
||||
UINT32 Height;
|
||||
UINT32 PhysicalWidth;
|
||||
UINT32 PhysicalHeight;
|
||||
UINT32 Orientation;
|
||||
UINT32 DesktopScaleFactor;
|
||||
UINT32 DeviceScaleFactor;
|
||||
};
|
||||
typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT;
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
|
||||
#define DISP_DVC_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl"
|
||||
|
||||
typedef struct _disp_client_context DispClientContext;
|
||||
|
||||
typedef int (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors);
|
||||
|
||||
struct _disp_client_context
|
||||
{
|
||||
void* handle;
|
||||
void* custom;
|
||||
|
||||
pcDispSendMonitorLayout SendMonitorLayout;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIENT_DISP_H */
|
||||
|
||||
@@ -137,12 +137,12 @@ typedef struct rdp_file rdpFile;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name);
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name);
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size);
|
||||
FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings);
|
||||
|
||||
FREERDP_API BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings);
|
||||
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode);
|
||||
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode);
|
||||
FREERDP_API size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size);
|
||||
|
||||
FREERDP_API rdpFile* freerdp_client_rdp_file_new(void);
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
FREERDP_API BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp);
|
||||
|
||||
FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height,
|
||||
wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e);
|
||||
|
||||
#endif /* FREERDP_CODEC_BITMAP_H */
|
||||
|
||||
@@ -42,9 +42,25 @@ struct _NSC_STREAM
|
||||
};
|
||||
typedef struct _NSC_STREAM NSC_STREAM;
|
||||
|
||||
struct _NSC_MESSAGE
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
UINT32 width;
|
||||
UINT32 height;
|
||||
BYTE* data;
|
||||
int scanline;
|
||||
UINT32 MaxPlaneSize;
|
||||
BYTE* PlaneBuffers[5];
|
||||
UINT32 OrgByteCount[4];
|
||||
UINT32 PlaneByteCount[4];
|
||||
};
|
||||
typedef struct _NSC_MESSAGE NSC_MESSAGE;
|
||||
|
||||
typedef struct _NSC_CONTEXT_PRIV NSC_CONTEXT_PRIV;
|
||||
|
||||
typedef struct _NSC_CONTEXT NSC_CONTEXT;
|
||||
|
||||
struct _NSC_CONTEXT
|
||||
{
|
||||
UINT32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */
|
||||
@@ -52,15 +68,15 @@ struct _NSC_CONTEXT
|
||||
UINT16 bpp;
|
||||
UINT16 width;
|
||||
UINT16 height;
|
||||
BYTE* bmpdata; /* final argb values in little endian order */
|
||||
UINT32 bmpdata_length; /* the maximum length of the buffer that bmpdata points to */
|
||||
BYTE* BitmapData; /* final argb values in little endian order */
|
||||
UINT32 BitmapDataLength; /* the maximum length of the buffer that bmpdata points to */
|
||||
RDP_PIXEL_FORMAT pixel_format;
|
||||
|
||||
/* color palette allocated by the application */
|
||||
const BYTE* palette;
|
||||
|
||||
void (*decode)(NSC_CONTEXT* context);
|
||||
void (*encode)(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride);
|
||||
void (*encode)(NSC_CONTEXT* context, BYTE* BitmapData, int rowstride);
|
||||
|
||||
NSC_CONTEXT_PRIV* priv;
|
||||
};
|
||||
@@ -73,6 +89,11 @@ FREERDP_API void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
|
||||
BYTE* bmpdata, int width, int height, int rowstride);
|
||||
FREERDP_API void nsc_context_free(NSC_CONTEXT* context);
|
||||
|
||||
FREERDP_API NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
|
||||
int width, int height, int scanline, int* numMessages, int maxDataSize);
|
||||
FREERDP_API int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message);
|
||||
FREERDP_API int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/constants.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
@@ -50,18 +51,36 @@ struct _RFX_TILE
|
||||
{
|
||||
UINT16 x;
|
||||
UINT16 y;
|
||||
int width;
|
||||
int height;
|
||||
BYTE* data;
|
||||
int scanline;
|
||||
|
||||
BYTE quantIdxY;
|
||||
BYTE quantIdxCb;
|
||||
BYTE quantIdxCr;
|
||||
UINT16 xIdx;
|
||||
UINT16 yIdx;
|
||||
UINT16 YLen;
|
||||
UINT16 CbLen;
|
||||
UINT16 CrLen;
|
||||
BYTE* YData;
|
||||
BYTE* CbData;
|
||||
BYTE* CrData;
|
||||
};
|
||||
typedef struct _RFX_TILE RFX_TILE;
|
||||
|
||||
struct _RFX_MESSAGE
|
||||
{
|
||||
UINT32 frameIdx;
|
||||
|
||||
/**
|
||||
* The rects array represents the updated region of the frame. The UI
|
||||
* requires to clip drawing destination base on the union of the rects.
|
||||
*/
|
||||
UINT16 num_rects;
|
||||
UINT16 numRects;
|
||||
RFX_RECT* rects;
|
||||
BOOL freeRects;
|
||||
|
||||
/**
|
||||
* The tiles array represents the actual frame data. Each tile is always
|
||||
@@ -69,15 +88,35 @@ struct _RFX_MESSAGE
|
||||
* rects described above) are valid. Pixels outside of the region may
|
||||
* contain arbitrary data.
|
||||
*/
|
||||
UINT16 num_tiles;
|
||||
UINT16 numTiles;
|
||||
RFX_TILE** tiles;
|
||||
|
||||
UINT16 numQuant;
|
||||
UINT32* quantVals;
|
||||
|
||||
UINT32 tilesDataSize;
|
||||
|
||||
BOOL freeArray;
|
||||
};
|
||||
typedef struct _RFX_MESSAGE RFX_MESSAGE;
|
||||
|
||||
typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV;
|
||||
|
||||
enum _RFX_STATE
|
||||
{
|
||||
RFX_STATE_INITIAL,
|
||||
RFX_STATE_SERVER_UNINITIALIZED,
|
||||
RFX_STATE_SEND_HEADERS,
|
||||
RFX_STATE_SEND_FRAME_DATA,
|
||||
RFX_STATE_FRAME_DATA_SENT,
|
||||
RFX_STATE_FINAL
|
||||
};
|
||||
typedef enum _RFX_STATE RFX_STATE;
|
||||
|
||||
struct _RFX_CONTEXT
|
||||
{
|
||||
RFX_STATE state;
|
||||
|
||||
UINT16 flags;
|
||||
UINT16 properties;
|
||||
UINT16 width;
|
||||
@@ -93,19 +132,20 @@ struct _RFX_CONTEXT
|
||||
const BYTE* palette;
|
||||
|
||||
/* temporary data within a frame */
|
||||
UINT32 frame_idx;
|
||||
BOOL header_processed;
|
||||
BYTE num_quants;
|
||||
UINT32 frameIdx;
|
||||
BYTE numQuant;
|
||||
UINT32* quants;
|
||||
BYTE quant_idx_y;
|
||||
BYTE quant_idx_cb;
|
||||
BYTE quant_idx_cr;
|
||||
BYTE quantIdxY;
|
||||
BYTE quantIdxCb;
|
||||
BYTE quantIdxCr;
|
||||
|
||||
/* routines */
|
||||
void (*quantization_decode)(INT16* buffer, const UINT32* quantization_values);
|
||||
void (*quantization_encode)(INT16* buffer, const UINT32* quantization_values);
|
||||
void (*dwt_2d_decode)(INT16* buffer, INT16* dwt_buffer);
|
||||
void (*dwt_2d_encode)(INT16* buffer, INT16* dwt_buffer);
|
||||
int (*rlgr_decode)(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
|
||||
int (*rlgr_encode)(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
|
||||
|
||||
/* private definitions */
|
||||
RFX_CONTEXT_PRIV* priv;
|
||||
@@ -128,6 +168,12 @@ FREERDP_API void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s);
|
||||
FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s,
|
||||
const RFX_RECT* rects, int num_rects, BYTE* image_data, int width, int height, int rowstride);
|
||||
|
||||
FREERDP_API RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
|
||||
int numRects, BYTE* data, int width, int height, int scanline);
|
||||
FREERDP_API RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
|
||||
BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize);
|
||||
FREERDP_API void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,7 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
|
||||
FREERDP_API int tls_wait_read(rdpTls* tls);
|
||||
FREERDP_API int tls_wait_write(rdpTls* tls);
|
||||
|
||||
FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname);
|
||||
FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
||||
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file);
|
||||
FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);
|
||||
|
||||
9
include/freerdp/error.h
Normal file → Executable file
9
include/freerdp/error.h
Normal file → Executable file
@@ -20,6 +20,10 @@
|
||||
#ifndef FREERDP_ERROR_H
|
||||
#define FREERDP_ERROR_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -128,6 +132,9 @@ extern "C" {
|
||||
#define ERRINFO_SUCCESS 0x00000000
|
||||
#define ERRINFO_NONE 0xFFFFFFFF
|
||||
|
||||
FREERDP_API const char* freerdp_get_error_info_string(UINT32 code);
|
||||
FREERDP_API const char* freerdp_get_error_info_name(UINT32 code);
|
||||
|
||||
/**
|
||||
* This static variable holds an error code if the return value from connect is FALSE.
|
||||
* This variable is always set to 0 in the beginning of the connect sequence.
|
||||
@@ -135,7 +142,7 @@ extern "C" {
|
||||
* The value can hold one of the defined error codes below OR an error according to errno
|
||||
*/
|
||||
|
||||
extern int connectErrorCode;
|
||||
FREERDP_API extern int connectErrorCode;
|
||||
|
||||
#define ERRORSTART 10000
|
||||
#define PREECONNECTERROR ERRORSTART + 1
|
||||
|
||||
@@ -41,6 +41,20 @@ DEFINE_EVENT_BEGIN(ResizeWindow)
|
||||
int width;
|
||||
int height;
|
||||
DEFINE_EVENT_END(ResizeWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(PanningChange)
|
||||
int XPan;
|
||||
int YPan;
|
||||
DEFINE_EVENT_END(PanningChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
||||
double ScalingFactor;
|
||||
DEFINE_EVENT_END(ScalingFactorChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
||||
int width;
|
||||
int height;
|
||||
DEFINE_EVENT_END(LocalResizeWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(EmbedWindow)
|
||||
BOOL embed;
|
||||
@@ -59,6 +73,20 @@ DEFINE_EVENT_BEGIN(Terminate)
|
||||
int code;
|
||||
DEFINE_EVENT_END(Terminate)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ConnectionResult)
|
||||
int result;
|
||||
DEFINE_EVENT_END(ConnectionResult)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ChannelConnected)
|
||||
const char* name;
|
||||
void* pInterface;
|
||||
DEFINE_EVENT_END(ChannelConnected)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ChannelDisconnected)
|
||||
const char* name;
|
||||
void* pInterface;
|
||||
DEFINE_EVENT_END(ChannelDisconnected)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -66,9 +66,6 @@ typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
||||
typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size);
|
||||
typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size);
|
||||
|
||||
typedef int (*pOnChannelConnected)(freerdp* instance, const char* name, void* pInterface);
|
||||
typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
/**
|
||||
* Defines the context for a given instance of RDP connection.
|
||||
* It is embedded in the rdp_freerdp structure, and allocated by a call to freerdp_context_new().
|
||||
@@ -208,9 +205,6 @@ struct rdp_freerdp
|
||||
This is called by freerdp_channel_process() (if not NULL).
|
||||
Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */
|
||||
|
||||
ALIGN64 pOnChannelConnected OnChannelConnected;
|
||||
ALIGN64 pOnChannelDisconnected OnChannelDisconnected;
|
||||
|
||||
UINT64 paddingE[80 - 66]; /* 66 */
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ extern "C" {
|
||||
typedef BOOL (*psListenerOpen)(freerdp_listener* instance, const char* bind_address, UINT16 port);
|
||||
typedef BOOL (*psListenerOpenLocal)(freerdp_listener* instance, const char* path);
|
||||
typedef BOOL (*psListenerGetFileDescriptor)(freerdp_listener* instance, void** rfds, int* rcount);
|
||||
typedef int (*psListenerGetEventHandles)(freerdp_listener* instance, HANDLE* events, DWORD* nCount);
|
||||
typedef BOOL (*psListenerCheckFileDescriptor)(freerdp_listener* instance);
|
||||
typedef void (*psListenerClose)(freerdp_listener* instance);
|
||||
typedef void (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client);
|
||||
@@ -50,6 +51,7 @@ struct rdp_freerdp_listener
|
||||
psListenerOpen Open;
|
||||
psListenerOpenLocal OpenLocal;
|
||||
psListenerGetFileDescriptor GetFileDescriptor;
|
||||
psListenerGetEventHandles GetEventHandles;
|
||||
psListenerCheckFileDescriptor CheckFileDescriptor;
|
||||
psListenerClose Close;
|
||||
|
||||
|
||||
@@ -205,6 +205,7 @@ extern "C" {
|
||||
|
||||
FREERDP_API DWORD freerdp_keyboard_init(DWORD keyboardLayoutId);
|
||||
FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types);
|
||||
FREERDP_API void freerdp_keyboard_layouts_free(RDP_KEYBOARD_LAYOUT* layouts);
|
||||
FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(DWORD keyboardLayoutId);
|
||||
FREERDP_API DWORD freerdp_keyboard_get_layout_id_from_name(const char* name);
|
||||
FREERDP_API DWORD freerdp_keyboard_get_rdp_scancode_from_x11_keycode(DWORD keycode);
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context);
|
||||
|
||||
typedef BOOL (*psPeerInitialize)(freerdp_peer* client);
|
||||
typedef BOOL (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount);
|
||||
typedef HANDLE (*psPeerGetEventHandle)(freerdp_peer* client);
|
||||
typedef BOOL (*psPeerCheckFileDescriptor)(freerdp_peer* client);
|
||||
typedef BOOL (*psPeerClose)(freerdp_peer* client);
|
||||
typedef void (*psPeerDisconnect)(freerdp_peer* client);
|
||||
@@ -60,6 +61,7 @@ struct rdp_freerdp_peer
|
||||
|
||||
psPeerInitialize Initialize;
|
||||
psPeerGetFileDescriptor GetFileDescriptor;
|
||||
psPeerGetEventHandle GetEventHandle;
|
||||
psPeerCheckFileDescriptor CheckFileDescriptor;
|
||||
psPeerClose Close;
|
||||
psPeerDisconnect Disconnect;
|
||||
|
||||
@@ -609,6 +609,9 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_WmClass 1549
|
||||
#define FreeRDP_EmbeddedWindow 1550
|
||||
#define FreeRDP_SmartSizing 1551
|
||||
#define FreeRDP_XPan 1552
|
||||
#define FreeRDP_YPan 1553
|
||||
#define FreeRDP_ScalingFactor 1554
|
||||
#define FreeRDP_SoftwareGdi 1601
|
||||
#define FreeRDP_LocalConnection 1602
|
||||
#define FreeRDP_AuthenticationOnly 1603
|
||||
@@ -630,6 +633,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_GatewayDomain 1989
|
||||
#define FreeRDP_GatewayCredentialsSource 1990
|
||||
#define FreeRDP_GatewayUseSameCredentials 1991
|
||||
#define FreeRDP_GatewayEnabled 1992
|
||||
#define FreeRDP_RemoteApplicationMode 2112
|
||||
#define FreeRDP_RemoteApplicationName 2113
|
||||
#define FreeRDP_RemoteApplicationIcon 2114
|
||||
@@ -677,6 +681,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_UnicodeInput 2629
|
||||
#define FreeRDP_FastPathInput 2630
|
||||
#define FreeRDP_MultiTouchInput 2631
|
||||
#define FreeRDP_MultiTouchGestures 2632
|
||||
#define FreeRDP_BrushSupportLevel 2688
|
||||
#define FreeRDP_GlyphSupportLevel 2752
|
||||
#define FreeRDP_GlyphCache 2753
|
||||
@@ -976,7 +981,10 @@ struct rdp_settings
|
||||
ALIGN64 char* WmClass; /* 1549 */
|
||||
ALIGN64 BOOL EmbeddedWindow; /* 1550 */
|
||||
ALIGN64 BOOL SmartSizing; /* 1551 */
|
||||
UINT64 padding1600[1600 - 1552]; /* 1552 */
|
||||
ALIGN64 int XPan; /* 1552 */
|
||||
ALIGN64 int YPan; /* 1553 */
|
||||
ALIGN64 double ScalingFactor; /* 1554 */
|
||||
UINT64 padding1600[1600 - 1555]; /* 1555 */
|
||||
|
||||
/* Miscellaneous */
|
||||
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
||||
@@ -1012,7 +1020,7 @@ struct rdp_settings
|
||||
*/
|
||||
|
||||
/* Gateway */
|
||||
ALIGN64 BOOL GatewayUsageMethod; /* 1984 */
|
||||
ALIGN64 UINT32 GatewayUsageMethod; /* 1984 */
|
||||
ALIGN64 UINT32 GatewayPort; /* 1985 */
|
||||
ALIGN64 char* GatewayHostname; /* 1986 */
|
||||
ALIGN64 char* GatewayUsername; /* 1987 */
|
||||
@@ -1020,7 +1028,8 @@ struct rdp_settings
|
||||
ALIGN64 char* GatewayDomain; /* 1989 */
|
||||
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
||||
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
||||
UINT64 padding2048[2048 - 1992]; /* 1992 */
|
||||
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
||||
UINT64 padding2048[2048 - 1993]; /* 1993 */
|
||||
UINT64 padding2112[2112 - 2048]; /* 2048 */
|
||||
|
||||
/**
|
||||
@@ -1101,7 +1110,8 @@ struct rdp_settings
|
||||
ALIGN64 BOOL UnicodeInput; /* 2629 */
|
||||
ALIGN64 BOOL FastPathInput; /* 2630 */
|
||||
ALIGN64 BOOL MultiTouchInput; /* 2631 */
|
||||
UINT64 padding2688[2688 - 2632]; /* 2632 */
|
||||
ALIGN64 BOOL MultiTouchGestures; /* 2632 */
|
||||
UINT64 padding2688[2688 - 2633]; /* 2633 */
|
||||
|
||||
/* Brush Capabilities */
|
||||
ALIGN64 UINT32 BrushSupportLevel; /* 2688 */
|
||||
@@ -1310,6 +1320,9 @@ FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings);
|
||||
FREERDP_API BOOL freerdp_get_param_bool(rdpSettings* settings, int id);
|
||||
FREERDP_API int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param);
|
||||
|
||||
FREERDP_API int freerdp_get_param_int(rdpSettings* settings, int id);
|
||||
FREERDP_API int freerdp_set_param_int(rdpSettings* settings, int id, int param);
|
||||
|
||||
FREERDP_API UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id);
|
||||
FREERDP_API int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param);
|
||||
|
||||
@@ -1319,6 +1332,9 @@ FREERDP_API int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 p
|
||||
FREERDP_API char* freerdp_get_param_string(rdpSettings* settings, int id);
|
||||
FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, char* param);
|
||||
|
||||
FREERDP_API double freerdp_get_param_double(rdpSettings* settings, int id);
|
||||
FREERDP_API int freerdp_set_param_double(rdpSettings* settings, int id, double param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -134,6 +134,14 @@ enum SURFCMD_FRAMEACTION
|
||||
SURFACECMD_FRAMEACTION_END = 0x0001
|
||||
};
|
||||
|
||||
struct _SURFACE_FRAME
|
||||
{
|
||||
UINT32 frameId;
|
||||
UINT32 commandCount;
|
||||
SURFACE_BITS_COMMAND* commands;
|
||||
};
|
||||
typedef struct _SURFACE_FRAME SURFACE_FRAME;
|
||||
|
||||
/* defined inside libfreerdp-core */
|
||||
typedef struct rdp_update_proxy rdpUpdateProxy;
|
||||
|
||||
|
||||
@@ -20,17 +20,15 @@
|
||||
#ifndef FREERDP_UTILS_STOPWATCH_H
|
||||
#define FREERDP_UTILS_STOPWATCH_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
struct _STOPWATCH
|
||||
{
|
||||
clock_t start;
|
||||
clock_t end;
|
||||
double elapsed;
|
||||
clock_t count;
|
||||
UINT64 start;
|
||||
UINT64 end;
|
||||
UINT64 elapsed;
|
||||
UINT32 count;
|
||||
};
|
||||
typedef struct _STOPWATCH STOPWATCH;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user