Merge pull request #1443 from bmiklautz/stable-1.1-sync
Backported commits from master
This commit is contained in:
commit
fe40452d65
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,6 +37,9 @@ external/*
|
||||
# Documentation
|
||||
docs/api
|
||||
client/X11/xfreerdp.1
|
||||
client/X11/xfreerdp.1.xml
|
||||
client/X11/xfreerdp-channels.1.xml
|
||||
client/X11/xfreerdp-examples.1.xml
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
@ -313,6 +313,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")
|
||||
@ -372,6 +376,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
|
||||
@ -400,12 +406,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)
|
||||
@ -430,8 +436,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)
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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)
|
||||
|
@ -286,6 +286,7 @@ static void parallel_free(DEVICE* device)
|
||||
MessageQueue_PostQuit(parallel->queue, 0);
|
||||
WaitForSingleObject(parallel->thread, INFINITE);
|
||||
|
||||
Stream_Free(parallel->device.data, TRUE);
|
||||
MessageQueue_Free(parallel->queue);
|
||||
CloseHandle(parallel->thread);
|
||||
|
||||
|
@ -179,13 +179,16 @@ static void* printer_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg;
|
||||
HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(printer_dev->event, INFINITE);
|
||||
DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(printer_dev->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (rc == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
else if( rc != WAIT_OBJECT_0 )
|
||||
continue;
|
||||
|
||||
ResetEvent(printer_dev->event);
|
||||
|
||||
|
@ -63,7 +63,9 @@ struct _SERIAL_DEVICE
|
||||
SERIAL_TTY* tty;
|
||||
|
||||
HANDLE thread;
|
||||
HANDLE mthread;
|
||||
HANDLE stopEvent;
|
||||
HANDLE newEvent;
|
||||
|
||||
wQueue* queue;
|
||||
LIST* pending_irps;
|
||||
@ -80,6 +82,7 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
|
||||
static void serial_check_for_events(SERIAL_DEVICE* serial);
|
||||
static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp);
|
||||
static BOOL serial_check_fds(SERIAL_DEVICE* serial);
|
||||
static void* serial_thread_mfunc(void* arg);
|
||||
|
||||
static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
|
||||
{
|
||||
@ -113,6 +116,18 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
|
||||
else
|
||||
{
|
||||
serial->tty = tty;
|
||||
|
||||
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_NONE,
|
||||
STATUS_CANCELLED);
|
||||
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_READ,
|
||||
STATUS_CANCELLED);
|
||||
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_WRITE,
|
||||
STATUS_CANCELLED);
|
||||
|
||||
serial->mthread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) serial_thread_mfunc, (void*) serial,
|
||||
0, NULL);
|
||||
|
||||
DEBUG_SVC("%s(%d) created.", serial->path, FileId);
|
||||
}
|
||||
|
||||
@ -139,6 +154,11 @@ static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp)
|
||||
{
|
||||
DEBUG_SVC("%s(%d) closed.", serial->path, tty->id);
|
||||
|
||||
TerminateThread(serial->mthread, 0);
|
||||
WaitForSingleObject(serial->mthread, INFINITE);
|
||||
CloseHandle(serial->mthread);
|
||||
serial->mthread = NULL;
|
||||
|
||||
serial_tty_free(tty);
|
||||
serial->tty = NULL;
|
||||
}
|
||||
@ -318,37 +338,67 @@ static void serial_process_irp(SERIAL_DEVICE* serial, IRP* irp)
|
||||
serial_check_for_events(serial);
|
||||
}
|
||||
|
||||
/* This thread is used as a workaround for the missing serial event
|
||||
* support in WaitForMultipleObjects.
|
||||
* It monitors the terminal for events and posts it in a supported
|
||||
* form that WaitForMultipleObjects can use it. */
|
||||
void* serial_thread_mfunc(void* arg)
|
||||
{
|
||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int sl;
|
||||
fd_set rd;
|
||||
|
||||
if(!serial->tty || serial->tty->fd <= 0)
|
||||
{
|
||||
DEBUG_WARN("Monitor thread still running, but no terminal opened!");
|
||||
sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_ZERO(&rd);
|
||||
FD_SET(serial->tty->fd, &rd);
|
||||
sl = select(serial->tty->fd + 1, &rd, NULL, NULL, NULL);
|
||||
if( sl > 0 )
|
||||
SetEvent(serial->newEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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), serial->newEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
status = WaitForMultipleObjects(3, ev, FALSE, INFINITE);
|
||||
|
||||
if (WAIT_OBJECT_0 == status)
|
||||
break;
|
||||
|
||||
status = WaitForSingleObject(Queue_Event(serial->queue), 10);
|
||||
|
||||
if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT))
|
||||
break;
|
||||
|
||||
serial->nfds = 1;
|
||||
FD_ZERO(&serial->read_fds);
|
||||
FD_ZERO(&serial->write_fds);
|
||||
|
||||
serial->tv.tv_sec = 1;
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
if (status == WAIT_OBJECT_0)
|
||||
else if (status == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
FD_ZERO(&serial->read_fds);
|
||||
FD_ZERO(&serial->write_fds);
|
||||
|
||||
serial->tv.tv_sec = 0;
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
|
||||
serial_process_irp(serial, irp);
|
||||
}
|
||||
else if (status == WAIT_OBJECT_0 + 2)
|
||||
ResetEvent(serial->newEvent);
|
||||
|
||||
serial_check_fds(serial);
|
||||
if(serial->tty)
|
||||
serial_check_fds(serial);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -367,10 +417,25 @@ static void serial_free(DEVICE* device)
|
||||
|
||||
DEBUG_SVC("freeing device");
|
||||
|
||||
/* Stop thread */
|
||||
SetEvent(serial->stopEvent);
|
||||
if(serial->mthread)
|
||||
{
|
||||
TerminateThread(serial->mthread, 0);
|
||||
WaitForSingleObject(serial->mthread, INFINITE);
|
||||
CloseHandle(serial->mthread);
|
||||
}
|
||||
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->newEvent);
|
||||
CloseHandle(serial->thread);
|
||||
free(serial);
|
||||
}
|
||||
|
||||
@ -383,6 +448,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)
|
||||
{
|
||||
@ -433,6 +503,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));
|
||||
|
||||
@ -478,6 +553,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;
|
||||
@ -492,6 +572,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)
|
||||
{
|
||||
@ -542,6 +627,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);
|
||||
@ -604,6 +694,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)
|
||||
@ -636,6 +731,13 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial)
|
||||
if (list_size(serial->pending_irps) == 0)
|
||||
return 1;
|
||||
|
||||
FD_ZERO(&serial->read_fds);
|
||||
FD_ZERO(&serial->write_fds);
|
||||
|
||||
serial->tv.tv_sec = 0;
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
serial_set_fds(serial);
|
||||
DEBUG_SVC("waiting %lu %lu", serial->tv.tv_sec, serial->tv.tv_usec);
|
||||
|
||||
@ -702,10 +804,13 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
serial->pending_irps = list_new();
|
||||
|
||||
serial->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
serial->newEvent = 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);
|
||||
serial->mthread = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -412,7 +412,11 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
|
||||
status = read(tty->fd, buffer, *Length);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
DEBUG_WARN("failed with %zd, errno=[%d] %s\n",
|
||||
status, errno, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tty->event_txempty = status;
|
||||
*Length = status;
|
||||
@ -456,6 +460,9 @@ void serial_tty_free(SERIAL_TTY* tty)
|
||||
{
|
||||
DEBUG_SVC("in");
|
||||
|
||||
if(!tty)
|
||||
return;
|
||||
|
||||
if (tty->fd >= 0)
|
||||
{
|
||||
if (tty->pold_termios)
|
||||
|
@ -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 = WaitForMultipleObjects(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);
|
||||
|
@ -31,6 +31,10 @@ set(${MODULE_PREFIX}_SRCS
|
||||
|
||||
include_directories(..)
|
||||
|
||||
find_package(UDev REQUIRED)
|
||||
find_package(UUID REQUIRED)
|
||||
find_package(DbusGlib REQUIRED)
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
@ -38,9 +42,9 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
#set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS
|
||||
dbus-glib-1
|
||||
udev
|
||||
uuid)
|
||||
${DBUS_GLIB_LIBRARIES}
|
||||
${UDEV_LIBRARIES}
|
||||
${UUID_LIBRARIES})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
@ -27,6 +27,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
|
||||
include_directories(..)
|
||||
|
||||
find_package(libusb-1.0 REQUIRED)
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
@ -35,9 +37,10 @@ set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
dbus-glib-1
|
||||
usb-1.0
|
||||
udev)
|
||||
${DBUS_GLIB_LIBRARIES}
|
||||
${UUID_LIBRARIES}
|
||||
${LIBUSB_1_LIBRARIES}
|
||||
)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
2
client/X11/.gitignore
vendored
Normal file
2
client/X11/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.xml
|
||||
generate_argument_docbook
|
@ -18,7 +18,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
|
||||
@ -65,18 +65,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")
|
||||
|
177
client/X11/generate_argument_docbook.c
Normal file
177
client/X11/generate_argument_docbook.c
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
/* We need to include the command line c file to get access to
|
||||
* the argument struct. */
|
||||
#include "../common/cmdline.c"
|
||||
|
||||
LPSTR tmp = NULL;
|
||||
|
||||
LPCSTR tr_esc_str(LPCSTR arg)
|
||||
{
|
||||
size_t cs = 0, x, ds;
|
||||
size_t s;
|
||||
|
||||
if( NULL == arg )
|
||||
return NULL;
|
||||
|
||||
s = strlen(arg);
|
||||
|
||||
/* Find trailing whitespaces */
|
||||
while( (s > 0) && isspace(arg[s-1]))
|
||||
s--;
|
||||
|
||||
/* Prepare a initial buffer with the size of the result string. */
|
||||
tmp = malloc(s * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not allocate string buffer.");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
/* Copy character for character and check, if it is necessary to escape. */
|
||||
ds = s + 1;
|
||||
for(x=0; x<s; x++)
|
||||
{
|
||||
switch(arg[x])
|
||||
{
|
||||
case '<':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-3);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'l';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '>':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-4);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'g';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '\'':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-5);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 's';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '"':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-6);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'q';
|
||||
tmp[cs++] = 'u';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '&':
|
||||
ds += 4;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-7);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'm';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
default:
|
||||
tmp[cs++] = arg[x];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assure, the string is '\0' terminated. */
|
||||
tmp[ds-1] = '\0';
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
size_t elements = sizeof(args)/sizeof(args[0]);
|
||||
size_t x;
|
||||
const char *fname = "xfreerdp-argument.1.xml";
|
||||
FILE *fp = NULL;
|
||||
|
||||
/* Open output file for writing, truncate if existing. */
|
||||
fp = fopen(fname, "w");
|
||||
if( NULL == fp )
|
||||
{
|
||||
fprintf(stderr, "Could not open '%s' for writing.", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The tag used as header in the manpage */
|
||||
fprintf(fp, "<refsect1>\n");
|
||||
fprintf(fp, "\t<title>Options</title>\n");
|
||||
fprintf(fp, "\t\t<variablelist>\n");
|
||||
|
||||
/* Iterate over argument struct and write data to docbook 4.5
|
||||
* compatible XML */
|
||||
if( elements < 2 )
|
||||
{
|
||||
fprintf(stderr, "The argument array 'args' is empty, writing an empty file.");
|
||||
elements = 1;
|
||||
}
|
||||
|
||||
for(x=0; x<elements - 1; x++)
|
||||
{
|
||||
const COMMAND_LINE_ARGUMENT_A *arg = &args[x];
|
||||
|
||||
fprintf(fp, "\t\t\t<varlistentry>\n");
|
||||
if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags )
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option> <replaceable>%s</replaceable></term>\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) );
|
||||
else
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option></term>\n", tr_esc_str(arg->Name) );
|
||||
fprintf(fp, "\t\t\t\t<listitem>\n");
|
||||
fprintf(fp, "\t\t\t\t\t<para>%s</para>\n", tr_esc_str(arg->Text));
|
||||
|
||||
fprintf(fp, "\t\t\t\t</listitem>\n");
|
||||
fprintf(fp, "\t\t\t</varlistentry>\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t</variablelist>\n");
|
||||
fprintf(fp, "\t</refsect1>\n");
|
||||
fclose(fp);
|
||||
|
||||
if(NULL != tmp)
|
||||
free(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
0
client/X11/xfreerdp-channels.1.xml
Normal file
0
client/X11/xfreerdp-channels.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp connection.rdp /p:Pwd123! /f</command></term>
|
||||
<listitem>
|
||||
<para>Connect in fullscreen mode using a stored configuration <replaceable>connection.rdp</replaceable> and the password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>rdp.contoso.com</replaceable> with user <replaceable>CONTOSO\\JohnDoe</replaceable> and password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>192.168.1.100</replaceable> on port <replaceable>4489</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable>. The screen width is set to <replaceable>1366</replaceable> and the height to <replaceable>768</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100</command></term>
|
||||
<listitem>
|
||||
<para>Establish a connection to host <replaceable>192.168.1.100</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable> and connect to Hyper-V console (use port 2179, disable negotiation) with VMID <replaceable>C824F53E-95D2-46C6-9A18-23A5BB403532</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>+clipboard</command></term>
|
||||
<listitem>
|
||||
<para>Activate clipboard redirection</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/drive:home,/home/user</command></term>
|
||||
<listitem>
|
||||
<para>Activate drive redirection of <replaceable>/home/user</replaceable> as home drive</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/smartcard:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate smartcard redirection for device <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/printer:<device>,<driver></command></term>
|
||||
<listitem>
|
||||
<para>Activate printer redirection for printer <replaceable>device</replaceable> using driver <replaceable>driver</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/serial:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate serial port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/parallel:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate parallel port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/sound:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio output redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/microphone:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio input redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/multimedia:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate multimedia redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/usb:id,dev:054c:0268</command></term>
|
||||
<listitem>
|
||||
<para>Activate USB device redirection for the device identified by <replaceable>054c:0268</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
@ -1,571 +0,0 @@
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>2011-08-27</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>2011-08-27</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [options] server[:port] [[options] server[:port] …]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>2011-08-27</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-0</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Attach to the admin console of the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-a <replaceable class="parameter">bpp</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the color depth for the connection to <replaceable class="parameter">bpp</replaceable> bits per pixel.
|
||||
Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="WorkingDir">
|
||||
<term>-c <replaceable class="parameter">dir</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the working-dir to <replaceable class="parameter">dir</replaceable>.
|
||||
This parameter is only used when an AlternateShell (<xref linkend="AlternateShell"/>) is requested.
|
||||
<replaceable class="parameter">dir</replaceable> should contain the executable file specified in the AlternateShell.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Removes the windows decorations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Domain used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-f</term>
|
||||
<listitem>
|
||||
<para>
|
||||
start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-T <replaceable class="parameter">text</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the window title to <replaceable class="parameter">text</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-g <replaceable class="parameter">geometry</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the size of the FreeRDP window (and of the remote desktop, when establishing a new connection).
|
||||
<replaceable class="parameter">geometry</replaceable> can have one of the following forms:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> -
|
||||
in this case the resulting window will be of
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> pixels.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">P</replaceable>% -
|
||||
in this case the resulting window will be <replaceable class="parameter">P</replaceable>%
|
||||
of your screen.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The special keyword <emphasis>workarea</emphasis> -
|
||||
in this case the resulting window will be of the same size as your workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print help.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the keyboard-layout-id to <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-K</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not interfere with window manager bindings. Normally, xfreerdp captures all keystrokes while its window is focused.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">hostname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the reported client hostname to <replaceable class="parameter">hostname</replaceable>.
|
||||
Default is to automatically detect the hostname.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-o</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Play audio on the console instead of redirecting to the client.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-p <replaceable class="parameter">password</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Password used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="AlternateShell">
|
||||
<term>-s <replaceable class="parameter">shell</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the startup-shell to <replaceable class="parameter">shell</replaceable>.
|
||||
This parameter should contain a complete path to the alternate shell.
|
||||
If the alternete shell requires a different working directory use <xref linkend="WorkingDir"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-t <replaceable class="parameter">port</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Connect to <replaceable class="parameter">port</replaceable>, instead of the default 3389.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-u <replaceable class="parameter">username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Username used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-x <replaceable class="parameter">flag</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the experience performance flags.
|
||||
<replaceable class="parameter">flag</replaceable> can be one of:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
m - (modem): Equivalent to 15.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
b - (broadband): Equivalent to 1.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
l - (lan): Equivalent to 0.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">num</replaceable> - A hexadecimal number that
|
||||
represents a bit-mask, were numbers mean the following
|
||||
<footnote><para>Taken from <ulink url="http://msdn.microsoft.com/en-us/library/cc240476%28v=prot.10%29.aspx">
|
||||
MS-RDPBCGR Section 2.2.1.11.1.1.1 - Extended Info Packet</ulink></para></footnote>:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>1: Disable desktop wallpaper.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>2: Disable full-window drag (only the window outline is displayed when the window is moved).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>4: Disable menu animations.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>8: Disable user interface themes.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>20: Disable mouse cursor shadows.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>40: Disable cursor blinking.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>80: Enable font smoothing.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>100: Enable Desktop Composition.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-X <replaceable class="parameter">xid</replaceable></term>
|
||||
<listitem>
|
||||
<para>embed xfreerdp into window with <replaceable class="parameter">xid</replaceable>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable compression.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--app</term>
|
||||
<listitem>
|
||||
<para>
|
||||
initialize a RemoteApp connection. This implies -g workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-auth</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--authonly</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Only authenticates. This is useful to test your credentials (username and password).
|
||||
Returns status code 0 if the client can connect, 1 otherwise. Requires a username,
|
||||
password and connection host at the command line.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--bcv3 <replaceable class="parameter">codec</replaceable></term>
|
||||
<listitem>
|
||||
<para>Use <replaceable class="parameter">codec</replaceable> for bitmap cache v3
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-bmp-cache</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable bitmap cache.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--certificate-name <replaceable class="parameter">name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
use <replaceable class="parameter">name</replaceable> for the logon certificate, instead of the server name
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--composition</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable composition (RDVH only, not to be confused with remote composition).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ext <replaceable class="parameter">extname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load extension <replaceable class="parameter">extname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-fastpath</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disables fast-path. Use slow-path packets instead, which have larger headers.
|
||||
It might be good for debugging certain issues when you suspect it might be
|
||||
linked to the parsing of one of the two header types.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--from-stdin</term>
|
||||
<listitem>
|
||||
<para>Prompts for unspecified arguments -u username, -p
|
||||
password, -d domain and connection host. This is useful to
|
||||
hide arguments from ps. Also useful for scripts that will
|
||||
feed these arguments to the client via (what else?) stdin.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-full-window-drag</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable full window drag.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--gdi <replaceable class="parameter">backend</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
GDI (Graphics Device Interface) rendering backend. <replaceable class="parameter">backend</replaceable> can be either sw (software) or hw (hardware).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ignore-certificate</term>
|
||||
<listitem>
|
||||
<para>
|
||||
ignore verification of logon certificate.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--kbd-list</term>
|
||||
<listitem>
|
||||
<para>
|
||||
list all keyboard layout ids used by -k
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-menu-animations</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable menu animations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-motion</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Don't send mouse motion events.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nego</term>
|
||||
<listitem>
|
||||
<para>disable negotiation of security layer and enforce highest enabled security protocol.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nla</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable network level authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--nsc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable NSCodec.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-osb</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable off screen bitmaps.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcb <replaceable class="parameter">blob</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">blob</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcid <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--plugin <replaceable class="parameter">pluginname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load <replaceable class="parameter">pluginname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-rdp</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable RemoteFX.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx-mode</term>
|
||||
<listitem>
|
||||
<para>
|
||||
RemoteFX operational flags. <replaceable class="parameter">flags</replaceable> can be either v[ideo], i[mage]), default is video.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-salted-checksum</term>
|
||||
<listitem>
|
||||
<para>
|
||||
disable salted checksums with Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ntlm</term>
|
||||
<listitem>
|
||||
<para>
|
||||
force NTLM protocol version. <replaceable class="parameter">version</replaceable> can be one of 1 or 2.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--sec <replaceable class="parameter">proto</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
force protocol security. <replaceable class="parameter">proto</replaceable> can be one of rdp, tls or nla.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-theming</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable theming.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-tls</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable TLS encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--tsg
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable> </term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use Terminal Server Gateway with
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print version information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-wallpaper</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable wallpaper.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
60
client/X11/xfreerdp.1.xml.in
Normal file
60
client/X11/xfreerdp.1.xml.in
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE refentry
|
||||
PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY syntax SYSTEM "xfreerdp-argument.1.xml">
|
||||
<!ENTITY channels SYSTEM "xfreerdp-channels.1.xml">
|
||||
<!ENTITY examples SYSTEM "xfreerdp-examples.1.xml">
|
||||
]
|
||||
>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [file] [options] [/v:server[:port]]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
&syntax;
|
||||
|
||||
&channels;
|
||||
|
||||
&examples;
|
||||
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
@ -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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2010-2011, Ethan Rublee
|
||||
# Copyright (c) 2011-2012, Andrey Kamaev
|
||||
# Copyright (c) 2011-2013, Andrey Kamaev
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -35,7 +35,6 @@
|
||||
#
|
||||
# The file is mantained by the OpenCV project. The latest version can be get at
|
||||
# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake
|
||||
# Git commit: 084b1c796900b0825fc4e0593ab3143da3f3a90e
|
||||
#
|
||||
# Usage Linux:
|
||||
# $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
|
||||
@ -282,8 +281,19 @@
|
||||
# [+] updated for NDK r8c
|
||||
# [+] added support for clang compiler
|
||||
# - December 2012
|
||||
# [+] suppress warning about unused CMAKE_TOOLCHAIN_FILE variable
|
||||
# [+] adjust API level to closest compatible as NDK does
|
||||
# [~] fixed ccache full path search
|
||||
# [+] updated for NDK r8d
|
||||
# [~] compiler options are aligned with NDK r8d
|
||||
# - March 2013
|
||||
# [+] updated for NDK r8e (x86 version)
|
||||
# [+] support x86_64 version of NDK
|
||||
# - April 2013
|
||||
# [+] support non-release NDK layouts (from Linaro git and Android git)
|
||||
# [~] automatically detect if explicit link to crtbegin_*.o is needed
|
||||
# - June 2013
|
||||
# [~] fixed stl include path for standalone toolchain made by NDK >= r8c
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required( VERSION 2.6.3 )
|
||||
@ -293,6 +303,10 @@ if( DEFINED CMAKE_CROSSCOMPILING )
|
||||
return()
|
||||
endif()
|
||||
|
||||
if( CMAKE_TOOLCHAIN_FILE )
|
||||
# touch toolchain variable only to suppress "unused variable" warning
|
||||
endif()
|
||||
|
||||
get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
|
||||
if( _CMAKE_IN_TRY_COMPILE )
|
||||
include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
|
||||
@ -312,7 +326,7 @@ endif()
|
||||
# rpath makes low sence for Android
|
||||
set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
|
||||
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
|
||||
if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS)
|
||||
if( CMAKE_HOST_WIN32 )
|
||||
file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
|
||||
@ -456,19 +470,32 @@ if( ANDROID_FORBID_SYGWIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# detect current host platform
|
||||
if( NOT DEFINED ANDROID_NDK_HOST_X64 AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64")
|
||||
set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" )
|
||||
mark_as_advanced( ANDROID_NDK_HOST_X64 )
|
||||
endif()
|
||||
|
||||
set( TOOL_OS_SUFFIX "" )
|
||||
if( CMAKE_HOST_APPLE )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" )
|
||||
elseif( CMAKE_HOST_WIN32 )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "windows" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" )
|
||||
set( TOOL_OS_SUFFIX ".exe" )
|
||||
elseif( CMAKE_HOST_UNIX )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" )
|
||||
else()
|
||||
message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
|
||||
endif()
|
||||
|
||||
if( NOT ANDROID_NDK_HOST_X64 )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} )
|
||||
endif()
|
||||
|
||||
# see if we have path to Android NDK
|
||||
__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
|
||||
if( NOT ANDROID_NDK )
|
||||
@ -500,35 +527,19 @@ if( NOT ANDROID_NDK )
|
||||
endif( ANDROID_NDK )
|
||||
endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
|
||||
endif( NOT ANDROID_NDK )
|
||||
|
||||
# remember found paths
|
||||
if( ANDROID_NDK )
|
||||
get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
|
||||
# try to detect change
|
||||
if( CMAKE_AR )
|
||||
string( LENGTH "${ANDROID_NDK}" __length )
|
||||
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
|
||||
if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK )
|
||||
message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
|
||||
" )
|
||||
endif()
|
||||
unset( __androidNdkPreviousPath )
|
||||
unset( __length )
|
||||
endif()
|
||||
set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE )
|
||||
set( BUILD_WITH_ANDROID_NDK True )
|
||||
file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_TXT LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? )
|
||||
|
||||
if(${ANDROID_NDK_RELEASE_TXT} MATCHES "^r[0-9]+[a-z] \([^ ]+\)$")
|
||||
string( REGEX REPLACE "^(r[0-9]+[a-z]) \(([^ ]+)\)$" "\\1" ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
string( REGEX REPLACE "^(r[0-9]+[a-z]) \(([^ ]+)\)$" "\\2" ANDROID_NDK_RELEASE_EXTRA "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
|
||||
set( ANDROID_NDK_64BIT True)
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME "${ANDROID_NDK_HOST_SYSTEM_NAME}_64" )
|
||||
|
||||
if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" )
|
||||
file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? )
|
||||
string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" )
|
||||
else()
|
||||
set( ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_TXT}" )
|
||||
set( ANDROID_NDK_RELEASE "r1x" )
|
||||
set( ANDROID_NDK_RELEASE_FULL "unreleased" )
|
||||
endif()
|
||||
|
||||
elseif( ANDROID_STANDALONE_TOOLCHAIN )
|
||||
get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
|
||||
# try to detect change
|
||||
@ -555,6 +566,51 @@ else()
|
||||
sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
|
||||
endif()
|
||||
|
||||
# android NDK layout
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
if( NOT DEFINED ANDROID_NDK_LAYOUT )
|
||||
# try to automatically detect the layout
|
||||
if( EXISTS "${ANDROID_NDK}/RELEASE.TXT")
|
||||
set( ANDROID_NDK_LAYOUT "RELEASE" )
|
||||
elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" )
|
||||
set( ANDROID_NDK_LAYOUT "LINARO" )
|
||||
elseif( EXISTS "${ANDROID_NDK}/../../gcc/" )
|
||||
set( ANDROID_NDK_LAYOUT "ANDROID" )
|
||||
endif()
|
||||
endif()
|
||||
set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" )
|
||||
mark_as_advanced( ANDROID_NDK_LAYOUT )
|
||||
if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
|
||||
elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" )
|
||||
set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
|
||||
else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE"
|
||||
set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" )
|
||||
endif()
|
||||
get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE )
|
||||
|
||||
# try to detect change of NDK
|
||||
if( CMAKE_AR )
|
||||
string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length )
|
||||
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
|
||||
if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH )
|
||||
message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
|
||||
" )
|
||||
endif()
|
||||
unset( __androidNdkPreviousPath )
|
||||
unset( __length )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# get all the details about standalone toolchain
|
||||
if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
__DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
|
||||
@ -582,22 +638,27 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar )
|
||||
foreach( __toolchain ${${__availableToolchainsVar}} )
|
||||
if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" )
|
||||
macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath )
|
||||
foreach( __toolchain ${${__availableToolchainsLst}} )
|
||||
if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" )
|
||||
string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
|
||||
else()
|
||||
set( __gcc_toolchain "${__toolchain}" )
|
||||
endif()
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" )
|
||||
if( __machine )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" )
|
||||
string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" )
|
||||
string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" )
|
||||
if( __machine MATCHES i686 )
|
||||
set( __arch "x86" )
|
||||
elseif( __machine MATCHES arm )
|
||||
set( __arch "arm" )
|
||||
elseif( __machine MATCHES mipsel )
|
||||
set( __arch "mipsel" )
|
||||
endif()
|
||||
list( APPEND __availableToolchainMachines "${__machine}" )
|
||||
list( APPEND __availableToolchainArchs "${__arch}" )
|
||||
list( APPEND __availableToolchainCompilerVersions "${__version}" )
|
||||
else()
|
||||
list( REMOVE_ITEM ${__availableToolchainsVar} "${__toolchain}" )
|
||||
list( APPEND ${__availableToolchainsVar} "${__toolchain}" )
|
||||
endif()
|
||||
unset( __gcc_toolchain )
|
||||
endforeach()
|
||||
@ -611,19 +672,31 @@ if( BUILD_WITH_ANDROID_NDK )
|
||||
set( __availableToolchainMachines "" )
|
||||
set( __availableToolchainArchs "" )
|
||||
set( __availableToolchainCompilerVersions "" )
|
||||
if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" )
|
||||
if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" )
|
||||
# do not go through all toolchains if we know the name
|
||||
set( __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
|
||||
if( __availableToolchains )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" )
|
||||
file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
|
||||
if( __availableToolchains )
|
||||
list(SORT __availableToolchains) # we need clang to go after gcc
|
||||
list(SORT __availableToolchainsLst) # we need clang to go after gcc
|
||||
endif()
|
||||
__LIST_FILTER( __availableToolchainsLst "^[.]" )
|
||||
__LIST_FILTER( __availableToolchainsLst "llvm" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
|
||||
if( __availableToolchains )
|
||||
set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
|
||||
endif()
|
||||
endif()
|
||||
__LIST_FILTER( __availableToolchains "^[.]" )
|
||||
__LIST_FILTER( __availableToolchains "llvm" )
|
||||
__GLOB_NDK_TOOLCHAINS( __availableToolchains )
|
||||
endif()
|
||||
if( NOT __availableToolchains )
|
||||
message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
|
||||
@ -636,11 +709,11 @@ set( __uniqToolchainArchNames ${__availableToolchainArchs} )
|
||||
list( REMOVE_DUPLICATES __uniqToolchainArchNames )
|
||||
list( SORT __uniqToolchainArchNames )
|
||||
foreach( __arch ${__uniqToolchainArchNames} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
|
||||
endforeach()
|
||||
unset( __uniqToolchainArchNames )
|
||||
if( NOT ANDROID_SUPPORTED_ABIS )
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
|
||||
endif()
|
||||
|
||||
# choose target ABI
|
||||
@ -752,6 +825,7 @@ else()
|
||||
list( GET __availableToolchainArchs ${__idx} __toolchainArch )
|
||||
if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
|
||||
list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
|
||||
string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}")
|
||||
if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
|
||||
set( __toolchainMaxVersion "${__toolchainVersion}" )
|
||||
set( __toolchainIdx ${__idx} )
|
||||
@ -779,11 +853,22 @@ unset( __availableToolchainCompilerVersions )
|
||||
# choose native API level
|
||||
__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
|
||||
string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
|
||||
# TODO: filter out unsupported levels
|
||||
# adjust API level
|
||||
set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} )
|
||||
foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
|
||||
if( NOT __level GREATER ANDROID_NATIVE_API_LEVEL AND NOT __level LESS __real_api_level )
|
||||
set( __real_api_level ${__level} )
|
||||
endif()
|
||||
endforeach()
|
||||
if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL EQUAL __real_api_level )
|
||||
message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'")
|
||||
set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} )
|
||||
endif()
|
||||
unset(__real_api_level)
|
||||
# validate
|
||||
list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
|
||||
if( __levelIdx EQUAL -1 )
|
||||
message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." )
|
||||
message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." )
|
||||
else()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
__DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
|
||||
@ -893,7 +978,11 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN )
|
||||
set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
|
||||
|
||||
if( NOT ANDROID_STL STREQUAL "none" )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" )
|
||||
# old location ( pre r8c )
|
||||
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
|
||||
endif()
|
||||
if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" )
|
||||
list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" )
|
||||
elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" )
|
||||
@ -944,11 +1033,11 @@ if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
|
||||
elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
|
||||
string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
|
||||
string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
message( FATAL_ERROR "Could not find the " )
|
||||
if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" )
|
||||
message( FATAL_ERROR "Could not find the Clang compiler driver" )
|
||||
endif()
|
||||
set( ANDROID_COMPILER_IS_CLANG 1 )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
else()
|
||||
set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
|
||||
unset( ANDROID_COMPILER_IS_CLANG CACHE )
|
||||
@ -962,7 +1051,7 @@ endif()
|
||||
|
||||
# setup paths and STL for NDK
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
|
||||
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
|
||||
set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
|
||||
|
||||
if( ANDROID_STL STREQUAL "none" )
|
||||
@ -1021,11 +1110,11 @@ if( BUILD_WITH_ANDROID_NDK )
|
||||
endif()
|
||||
# find libsupc++.a - rtti & exceptions
|
||||
if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
|
||||
if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b")
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
|
||||
else( ANDROID_NDK_RELEASE STRLESS "r7" )
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer
|
||||
if( NOT EXISTS "${__libsupcxx}" )
|
||||
set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8
|
||||
endif()
|
||||
if( NOT EXISTS "${__libsupcxx}" ) # before r7
|
||||
if( ARMEABI_V7A )
|
||||
if( ANDROID_FORCE_ARM_BUILD )
|
||||
set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
|
||||
@ -1075,7 +1164,7 @@ unset( _ndk_ccache )
|
||||
|
||||
# setup the cross-compiler
|
||||
if( NOT CMAKE_C_COMPILER )
|
||||
if( NDK_CCACHE )
|
||||
if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
|
||||
set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
|
||||
if( ANDROID_COMPILER_IS_CLANG )
|
||||
@ -1147,11 +1236,25 @@ set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
|
||||
remove_definitions( -DANDROID )
|
||||
add_definitions( -DANDROID )
|
||||
|
||||
if(ANDROID_SYSROOT MATCHES "[ ;\"]")
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
|
||||
if( ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
if( CMAKE_HOST_WIN32 )
|
||||
# try to convert path to 8.3 form
|
||||
file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" )
|
||||
execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}"
|
||||
OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE __result ERROR_QUIET )
|
||||
if( __result EQUAL 0 )
|
||||
file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT )
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" )
|
||||
endif()
|
||||
if( NOT _CMAKE_IN_TRY_COMPILE )
|
||||
# quotes will break try_compile and compiler identification
|
||||
message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.")
|
||||
# quotes can break try_compile and compiler identification
|
||||
message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n")
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
|
||||
@ -1159,38 +1262,52 @@ endif()
|
||||
|
||||
# NDK flags
|
||||
if( ARMEABI OR ARMEABI_V7A )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables" )
|
||||
if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
|
||||
# It is recommended to use the -mthumb compiler flag to force the generation
|
||||
# of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-mthumb" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -finline-limit=64" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" )
|
||||
endif()
|
||||
else()
|
||||
# always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
|
||||
# O3 instead of O2/Os in release mode - like cmake sets for desktop gcc
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-marm" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -finline-limit=300" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
|
||||
endif()
|
||||
endif()
|
||||
elseif( X86 )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-finline-limit=300" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
|
||||
else()
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fPIC" )
|
||||
endif()
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" )
|
||||
elseif( MIPS )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -frename-registers" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-finline-limit=300 -fno-strict-aliasing" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-finline-functions -fgcse-after-reload -frerun-cse-after-loop" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer" )
|
||||
if( NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
|
||||
endif()
|
||||
elseif()
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "" )
|
||||
endif()
|
||||
|
||||
if( NOT X86 )
|
||||
set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
|
||||
|
||||
if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -fomit-frame-pointer" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer" )
|
||||
if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/
|
||||
endif()
|
||||
|
||||
# ABI-specific flags
|
||||
if( ARMEABI_V7A )
|
||||
@ -1208,22 +1325,18 @@ elseif( ARMEABI )
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
|
||||
endif()
|
||||
|
||||
if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
else()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
endif()
|
||||
|
||||
# STL
|
||||
if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
|
||||
if( ANDROID_STL MATCHES "gnustl" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
else()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
|
||||
endif()
|
||||
if ( X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" )
|
||||
# workaround "undefined reference to `__dso_handle'" problem
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
endif()
|
||||
if( EXISTS "${__libstl}" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" )
|
||||
@ -1242,9 +1355,12 @@ if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
|
||||
set( CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
|
||||
endif()
|
||||
if( ANDROID_STL MATCHES "gnustl" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} -lm" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} -lm" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lm" )
|
||||
if( NOT EXISTS "${ANDROID_LIBM_PATH}" )
|
||||
set( ANDROID_LIBM_PATH -lm )
|
||||
endif()
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" )
|
||||
set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -1280,7 +1396,14 @@ if( ARMEABI_V7A )
|
||||
endif()
|
||||
|
||||
if( ANDROID_NO_UNDEFINED )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
|
||||
if( MIPS )
|
||||
# there is some sysroot-related problem in mips linker...
|
||||
if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" )
|
||||
endif()
|
||||
else()
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( ANDROID_SO_UNDEFINED )
|
||||
@ -1327,9 +1450,6 @@ if( ANDROID_COMPILER_IS_CLANG )
|
||||
set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
if( BUILD_WITH_ANDROID_NDK )
|
||||
if(ANDROID_ARCH_NAME STREQUAL "arm" )
|
||||
set( ANDROID_CXX_FLAGS "-isystem ${ANDROID_CLANG_TOOLCHAIN_ROOT}/lib/clang/${ANDROID_CLANG_VERSION}/include ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
|
||||
endif()
|
||||
endif()
|
||||
@ -1345,6 +1465,12 @@ set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "shared li
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "module linker flags" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "executable linker flags" )
|
||||
|
||||
# put flags to cache (for debug purpose only)
|
||||
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Android specific c/c++ flags" )
|
||||
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" )
|
||||
set( ANDROID_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG}" CACHE INTERNAL "Android specific c/c++ Debug flags" )
|
||||
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android specific c/c++ linker flags" )
|
||||
|
||||
# finish flags
|
||||
set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
|
||||
set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
|
||||
@ -1357,9 +1483,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL
|
||||
set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
|
||||
if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||
endif()
|
||||
|
||||
# configure rtti
|
||||
@ -1386,6 +1512,43 @@ endif()
|
||||
include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
|
||||
link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
|
||||
|
||||
# detect if need link crtbegin_so.o explicitly
|
||||
if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK )
|
||||
set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" )
|
||||
string( REPLACE "<CMAKE_CXX_COMPILER>" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_CXX_FLAGS>" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LANGUAGE_COMPILE_FLAGS>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LINK_FLAGS>" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>" "-shared" __cmd "${__cmd}" )
|
||||
string( REPLACE "<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<TARGET_SONAME>" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "<TARGET>" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" )
|
||||
string( REPLACE "<OBJECTS>" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" )
|
||||
string( REPLACE "<LINK_LIBRARIES>" "" __cmd "${__cmd}" )
|
||||
separate_arguments( __cmd )
|
||||
foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN )
|
||||
if( ${__var} )
|
||||
set( __tmp "${${__var}}" )
|
||||
separate_arguments( __tmp )
|
||||
string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}")
|
||||
endif()
|
||||
endforeach()
|
||||
string( REPLACE "'" "" __cmd "${__cmd}" )
|
||||
string( REPLACE "\"" "" __cmd "${__cmd}" )
|
||||
execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET )
|
||||
if( __cmd_result EQUAL 0 )
|
||||
set( ANDROID_EXPLICIT_CRT_LINK ON )
|
||||
else()
|
||||
set( ANDROID_EXPLICIT_CRT_LINK OFF )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( ANDROID_EXPLICIT_CRT_LINK )
|
||||
set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
|
||||
endif()
|
||||
|
||||
# setup output directories
|
||||
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
|
||||
set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
|
||||
@ -1475,7 +1638,9 @@ endmacro()
|
||||
if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
|
||||
set( __toolchain_config "")
|
||||
foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN ANDROID_SET_OBSOLETE_VARIABLES
|
||||
ANDROID_NDK_HOST_X64
|
||||
ANDROID_NDK
|
||||
ANDROID_NDK_LAYOUT
|
||||
ANDROID_STANDALONE_TOOLCHAIN
|
||||
ANDROID_TOOLCHAIN_NAME
|
||||
ANDROID_ABI
|
||||
@ -1489,6 +1654,8 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
|
||||
ANDROID_GOLD_LINKER
|
||||
ANDROID_NOEXECSTACK
|
||||
ANDROID_RELRO
|
||||
ANDROID_LIBM_PATH
|
||||
ANDROID_EXPLICIT_CRT_LINK
|
||||
)
|
||||
if( DEFINED ${__var} )
|
||||
if( "${__var}" MATCHES " ")
|
||||
@ -1531,6 +1698,8 @@ endif()
|
||||
# ANDROID_NDK
|
||||
# ANDROID_STANDALONE_TOOLCHAIN
|
||||
# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
|
||||
# ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
|
||||
# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
|
||||
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
|
||||
# NDK_CCACHE : <path to your ccache executable>
|
||||
# Obsolete:
|
||||
@ -1553,7 +1722,7 @@ endif()
|
||||
# BUILD_ANDROID : always TRUE
|
||||
# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
|
||||
# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
|
||||
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86", "linux-x86_64" or "darwin-x86" depending on host platform
|
||||
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
|
||||
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI
|
||||
# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d, r8e; set only for NDK
|
||||
# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI
|
||||
@ -1576,6 +1745,7 @@ endif()
|
||||
# ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
|
||||
# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
|
||||
# ANDROID_CLANG_VERSION : version of clang compiler if clang is used
|
||||
# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
|
||||
#
|
||||
# Defaults:
|
||||
# ANDROID_DEFAULT_NDK_API_LEVEL
|
||||
|
73
cmake/FindDBus.cmake
Normal file
73
cmake/FindDBus.cmake
Normal file
@ -0,0 +1,73 @@
|
||||
# - Try to find the low-level D-Bus library
|
||||
# Once done this will define
|
||||
#
|
||||
# DBUS_FOUND - system has D-Bus
|
||||
# DBUS_INCLUDE_DIR - the D-Bus include directory
|
||||
# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory
|
||||
# DBUS_LIBRARIES - the libraries needed to use D-Bus
|
||||
|
||||
# Copyright (c) 2008, Kevin Kofler, <kevin.kofler@chello.at>
|
||||
# modeled after FindLibArt.cmake:
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
# in cache already
|
||||
SET(DBUS_FOUND TRUE)
|
||||
|
||||
else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
IF (PKG_CONFIG_FOUND)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
pkg_check_modules(_DBUS_PC QUIET dbus-1)
|
||||
ENDIF (PKG_CONFIG_FOUND)
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/include/dbus-1.0
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/lib${LIB_SUFFIX}/include
|
||||
/usr/lib${LIB_SUFFIX}/dbus-1.0/include
|
||||
/usr/lib64/include
|
||||
/usr/lib64/dbus-1.0/include
|
||||
/usr/lib/include
|
||||
/usr/lib/dbus-1.0/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus
|
||||
PATHS
|
||||
${_DBUS_PC_LIBDIR}
|
||||
)
|
||||
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
set(DBUS_FOUND TRUE)
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
|
||||
if (DBUS_FOUND)
|
||||
if (NOT DBus_FIND_QUIETLY)
|
||||
message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}")
|
||||
endif (NOT DBus_FIND_QUIETLY)
|
||||
else (DBUS_FOUND)
|
||||
if (DBus_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find D-Bus")
|
||||
endif (DBus_FIND_REQUIRED)
|
||||
endif (DBUS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES)
|
||||
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
38
cmake/FindDbusGlib.cmake
Normal file
38
cmake/FindDbusGlib.cmake
Normal file
@ -0,0 +1,38 @@
|
||||
# DbusGlib library detection
|
||||
#
|
||||
# Copyright 2013 Thinstuff Technologies GmbH
|
||||
# Copyright 2013 Armin Novak <anovak@thinstuff.at>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_DBUS_GLIB QUIET dbus-glib-1)
|
||||
set(DBUS_GLIB_DEFINITIONS ${PC_DBUS_GLIB_CFLAGS_OTHER})
|
||||
|
||||
find_path(DBUS_GLIB_INCLUDE_DIR dbus/dbus-glib.h
|
||||
HINTS ${PC_DBUS_GLIB_INCLUDEDIR} ${PC_DBUS_GLIB_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES dbus-glib-1 )
|
||||
|
||||
find_library(DBUS_GLIB_LIBRARY NAMES dbus-glib-1 dbus-glib
|
||||
HINTS ${PC_DBUS_GLIB_LIBDIR} ${PC_DBUS_GLIB_LIBRARY_DIRS} )
|
||||
|
||||
set(DBUS_GLIB_LIBRARIES ${DBUS_GLIB_LIBRARY} )
|
||||
set(DBUS_GLIB_INCLUDE_DIRS ${DBUS_GLIB_INCLUDE_DIR} )
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set DBUS_GLIB_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(dbus-glib DEFAULT_MSG
|
||||
DBUS_GLIB_LIBRARY DBUS_GLIB_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(DBUS_GLIB_INCLUDE_DIR DBUS_GLIB_LIBRARY )
|
52
cmake/FindDocBookXSL.cmake
Normal file
52
cmake/FindDocBookXSL.cmake
Normal file
@ -0,0 +1,52 @@
|
||||
# Try to find DocBook XSL stylesheet
|
||||
# Once done, it will define:
|
||||
#
|
||||
# DOCBOOKXSL_FOUND - system has the required DocBook XML DTDs
|
||||
# DOCBOOKXSL_DIR - the directory containing the stylesheets
|
||||
# used to process DocBook XML
|
||||
|
||||
# Copyright (c) 2010, Luigi Toscano, <luigi.toscano@tiscali.it>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
set (STYLESHEET_PATH_LIST
|
||||
share/xml/docbook/stylesheet/docbook-xsl
|
||||
share/xml/docbook/xsl-stylesheets
|
||||
share/sgml/docbook/xsl-stylesheets
|
||||
share/xml/docbook/stylesheet/nwalsh/current
|
||||
share/xml/docbook/stylesheet/nwalsh
|
||||
share/xsl/docbook
|
||||
share/xsl/docbook-xsl
|
||||
)
|
||||
|
||||
find_path (DOCBOOKXSL_DIR lib/lib.xsl
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
|
||||
if (NOT DOCBOOKXSL_DIR)
|
||||
# hacks for systems that put the version in the stylesheet dirs
|
||||
set (STYLESHEET_PATH_LIST)
|
||||
foreach (STYLESHEET_PREFIX_ITER ${CMAKE_SYSTEM_PREFIX_PATH})
|
||||
file(GLOB STYLESHEET_SUFFIX_ITER RELATIVE ${STYLESHEET_PREFIX_ITER}
|
||||
${STYLESHEET_PREFIX_ITER}/share/xml/docbook/xsl-stylesheets-*
|
||||
)
|
||||
if (STYLESHEET_SUFFIX_ITER)
|
||||
list (APPEND STYLESHEET_PATH_LIST ${STYLESHEET_SUFFIX_ITER})
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
find_path (DOCBOOKXSL_DIR VERSION
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
endif (NOT DOCBOOKXSL_DIR)
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (DocBookXSL
|
||||
"Could NOT find DocBook XSL stylesheets"
|
||||
DOCBOOKXSL_DIR)
|
||||
|
||||
mark_as_advanced (DOCBOOKXSL_DIR)
|
53
cmake/FindUDev.cmake
Normal file
53
cmake/FindUDev.cmake
Normal file
@ -0,0 +1,53 @@
|
||||
# razor-de: Configure libudev environment
|
||||
#
|
||||
# UDEV_FOUND - system has a libudev
|
||||
# UDEV_INCLUDE_DIR - where to find header files
|
||||
# UDEV_LIBRARIES - the libraries to link against udev
|
||||
# UDEV_STABLE - it's true when is the version greater or equals to 143 - version when the libudev was stabilized in its API
|
||||
#
|
||||
# copyright (c) 2011 Petr Vanek <petr@scribus.info>
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
#
|
||||
|
||||
FIND_PATH(
|
||||
UDEV_INCLUDE_DIR
|
||||
libudev.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
${UDEV_PATH_INCLUDES}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
UDEV_LIBRARIES
|
||||
NAMES udev libudev
|
||||
PATHS
|
||||
/usr/lib${LIB_SUFFIX}
|
||||
/usr/local/lib${LIB_SUFFIX}
|
||||
${UDEV_PATH_LIB}
|
||||
)
|
||||
|
||||
IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
||||
SET(UDEV_FOUND "YES")
|
||||
execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE)
|
||||
# retvale is 0 of the condition is "true" so we need to negate the value...
|
||||
if (UDEV_STABLE)
|
||||
set(UDEV_STABLE 0)
|
||||
else (UDEV_STABLE)
|
||||
set(UDEV_STABLE 1)
|
||||
endif (UDEV_STABLE)
|
||||
message(STATUS "libudev stable: ${UDEV_STABLE}")
|
||||
ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
||||
|
||||
IF (UDEV_FOUND)
|
||||
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
|
||||
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
|
||||
ELSE (UDEV_FOUND)
|
||||
MESSAGE(STATUS "UDev not found.")
|
||||
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
|
||||
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
|
||||
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
|
||||
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
|
||||
IF (UDev_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find UDev library")
|
||||
ENDIF (UDev_FIND_REQUIRED)
|
||||
ENDIF (UDEV_FOUND)
|
113
cmake/FindUUID.cmake
Normal file
113
cmake/FindUUID.cmake
Normal file
@ -0,0 +1,113 @@
|
||||
# - Try to find UUID
|
||||
# Once done this will define
|
||||
#
|
||||
# UUID_FOUND - system has UUID
|
||||
# UUID_INCLUDE_DIRS - the UUID include directory
|
||||
# UUID_LIBRARIES - Link these to use UUID
|
||||
# UUID_DEFINITIONS - Compiler switches required for using UUID
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(UUID_FOUND TRUE)
|
||||
else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
||||
find_path(UUID_INCLUDE_DIR
|
||||
NAMES
|
||||
uuid/uuid.h
|
||||
PATHS
|
||||
${UUID_DIR}/include
|
||||
$ENV{UUID_DIR}/include
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/inc
|
||||
$ENV{DELTA_ROOT}/ext/inc
|
||||
$ENV{DELTA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/usr/include/gdal
|
||||
/sw/include # Fink
|
||||
/opt/local/include # DarwinPorts
|
||||
/opt/csw/include # Blastwave
|
||||
/opt/include
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]/include
|
||||
/usr/freeware/include
|
||||
|
||||
)
|
||||
|
||||
find_library(UUID_LIBRARY
|
||||
NAMES
|
||||
uuid
|
||||
PATHS
|
||||
${UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/lib
|
||||
$ENV{DELTA_ROOT}/ext/lib
|
||||
$ENV{DELTA_ROOT}
|
||||
$ENV{OSG_ROOT}/lib
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
/usr/freeware/lib64
|
||||
)
|
||||
|
||||
find_library(UUID_LIBRARY_DEBUG
|
||||
NAMES
|
||||
uuidd
|
||||
PATHS
|
||||
${UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}/lib
|
||||
$ENV{UUID_DIR}
|
||||
${DELTA3D_EXT_DIR}/lib
|
||||
$ENV{DELTA_ROOT}/ext/lib
|
||||
$ENV{DELTA_ROOT}
|
||||
$ENV{OSG_ROOT}/lib
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
/usr/freeware/lib64
|
||||
)
|
||||
|
||||
set(UUID_INCLUDE_DIRS
|
||||
${UUID_INCLUDE_DIR}
|
||||
)
|
||||
set(UUID_LIBRARIES
|
||||
${UUID_LIBRARY}
|
||||
)
|
||||
|
||||
if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
|
||||
set(UUID_FOUND TRUE)
|
||||
endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
|
||||
|
||||
if (UUID_FOUND)
|
||||
if (NOT UUID_FIND_QUIETLY)
|
||||
message(STATUS "Found UUID: ${UUID_LIBRARIES}")
|
||||
endif (NOT UUID_FIND_QUIETLY)
|
||||
else (UUID_FOUND)
|
||||
if (UUID_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find UUID")
|
||||
endif (UUID_FIND_REQUIRED)
|
||||
endif (UUID_FOUND)
|
||||
|
||||
# show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(UUID_INCLUDE_DIRS UUID_LIBRARIES)
|
||||
|
||||
endif (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
|
98
cmake/Findlibusb-1.0.cmake
Normal file
98
cmake/Findlibusb-1.0.cmake
Normal file
@ -0,0 +1,98 @@
|
||||
# - Try to find libusb-1.0
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBUSB_1_FOUND - system has libusb
|
||||
# LIBUSB_1_INCLUDE_DIRS - the libusb include directory
|
||||
# LIBUSB_1_LIBRARIES - Link these to use libusb
|
||||
# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb
|
||||
#
|
||||
# Adapted from cmake-modules Google Code project
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# (Changes for libusb) Copyright (c) 2008 Kyle Machulis <kyle@nonpolynomial.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||
#
|
||||
# CMake-Modules Project New BSD License
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the CMake-Modules Project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
|
||||
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBUSB_FOUND TRUE)
|
||||
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
find_path(LIBUSB_1_INCLUDE_DIR
|
||||
NAMES
|
||||
libusb.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES
|
||||
libusb-1.0
|
||||
)
|
||||
|
||||
find_library(LIBUSB_1_LIBRARY
|
||||
NAMES
|
||||
usb-1.0 usb
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(LIBUSB_1_INCLUDE_DIRS
|
||||
${LIBUSB_1_INCLUDE_DIR}
|
||||
)
|
||||
set(LIBUSB_1_LIBRARIES
|
||||
${LIBUSB_1_LIBRARY}
|
||||
)
|
||||
|
||||
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
set(LIBUSB_1_FOUND TRUE)
|
||||
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
|
||||
if (LIBUSB_1_FOUND)
|
||||
if (NOT libusb_1_FIND_QUIETLY)
|
||||
message(STATUS "Found libusb-1.0:")
|
||||
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
||||
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
||||
endif (NOT libusb_1_FIND_QUIETLY)
|
||||
else (LIBUSB_1_FOUND)
|
||||
if (libusb_1_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find libusb")
|
||||
endif (libusb_1_FIND_REQUIRED)
|
||||
endif (LIBUSB_1_FOUND)
|
||||
|
||||
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
||||
|
||||
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
16
cmake/today.cmake
Normal file
16
cmake/today.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
# This script returns the current date in ISO format
|
||||
#
|
||||
# YYYY-MM-DD
|
||||
#
|
||||
MACRO (TODAY RESULT)
|
||||
IF (WIN32)
|
||||
EXECUTE_PROCESS(COMMAND "cmd" " /C date +%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSEIF(UNIX)
|
||||
EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSE (WIN32)
|
||||
MESSAGE(SEND_ERROR "date not implemented")
|
||||
SET(${RESULT} 000000)
|
||||
ENDIF (WIN32)
|
||||
ENDMACRO (TODAY)
|
@ -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
|
||||
|
||||
|
||||
|
@ -227,6 +227,8 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
|
||||
if (context->priv->MaxThreadCount)
|
||||
SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount);
|
||||
|
||||
context->priv->EncoderStreamPool = StreamPool_New(TRUE, 64*64*3+19);
|
||||
}
|
||||
|
||||
/* initialize the default pixel format */
|
||||
@ -261,6 +263,7 @@ void rfx_context_free(RFX_CONTEXT* context)
|
||||
{
|
||||
CloseThreadpool(context->priv->ThreadPool);
|
||||
DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv);
|
||||
StreamPool_Free(context->priv->EncoderStreamPool);
|
||||
#ifdef WITH_PROFILER
|
||||
fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
|
||||
#endif
|
||||
@ -312,8 +315,7 @@ RFX_TILE* rfx_tile_pool_take(RFX_CONTEXT* context)
|
||||
{
|
||||
RFX_TILE* tile = NULL;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(context->priv->TilePool), 0) == WAIT_OBJECT_0)
|
||||
tile = Queue_Dequeue(context->priv->TilePool);
|
||||
tile = Queue_Dequeue(context->priv->TilePool);
|
||||
|
||||
if (!tile)
|
||||
{
|
||||
@ -583,17 +585,17 @@ static BOOL rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, wStre
|
||||
tile->data, 64 * 4);
|
||||
}
|
||||
|
||||
struct _RFX_TILE_WORK_PARAM
|
||||
struct _RFX_TILE_PROCESS_WORK_PARAM
|
||||
{
|
||||
wStream s;
|
||||
RFX_TILE* tile;
|
||||
RFX_CONTEXT* context;
|
||||
};
|
||||
typedef struct _RFX_TILE_WORK_PARAM RFX_TILE_WORK_PARAM;
|
||||
typedef struct _RFX_TILE_PROCESS_WORK_PARAM RFX_TILE_PROCESS_WORK_PARAM;
|
||||
|
||||
void CALLBACK rfx_process_message_tile_work_callback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
|
||||
{
|
||||
RFX_TILE_WORK_PARAM* param = (RFX_TILE_WORK_PARAM*) context;
|
||||
RFX_TILE_PROCESS_WORK_PARAM* param = (RFX_TILE_PROCESS_WORK_PARAM*) context;
|
||||
rfx_process_message_tile(param->context, param->tile, &(param->s));
|
||||
}
|
||||
|
||||
@ -608,7 +610,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
UINT32 blockType;
|
||||
UINT32 tilesDataSize;
|
||||
PTP_WORK* work_objects = NULL;
|
||||
RFX_TILE_WORK_PARAM* params = NULL;
|
||||
RFX_TILE_PROCESS_WORK_PARAM* params = NULL;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 14)
|
||||
{
|
||||
@ -692,7 +694,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->num_tiles);
|
||||
params = (RFX_TILE_WORK_PARAM*) malloc(sizeof(RFX_TILE_WORK_PARAM) * message->num_tiles);
|
||||
params = (RFX_TILE_PROCESS_WORK_PARAM*) malloc(sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->num_tiles);
|
||||
}
|
||||
|
||||
/* tiles */
|
||||
@ -1044,6 +1046,41 @@ static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s,
|
||||
Stream_SetPosition(s, end_pos);
|
||||
}
|
||||
|
||||
|
||||
struct _RFX_TILE_COMPOSE_WORK_PARAM
|
||||
{
|
||||
RFX_CONTEXT* context;
|
||||
wStream *s;
|
||||
BYTE* tile_data;
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
int rowstride;
|
||||
UINT32* quantVals;
|
||||
int quantIdxY;
|
||||
int quantIdxCb;
|
||||
int quantIdxCr;
|
||||
int xIdx;
|
||||
int yIdx;
|
||||
};
|
||||
typedef struct _RFX_TILE_COMPOSE_WORK_PARAM RFX_TILE_COMPOSE_WORK_PARAM;
|
||||
|
||||
void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
|
||||
{
|
||||
RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context;
|
||||
|
||||
/**
|
||||
* Some component of the encoder chain (I suspect the rlgr encoder) expects
|
||||
* the output buffer to be zeroed. The multithreaded RemoteFX encoder uses
|
||||
* wStreams from the StreamPool which are reused and not zeroed out of
|
||||
* course. For now, in order to prevent data corruption we clear the stream.
|
||||
*/
|
||||
Stream_Clear(param->s);
|
||||
|
||||
rfx_compose_message_tile(param->context, param->s,
|
||||
param->tile_data, param->tile_width, param->tile_height, param->rowstride,
|
||||
param->quantVals, param->quantIdxY, param->quantIdxCb, param->quantIdxCr, param->xIdx, param->yIdx);
|
||||
}
|
||||
|
||||
static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
|
||||
BYTE* image_data, int width, int height, int rowstride)
|
||||
{
|
||||
@ -1062,6 +1099,11 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
|
||||
int xIdx;
|
||||
int yIdx;
|
||||
int tilesDataSize;
|
||||
BYTE* tileData;
|
||||
int tileWidth;
|
||||
int tileHeight;
|
||||
PTP_WORK* work_objects = NULL;
|
||||
RFX_TILE_COMPOSE_WORK_PARAM* params = NULL;
|
||||
|
||||
if (context->num_quants == 0)
|
||||
{
|
||||
@ -1110,17 +1152,64 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
|
||||
DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride);
|
||||
|
||||
end_pos = Stream_GetPosition(s);
|
||||
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * numTiles);
|
||||
params = (RFX_TILE_COMPOSE_WORK_PARAM*) malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * numTiles);
|
||||
}
|
||||
|
||||
for (yIdx = 0; yIdx < numTilesY; yIdx++)
|
||||
{
|
||||
for (xIdx = 0; xIdx < numTilesX; xIdx++)
|
||||
{
|
||||
rfx_compose_message_tile(context, s,
|
||||
image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel,
|
||||
(xIdx < numTilesX - 1) ? 64 : width - xIdx * 64,
|
||||
(yIdx < numTilesY - 1) ? 64 : height - yIdx * 64,
|
||||
rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx);
|
||||
tileData = image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel;
|
||||
tileWidth = (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64;
|
||||
tileHeight = (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64;
|
||||
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
i = yIdx * numTilesX + xIdx;
|
||||
|
||||
params[i].context = context;
|
||||
params[i].s = StreamPool_Take(context->priv->EncoderStreamPool, 0);
|
||||
params[i].tile_data = tileData;
|
||||
params[i].tile_width = tileWidth;
|
||||
params[i].tile_height = tileHeight;
|
||||
params[i].rowstride = rowstride;
|
||||
params[i].quantVals = (UINT32*)quantVals;
|
||||
params[i].quantIdxY = quantIdxY;
|
||||
params[i].quantIdxCb = quantIdxCb;
|
||||
params[i].quantIdxCr = quantIdxCr;
|
||||
params[i].xIdx = xIdx;
|
||||
params[i].yIdx = yIdx;
|
||||
|
||||
work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback,
|
||||
(void*) ¶ms[i], &context->priv->ThreadPoolEnv);
|
||||
|
||||
SubmitThreadpoolWork(work_objects[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rfx_compose_message_tile(context, s, tileData, tileWidth, tileHeight,
|
||||
rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
for (i = 0; i < numTiles; i++)
|
||||
{
|
||||
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
|
||||
CloseThreadpoolWork(work_objects[i]);
|
||||
Stream_Write(s, Stream_Buffer(params[i].s), Stream_GetPosition(params[i].s));
|
||||
StreamPool_Return(context->priv->EncoderStreamPool, params[i].s);
|
||||
}
|
||||
free(work_objects);
|
||||
free(params);
|
||||
}
|
||||
|
||||
tilesDataSize = Stream_GetPosition(s) - end_pos;
|
||||
size += tilesDataSize;
|
||||
end_pos = Stream_GetPosition(s);
|
||||
|
@ -49,6 +49,7 @@ struct _RFX_CONTEXT_PRIV
|
||||
TP_CALLBACK_ENVIRON ThreadPoolEnv;
|
||||
|
||||
wBufferPool* BufferPool;
|
||||
wStreamPool* EncoderStreamPool;
|
||||
|
||||
/* profilers */
|
||||
PROFILER_DEFINE(prof_rfx_decode_rgb);
|
||||
|
@ -194,24 +194,38 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
|
||||
rdp_client_disconnect(rdp);
|
||||
|
||||
/* FIXME: this is a subset of rdp_free */
|
||||
/* --> this should really go into rdp.c */
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = NULL ;
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = NULL;
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
rdp->fips_encrypt = NULL ;
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
rdp->fips_decrypt = NULL ;
|
||||
crypto_hmac_free(rdp->fips_hmac);
|
||||
rdp->fips_hmac = NULL ;
|
||||
|
||||
free(settings->ServerRandom);
|
||||
settings->ServerRandom = NULL ;
|
||||
free(settings->ServerCertificate);
|
||||
settings->ServerCertificate = NULL ;
|
||||
free(settings->ClientAddress);
|
||||
settings->ClientAddress = NULL ;
|
||||
|
||||
mppc_enc_free(rdp->mppc_enc);
|
||||
mppc_dec_free(rdp->mppc_dec);
|
||||
mcs_free(rdp->mcs);
|
||||
nego_free(rdp->nego);
|
||||
license_free(rdp->license);
|
||||
transport_free(rdp->transport);
|
||||
|
||||
free(settings->ServerRandom);
|
||||
free(settings->ServerCertificate);
|
||||
free(settings->ClientAddress);
|
||||
|
||||
rdp->transport = transport_new(settings);
|
||||
rdp->license = license_new(rdp);
|
||||
rdp->nego = nego_new(rdp->transport);
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
rdp->mppc_dec = mppc_dec_new();
|
||||
rdp->mppc_enc = mppc_enc_new(PROTO_RDP_50);
|
||||
|
||||
rdp->transport->layer = TRANSPORT_LAYER_TCP;
|
||||
settings->RedirectedSessionId = redirection->sessionID;
|
||||
|
@ -856,6 +856,8 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
||||
comp_flags = FASTPATH_OUTPUT_COMPRESSION_USED;
|
||||
header_bytes = 7 + sec_bytes;
|
||||
bm = (BYTE*) (rdp->mppc_enc->outputBuffer - header_bytes);
|
||||
if (comp_update)
|
||||
Stream_Free(comp_update, FALSE);
|
||||
comp_update = Stream_New(bm, pdu_data_bytes + header_bytes);
|
||||
ls = comp_update;
|
||||
}
|
||||
@ -902,6 +904,8 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
||||
|
||||
Stream_Write_UINT16(ls, pdu_data_bytes);
|
||||
|
||||
if (update)
|
||||
Stream_Free(update, FALSE);
|
||||
update = Stream_New(bm, pduLength);
|
||||
Stream_Seek(update, pduLength);
|
||||
|
||||
|
@ -740,7 +740,11 @@ int transport_check_fds(rdpTransport** ptransport)
|
||||
|
||||
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
|
||||
|
||||
Stream_Release(received);
|
||||
if (transport == *ptransport)
|
||||
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
|
||||
/* so only release if still valid */
|
||||
Stream_Release(received);
|
||||
|
||||
|
||||
if (recv_status < 0)
|
||||
status = -1;
|
||||
|
@ -63,11 +63,14 @@ endif()
|
||||
|
||||
if(FREERDP_BUILD)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include PARENT_SCOPE)
|
||||
else()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/winpr/config.h)
|
||||
|
||||
add_subdirectory(include)
|
||||
|
||||
|
@ -58,7 +58,7 @@ struct _wQueue
|
||||
int tail;
|
||||
int size;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
@ -67,8 +67,8 @@ typedef struct _wQueue wQueue;
|
||||
|
||||
WINPR_API int Queue_Count(wQueue* queue);
|
||||
|
||||
WINPR_API BOOL Queue_Lock(wQueue* queue);
|
||||
WINPR_API BOOL Queue_Unlock(wQueue* queue);
|
||||
WINPR_API void Queue_Lock(wQueue* queue);
|
||||
WINPR_API void Queue_Unlock(wQueue* queue);
|
||||
|
||||
WINPR_API HANDLE Queue_Event(wQueue* queue);
|
||||
|
||||
@ -93,7 +93,7 @@ struct _wStack
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
wObject object;
|
||||
};
|
||||
@ -125,7 +125,7 @@ struct _wArrayList
|
||||
|
||||
int size;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
@ -137,8 +137,8 @@ WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
|
||||
|
||||
WINPR_API BOOL ArrayList_Lock(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_Unlock(wArrayList* arrayList);
|
||||
WINPR_API void ArrayList_Lock(wArrayList* arrayList);
|
||||
WINPR_API void ArrayList_Unlock(wArrayList* arrayList);
|
||||
|
||||
WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index);
|
||||
WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj);
|
||||
@ -165,7 +165,7 @@ WINPR_API void ArrayList_Free(wArrayList* arrayList);
|
||||
struct _wDictionary
|
||||
{
|
||||
BOOL synchronized;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
typedef struct _wDictionary wDictionary;
|
||||
|
||||
@ -184,7 +184,7 @@ struct _wListDictionaryItem
|
||||
struct _wListDictionary
|
||||
{
|
||||
BOOL synchronized;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wListDictionaryItem* head;
|
||||
};
|
||||
@ -227,7 +227,7 @@ typedef int (*REFERENCE_FREE)(void* context, void* ptr);
|
||||
struct _wReferenceTable
|
||||
{
|
||||
UINT32 size;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
void* context;
|
||||
BOOL synchronized;
|
||||
wReference* array;
|
||||
@ -246,7 +246,7 @@ WINPR_API void ReferenceTable_Free(wReferenceTable* referenceTable);
|
||||
struct _wCountdownEvent
|
||||
{
|
||||
DWORD count;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
DWORD initialCount;
|
||||
};
|
||||
@ -271,7 +271,7 @@ struct _wBufferPool
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
int fixedSize;
|
||||
DWORD alignment;
|
||||
BOOL synchronized;
|
||||
@ -292,7 +292,7 @@ struct _wObjectPool
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
wObject object;
|
||||
BOOL synchronized;
|
||||
};
|
||||
@ -330,7 +330,7 @@ struct _wMessageQueue
|
||||
int size;
|
||||
int capacity;
|
||||
wMessage* array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
};
|
||||
typedef struct _wMessageQueue wMessageQueue;
|
||||
@ -427,7 +427,7 @@ typedef struct _wEventType wEventType;
|
||||
|
||||
struct _wPubSub
|
||||
{
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
|
||||
int size;
|
||||
@ -436,8 +436,8 @@ struct _wPubSub
|
||||
};
|
||||
typedef struct _wPubSub wPubSub;
|
||||
|
||||
WINPR_API BOOL PubSub_Lock(wPubSub* pubSub);
|
||||
WINPR_API BOOL PubSub_Unlock(wPubSub* pubSub);
|
||||
WINPR_API void PubSub_Lock(wPubSub* pubSub);
|
||||
WINPR_API void PubSub_Unlock(wPubSub* pubSub);
|
||||
|
||||
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
|
||||
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/endian.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -236,7 +237,7 @@ struct _wStreamPool
|
||||
int uCapacity;
|
||||
wStream** uArray;
|
||||
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
size_t defaultSize;
|
||||
};
|
||||
|
@ -139,14 +139,22 @@ typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
|
||||
|
||||
/* Critical Section */
|
||||
|
||||
#if defined(__linux__)
|
||||
/**
|
||||
* Linux NPTL thread synchronization primitives are implemented using
|
||||
* the futex system calls ... we can't beat futex with a spin loop.
|
||||
*/
|
||||
#define WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT
|
||||
#endif
|
||||
|
||||
typedef struct _RTL_CRITICAL_SECTION
|
||||
{
|
||||
void* DebugInfo;
|
||||
PVOID DebugInfo;
|
||||
LONG LockCount;
|
||||
LONG RecursionCount;
|
||||
PVOID OwningThread;
|
||||
PVOID LockSemaphore;
|
||||
ULONG SpinCount;
|
||||
HANDLE OwningThread;
|
||||
HANDLE LockSemaphore;
|
||||
ULONG_PTR SpinCount;
|
||||
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
|
||||
|
||||
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
|
||||
|
@ -34,7 +34,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SO
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-handle winpr-synch)
|
||||
MODULES winpr-crt winpr-handle)
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
|
||||
|
@ -18,6 +18,15 @@
|
||||
set(MODULE_NAME "winpr-synch")
|
||||
set(MODULE_PREFIX "WINPR_SYNCH")
|
||||
|
||||
INCLUDE (CheckLibraryExists)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_library_exists(pthread pthread_tryjoin_np "" HAVE_PTHREAD_GNU_EXT)
|
||||
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
|
||||
if(HAVE_PTHREAD_GNU_EXT)
|
||||
add_definitions(-D_GNU_SOURCE -DHAVE_PTHREAD_GNU_EXT)
|
||||
endif(HAVE_PTHREAD_GNU_EXT)
|
||||
|
||||
include_directories(../thread)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
@ -53,7 +62,7 @@ endif()
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
|
||||
MODULE winpr
|
||||
MODULES winpr-handle)
|
||||
MODULES winpr-handle winpr-interlocked winpr-thread)
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
@ -64,3 +73,6 @@ endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Norbert Federa <norbert.federa@thinstuff.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,6 +23,9 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/interlocked.h>
|
||||
#include <winpr/thread.h>
|
||||
|
||||
#include "synch.h"
|
||||
|
||||
@ -33,56 +37,79 @@
|
||||
|
||||
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
if (lpCriticalSection)
|
||||
{
|
||||
lpCriticalSection->DebugInfo = NULL;
|
||||
|
||||
lpCriticalSection->LockCount = 0;
|
||||
lpCriticalSection->RecursionCount = 0;
|
||||
lpCriticalSection->SpinCount = 0;
|
||||
|
||||
lpCriticalSection->OwningThread = NULL;
|
||||
lpCriticalSection->LockSemaphore = NULL;
|
||||
|
||||
lpCriticalSection->LockSemaphore = (winpr_sem_t*) malloc(sizeof(winpr_sem_t));
|
||||
#if defined __APPLE__
|
||||
semaphore_create(mach_task_self(), lpCriticalSection->LockSemaphore, SYNC_POLICY_FIFO, 1);
|
||||
#else
|
||||
sem_init(lpCriticalSection->LockSemaphore, 0, 1);
|
||||
#endif
|
||||
}
|
||||
InitializeCriticalSectionEx(lpCriticalSection, 0, 0);
|
||||
}
|
||||
|
||||
BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags)
|
||||
{
|
||||
/**
|
||||
* See http://msdn.microsoft.com/en-us/library/ff541979(v=vs.85).aspx
|
||||
* - The LockCount field indicates the number of times that any thread has
|
||||
* called the EnterCriticalSection routine for this critical section,
|
||||
* minus one. This field starts at -1 for an unlocked critical section.
|
||||
* Each call of EnterCriticalSection increments this value; each call of
|
||||
* LeaveCriticalSection decrements it.
|
||||
* - The RecursionCount field indicates the number of times that the owning
|
||||
* thread has called EnterCriticalSection for this critical section.
|
||||
*/
|
||||
|
||||
if (Flags != 0) {
|
||||
fprintf(stderr, "warning: InitializeCriticalSectionEx Flags unimplemented\n");
|
||||
}
|
||||
|
||||
lpCriticalSection->DebugInfo = NULL;
|
||||
lpCriticalSection->LockCount = -1;
|
||||
lpCriticalSection->SpinCount = 0;
|
||||
lpCriticalSection->RecursionCount = 0;
|
||||
lpCriticalSection->OwningThread = NULL;
|
||||
|
||||
lpCriticalSection->LockSemaphore = (winpr_sem_t*) malloc(sizeof(winpr_sem_t));
|
||||
#if defined(__APPLE__)
|
||||
semaphore_create(mach_task_self(), lpCriticalSection->LockSemaphore, SYNC_POLICY_FIFO, 0);
|
||||
#else
|
||||
sem_init(lpCriticalSection->LockSemaphore, 0, 0);
|
||||
#endif
|
||||
|
||||
SetCriticalSectionSpinCount(lpCriticalSection, dwSpinCount);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount)
|
||||
{
|
||||
return TRUE;
|
||||
return InitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, 0);
|
||||
}
|
||||
|
||||
DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount)
|
||||
{
|
||||
#if !defined(WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT)
|
||||
SYSTEM_INFO sysinfo;
|
||||
DWORD dwPreviousSpinCount = lpCriticalSection->SpinCount;
|
||||
|
||||
if (dwSpinCount)
|
||||
{
|
||||
/* Don't spin on uniprocessor systems! */
|
||||
GetNativeSystemInfo(&sysinfo);
|
||||
if (sysinfo.dwNumberOfProcessors < 2)
|
||||
dwSpinCount = 0;
|
||||
}
|
||||
lpCriticalSection->SpinCount = dwSpinCount;
|
||||
return dwPreviousSpinCount;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
#if defined(__APPLE__)
|
||||
semaphore_wait(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
#else
|
||||
sem_wait((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_signal(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
@ -91,13 +118,118 @@ VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if !defined(WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT)
|
||||
ULONG SpinCount = lpCriticalSection->SpinCount;
|
||||
|
||||
/* If we're lucky or if the current thread is already owner we can return early */
|
||||
if (SpinCount && TryEnterCriticalSection(lpCriticalSection))
|
||||
return;
|
||||
|
||||
/* Spin requested times but don't compete with another waiting thread */
|
||||
while (SpinCount-- && lpCriticalSection->LockCount < 1)
|
||||
{
|
||||
/* Atomically try to acquire and check the if the section is free. */
|
||||
if (InterlockedCompareExchange(&lpCriticalSection->LockCount, 0, -1) == -1)
|
||||
{
|
||||
lpCriticalSection->RecursionCount = 1;
|
||||
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
|
||||
return;
|
||||
}
|
||||
/* Failed to get the lock. Let the scheduler know that we're spinning. */
|
||||
if (sched_yield()!=0)
|
||||
{
|
||||
/**
|
||||
* On some operating systems sched_yield is a stub.
|
||||
* usleep should at least trigger a context switch if any thread is waiting.
|
||||
* A ThreadYield() would be nice in winpr ...
|
||||
*/
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* First try the fastest posssible path to get the lock. */
|
||||
if (InterlockedIncrement(&lpCriticalSection->LockCount))
|
||||
{
|
||||
/* Section is already locked. Check if it is owned by the current thread. */
|
||||
if (lpCriticalSection->OwningThread == (HANDLE)GetCurrentThreadId())
|
||||
{
|
||||
/* Recursion. No need to wait. */
|
||||
lpCriticalSection->RecursionCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Section is locked by another thread. We have to wait. */
|
||||
_WaitForCriticalSection(lpCriticalSection);
|
||||
}
|
||||
/* We got the lock. Own it ... */
|
||||
lpCriticalSection->RecursionCount = 1;
|
||||
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
|
||||
}
|
||||
|
||||
BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
HANDLE current_thread = (HANDLE)GetCurrentThreadId();
|
||||
|
||||
/* Atomically acquire the the lock if the section is free. */
|
||||
if (InterlockedCompareExchange(&lpCriticalSection->LockCount, 0, -1 ) == -1)
|
||||
{
|
||||
lpCriticalSection->RecursionCount = 1;
|
||||
lpCriticalSection->OwningThread = current_thread;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Section is already locked. Check if it is owned by the current thread. */
|
||||
if (lpCriticalSection->OwningThread == current_thread)
|
||||
{
|
||||
/* Recursion, return success */
|
||||
lpCriticalSection->RecursionCount++;
|
||||
InterlockedIncrement(&lpCriticalSection->LockCount);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
/* Decrement RecursionCount and check if this is the last LeaveCriticalSection call ...*/
|
||||
if (--lpCriticalSection->RecursionCount < 1)
|
||||
{
|
||||
/* Last recursion, clear owner, unlock and if there are other waiting threads ... */
|
||||
lpCriticalSection->OwningThread = NULL;
|
||||
if (InterlockedDecrement(&lpCriticalSection->LockCount) >= 0)
|
||||
{
|
||||
/* ...signal the semaphore to unblock the next waiting thread */
|
||||
_UnWaitCriticalSection(lpCriticalSection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedDecrement(&lpCriticalSection->LockCount);
|
||||
}
|
||||
}
|
||||
|
||||
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
lpCriticalSection->LockCount = -1;
|
||||
lpCriticalSection->SpinCount = 0;
|
||||
lpCriticalSection->RecursionCount = 0;
|
||||
lpCriticalSection->OwningThread = NULL;
|
||||
|
||||
if (lpCriticalSection->LockSemaphore != NULL)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
#else
|
||||
sem_destroy((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
sem_destroy((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
#endif
|
||||
free(lpCriticalSection->LockSemaphore);
|
||||
lpCriticalSection->LockSemaphore = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
3
winpr/libwinpr/synch/test/.gitignore
vendored
Normal file
3
winpr/libwinpr/synch/test/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
TestSynch
|
||||
TestSynch.c
|
||||
|
31
winpr/libwinpr/synch/test/CMakeLists.txt
Normal file
31
winpr/libwinpr/synch/test/CMakeLists.txt
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
set(MODULE_NAME "TestSynch")
|
||||
set(MODULE_PREFIX "TEST_SYNCH")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestSynchCritical.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-synch winpr-sysinfo)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
|
329
winpr/libwinpr/synch/test/TestSynchCritical.c
Normal file
329
winpr/libwinpr/synch/test/TestSynchCritical.c
Normal file
@ -0,0 +1,329 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/windows.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
|
||||
#define TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS 500
|
||||
#define TEST_SYNC_CRITICAL_TEST1_RUNS 4
|
||||
|
||||
CRITICAL_SECTION critical;
|
||||
LONG gTestValueVulnerable = 0;
|
||||
LONG gTestValueSerialized = 0;
|
||||
|
||||
BOOL TestSynchCritical_TriggerAndCheckRaceCondition(HANDLE OwningThread, LONG RecursionCount)
|
||||
{
|
||||
/* if called unprotected this will hopefully trigger a race condition ... */
|
||||
gTestValueVulnerable++;
|
||||
|
||||
if (critical.OwningThread != OwningThread)
|
||||
{
|
||||
printf("CriticalSection failure: OwningThread is invalid\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (critical.RecursionCount != RecursionCount)
|
||||
{
|
||||
printf("CriticalSection failure: RecursionCount is invalid\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ... which we try to detect using the serialized counter */
|
||||
if (gTestValueVulnerable != InterlockedIncrement(&gTestValueSerialized))
|
||||
{
|
||||
printf("CriticalSection failure: Data corruption detected\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* this thread function shall increment the global dwTestValue until the PBOOL passsed in arg is FALSE */
|
||||
static PVOID TestSynchCritical_Test1(PVOID arg)
|
||||
{
|
||||
int i, j, rc;
|
||||
HANDLE hThread = (HANDLE)GetCurrentThreadId();
|
||||
|
||||
PBOOL pbContinueRunning = (PBOOL)arg;
|
||||
|
||||
while(*pbContinueRunning)
|
||||
{
|
||||
EnterCriticalSection(&critical);
|
||||
|
||||
rc = 1;
|
||||
|
||||
if (!TestSynchCritical_TriggerAndCheckRaceCondition(hThread, rc))
|
||||
return (PVOID)1;
|
||||
|
||||
/* add some random recursion level */
|
||||
j = rand()%5;
|
||||
for (i=0; i<j; i++)
|
||||
{
|
||||
if (!TestSynchCritical_TriggerAndCheckRaceCondition(hThread, rc++))
|
||||
return (PVOID)2;
|
||||
EnterCriticalSection(&critical);
|
||||
}
|
||||
for (i=0; i<j; i++)
|
||||
{
|
||||
if (!TestSynchCritical_TriggerAndCheckRaceCondition(hThread, rc--))
|
||||
return (PVOID)2;
|
||||
LeaveCriticalSection(&critical);
|
||||
}
|
||||
|
||||
if (!TestSynchCritical_TriggerAndCheckRaceCondition(hThread, rc))
|
||||
return (PVOID)3;
|
||||
|
||||
LeaveCriticalSection(&critical);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this thread function tries to call TryEnterCriticalSection while the main thread holds the lock */
|
||||
static PVOID TestSynchCritical_Test2(PVOID arg)
|
||||
{
|
||||
if (TryEnterCriticalSection(&critical)==TRUE)
|
||||
{
|
||||
LeaveCriticalSection(&critical);
|
||||
return (PVOID)1;
|
||||
}
|
||||
return (PVOID)0;
|
||||
}
|
||||
|
||||
|
||||
static PVOID TestSynchCritical_Main(PVOID arg)
|
||||
{
|
||||
int i, j;
|
||||
SYSTEM_INFO sysinfo;
|
||||
DWORD dwPreviousSpinCount;
|
||||
DWORD dwSpinCount;
|
||||
DWORD dwSpinCountExpected;
|
||||
HANDLE hMainThread;
|
||||
HANDLE* hThreads;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadCount;
|
||||
DWORD dwThreadExitCode;
|
||||
BOOL bTest1Running;
|
||||
|
||||
PBOOL pbThreadTerminated = (PBOOL)arg;
|
||||
|
||||
GetNativeSystemInfo(&sysinfo);
|
||||
|
||||
hMainThread = (HANDLE)GetCurrentThreadId();
|
||||
|
||||
/**
|
||||
* Test SpinCount in SetCriticalSectionSpinCount, InitializeCriticalSectionEx and InitializeCriticalSectionAndSpinCount
|
||||
* SpinCount must be forced to be zero on on uniprocessor systems and on systems
|
||||
* where WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT is defined
|
||||
*/
|
||||
|
||||
dwSpinCount = 100;
|
||||
InitializeCriticalSectionEx(&critical, dwSpinCount, 0);
|
||||
while(--dwSpinCount)
|
||||
{
|
||||
dwPreviousSpinCount = SetCriticalSectionSpinCount(&critical, dwSpinCount);
|
||||
dwSpinCountExpected = 0;
|
||||
#if !defined(WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT)
|
||||
if (sysinfo.dwNumberOfProcessors > 1)
|
||||
dwSpinCountExpected = dwSpinCount+1;
|
||||
#endif
|
||||
if (dwPreviousSpinCount != dwSpinCountExpected)
|
||||
{
|
||||
printf("CriticalSection failure: SetCriticalSectionSpinCount returned %lu (expected: %lu)\n", dwPreviousSpinCount, dwSpinCountExpected);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&critical);
|
||||
|
||||
if (dwSpinCount%2==0)
|
||||
InitializeCriticalSectionAndSpinCount(&critical, dwSpinCount);
|
||||
else
|
||||
InitializeCriticalSectionEx(&critical, dwSpinCount, 0);
|
||||
}
|
||||
DeleteCriticalSection(&critical);
|
||||
|
||||
|
||||
/**
|
||||
* Test single-threaded recursive TryEnterCriticalSection/EnterCriticalSection/LeaveCriticalSection
|
||||
*
|
||||
*/
|
||||
|
||||
InitializeCriticalSection(&critical);
|
||||
|
||||
for (i=0; i<1000; i++)
|
||||
{
|
||||
if (critical.RecursionCount != i)
|
||||
{
|
||||
printf("CriticalSection failure: RecursionCount field is %ld instead of %d.\n", critical.RecursionCount, i);
|
||||
goto fail;
|
||||
}
|
||||
if (i%2==0)
|
||||
{
|
||||
EnterCriticalSection(&critical);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryEnterCriticalSection(&critical) == FALSE)
|
||||
{
|
||||
printf("CriticalSection failure: TryEnterCriticalSection failed where it should not.\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (critical.OwningThread != hMainThread)
|
||||
{
|
||||
printf("CriticalSection failure: Could not verify section ownership (loop index=%d).\n", i);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
while (--i >= 0)
|
||||
{
|
||||
LeaveCriticalSection(&critical);
|
||||
if (critical.RecursionCount != i)
|
||||
{
|
||||
printf("CriticalSection failure: RecursionCount field is %ld instead of %d.\n", critical.RecursionCount, i);
|
||||
goto fail;
|
||||
}
|
||||
if (critical.OwningThread != (HANDLE)(i ? hMainThread : NULL))
|
||||
{
|
||||
printf("CriticalSection failure: Could not verify section ownership (loop index=%d).\n", i);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
DeleteCriticalSection(&critical);
|
||||
|
||||
|
||||
/**
|
||||
* Test using multiple threads modifying the same value
|
||||
*/
|
||||
|
||||
dwThreadCount = sysinfo.dwNumberOfProcessors > 1 ? sysinfo.dwNumberOfProcessors : 2;
|
||||
|
||||
hThreads = (HANDLE*)calloc(dwThreadCount, sizeof(HANDLE));
|
||||
|
||||
for (j=0; j < TEST_SYNC_CRITICAL_TEST1_RUNS; j++)
|
||||
{
|
||||
dwSpinCount = j * 1000;
|
||||
InitializeCriticalSectionAndSpinCount(&critical, dwSpinCount);
|
||||
|
||||
gTestValueVulnerable = 0;
|
||||
gTestValueSerialized = 0;
|
||||
|
||||
/* the TestSynchCritical_Test1 threads shall run until bTest1Running is FALSE */
|
||||
bTest1Running = TRUE;
|
||||
for (i=0; i<dwThreadCount; i++) {
|
||||
hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TestSynchCritical_Test1, &bTest1Running, 0, NULL);
|
||||
}
|
||||
/* let it run for TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS ... */
|
||||
Sleep(TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS);
|
||||
bTest1Running = FALSE;
|
||||
|
||||
for (i=0; i<dwThreadCount; i++)
|
||||
{
|
||||
if (WaitForSingleObject(hThreads[i], INFINITE) != WAIT_OBJECT_0)
|
||||
{
|
||||
printf("CriticalSection failure: Failed to wait for thread #%d\n", i);
|
||||
goto fail;
|
||||
}
|
||||
GetExitCodeThread(hThreads[i], &dwThreadExitCode);
|
||||
if(dwThreadExitCode != 0)
|
||||
{
|
||||
printf("CriticalSection failure: Thread #%d returned error code %lu\n", i, dwThreadExitCode);
|
||||
goto fail;
|
||||
}
|
||||
CloseHandle(hThreads[i]);
|
||||
}
|
||||
|
||||
if (gTestValueVulnerable != gTestValueSerialized)
|
||||
{
|
||||
printf("CriticalSection failure: unexpected test value %ld (expected %ld)\n", gTestValueVulnerable, gTestValueSerialized);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&critical);
|
||||
}
|
||||
|
||||
free(hThreads);
|
||||
|
||||
|
||||
/**
|
||||
* TryEnterCriticalSection in thread must fail if we hold the lock in the main thread
|
||||
*/
|
||||
|
||||
InitializeCriticalSection(&critical);
|
||||
|
||||
if (TryEnterCriticalSection(&critical) == FALSE)
|
||||
{
|
||||
printf("CriticalSection failure: TryEnterCriticalSection unexpectedly failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
/* This thread tries to call TryEnterCriticalSection which must fail */
|
||||
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TestSynchCritical_Test2, NULL, 0, NULL);
|
||||
if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0)
|
||||
{
|
||||
printf("CriticalSection failure: Failed to wait for thread\n");
|
||||
goto fail;
|
||||
}
|
||||
GetExitCodeThread(hThread, &dwThreadExitCode);
|
||||
if(dwThreadExitCode != 0)
|
||||
{
|
||||
printf("CriticalSection failure: Thread returned error code %lu\n", dwThreadExitCode);
|
||||
goto fail;
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
|
||||
*pbThreadTerminated = TRUE; /* requ. for winpr issue, see below */
|
||||
return (PVOID)0;
|
||||
|
||||
fail:
|
||||
*pbThreadTerminated = TRUE; /* requ. for winpr issue, see below */
|
||||
return (PVOID)1;
|
||||
}
|
||||
|
||||
|
||||
int TestSynchCritical(int argc, char* argv[])
|
||||
{
|
||||
BOOL bThreadTerminated = FALSE;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadExitCode;
|
||||
DWORD dwDeadLockDetectionTimeMs;
|
||||
int i;
|
||||
|
||||
dwDeadLockDetectionTimeMs = 2 * TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS * TEST_SYNC_CRITICAL_TEST1_RUNS;
|
||||
|
||||
printf("Deadlock will be assumed after %lu ms.\n", dwDeadLockDetectionTimeMs);
|
||||
|
||||
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TestSynchCritical_Main, &bThreadTerminated, 0, NULL);
|
||||
|
||||
/**
|
||||
* We have to be able to detect dead locks in this test.
|
||||
* At the time of writing winpr's WaitForSingleObject has not implemented timeout for thread wait
|
||||
*
|
||||
* Workaround checking the value of bThreadTerminated which is passed in the thread arg
|
||||
*/
|
||||
|
||||
for (i=0; i<dwDeadLockDetectionTimeMs; i+=100)
|
||||
{
|
||||
if (bThreadTerminated)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
if (!bThreadTerminated)
|
||||
{
|
||||
printf("CriticalSection failure: Possible dead lock detected\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
GetExitCodeThread(hThread, &dwThreadExitCode);
|
||||
CloseHandle(hThread);
|
||||
|
||||
if(dwThreadExitCode != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -25,6 +25,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
@ -43,6 +45,18 @@
|
||||
|
||||
#include "../handle/handle.h"
|
||||
|
||||
static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
|
||||
{
|
||||
ts->tv_sec += dwMilliseconds / 1000L;
|
||||
ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L;
|
||||
|
||||
while(ts->tv_nsec >= 1000000000L)
|
||||
{
|
||||
ts->tv_sec ++;
|
||||
ts->tv_nsec -= 1000000000L;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
ULONG Type;
|
||||
@ -53,22 +67,37 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
|
||||
if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
int status;
|
||||
int status = 0;
|
||||
WINPR_THREAD* thread;
|
||||
void* thread_status = NULL;
|
||||
|
||||
if (dwMilliseconds != INFINITE)
|
||||
fprintf(stderr, "WaitForSingleObject: timeout not implemented for thread wait\n");
|
||||
|
||||
thread = (WINPR_THREAD*) Object;
|
||||
|
||||
status = pthread_join(thread->thread, &thread_status);
|
||||
if (thread->started)
|
||||
{
|
||||
if (dwMilliseconds != INFINITE)
|
||||
{
|
||||
#if HAVE_PTHREAD_GNU_EXT
|
||||
struct timespec timeout;
|
||||
|
||||
if (status != 0)
|
||||
fprintf(stderr, "WaitForSingleObject: pthread_join failure: %d\n", status);
|
||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||
ts_add_ms(&timeout, dwMilliseconds);
|
||||
|
||||
if (thread_status)
|
||||
thread->dwExitCode = ((DWORD) (size_t) thread_status);
|
||||
status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout);
|
||||
#else
|
||||
fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__);
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
status = pthread_join(thread->thread, &thread_status);
|
||||
|
||||
if (status != 0)
|
||||
fprintf(stderr, "WaitForSingleObject: pthread_join failure: %d\n", status);
|
||||
|
||||
if (thread_status)
|
||||
thread->dwExitCode = ((DWORD) (size_t) thread_status);
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_MUTEX)
|
||||
{
|
||||
@ -76,10 +105,19 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
|
||||
mutex = (WINPR_MUTEX*) Object;
|
||||
|
||||
#if HAVE_PTHREAD_GNU_EXT
|
||||
if (dwMilliseconds != INFINITE)
|
||||
fprintf(stderr, "WaitForSingleObject: timeout not implemented for mutex wait\n");
|
||||
{
|
||||
struct timespec timeout;
|
||||
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||
ts_add_ms(&timeout, dwMilliseconds);
|
||||
|
||||
pthread_mutex_timedlock(&mutex->mutex, &timeout);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_EVENT)
|
||||
{
|
||||
@ -165,6 +203,8 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
|
||||
DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
@ -186,7 +226,10 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if (bWaitAll)
|
||||
{
|
||||
fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (index = 0; index < nCount; index++)
|
||||
{
|
||||
@ -261,11 +304,15 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
|
||||
DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,18 +83,18 @@ BOOL ArrayList_IsSynchronized(wArrayList* arrayList)
|
||||
* Lock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Lock(wArrayList* arrayList)
|
||||
void ArrayList_Lock(wArrayList* arrayList)
|
||||
{
|
||||
return (WaitForSingleObject(arrayList->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Unlock(wArrayList* arrayList)
|
||||
void ArrayList_Unlock(wArrayList* arrayList)
|
||||
{
|
||||
return ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +164,7 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
int index;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -177,7 +177,7 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
arrayList->size = 0;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,10 +187,10 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -204,7 +204,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
int index;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (arrayList->size + 1 > arrayList->capacity)
|
||||
{
|
||||
@ -216,7 +216,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
index = arrayList->size;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -228,7 +228,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
void ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -237,7 +237,7 @@ void ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,7 +250,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -265,7 +265,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
ArrayList_Shift(arrayList, index, -1);
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -275,7 +275,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
void ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -283,7 +283,7 @@ void ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,7 +302,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
@ -323,7 +323,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -344,7 +344,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
@ -365,7 +365,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -390,7 +390,7 @@ wArrayList* ArrayList_New(BOOL synchronized)
|
||||
|
||||
arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity);
|
||||
|
||||
arrayList->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000);
|
||||
|
||||
ZeroMemory(&arrayList->object, sizeof(wObject));
|
||||
}
|
||||
@ -402,7 +402,7 @@ void ArrayList_Free(wArrayList* arrayList)
|
||||
{
|
||||
ArrayList_Clear(arrayList);
|
||||
|
||||
CloseHandle(arrayList->mutex);
|
||||
DeleteCriticalSection(&arrayList->lock);
|
||||
free(arrayList->array);
|
||||
free(arrayList);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
void* buffer = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -64,7 +64,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@ -76,7 +76,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
@ -87,7 +87,7 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
pool->array[(pool->size)++] = buffer;
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +97,7 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
void BufferPool_Clear(wBufferPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->size > 0)
|
||||
{
|
||||
@ -110,7 +110,7 @@ void BufferPool_Clear(wBufferPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
|
||||
pool->synchronized = synchronized;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
|
||||
|
||||
if (!pool->fixedSize)
|
||||
{
|
||||
@ -156,7 +156,7 @@ void BufferPool_Free(wBufferPool* pool)
|
||||
BufferPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->array);
|
||||
|
||||
|
@ -89,14 +89,14 @@ HANDLE CountdownEvent_WaitHandle(wCountdownEvent* countdown)
|
||||
|
||||
void CountdownEvent_AddCount(wCountdownEvent* countdown, DWORD signalCount)
|
||||
{
|
||||
WaitForSingleObject(countdown->mutex, INFINITE);
|
||||
EnterCriticalSection(&countdown->lock);
|
||||
|
||||
countdown->count += signalCount;
|
||||
|
||||
if (countdown->count > 0)
|
||||
ResetEvent(countdown->event);
|
||||
|
||||
ReleaseMutex(countdown->mutex);
|
||||
LeaveCriticalSection(&countdown->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +111,7 @@ BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount)
|
||||
|
||||
status = newStatus = oldStatus = FALSE;
|
||||
|
||||
WaitForSingleObject(countdown->mutex, INFINITE);
|
||||
EnterCriticalSection(&countdown->lock);
|
||||
|
||||
if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
|
||||
oldStatus = TRUE;
|
||||
@ -130,7 +130,7 @@ BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount)
|
||||
status = TRUE;
|
||||
}
|
||||
|
||||
ReleaseMutex(countdown->mutex);
|
||||
LeaveCriticalSection(&countdown->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -158,7 +158,7 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount)
|
||||
{
|
||||
countdown->count = initialCount;
|
||||
countdown->initialCount = initialCount;
|
||||
countdown->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000);
|
||||
countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (countdown->count == 0)
|
||||
@ -170,7 +170,7 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount)
|
||||
|
||||
void CountdownEvent_Free(wCountdownEvent* countdown)
|
||||
{
|
||||
CloseHandle(countdown->mutex);
|
||||
DeleteCriticalSection(&countdown->lock);
|
||||
CloseHandle(countdown->event);
|
||||
|
||||
free(countdown);
|
||||
|
@ -69,7 +69,7 @@ BOOL MessageQueue_Wait(wMessageQueue* queue)
|
||||
|
||||
void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
{
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
{
|
||||
@ -100,7 +100,7 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
if (queue->size > 0)
|
||||
SetEvent(queue->event);
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam)
|
||||
@ -127,7 +127,7 @@ int MessageQueue_Get(wMessageQueue* queue, wMessage* message)
|
||||
if (!MessageQueue_Wait(queue))
|
||||
return status;
|
||||
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -142,7 +142,7 @@ int MessageQueue_Get(wMessageQueue* queue, wMessage* message)
|
||||
status = (message->id != WMQ_QUIT) ? 1 : 0;
|
||||
}
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -151,7 +151,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -169,7 +169,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove)
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -194,7 +194,7 @@ wMessageQueue* MessageQueue_New()
|
||||
queue->array = (wMessage*) malloc(sizeof(wMessage) * queue->capacity);
|
||||
ZeroMemory(queue->array, sizeof(wMessage) * queue->capacity);
|
||||
|
||||
queue->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&queue->lock, 4000);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ wMessageQueue* MessageQueue_New()
|
||||
void MessageQueue_Free(wMessageQueue* queue)
|
||||
{
|
||||
CloseHandle(queue->event);
|
||||
CloseHandle(queue->mutex);
|
||||
DeleteCriticalSection(&queue->lock);
|
||||
|
||||
free(queue->array);
|
||||
free(queue);
|
||||
|
@ -43,7 +43,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
void* obj = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (pool->size > 0)
|
||||
obj = pool->array[--(pool->size)];
|
||||
@ -55,7 +55,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -67,7 +67,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
@ -78,7 +78,7 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
pool->array[(pool->size)++] = obj;
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +88,7 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
void ObjectPool_Clear(wObjectPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->size > 0)
|
||||
{
|
||||
@ -99,7 +99,7 @@ void ObjectPool_Clear(wObjectPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +119,7 @@ wObjectPool* ObjectPool_New(BOOL synchronized)
|
||||
pool->synchronized = synchronized;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
|
||||
|
||||
pool->size = 0;
|
||||
pool->capacity = 32;
|
||||
@ -136,7 +136,7 @@ void ObjectPool_Free(wObjectPool* pool)
|
||||
ObjectPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->array);
|
||||
|
||||
|
@ -46,14 +46,14 @@ wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count)
|
||||
* Methods
|
||||
*/
|
||||
|
||||
BOOL PubSub_Lock(wPubSub* pubSub)
|
||||
void PubSub_Lock(wPubSub* pubSub)
|
||||
{
|
||||
return (WaitForSingleObject(pubSub->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
BOOL PubSub_Unlock(wPubSub* pubSub)
|
||||
void PubSub_Unlock(wPubSub* pubSub)
|
||||
{
|
||||
return ReleaseMutex(pubSub->mutex);
|
||||
LeaveCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
|
||||
@ -202,7 +202,7 @@ wPubSub* PubSub_New(BOOL synchronized)
|
||||
pubSub->synchronized = synchronized;
|
||||
|
||||
if (pubSub->synchronized)
|
||||
pubSub->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000);
|
||||
|
||||
pubSub->count = 0;
|
||||
pubSub->size = 64;
|
||||
@ -219,7 +219,7 @@ void PubSub_Free(wPubSub* pubSub)
|
||||
if (pubSub)
|
||||
{
|
||||
if (pubSub->synchronized)
|
||||
CloseHandle(pubSub->mutex);
|
||||
DeleteCriticalSection(&pubSub->lock);
|
||||
|
||||
if (pubSub->events)
|
||||
free(pubSub->events);
|
||||
|
@ -47,18 +47,18 @@ int Queue_Count(wQueue* queue)
|
||||
* Lock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL Queue_Lock(wQueue* queue)
|
||||
void Queue_Lock(wQueue* queue)
|
||||
{
|
||||
return (WaitForSingleObject(queue->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL Queue_Unlock(wQueue* queue)
|
||||
void Queue_Unlock(wQueue* queue)
|
||||
{
|
||||
return ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +83,7 @@ void Queue_Clear(wQueue* queue)
|
||||
int index;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
for (index = queue->head; index != queue->tail; index = (index + 1) % queue->capacity)
|
||||
{
|
||||
@ -97,7 +97,7 @@ void Queue_Clear(wQueue* queue)
|
||||
queue->head = queue->tail = 0;
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +110,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
for (index = 0; index < queue->tail; index++)
|
||||
{
|
||||
@ -122,7 +122,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
}
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
@ -134,7 +134,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
{
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
{
|
||||
@ -162,7 +162,7 @@ void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
SetEvent(queue->event);
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,7 +174,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -188,7 +188,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
ResetEvent(queue->event);
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -202,13 +202,13 @@ void* Queue_Peek(wQueue* queue)
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
obj = queue->array[queue->head];
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -243,7 +243,7 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
||||
queue->array = (void**) malloc(sizeof(void*) * queue->capacity);
|
||||
ZeroMemory(queue->array, sizeof(void*) * queue->capacity);
|
||||
|
||||
queue->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&queue->lock, 4000);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
ZeroMemory(&queue->object, sizeof(wObject));
|
||||
@ -257,7 +257,7 @@ void Queue_Free(wQueue* queue)
|
||||
Queue_Clear(queue);
|
||||
|
||||
CloseHandle(queue->event);
|
||||
CloseHandle(queue->mutex);
|
||||
DeleteCriticalSection(&queue->lock);
|
||||
free(queue->array);
|
||||
free(queue);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr)
|
||||
wReference* reference = NULL;
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
WaitForSingleObject(referenceTable->mutex, INFINITE);
|
||||
EnterCriticalSection(&referenceTable->lock);
|
||||
|
||||
reference = ReferenceTable_FindEntry(referenceTable, ptr);
|
||||
|
||||
@ -102,7 +102,7 @@ UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr)
|
||||
count = ++(reference->Count);
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
ReleaseMutex(referenceTable->mutex);
|
||||
LeaveCriticalSection(&referenceTable->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -113,7 +113,7 @@ UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr)
|
||||
wReference* reference = NULL;
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
WaitForSingleObject(referenceTable->mutex, INFINITE);
|
||||
EnterCriticalSection(&referenceTable->lock);
|
||||
|
||||
reference = ReferenceTable_FindEntry(referenceTable, ptr);
|
||||
|
||||
@ -133,7 +133,7 @@ UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr)
|
||||
}
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
ReleaseMutex(referenceTable->mutex);
|
||||
LeaveCriticalSection(&referenceTable->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -154,7 +154,7 @@ wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context, REFERENCE_
|
||||
ZeroMemory(referenceTable->array, sizeof(wReference) * referenceTable->size);
|
||||
|
||||
referenceTable->synchronized = synchronized;
|
||||
referenceTable->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&referenceTable->lock, 4000);
|
||||
}
|
||||
|
||||
return referenceTable;
|
||||
@ -164,7 +164,7 @@ void ReferenceTable_Free(wReferenceTable* referenceTable)
|
||||
{
|
||||
if (referenceTable)
|
||||
{
|
||||
CloseHandle(referenceTable->mutex);
|
||||
DeleteCriticalSection(&referenceTable->lock);
|
||||
free(referenceTable->array);
|
||||
free(referenceTable);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ BOOL Stack_Contains(wStack* stack, void* obj)
|
||||
void Stack_Push(wStack* stack, void* obj)
|
||||
{
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if ((stack->size + 1) >= stack->capacity)
|
||||
{
|
||||
@ -95,7 +95,7 @@ void Stack_Push(wStack* stack, void* obj)
|
||||
stack->array[(stack->size)++] = obj;
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,13 +107,13 @@ void* Stack_Pop(wStack* stack)
|
||||
void* obj = NULL;
|
||||
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if (stack->size > 0)
|
||||
obj = stack->array[--(stack->size)];
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -127,13 +127,13 @@ void* Stack_Peek(wStack* stack)
|
||||
void* obj = NULL;
|
||||
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if (stack->size > 0)
|
||||
obj = stack->array[stack->size];
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -153,7 +153,7 @@ wStack* Stack_New(BOOL synchronized)
|
||||
stack->synchronized = synchronized;
|
||||
|
||||
if (stack->synchronized)
|
||||
stack->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&stack->lock, 4000);
|
||||
|
||||
stack->size = 0;
|
||||
stack->capacity = 32;
|
||||
@ -168,7 +168,7 @@ void Stack_Free(wStack* stack)
|
||||
if (stack)
|
||||
{
|
||||
if (stack->synchronized)
|
||||
CloseHandle(stack->mutex);
|
||||
DeleteCriticalSection(&stack->lock);
|
||||
|
||||
free(stack->array);
|
||||
|
||||
|
@ -44,7 +44,8 @@ void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count)
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wStream*));
|
||||
if (pool->uSize - index + count > 0)
|
||||
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index + count) * sizeof(wStream*));
|
||||
pool->uSize += count;
|
||||
}
|
||||
}
|
||||
@ -101,7 +102,8 @@ void StreamPool_ShiftAvailable(wStreamPool* pool, int index, int count)
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wStream*));
|
||||
if (pool->aSize - index + count > 0)
|
||||
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index + count) * sizeof(wStream*));
|
||||
pool->aSize += count;
|
||||
}
|
||||
}
|
||||
@ -118,7 +120,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (size == 0)
|
||||
size = pool->defaultSize;
|
||||
@ -153,7 +155,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
StreamPool_AddUsed(pool, s);
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -165,7 +167,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->aSize + 1) >= pool->aCapacity)
|
||||
{
|
||||
@ -177,7 +179,7 @@ void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
StreamPool_RemoveUsed(pool, s);
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +188,7 @@ void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
|
||||
void StreamPool_Lock(wStreamPool* pool)
|
||||
{
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +197,7 @@ void StreamPool_Lock(wStreamPool* pool)
|
||||
|
||||
void StreamPool_Unlock(wStreamPool* pool)
|
||||
{
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +243,7 @@ wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
|
||||
wStream* s = NULL;
|
||||
BOOL found = FALSE;
|
||||
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
for (index = 0; index < pool->uSize; index++)
|
||||
{
|
||||
@ -254,7 +256,7 @@ wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return (found) ? s : NULL;
|
||||
}
|
||||
@ -294,7 +296,7 @@ void StreamPool_Release(wStreamPool* pool, BYTE* ptr)
|
||||
void StreamPool_Clear(wStreamPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->aSize > 0)
|
||||
{
|
||||
@ -303,7 +305,7 @@ void StreamPool_Clear(wStreamPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,8 +325,7 @@ wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize)
|
||||
pool->synchronized = synchronized;
|
||||
pool->defaultSize = defaultSize;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
|
||||
|
||||
pool->aSize = 0;
|
||||
pool->aCapacity = 32;
|
||||
@ -344,8 +345,7 @@ void StreamPool_Free(wStreamPool* pool)
|
||||
{
|
||||
StreamPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->aArray);
|
||||
free(pool->uArray);
|
||||
|
Loading…
Reference in New Issue
Block a user