Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Mike McDonald
2013-08-27 15:21:24 -04:00
219 changed files with 11078 additions and 3017 deletions

3
.gitignore vendored
View File

@@ -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

View File

@@ -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()

View File

@@ -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>

View File

@@ -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;

View File

@@ -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}

View File

@@ -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;
}

View File

@@ -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)

View 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()

View 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})

View 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")

View 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;
}

View 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 */

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -35,7 +35,8 @@
/* Protocol Version */
#define RDPINPUT_PROTOCOL_V1 0x00010000
#define RDPINPUT_PROTOCOL_V10 0x00010000
#define RDPINPUT_PROTOCOL_V101 0x00010001
/* Client Ready Flags */

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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}

View File

@@ -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}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -57,4 +57,4 @@ endif()
if (WITH_DOTNET)
add_subdirectory(DotNetClient)
endif()
endif()

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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];
}
}

View File

@@ -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()

View File

@@ -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">

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()

View File

@@ -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
View File

@@ -0,0 +1,2 @@
*.xml
generate_argument_docbook

View File

@@ -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})

View 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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -44,6 +44,7 @@ extern "C" {
* Client Interface
*/
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
#ifdef __cplusplus

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -44,6 +44,7 @@
#ifdef WITH_XI
#include <X11/extensions/XInput2.h>
#include "xf_input.h"
#endif
#include "xf_input.h"

View File

View 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:&lt;device&gt;</command></term>
<listitem>
<para>Activate smartcard redirection for device <replaceable>device</replaceable></para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>/printer:&lt;device&gt;,&lt;driver&gt;</command></term>
<listitem>
<para>Activate printer redirection for printer <replaceable>device</replaceable> using driver <replaceable>driver</replaceable></para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>/serial:&lt;device&gt;</command></term>
<listitem>
<para>Activate serial port redirection for port <replaceable>device</replaceable></para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>/parallel:&lt;device&gt;</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>

View File

@@ -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>

View 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>

View File

@@ -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);

View File

@@ -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")

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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")
{

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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
View 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
View 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 )

View 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
View 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
View 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
View 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
View 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)

View File

@@ -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.

View File

@@ -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)

View 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)

View File

@@ -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
View 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
View 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)

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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
View 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.

View File

@@ -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

View File

@@ -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
}

View 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 */

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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 */
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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