Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

101
third_party/FreeRDP/scripts/LECHash.c vendored Normal file
View File

@@ -0,0 +1,101 @@
#include <stdio.h>
typedef unsigned short UINT16;
static UINT16 HuffCodeLEC[] = {
0x0004, 0x0024, 0x0014, 0x0011, 0x0051, 0x0031, 0x0071, 0x0009, 0x0049, 0x0029, 0x0069, 0x0015,
0x0095, 0x0055, 0x00d5, 0x0035, 0x00b5, 0x0075, 0x001d, 0x00f5, 0x011d, 0x009d, 0x019d, 0x005d,
0x000d, 0x008d, 0x015d, 0x00dd, 0x01dd, 0x003d, 0x013d, 0x00bd, 0x004d, 0x01bd, 0x007d, 0x006b,
0x017d, 0x00fd, 0x01fd, 0x0003, 0x0103, 0x0083, 0x0183, 0x026b, 0x0043, 0x016b, 0x036b, 0x00eb,
0x0143, 0x00c3, 0x02eb, 0x01c3, 0x01eb, 0x0023, 0x03eb, 0x0123, 0x00a3, 0x01a3, 0x001b, 0x021b,
0x0063, 0x011b, 0x0163, 0x00e3, 0x00cd, 0x01e3, 0x0013, 0x0113, 0x0093, 0x031b, 0x009b, 0x029b,
0x0193, 0x0053, 0x019b, 0x039b, 0x005b, 0x025b, 0x015b, 0x035b, 0x0153, 0x00d3, 0x00db, 0x02db,
0x01db, 0x03db, 0x003b, 0x023b, 0x013b, 0x01d3, 0x033b, 0x00bb, 0x02bb, 0x01bb, 0x03bb, 0x007b,
0x002d, 0x027b, 0x017b, 0x037b, 0x00fb, 0x02fb, 0x01fb, 0x03fb, 0x0007, 0x0207, 0x0107, 0x0307,
0x0087, 0x0287, 0x0187, 0x0387, 0x0033, 0x0047, 0x0247, 0x0147, 0x0347, 0x00c7, 0x02c7, 0x01c7,
0x0133, 0x03c7, 0x0027, 0x0227, 0x0127, 0x0327, 0x00a7, 0x00b3, 0x0019, 0x01b3, 0x0073, 0x02a7,
0x0173, 0x01a7, 0x03a7, 0x0067, 0x00f3, 0x0267, 0x0167, 0x0367, 0x00e7, 0x02e7, 0x01e7, 0x03e7,
0x01f3, 0x0017, 0x0217, 0x0117, 0x0317, 0x0097, 0x0297, 0x0197, 0x0397, 0x0057, 0x0257, 0x0157,
0x0357, 0x00d7, 0x02d7, 0x01d7, 0x03d7, 0x0037, 0x0237, 0x0137, 0x0337, 0x00b7, 0x02b7, 0x01b7,
0x03b7, 0x0077, 0x0277, 0x07ff, 0x0177, 0x0377, 0x00f7, 0x02f7, 0x01f7, 0x03f7, 0x03ff, 0x000f,
0x020f, 0x010f, 0x030f, 0x008f, 0x028f, 0x018f, 0x038f, 0x004f, 0x024f, 0x014f, 0x034f, 0x00cf,
0x000b, 0x02cf, 0x01cf, 0x03cf, 0x002f, 0x022f, 0x010b, 0x012f, 0x032f, 0x00af, 0x02af, 0x01af,
0x008b, 0x03af, 0x006f, 0x026f, 0x018b, 0x016f, 0x036f, 0x00ef, 0x02ef, 0x01ef, 0x03ef, 0x001f,
0x021f, 0x011f, 0x031f, 0x009f, 0x029f, 0x019f, 0x039f, 0x005f, 0x004b, 0x025f, 0x015f, 0x035f,
0x00df, 0x02df, 0x01df, 0x03df, 0x003f, 0x023f, 0x013f, 0x033f, 0x00bf, 0x02bf, 0x014b, 0x01bf,
0x00ad, 0x00cb, 0x01cb, 0x03bf, 0x002b, 0x007f, 0x027f, 0x017f, 0x012b, 0x037f, 0x00ff, 0x02ff,
0x00ab, 0x01ab, 0x006d, 0x0059, 0x17ff, 0x0fff, 0x0039, 0x0079, 0x01ff, 0x0005, 0x0045, 0x0034,
0x000c, 0x002c, 0x001c, 0x0000, 0x003c, 0x0002, 0x0022, 0x0010, 0x0012, 0x0008, 0x0032, 0x000a,
0x002a, 0x001a, 0x003a, 0x0006, 0x0026, 0x0016, 0x0036, 0x000e, 0x002e, 0x001e, 0x003e, 0x0001,
0x00ed, 0x0018, 0x0021, 0x0025, 0x0065
};
UINT16 HashTable[512] = { [0 ... 511] = 0xffff };
static UINT16 tab[8] = { 511, 0, 508, 448, 494, 347, 486, 482 };
UINT16 hash(UINT16 key)
{
UINT16 h;
h = (key & 0x1ff) ^ (key >> 9) ^ (key >> 4) ^ (key >> 7);
return h;
}
UINT16 minihash(UINT16 key)
{
UINT16 h;
h = ((((key >> 8) ^ (key & 0xff)) >> 2) & 0xf);
if (key >> 9)
h = ~h;
return (h % 12);
}
void buildhashtable(void)
{
for (int i = 0; i < 293; i++)
{
UINT16 h = hash(HuffCodeLEC[i]);
if (HashTable[h] != 0xffff)
{
HashTable[h] ^= (HuffCodeLEC[i] & 0xfe00) ^ 0xfe00;
HashTable[tab[minihash(HuffCodeLEC[i])]] = i;
}
else
{
HashTable[h] = i;
HashTable[h] ^= 0xfe00;
}
}
}
UINT16 getvalue(UINT16 huff)
{
UINT16 h = HashTable[hash(huff)];
if ((h ^ huff) >> 9)
return h & 0x1ff;
else
return HashTable[tab[minihash(huff)]];
}
main()
{
buildhashtable();
printf("static UINT16 HuffIndexLEC[512] = {\n");
for (int i = 0; i < 512; i++)
{
if (i == 511)
printf("0x%04" PRIx16 " };\n", HashTable[i]);
else
printf("0x%04" PRIx16 ", ", HashTable[i]);
}
for (int i = 0; i < 293; i++)
if (i != getvalue(HuffCodeLEC[i]))
printf("Fail :( at %d : 0x%04" PRIx16 "\n", i, HuffCodeLEC[i]);
return 0;
}

77
third_party/FreeRDP/scripts/LOMHash.c vendored Normal file
View File

@@ -0,0 +1,77 @@
#include <stdio.h>
typedef unsigned short UINT16;
typedef unsigned char BYTE;
static UINT16 HuffCodeLOM[] = { 0x0001, 0x0000, 0x0002, 0x0009, 0x0006, 0x0005, 0x000d, 0x000b,
0x0003, 0x001b, 0x0007, 0x0017, 0x0037, 0x000f, 0x004f, 0x006f,
0x002f, 0x00ef, 0x001f, 0x005f, 0x015f, 0x009f, 0x00df, 0x01df,
0x003f, 0x013f, 0x00bf, 0x01bf, 0x007f, 0x017f, 0x00ff, 0x01ff };
UINT16 HashTable[32] = { [0 ... 31] = 0xffff };
BYTE tab[4] = { 0, 4, 10, 19 };
UINT16 hash(UINT16 key)
{
return ((key & 0x1f) ^ (key >> 5) ^ (key >> 9));
}
BYTE minihash(UINT16 key)
{
BYTE h;
h = (key >> 4) & 0xf;
return ((h ^ (h >> 2) ^ (h >> 3)) & 0x3);
}
void buildhashtable(void)
{
for (int i = 0; i < 32; i++)
{
UINT16 h = hash(HuffCodeLOM[i]);
if (HashTable[h] != 0xffff)
{
HashTable[h] ^= (HuffCodeLOM[i] & 0xfe0) ^ 0xfe0;
HashTable[tab[minihash(HuffCodeLOM[i])]] = i;
}
else
{
HashTable[h] = i;
HashTable[h] ^= 0xfe0;
}
printf("at %d %" PRIu16 "=0x%" PRIx16 "\n", i, h, HashTable[h]);
}
}
BYTE getvalue(UINT16 huff)
{
UINT16 h = HashTable[hash(huff)];
if ((h ^ huff) >> 5)
{
return h & 0x1f;
}
else
return HashTable[tab[minihash(huff)]];
}
main()
{
buildhashtable();
printf("static UINT16 HuffIndexLOM[32] = {\n");
for (int i = 0; i < 32; i++)
{
if (i == 31)
printf("0x%" PRIx16 " };\n", HashTable[i]);
else
printf("0x%" PRIx16 ", ", HashTable[i]);
}
for (int i = 0; i < 32; i++)
if (i != getvalue(HuffCodeLOM[i]))
printf("Fail :( at %d : 0x%04" PRIx16 " got %" PRIu8 "\n", i, HuffCodeLOM[i],
getvalue(HuffCodeLOM[i]));
return 0;
}

View File

@@ -0,0 +1,153 @@
#!/bin/bash -xe
#
# Copyright 2015 Thincast Technologies GmbH
#
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This script will download and build openssl for iOS and simulator - see ARCHS for architectures built
## Settings
# openssl version to use
OPENSSLVERSION="3.4.0"
SHA256SUM="e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf"
# SDK version to use - if not set latest version found is used
SDK_VERSION=""
# Minimum SDK version the application supports
MIN_SDK_VERSION="15.0"
## Defaults
INSTALLDIR="external"
# Architectures to build
ARCHS="arm64 x86_64"
# Use default SDK version if not set
if [ -z ${SDK_VERSION} ]; then
SDK_VERSION=`xcrun -sdk iphoneos --show-sdk-version`
fi
CORES=`sysctl hw.ncpu | awk '{print $2}'`
MAKEOPTS="-j $CORES"
DEVELOPER=`xcode-select -print-path`
if [ ! -d "$DEVELOPER" ]; then
echo "xcode path is not set correctly $DEVELOPER does not exist (most likely because of xcode > 4.3)"
echo "run"
echo "sudo xcode-select -switch <xcode path>"
echo "for default installation:"
echo "sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer"
exit 1
fi
# Functions
function buildArch(){
ARCH=$1
if [[ "${ARCH}" == "i386" || "${ARCH}" == "x86_64" ]];
then
PLATFORM="iPhoneSimulator"
else
sed -ie "s!static volatile intr_signal;!static volatile sig_atomic_t intr_signal;!" "crypto/ui/ui_openssl.c"
PLATFORM="iPhoneOS"
fi
export CROSS_TOP="${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer"
export CROSS_SDK="${PLATFORM}${SDK_VERSION}.sdk"
export BUILD_TOOLS="${DEVELOPER}"
export CC="${BUILD_TOOLS}/usr/bin/gcc -arch ${ARCH}"
if [ ! -z $MIN_SDK_VERSION ]; then
export CC="$CC -miphoneos-version-min=${MIN_SDK_VERSION}"
fi
echo "Building openssl-${OPENSSLVERSION} for ${PLATFORM} ${SDK_VERSION} ${ARCH} (min SDK set: ${MIN_SDK_VERSION:-"none"})"
LOGFILE="BuildLog.darwin-${ARCH}.txt"
echo -n " Please wait ..."
if [[ "$OPENSSLVERSION" =~ 1.0.0. ]]; then
CONFIG_ARGS=BSD-generic32
elif [ "${ARCH}" == "x86_64" ]; then
CONFIG_ARGS=darwin64-x86_64-cc
elif [ "${ARCH}" == "i386" ]; then
CONFIG_ARGS="iphoneos-cross no-asm"
else
CONFIG_ARGS=iphoneos-cross
fi
./Configure $CONFIG_ARGS 2>&1 | tee ${LOGFILE}
make ${MAKEOPTS} 2>&1 | tee ${LOGFILE}
echo " Done. Build log saved in ${LOGFILE}"
cp libcrypto.a ../../lib/libcrypto_${ARCH}.a
cp libssl.a ../../lib/libssl_${ARCH}.a
make clean 2>&1 | tee ${LOGFILE}
}
# main
if [ $# -gt 0 ];then
INSTALLDIR=$1
if [ ! -d $INSTALLDIR ];then
echo "Install directory \"$INSTALLDIR\" does not exist"
exit 1
fi
fi
cd $INSTALLDIR
if [ ! -d openssl ];then
mkdir openssl
fi
cd openssl
CS=`shasum -a 256 "openssl-$OPENSSLVERSION.tar.gz" | cut -d ' ' -f1`
if [ ! "$CS" = "$SHA256SUM" ]; then
echo "Downloading OpenSSL Version $OPENSSLVERSION ..."
rm -f "openssl-$OPENSSLVERSION.tar.gz"
curl -Lo openssl-$OPENSSLVERSION.tar.gz https://github.com/openssl/openssl/releases/download/openssl-$OPENSSLVERSION/openssl-$OPENSSLVERSION.tar.gz
CS=`shasum -a 256 "openssl-$OPENSSLVERSION.tar.gz" | cut -d ' ' -f1`
if [ ! "$CS" = "$SHA256SUM" ]; then
echo "Download failed or invalid checksum. Have a nice day."
exit 1
fi
fi
# remove old build dir
rm -rf openssltmp
mkdir openssltmp
cd openssltmp
echo "Unpacking OpenSSL ..."
tar xfz "../openssl-$OPENSSLVERSION.tar.gz"
if [ ! $? = 0 ]; then
echo "Unpacking failed."
exit 1
fi
echo
cd "openssl-$OPENSSLVERSION"
case `pwd` in
*\ * )
echo "The build path (`pwd`) contains whitespaces - fix this."
exit 1
;;
esac
# Cleanup old build artifacts
rm -rf ../../include
mkdir -p ../../include
rm -rf ../../lib
mkdir -p ../../lib
for i in ${ARCHS}; do
buildArch $i
done
echo "Copying header files ..."
cp -r include/ ../../include/
echo
echo "Combining to universal binary"
lipo -create ../../lib/libcrypto_*.a -o ../../lib/libcrypto.a
lipo -create ../../lib/libssl_*.a -o ../../lib/libssl.a
echo "Finished. Please verify the contents of the openssl folder in \"$INSTALLDIR\""

21
third_party/FreeRDP/scripts/abi-diff.sh vendored Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash -xe
#
SCRIPT_NAME="${BASH_SOURCE[0]}"
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
if [ $# -ne 1 ]; then
echo "$0 <reference commit or tag>"
exit 1
fi
BASE_REF=$1
cd "$SCRIPT_PATH/.."
mkdir -p abi-checker
cp ci/cmake-preloads/config-abi.txt abi-checker/
cp scripts/abi-suppr.txt abi-checker/
curl https://gist.githubusercontent.com/akallabeth/aa35caed0d39241fa17c3dc8a0539ea3/raw/ef12f8c720ac6be51aa1878710e2502b1b39cf4c/check-abi -o abi-checker/check-abi
chmod +x abi-checker/check-abi
./abi-checker/check-abi -s abi-checker/abi-suppr.txt --parameters="-Cabi-checker/config-abi.txt" $BASE_REF $(git rev-parse HEAD)

View File

@@ -0,0 +1,292 @@
# settings are opaque, ignore all changes
[suppress_type]
type_kind = struct
name = rdp_settings
# allow insertions at end of structs
[suppress_type]
type_kind = struct
has_data_members_inserted_at = end
# winpr_strerror did use unsigned instead of signed int as argument
[suppress_function]
change_kind = function-subtype-change
name = winpr_strerror
parameter = '0 INT32
# NtStatus2Tag did use unsigned instead of signed NTSTATUS as argument
[suppress_function]
change_kind = function-subtype-change
name = NtStatus2Tag
parameter = '0 NTSTATUS
# rdpdr_write_iocompletion_header did use unsigned instead of signed NTSTATUS as argument
[suppress_function]
change_kind = function-subtype-change
name = rdpdr_write_iocompletion_header
parameter = '3 NTSTATUS
# smartcard_irp_device_control_call did use unsigned instead of signed NTSTATUS as argument
[suppress_function]
change_kind = function-subtype-change
name = smartcard_irp_device_control_call
parameter = '2 NTSTATUS*
# freerdp_passphrase_read did not return const char* but char*
[suppress_function]
change_kind = function-subtype-change
name = freerdp_passphrase_read
return_type_name = const char*
[suppress_type]
change_kind = enum
name = FreeRDP_Settings_Keys_UInt32
changed_enumerators = FreeRDP_MonitorLocalShiftX, FreeRDP_MonitorLocalShiftY
# gdi_graphics_pipeline_init_ex subtype change (__uint32 to uint32_t)
[suppress_type]
change_kind = typedef
name = UINT
[suppress_type]
change_kind = typedef
name = UINT16
[suppress_type]
change_kind = typedef
name = UINT32
[suppress_type]
change_kind = typedef
name = UINT64
# msusb_msconfig_dump did use MSUSB_CONFIG_DESCRIPTOR* instead of const MSUSB_CONFIG_DESCRIPTOR*
[suppress_function]
change_kind = function-subtype-change
name = msusb_msconfig_dump
[suppress_function]
change_kind = function-subtype-change
name = gdi_CopyRect
parameter = '0 GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = gdi_CopyRect
parameter = '1 const GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = gdi_EqualRgn
[suppress_function]
change_kind = function-subtype-change
name = gdi_CRectToRgn
parameter = '4 GDI_RGN*
[suppress_function]
change_kind = function-subtype-change
name = gdi_CreateRect
[suppress_function]
change_kind = function-subtype-change
name = gdi_CreateRectRgn
[suppress_function]
change_kind = function-subtype-change
name = gdi_RectToRgn
parameter = '1 GDI_RGN*
[suppress_function]
change_kind = function-subtype-change
name = gdi_SetRgn
parameter = '0 GDI_RGN*
[suppress_function]
change_kind = function-subtype-change
name = gdi_RgnToRect
parameter = '1 GDI_RGN*
[suppress_function]
change_kind = function-subtype-change
name = gdi_SetRectRgn
parameter = '0 GDI_RGN*
[suppress_function]
change_kind = function-subtype-change
name = gdi_SetRect
parameter = '0 GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = gdi_PtInRect
[suppress_function]
change_kind = function-subtype-change
name = gdi_FillRect
[suppress_function]
change_kind = function-subtype-change
name = gdi_RgnToRect
parameter = '1 GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = gdi_CRgnToRect
parameter = '4 GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = gdi_RectToCRgn
[suppress_function]
change_kind = function-subtype-change
name = gdi_RgnToCRect
[suppress_function]
change_kind = function-subtype-change
name = gdi_CRgnToRect
parameter = '4 GDI_RECT*
[suppress_function]
change_kind = function-subtype-change
name = freerdp_client_settings_parse_command_line_arguments_ex
parameter = '6 freerdp_command_line_handle_option_t
[suppress_function]
change_kind = function-subtype-change
name = freerdp_shall_disconnect_context
[suppress_function]
change_kind = function-subtype-change
name = GetDynamicTimeZoneInformationEffectiveYears
[suppress_type]
change_kind = typedef
name = SEC_WINNT_AUTH_IDENTITY_INFO
[suppress_function]
change_kind = function-subtype-change
parameter = '0 /.*restrict.*/
[suppress_function]
change_kind = function-subtype-change
parameter = '1 /.*restrict.*/
[suppress_function]
change_kind = function-subtype-change
parameter = '7 /.*restrict.*/
[suppress_function]
change_kind = function-subtype-change
name = shadow_server_command_line_status_print
parameter = '4 /.*const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_error_info
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_get_disconnect_ultimatum
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_get_last_error
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_get_transport_sent
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_nego_get_routing_token
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_shall_disconnect
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = getChannelError
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = getChannelErrorDescription
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = freerdp_get_nla_sspi_error
parameter = '0 /^const.*/
[suppress_function]
change_kind = function-subtype-change
name = msusb_msconfig_free
[suppress_function]
change_kind = function-subtype-change
name = msusb_msconfig_new
[suppress_function]
change_kind = function-subtype-change
name = msusb_msinterface_free
# Functions not actually part of the API
# These were not hidden in versions < 3.23.0
# ignore these.
[suppress_function]
change_kind = deleted-function
name = add_device
[suppress_function]
change_kind = deleted-function
name = del_device
[suppress_function]
change_kind = deleted-function
name = msusb_msconfig_dump
[suppress_function]
change_kind = deleted-function
name = msusb_msconfig_free
[suppress_function]
change_kind = deleted-function
name = msusb_msconfig_new
[suppress_function]
change_kind = deleted-function
name = msusb_msconfig_read
[suppress_function]
change_kind = deleted-function
name = msusb_msconfig_write
[suppress_function]
change_kind = deleted-function
name = msusb_msinterface_free
[suppress_function]
change_kind = deleted-function
name = msusb_msinterface_read
[suppress_function]
change_kind = deleted-function
name = msusb_msinterface_replace
[suppress_function]
change_kind = deleted-function
name = msusb_msinterface_write
[suppress_function]
change_kind = deleted-function
name = msusb_mspipes_replace

View File

@@ -0,0 +1,36 @@
#!/bin/bash
#
# Android build configuration
#
# Note: This is a simple configuration to build all
# architectures in one rush.
# Since android 64 bit support was introduced with NDK API 21
# this is the minimal common denominator.
# If you require support for older NDK API levels,
# create separate configurations for each NDK API level
# and architecture you want to support.
WITH_OPENH264=0
WITH_OPENSSL=1
WITH_FFMPEG=1
WITH_AAD=1
BUILD_DEPS=1
DEPS_ONLY=0
NDK_TARGET=21
WITH_MEDIACODEC=0
OPENH264_TAG=v2.6.0
OPENH264_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
OPENSSL_TAG=openssl-3.5.3
OPENSSL_HASH=c9489d2abcf943cdc8329a57092331c598a402938054dc3a22218aea8a8ec3bf
FFMPEG_TAG=n7.1.2
FFMPEG_HASH=8cb1bb8cfa9aeae13279b4da42ae8307ae6777456d4270f2e603c95aa08ca8ef
CJSON_TAG=v1.7.19
CJSON_HASH=7fa616e3046edfa7a28a32d5f9eacfd23f92900fe1f8ccd988c1662f30454562
SRC_DIR=$SCRIPT_PATH/..
BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs
BUILD_SRC=$SRC_DIR/build
CMAKE_BUILD_TYPE=Release
BUILD_ARCH="armeabi-v7a x86"

View File

@@ -0,0 +1,36 @@
#!/bin/bash
#
# Android build configuration
#
# Note: This is a simple configuration to build all
# architectures in one rush.
# Since android 64 bit support was introduced with NDK API 21
# this is the minimal common denominator.
# If you require support for older NDK API levels,
# create separate configurations for each NDK API level
# and architecture you want to support.
WITH_OPENH264=1
WITH_OPENSSL=1
WITH_FFMPEG=1
WITH_AAD=1
BUILD_DEPS=1
DEPS_ONLY=0
NDK_TARGET=21
WITH_MEDIACODEC=0
OPENH264_TAG=v2.6.0
OPENH264_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
OPENSSL_TAG=openssl-3.5.3
OPENSSL_HASH=c9489d2abcf943cdc8329a57092331c598a402938054dc3a22218aea8a8ec3bf
FFMPEG_TAG=n7.1.2
FFMPEG_HASH=8cb1bb8cfa9aeae13279b4da42ae8307ae6777456d4270f2e603c95aa08ca8ef
CJSON_TAG=v1.7.19
CJSON_HASH=7fa616e3046edfa7a28a32d5f9eacfd23f92900fe1f8ccd988c1662f30454562
SRC_DIR=$SCRIPT_PATH/..
BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs
BUILD_SRC=$SRC_DIR/build
CMAKE_BUILD_TYPE=Release
BUILD_ARCH="arm64-v8a x86_64"

View File

@@ -0,0 +1,40 @@
#!/bin/bash
SCM_URL=https://github.com/DaveGamble/cJSON/archive
SCM_TAG=v1.7.18
SCM_HASH=451131a92c55efc5457276807fc0c4c2c2707c9ee96ef90c47d68852d5384c6c
source $(dirname "${BASH_SOURCE[0]}")/android-build-common.sh
# Run the main program.
common_parse_arguments $@
common_update $SCM_URL $SCM_TAG $BUILD_SRC $SCM_HASH
# Prepare the environment
common_run mkdir -p $BUILD_SRC
CMAKE_CMD_ARGS="-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_NATIVE_API_LEVEL=android-${NDK_TARGET} \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
-DENABLE_CJSON_TEST=OFF \
-DENABLE_HIDDEN_SYMBOLS=OFF \
-DCMAKE_MAKE_PROGRAM=make"
BASE=$(pwd)
for ARCH in $BUILD_ARCH; do
common_run cd $BASE
common_run mkdir -p $BUILD_SRC/cJSON-build/$ARCH
common_run cd $BUILD_SRC/cJSON-build/$ARCH
common_run export ANDROID_NDK=$ANDROID_NDK
common_run $CMAKE_PROGRAM $CMAKE_CMD_ARGS \
-DANDROID_ABI=$ARCH \
-DCMAKE_INSTALL_PREFIX=$BUILD_DST/$ARCH \
-DCMAKE_INSTALL_LIBDIR=. \
-B . \
-S $BUILD_SRC
echo $(pwd)
common_run $CMAKE_PROGRAM --build . --target install
done
echo "Successfully build library for architectures $BUILD_ARCH"

View File

@@ -0,0 +1,309 @@
#!/bin/bash -x
SCRIPT_NAME="${BASH_SOURCE[0]}"
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
FIND_ARGS="-type f -print -quit"
case "$(uname -s)" in
Darwin)
FIND_ARGS="-perm +111 $FIND_ARGS"
;;
*)
FIND_ARGS="-executable $FIND_ARGS"
;;
esac
if [ -z $BUILD_ARCH ]; then
BUILD_ARCH="armeabi-v7a x86 x86_64 arm64-v8a"
fi
if [ -z $NDK_TARGET ]; then
NDK_TARGET=21
fi
if [ -z $CMAKE_PROGRAM ]; then
CMAKE_PROGRAM="cmake-missing"
fi
if [ -z $CCACHE ]; then
CCACHE=$(which ccache)
fi
if [ -z $ANDROID_NDK ]; then
ANDROID_NDK="ndk-missing"
fi
if [ -z $ANDROID_SDK ]; then
ANDROID_SDK="sdk-missing"
fi
if [ -z $BUILD_DST ]; then
BUILD_DST=$(pwd)/libs
fi
if [ -z $BUILD_SRC ]; then
BUILD_SRC=$(pwd)/src
fi
if [ -z $SCM_URL ]; then
SCM_URL="missing"
fi
if [ -z $SCM_TAG ]; then
SCM_TAG=master
fi
if [ -z $SCM_HASH ]; then
SCM_HASH="missing"
fi
CLEAN_BUILD_DIR=0
function common_help {
echo "$SCRIPT_NAME supports the following arguments:"
echo " --ndk The base directory of your android NDK defa"
echo " ANDROID_NDK=$ANDROID_NDK"
echo " --sdk The base directory of your android SDK defa"
echo " ANDROID_SDK=$ANDROID_SDK"
echo " --arch A list of architectures to build"
echo " BUILD_ARCH=$BUILD_ARCH"
echo " --dst The destination directory for include and library files"
echo " BUILD_DST=$BUILD_DST"
echo " --src The source directory for SCM checkout"
echo " BUILD_SRC=$BUILD_SRC"
echo " --url The SCM source url"
echo " SCM_URL=$SCM_URL"
echo " --tag The SCM branch or tag to check out"
echo " SCM_TAG=$SCM_TAG"
echo " --hash The SCM commit or hash to check out"
echo " SCM_HASH=$SCM_HASH"
echo " --clean Clean the destination before build"
echo " --help Display this help"
exit 0
}
function common_run {
echo "[RUN] $@"
"$@"
RES=$?
if [[ $RES -ne 0 ]]; then
echo "[ERROR] $@ returned $RES"
exit 1
fi
}
function common_check_requirements {
if [[ ! -d $ANDROID_NDK ]]; then
echo "export ANDROID_NDK to point to your NDK location."
exit 1
fi
if [[ ! -d $ANDROID_SDK ]]; then
echo "export ANDROID_SDK to point to your SDK location."
exit 1
fi
if [[ -z $BUILD_DST ]]; then
echo "Destination directory not valid"
exit 1
fi
if [[ -z $BUILD_SRC ]]; then
echo "Source directory not valid"
exit 1
fi
if [[ -z $SCM_URL ]]; then
echo "Source URL not defined! Define SCM_URL"
exit 1
fi
if [[ -z $SCM_TAG ]]; then
echo "SCM_TAG / BRANCH not defined! Define SCM_TAG"
exit 1
fi
if [[ -z $SCM_HASH ]]; then
echo "SCM_HASH not defined! Define SCM_HASH"
exit 1
fi
if [[ -z $NDK_TARGET ]]; then
echo "Android platform NDK_TARGET not defined"
exit 1
fi
if [ -z $CMAKE_PROGRAM ] || [ "$CMAKE_PROGRAM" == "cmake-missing" ]; then
CMAKE_PROGRAM=$(find $ANDROID_SDK/cmake -name cmake $FIND_ARGS)
if [ -z $CMAKE_PROGRAM ]; then
echo "CMake not found in $ANDROID_SDK, install CMake from the android SDK!"
exit 1
fi
fi
for CMD in make git $CMAKE_PROGRAM; do
if ! type $CMD >/dev/null; then
echo "Command $CMD not found. Install and add it to the PATH."
exit 1
fi
done
if [ "${BUILD_SRC:0:1}" != "/" ]; then
BUILD_SRC=$(pwd)/$BUILD_SRC
fi
if [ "${BUILD_DST:0:1}" != "/" ]; then
BUILD_DST=$(pwd)/$BUILD_DST
fi
}
function common_parse_arguments {
while [[ $# > 0 ]]; do
key="$1"
case $key in
--conf)
source "$2" || exit 1
shift
;;
--target)
NDK_TARGET="$2"
shift
;;
--ndk)
ANDROID_NDK="$2"
shift
;;
--sdk)
ANDROID_SDK="$2"
shift
;;
--arch)
BUILD_ARCH="$2"
shift
;;
--dst)
BUILD_DST="$2"
shift
;;
--src)
BUILD_SRC="$2"
shift
;;
--url)
SCM_URL="$2"
shift
;;
--tag)
SCM_TAG="$2"
shift
;;
--hash)
SCM_HASH="$2"
shift
;;
--clean)
CLEAN_BUILD_DIR=1
shift
;;
--help)
common_help
shift
;;
*) # Unknown
;;
esac
shift
done
common_check_requirements
}
function common_update {
if [ $# -ne 4 ]; then
echo "Invalid arguments to update function $@"
exit 1
fi
SCM_URL=$1
SCM_TAG=$2
BUILD_SRC=$3
SCM_HASH=$4
echo "Preparing checkout..."
BASE=$(pwd)
CACHE=$(realpath $SCRIPT_PATH/../cache)
common_run mkdir -p $CACHE
TARFILE="$CACHE/$SCM_TAG.tar.gz"
if [[ ! -f "$TARFILE" ]]; then
WGET=$(which wget)
CURL=$(which curl)
if [ -x "$CURL" ]; then
common_run $CURL -L -o "$TARFILE" "$SCM_URL/$SCM_TAG.tar.gz"
elif [ -x "$WGET" ]; then
common_run $WGET -O "$TARFILE" "$SCM_URL/$SCM_TAG.tar.gz"
else
echo "Neither wget nor curl installed, aborting"
exit -1
fi
fi
echo "$SCM_HASH $TARFILE" >$TARFILE.sha256sum
common_run sha256sum -c $TARFILE.sha256sum
if [[ -d $BUILD_SRC ]]; then
common_run rm -rf $BUILD_SRC
fi
common_run mkdir -p $BUILD_SRC
common_run cd $BUILD_SRC
common_run tar zxf "$TARFILE" --strip 1
common_run cd $BASE
}
function common_clean {
if [ $CLEAN_BUILD_DIR -ne 1 ]; then
return
fi
if [ $# -ne 1 ]; then
echo "Invalid arguments to clean function $@"
exit 1
fi
echo "Cleaning up $1..."
common_run rm -rf $1
}
function common_copy {
if [ $# -ne 2 ]; then
echo "Invalid arguments to copy function $@"
exit 1
fi
if [ ! -d $1 ] || [ ! -d $1/include ] || [ ! -d $1/libs ]; then
echo "Invalid source $1"
exit 1
fi
if [ -z $2 ]; then
echo "Invalid destination $2"
exit 1
fi
if [ ! -d $2 ]; then
common_run mkdir -p $2
fi
common_run cp -L -r $1/include $2
common_run cp -L -r $1/libs/* $2
}

View File

@@ -0,0 +1,217 @@
#!/bin/bash
SCM_URL=https://github.com/FFmpeg/FFmpeg/archive
SCM_TAG=n7.1.1
SCM_HASH=f117507dc501f2a6c11f9241d8d0c3213846cfad91764361af37befd6b6c523d
OLD_PATH=$PATH
source $(dirname "${BASH_SOURCE[0]}")/android-build-common.sh
function get_toolchain() {
HOST_OS=$(uname -s)
case ${HOST_OS} in
Darwin) HOST_OS=darwin ;;
Linux) HOST_OS=linux ;;
FreeBsd) HOST_OS=freebsd ;;
CYGWIN* | *_NT-*) HOST_OS=cygwin ;;
esac
HOST_ARCH=$(uname -m)
case ${HOST_ARCH} in
i?86) HOST_ARCH=x86 ;;
x86_64 | amd64) HOST_ARCH=x86_64 ;;
esac
echo "${HOST_OS}-${HOST_ARCH}"
}
function get_build_host() {
case ${ARCH} in
armeabi-v7a)
echo "arm-linux-androideabi"
;;
arm64-v8a)
echo "aarch64-linux-android"
;;
x86)
echo "i686-linux-android"
;;
x86_64)
echo "x86_64-linux-android"
;;
esac
}
function get_clang_target_host() {
case ${ARCH} in
armeabi-v7a)
echo "armv7a-linux-androideabi${NDK_TARGET}"
;;
arm64-v8a)
echo "aarch64-linux-android${NDK_TARGET}"
;;
x86)
echo "i686-linux-android${NDK_TARGET}"
;;
x86_64)
echo "x86_64-linux-android${NDK_TARGET}"
;;
esac
}
function get_arch_specific_ldflags() {
case ${ARCH} in
armeabi-v7a)
echo "-march=armv7-a -mfpu=neon -mfloat-abi=softfp -Wl,--fix-cortex-a8"
;;
arm64-v8a)
echo "-march=armv8-a"
;;
x86)
echo "-march=i686"
;;
x86_64)
echo "-march=x86-64"
;;
esac
}
function set_toolchain_clang_paths {
TOOLCHAIN=$(get_toolchain)
common_run export PATH=$PATH:${ANDROID_NDK}/toolchains/llvm/prebuilt/${TOOLCHAIN}/bin
AR=llvm-ar
NM=llvm-nm
RANLIB=llvm-ranlib
STRIP=llvm-strip
CC=$(get_clang_target_host)-clang
CXX=$(get_clang_target_host)-clang++
case ${ARCH} in
arm64-v8a)
common_run export ac_cv_c_bigendian=no
;;
esac
}
function build {
echo "Building FFmpeg architecture $1..."
BASE=$(pwd)
common_run cd $BUILD_SRC
BUILD_HOST=$(get_build_host)
set_toolchain_clang_paths
LDFLAGS=$(get_arch_specific_ldflags)
CARCH=$TARGET_ARCH
if [ "$CARCH" == "x86_64" ]; then
CARCH="x86-64"
fi
PATH=$ANDROID_NDK:$PATH
common_run ./configure \
--cross-prefix="${BUILD_HOST}-" \
--sysroot="${ANDROID_NDK}/toolchains/llvm/prebuilt/${TOOLCHAIN}/sysroot" \
--arch="${CARCH}" \
--cpu="${TARGET_CPU}" \
--cc="${CC}" \
--cxx="${CXX}" \
--ar="${AR}" \
--nm="${NM}" \
--ranlib="${RANLIB}" \
--strip="${STRIP}" \
--extra-ldflags="${LDFLAGS}" \
--prefix="${BUILD_DST}/${ARCH}" \
--pkg-config="${HOST_PKG_CONFIG_PATH}" \
--target-os=android \
${ARCH_OPTIONS} \
--enable-cross-compile \
--enable-pic \
--enable-lto \
--enable-jni \
--enable-mediacodec \
--enable-shared \
--disable-vulkan \
--disable-stripping \
--disable-programs \
--disable-doc \
--disable-avdevice \
--disable-avfilter \
--disable-avformat \
--disable-everything \
--enable-encoder=aac \
--enable-encoder=libfdk_aac \
--enable-encoder=libgsm \
--enable-encoder=libgsm_ms \
--enable-encoder=libopenh264 \
--enable-encoder=libopus \
--enable-encoder=pcm_alaw \
--enable-encoder=pcm_mulaw \
--enable-encoder=pcm_s16le \
--enable-encoder=pcm_u16le \
--enable-encoder=h264 \
--enable-encoder=h264_omx \
--enable-encoder=h264_mediacodec \
--enable-encoder=h264_vulkan \
--enable-decoder=aac \
--enable-decoder=aac_mediacodec \
--enable-decoder=adpcm_g722 \
--enable-decoder=adpcm_g726 \
--enable-decoder=adpcm_g726le \
--enable-decoder=gsm \
--enable-decoder=gsm_ms \
--enable-decoder=mp3 \
--enable-decoder=mp3_mediacodec \
--enable-decoder=h264 \
--enable-decoder=h264_mediacodec \
--enable-decoder=libopus \
--enable-decoder=pcm_alaw \
--enable-decoder=pcm_mulaw \
--enable-decoder=pcm_s16le \
--enable-decoder=pcm_u16le
common_run make clean
common_run make -j
common_run make install
}
# Run the main program.
common_parse_arguments $@
common_update $SCM_URL $SCM_TAG $BUILD_SRC $SCM_HASH
HOST_PKG_CONFIG_PATH=$(command -v pkg-config)
if [ -z ${HOST_PKG_CONFIG_PATH} ]; then
echo "(*) pkg-config command not found\n"
exit 1
fi
for ARCH in $BUILD_ARCH; do
case ${ARCH} in
armeabi-v7a)
TARGET_CPU="armv7-a"
TARGET_ARCH="armv7-a"
ARCH_OPTIONS=" --enable-neon --enable-asm --enable-inline-asm"
;;
arm64-v8a)
TARGET_CPU="armv8-a"
TARGET_ARCH="aarch64"
ARCH_OPTIONS=" --enable-neon --enable-asm --enable-inline-asm"
;;
x86)
TARGET_CPU="i686"
TARGET_ARCH="i686"
# asm disabled due to this ticker https://trac.ffmpeg.org/ticket/4928
ARCH_OPTIONS=" --disable-neon --disable-asm --disable-inline-asm"
;;
x86_64)
TARGET_CPU="x86_64"
TARGET_ARCH="x86_64"
ARCH_OPTIONS=" --disable-neon --enable-asm --enable-inline-asm"
;;
esac
build
common_run cp -L $BUILD_DST/$ARCH/lib/*.so $BUILD_DST/$ARCH/
common_run export PATH=$OLD_PATH
done

View File

@@ -0,0 +1,204 @@
#!/bin/bash
OPENH264_TAG=v2.6.0
OPENH264_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
OPENSSL_TAG=openssl-3.5.3
OPENSSL_HASH=c9489d2abcf943cdc8329a57092331c598a402938054dc3a22218aea8a8ec3bf
FFMPEG_TAG=n7.1.2
FFMPEG_HASH=7ddad2d992bd250a6c56053c26029f7e728bebf0f37f80cf3f8a0e6ec706431a
CJSON_TAG=v1.7.19
CJSON_HASH=7fa616e3046edfa7a28a32d5f9eacfd23f92900fe1f8ccd988c1662f30454562
WITH_OPENH264=0
WITH_OPENSSL=0
WITH_FFMPEG=0
WITH_AAD=0
SRC_DIR=$(dirname "${BASH_SOURCE[0]}")
SRC_DIR=$(realpath "$SRC_DIR")
BUILD_SRC=$(pwd)
BUILD_DST=$(pwd)
CMAKE_BUILD_TYPE=Debug
BUILD_DEPS=0
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
source $SCRIPT_PATH/android-build-common.sh
source $SCRIPT_PATH/android-build.conf
# Parse arguments.
REMAINING=""
while [[ $# > 0 ]]; do
key="$1"
case $key in
--freerdp-src)
SRC_DIR="$2"
shift
;;
--openh264)
WITH_OPENH264=1
shift
;;
--openh264-ndk)
shift
ANDROID_NDK_OPENH264=$1
shift
;;
--ffmpeg)
WITH_FFMPEG=1
shift
;;
--cjson)
WITH_AAD=1
shift
;;
--openssl)
WITH_OPENSSL=1
shift
;;
--debug)
CMAKE_BUILD_TYPE=Debug
shift
;;
--release)
CMAKE_BUILD_TYPE=Release
shift
;;
--relWithDebug)
CMAKE_BUILD_TYPE=RelWithDebug
shift
;;
--build-deps)
BUILD_DEPS=1
shift
;;
*)
REMAINING="$REMAINING $key"
shift
;;
esac
done
common_parse_arguments $REMAINING
if [ -z ${WITH_MEDIACODEC+x} ]; then
common_run echo "WITH_MEDIACODEC unset, defining WITH_MEDIACODEC=1"
WITH_MEDIACODEC=1
fi
# clean up top
if [ -d $BUILD_SRC ]; then
common_clean $BUILD_SRC
fi
if [ -d $BUILD_DST ]; then
common_run mkdir -p $BUILD_DST
fi
# Prepare the environment
common_run mkdir -p $BUILD_SRC
CMAKE_CMD_ARGS="-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_NATIVE_API_LEVEL=android-${NDK_TARGET} \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
-DFREERDP_EXTERNAL_PATH=$BUILD_DST \
-DWITHOUT_FREERDP_3x_DEPRECATED=ON \
-DWITH_CLIENT_SDL=OFF \
-DWITH_SERVER=OFF \
-DWITH_INTERNAL_RC4=ON \
-DWITH_INTERNAL_MD4=ON \
-DWITH_INTERNAL_MD5=ON \
-DWITH_MANPAGES=OFF \
-DCMAKE_MAKE_PROGRAM=make"
BASE=$(pwd)
for ARCH in $BUILD_ARCH; do
# build dependencies.
if [ $WITH_OPENH264 -ne 0 ]; then
if [ -z "$ANDROID_NDK_OPENH264" ]; then
echo
echo "Warning: Missing openh264-ndk, using $ANDROID_NDK" >&2
echo
ANDROID_NDK_OPENH264=$ANDROID_NDK
fi
if [ $BUILD_DEPS -ne 0 ]; then
common_run bash $SCRIPT_PATH/android-build-openh264.sh \
--src $BUILD_SRC/openh264 --dst $BUILD_DST \
--sdk "$ANDROID_SDK" \
--ndk "$ANDROID_NDK_OPENH264" \
--arch $ARCH \
--target $NDK_TARGET \
--tag $OPENH264_TAG \
--hash $OPENH264_HASH
fi
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_OPENH264=ON"
else
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_OPENH264=OFF"
fi
if [ $WITH_MEDIACODEC -ne 0 ]; then
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_MEDIACODEC=ON"
else
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_MEDIACODEC=OFF"
fi
if [ $WITH_FFMPEG -ne 0 ]; then
if [ $BUILD_DEPS -ne 0 ]; then
common_run bash $SCRIPT_PATH/android-build-ffmpeg.sh \
--src $BUILD_SRC/ffmpeg --dst $BUILD_DST \
--sdk "$ANDROID_SDK" \
--ndk "$ANDROID_NDK" \
--arch $ARCH \
--target $NDK_TARGET \
--tag $FFMPEG_TAG \
--hash $FFMPEG_HASH
fi
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_FFMPEG=ON -DWITH_SWCALE=ON"
else
CMAKE_CMD_ARGS="$CMAKE_CMD_ARGS -DWITH_FFMPEG=OFF -DWITH_SWSCALE=OFF"
fi
if [ $WITH_AAD -ne 0 ]; then
if [ $BUILD_DEPS -ne 0 ]; then
common_run bash $SCRIPT_PATH/android-build-cjson.sh \
--src $BUILD_SRC/cjson --dst $BUILD_DST \
--sdk "$ANDROID_SDK" \
--ndk "$ANDROID_NDK" \
--arch $ARCH \
--target $NDK_TARGET \
--tag $CJSON_TAG \
--hash $CJSON_HASH
fi
fi
if [ $WITH_OPENSSL -ne 0 ]; then
if [ $BUILD_DEPS -ne 0 ]; then
common_run bash $SCRIPT_PATH/android-build-openssl.sh \
--src $BUILD_SRC/openssl --dst $BUILD_DST \
--sdk "$ANDROID_SDK" \
--ndk $ANDROID_NDK \
--arch $ARCH \
--target $NDK_TARGET \
--tag $OPENSSL_TAG \
--hash $OPENSSL_HASH
fi
fi
# Build and install the library.
if [ $DEPS_ONLY -eq 0 ]; then
common_run cd $BASE
common_run mkdir -p $BUILD_SRC/freerdp-build/$ARCH
common_run cd $BUILD_SRC/freerdp-build/$ARCH
common_run export ANDROID_NDK=$ANDROID_NDK
common_run $CMAKE_PROGRAM $CMAKE_CMD_ARGS \
-DANDROID_ABI=$ARCH \
-DCMAKE_INSTALL_PREFIX=$BUILD_DST/$ARCH \
-DCMAKE_INSTALL_LIBDIR=. \
-DCMAKE_PREFIX_PATH=$BUILD_DST/$ARCH \
-DCMAKE_SHARED_LINKER_FLAGS="-L$BUILD_DST/$ARCH" \
-DcJSON_DIR=$BUILD_DST/$ARCH/cmake/cJSON \
$SRC_DIR
echo $(pwd)
common_run $CMAKE_PROGRAM --build . --target install
fi
done
echo "Successfully build library for architectures $BUILD_ARCH"

View File

@@ -0,0 +1,60 @@
#!/bin/bash
SCM_URL=https://github.com/cisco/openh264/archive
SCM_TAG=v2.6.0
SCM_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
source $(dirname "${BASH_SOURCE[0]}")/android-build-common.sh
function build {
echo "Building architecture $1..."
BASE=$(pwd)
common_run cd $BUILD_SRC
PATH=$ANDROID_NDK:$PATH
MAKE="make LDFLAGS=-static-libstdc++ PATH=$PATH ENABLEPIC=Yes OS=android NDKROOT=$ANDROID_NDK NDK_TOOLCHAIN_VERSION=clang TARGET=android-$2 NDKLEVEL=$2 ARCH=$1 -j libraries"
common_run export QUIET_AR="$CCACHE "
common_run export QUIET_ASM="$CCACHE "
common_run export QUIET_CC="$CCACHE "
common_run export QUIET_CCAR="$CCACHE "
common_run export QUIET_CXX="$CCACHE "
common_run $MAKE
# Install creates a non optimal directory layout, fix that
common_run $MAKE PREFIX=$BUILD_SRC/libs/$1 install
common_run cd $BASE
}
# Run the main program.
common_parse_arguments $@
common_update $SCM_URL $SCM_TAG $BUILD_SRC $SCM_HASH
for ARCH in $BUILD_ARCH; do
case $ARCH in
"armeabi")
OARCH="arm"
;;
"armeabi-v7a")
OARCH="arm"
;;
"arm64-v8a")
OARCH="arm64"
;;
*)
OARCH=$ARCH
;;
esac
echo "$ARCH=$OARCH"
build $OARCH $NDK_TARGET
if [ ! -d $BUILD_DST/$ARCH/include ]; then
common_run mkdir -p $BUILD_DST/$ARCH/include
fi
common_run cp -L -r $BUILD_SRC/libs/$OARCH/include/ $BUILD_DST/$ARCH/
if [ ! -d $BUILD_DST/$ARCH ]; then
common_run mkdir -p $BUILD_DST/$ARCH
fi
common_run cp -L $BUILD_SRC/libs/$OARCH/lib/*.so $BUILD_DST/$ARCH/
done

View File

@@ -0,0 +1,83 @@
#!/bin/bash
SCM_URL=https://github.com/openssl/openssl/releases/download/
SCM_TAG=openssl-3.5.0
SCM_HASH=344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0
COMPILER=4.9
source $(dirname "${BASH_SOURCE[0]}")/android-build-common.sh
function build {
if [ $# -ne 2 ]; then
echo "Invalid arguments $@"
exit 1
fi
CONFIG=$1
DST_PREFIX=$2
common_run export CC=clang
common_run export PATH=$(${SCRIPT_PATH}/toolchains_path.py --ndk ${ANDROID_NDK}):$ORG_PATH
common_run export ANDROID_NDK=${ANDROID_NDK}
common_run export ANDROID_NDK_ROOT=${ANDROID_NDK}
common_run export ANDROID_NDK_HOME=${ANDROID_NDK}
echo "CONFIG=$CONFIG"
echo "DST_PREFIX=$DST_PREFIX"
echo "PATH=$PATH"
BASE=$(pwd)
DST_DIR=$BUILD_DST/$DST_PREFIX
common_run cd $BUILD_SRC
common_run ./Configure ${CONFIG} -U__ANDROID_API__ -D__ANDROID_API__=$NDK_TARGET
common_run make SHLIB_EXT=.so -j build_libs
if [ ! -d $DST_DIR ]; then
common_run mkdir -p $DST_DIR
fi
common_run cp *.so $DST_DIR/
common_run cd $BASE
}
# Run the main program.
common_parse_arguments $@
SCM_MOD_TAG=$SCM_TAG
# Workaround for naming of OpenSSL releases changing with every major version
case $SCM_TAG in OpenSSL_*)
SCM_MOD_TAG=${SCM_TAG//OpenSSL_/openssl-}
SCM_MOD_TAG=${SCM_MOD_TAG//_/.}
;;
esac
common_update "$SCM_URL/$SCM_TAG" $SCM_MOD_TAG $BUILD_SRC $SCM_HASH
ORG_PATH=$PATH
for ARCH in $BUILD_ARCH; do
case $ARCH in
"armeabi-v7a")
build "android-arm" "armeabi-v7a"
;;
"x86")
build "android-x86" "x86"
;;
"arm64-v8a")
build "android-arm64" "arm64-v8a"
;;
"x86_64")
build "android-x86_64" "x86_64"
;;
*)
echo "[WARNING] Skipping unsupported architecture $ARCH"
continue
;;
esac
done
if [ ! -d $BUILD_DST/$ARCH/include ]; then
common_run mkdir -p $BUILD_DST/$ARCH/include
fi
common_run cp -L -R $BUILD_SRC/include/openssl $BUILD_DST/$ARCH/include/

View File

@@ -0,0 +1,36 @@
#!/bin/bash
#
# Android build configuration
#
# Note: This is a simple configuration to build all
# architectures in one rush.
# Since android 64 bit support was introduced with NDK API 21
# this is the minimal common denominator.
# If you require support for older NDK API levels,
# create separate configurations for each NDK API level
# and architecture you want to support.
WITH_OPENH264=1
WITH_OPENSSL=1
WITH_FFMPEG=1
WITH_AAD=1
BUILD_DEPS=1
DEPS_ONLY=0
NDK_TARGET=23
WITH_MEDIACODEC=0
OPENH264_TAG=v2.6.0
OPENH264_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
OPENSSL_TAG=openssl-3.5.3
OPENSSL_HASH=c9489d2abcf943cdc8329a57092331c598a402938054dc3a22218aea8a8ec3bf
FFMPEG_TAG=n7.1.2
FFMPEG_HASH=8cb1bb8cfa9aeae13279b4da42ae8307ae6777456d4270f2e603c95aa08ca8ef
CJSON_TAG=v1.7.19
CJSON_HASH=7fa616e3046edfa7a28a32d5f9eacfd23f92900fe1f8ccd988c1662f30454562
SRC_DIR=$SCRIPT_PATH/..
BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs
BUILD_SRC=$SRC_DIR/build
CMAKE_BUILD_TYPE=Release
BUILD_ARCH="armeabi-v7a x86 arm64-v8a x86_64"

View File

@@ -0,0 +1,36 @@
#!/bin/bash
#
# Android build configuration
#
# Note: This is a simple configuration to build all
# architectures in one rush.
# Since android 64 bit support was introduced with NDK API 21
# this is the minimal common denominator.
# If you require support for older NDK API levels,
# create separate configurations for each NDK API level
# and architecture you want to support.
WITH_OPENH264=0
WITH_OPENSSL=1
WITH_FFMPEG=1
WITH_AAD=1
BUILD_DEPS=1
DEPS_ONLY=0
NDK_TARGET=21
WITH_MEDIACODEC=0
OPENH264_TAG=v2.6.0
OPENH264_HASH=558544ad358283a7ab2930d69a9ceddf913f4a51ee9bf1bfb9e377322af81a69
OPENSSL_TAG=openssl-3.5.3
OPENSSL_HASH=c9489d2abcf943cdc8329a57092331c598a402938054dc3a22218aea8a8ec3bf
FFMPEG_TAG=n7.1.2
FFMPEG_HASH=8cb1bb8cfa9aeae13279b4da42ae8307ae6777456d4270f2e603c95aa08ca8ef
CJSON_TAG=v1.7.19
CJSON_HASH=7fa616e3046edfa7a28a32d5f9eacfd23f92900fe1f8ccd988c1662f30454562
SRC_DIR=$SCRIPT_PATH/..
BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs
BUILD_SRC=$SRC_DIR/build
CMAKE_BUILD_TYPE=Debug
BUILD_ARCH="armeabi-v7a arm64-v8a"

32
third_party/FreeRDP/scripts/bash-format.sh vendored Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash -e
#
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
SRC_PATH="${SCRIPT_PATH}/.."
if [ $# -ne 0 ]; then
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "usage: $0 [options]"
echo "\t--check.-c ... run format check only, no files changed (default)"
echo "\t--format,-f ... format files in place"
echo "\t--help,-h ... print this help"
exit 1
fi
if [ "$1" = "--check" ] || [ "$1" = "-c" ]; then
FORMAT_ARG=""
REST_ARGS="${@:2}"
fi
if [ "$1" = "--format" ] || [ "$1" = "-f" ]; then
FORMAT_ARG="-w"
REST_ARGS="${@:2}"
fi
fi
SCRIPTS=$(find ${SRC_PATH} -name "*.sh" -not -path "${SRC_PATH}/.git/*")
for script in $SCRIPTS; do
echo $script
shfmt -i 2 $FORMAT_ARG $script
done

294
third_party/FreeRDP/scripts/bundle-mac-os.sh vendored Executable file
View File

@@ -0,0 +1,294 @@
#!/bin/bash -xe
SCRIPT_PATH="$(dirname -- "${BASH_SOURCE[0]}")" # relative
SCRIPT_PATH="$(cd -- "$SCRIPT_PATH" && pwd)" # absolutized and normalized
BASE=$(pwd)
SRC="$BASE/src"
BUILD="$BASE/build"
INSTALL="$BASE/install/MacFreeRDP.app/Contents"
BINDIR=MacOS
LIBDIR=Frameworks
DATADIR=Resources
DEPLOYMENT_ARCH='arm64 x86_64'
DEPLOYMENT_TARGET=12
usage() {
echo "${BASH_SOURCE[0]} [-a|--arch 'arch1 arch2 ...'] [-t|--target target][-h|--help]"
echo ""
echo "default options:"
echo "arch [$DEPLOYMENT_ARCH]"
echo "target [$DEPLOYMENT_TARGET]"
}
check_tools() {
for TOOL in mkdir rm mv git dirname pwd find cut basename grep xargs cmake ninja autoconf automake aclocal autoheader glibtoolize lipo otool install_name_tool meson; do
set +e
TOOL_PATH=$(which "$TOOL")
set -e
echo "$TOOL: $TOOL_PATH"
if [ ! -f "$TOOL_PATH" ]; then
echo "Missing $TOOL! please install and add to PATH."
exit 1
fi
done
}
while [[ $# -gt 0 ]]; do
case $1 in
-a | --arch)
DEPLOYMENT_ARCH="$2"
shift # past argument
shift # past value
;;
-t | --target)
DEPLOYMENT_TARGET="$2"
shift # past argument
shift # past value
;;
-t | --target)
usage
exit 0
;;
-* | --*)
usage
exit 1
;;
*)
usage
exit 1
;;
esac
done
check_tools
fix_rpath() {
SEARCH_PATH=$1
FIX_PATH=$1
EXT=".dylib"
if [ "$#" -gt 1 ]; then
FIX_PATH=$2
fi
if [ "$#" -gt 2 ]; then
EXT=$3
fi
# some build systems do not handle @rpath on mac os correctly.
# do check that and fix it.
DYLIB_ABS_NAMES=$(find $SEARCH_PATH -type f -name "*$EXT")
for DYLIB_ABS in $DYLIB_ABS_NAMES; do
DYLIB_NAME=$(basename $DYLIB_ABS)
install_name_tool -id @rpath/$DYLIB_NAME $DYLIB_ABS
for DYLIB_DEP in $(otool -L $DYLIB_ABS | grep "$FIX_PATH" | cut -d' ' -f1); do
if [[ $DYLIB_DEP == $DYLIB_ABS ]]; then
continue
elif [[ $DYLIB_DEP == $FIX_PATH/* ]]; then
DEP_BASE=$(basename $DYLIB_DEP)
install_name_tool -change $DYLIB_DEP @rpath/$DEP_BASE $DYLIB_ABS
fi
done
done
}
replace_rpath() {
FILE=$1
for PTH in $(otool -l $FILE | grep -A2 LC_RPATH | grep path | xargs -J ' ' | cut -d ' ' -f2); do
install_name_tool -delete_rpath $PTH $FILE
done
install_name_tool -add_rpath @loader_path/../$LIBDIR $FILE
}
CMAKE_ARCHS=
OSSL_FLAGS="-mmacosx-version-min=$DEPLOYMENT_TARGET -I$INSTALL/include -L$INSTALL/lib"
for ARCH in $DEPLOYMENT_ARCH; do
OSSL_FLAGS="$OSSL_FLAGS -arch $ARCH"
CMAKE_ARCHS="$ARCH;$CMAKE_ARCHS"
done
echo "build arch [$DEPLOYMENT_ARCH]"
echo "build target [$DEPLOYMENT_TARGET]"
CMAKE_ARGS="-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_MANPAGES=OFF \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_OSX_ARCHITECTURES=$CMAKE_ARCHS \
-DCMAKE_OSX_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET \
-DCMAKE_INSTALL_PREFIX='$INSTALL' \
-DCMAKE_INSTALL_LIBDIR='lib' \
-DCMAKE_INSTALL_BINDIR='bin' \
-DCMAKE_INSTALL_DATADIR='$DATADIR' \
-DINSTALL_LIB_DIR='$INSTALL/lib' \
-DINSTALL_BIN_DIR='$INSTALL/bin' \
-DCMAKE_PREFIX_PATH='$INSTALL;$INSTALL/lib;$INSTALL/lib/cmake' \
-DCMAKE_IGNORE_PATH='/opt/local;/usr/local;/opt/homebrew;/Library;~/Library'
-DCMAKE_IGNORE_PREFIX_PATH='/opt/local;/usr/local;/opt/homebrew;/Library;~/Library'
"
if [ ! -d $SRC ]; then
mkdir -p $SRC
cd $SRC
git clone --depth 1 -b openssl-3.6.0 https://github.com/openssl/openssl.git
git clone --depth 1 -b v1.3.1.2 https://github.com/madler/zlib.git
git clone --depth 1 -b uriparser-1.0.0 https://github.com/uriparser/uriparser.git
git clone --depth 1 -b json-c-0.18-20240915 https://github.com/json-c/json-c.git
git clone --depth 1 -b release-3.2.28 https://github.com/libsdl-org/SDL.git
git clone --depth 1 --shallow-submodules --recurse-submodules -b release-3.2.2 https://github.com/libsdl-org/SDL_ttf.git
git clone --depth 1 --shallow-submodules --recurse-submodules -b release-3.2.4 https://github.com/libsdl-org/SDL_image.git
git clone --depth 1 --shallow-submodules --recurse-submodules -b v1.0.29-0 https://github.com/libusb/libusb-cmake.git
git clone --depth 1 -b n8.0.1 https://github.com/FFmpeg/FFmpeg.git
git clone --depth 1 -b master https://github.com/cisco/openh264.git
git clone --depth 1 -b v1.6 https://gitlab.xiph.org/xiph/opus.git
git clone --depth 1 -b v2.0.3 https://github.com/mstorsjo/fdk-aac.git
fi
if [ -d $INSTALL ]; then
rm -rf $INSTALL
fi
if [ -d $BUILD ]; then
rm -rf $BUILD
fi
mkdir -p $BUILD
cd $BUILD
cmake -GNinja -Bzlib -S$SRC/zlib $CMAKE_ARGS
cmake --build zlib
cmake --install zlib
cmake -GNinja -Buriparser -S$SRC/uriparser $CMAKE_ARGS -DURIPARSER_BUILD_DOCS=OFF -DURIPARSER_BUILD_TESTS=OFF \
-DURIPARSER_BUILD_TOOLS=OFF
cmake --build uriparser
cmake --install uriparser
cmake -GNinja -Bjson-c -S$SRC/json-c $CMAKE_ARGS -DBUILD_APPS=OFF -DBUILD_TESTING=OFF -DBUILD_STATIC_LIBS=OFF
cmake --build json-c
cmake --install json-c
cmake -GNinja -Bopus -S$SRC/opus $CMAKE_ARGS -DOPUS_BUILD_SHARED_LIBRARY=ON
cmake --build opus
cmake --install opus
cmake -GNinja -Bfdk-aac -S$SRC/fdk-aac $CMAKE_ARGS -DBUILD_PROGRAMS=OFF
cmake --build fdk-aac
cmake --install fdk-aac
cmake -GNinja -BSDL -S$SRC/SDL $CMAKE_ARGS -DSDL_TEST=OFF -DSDL_TESTS=OFF -DSDL_STATIC_PIC=ON
cmake --build SDL
cmake --install SDL
cmake -GNinja -BSDL_ttf -S$SRC/SDL_ttf $CMAKE_ARGS -DSDLTTF_HARFBUZZ=ON -DSDLTTF_FREETYPE=ON -DSDLTTF_VENDORED=ON \
-DFT_DISABLE_ZLIB=OFF -DSDLTTF_SAMPLES=OFF
cmake --build SDL_ttf
cmake --install SDL_ttf
cmake -GNinja -BSDL_image -S$SRC/SDL_image $CMAKE_ARGS -DSDLIMAGE_SAMPLES=OFF -DSDLIMAGE_DEPS_SHARED=OFF
cmake --build SDL_image
cmake --install SDL_image
cmake -GNinja -Blibusb-cmake -S$SRC/libusb-cmake $CMAKE_ARGS -DLIBUSB_BUILD_EXAMPLES=OFF -DLIBUSB_BUILD_TESTING=OFF \
-DLIBUSB_ENABLE_DEBUG_LOGGING=OFF -DLIBUSB_BUILD_SHARED_LIBS=ON
cmake --build libusb-cmake
cmake --install libusb-cmake
mkdir -p openssl
cd openssl
NPROC=$(sysctl -n hw.ncpu)
CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS $SRC/openssl/config --prefix=$INSTALL --libdir=lib no-asm no-tests no-docs no-apps zlib
CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS make -j $NPROC build_sw
CFLAGS=$OSSL_FLAGS LDFLAGS=$OSSL_FLAGS make -j $NPROC install_sw
cd $BUILD
meson setup --prefix="$INSTALL" -Doptimization=3 -Db_lto=true -Db_pie=true -Dc_args="$OSSL_FLAGS -Wno-error" -Dc_link_args="$OSSL_FLAGS" \
-Dcpp_args="$OSSL_FLAGS -Wno-error" -Dcpp_link_args="$OSSL_FLAGS" -Dpkgconfig.relocatable=true -Dtests=disabled -Dwerror=false \
-Dlibdir=lib openh264 $SRC/openh264
ninja -C openh264 install
for ARCH in $DEPLOYMENT_ARCH; do
mkdir -p $BUILD/FFmpeg/$ARCH
cd $BUILD/FFmpeg/$ARCH
FFCFLAGS="-arch $ARCH -mmacosx-version-min=$DEPLOYMENT_TARGET"
FINSTPATH=$BUILD/FFmpeg/install/$ARCH
CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS $SRC/FFmpeg/configure --prefix=$FINSTPATH --disable-all \
--enable-shared --disable-static --enable-swscale --disable-asm --disable-libxcb \
--disable-securetransport --disable-xlib --enable-cross-compile
CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS make -j $NPROC
CFLAGS=$FFCFLAGS LDFLAGS=$FFCFLAGS make -j $NPROC install
fix_rpath "$FINSTPATH/lib"
done
BASE_ARCH="${DEPLOYMENT_ARCH%% *}"
cd $BUILD/FFmpeg/install/$ARCH
cp -r include/* $INSTALL/include/
find lib -type l -exec cp -P {} $INSTALL/lib/ \;
BASE_LIBS=$(find lib -type f -name "*.dylib" -exec basename {} \;)
cd $BUILD/FFmpeg/install
for LIB in $BASE_LIBS; do
LIBS=$(find . -name $LIB)
lipo $LIBS -output $INSTALL/lib/$LIB -create
done
cd $BUILD
cmake -GNinja -Bfreerdp -S"$SCRIPT_PATH/.." \
$CMAKE_ARGS \
-DWITH_PLATFORM_SERVER=OFF \
-DWITH_CLIENT_SDL2=OFF \
-DWITH_SIMD=ON \
-DWITH_FFMPEG=OFF \
-DWITH_VERBOSE_WINPR_ASSERT=OFF \
-DWITH_OPENH264=ON \
-DWITH_SWSCALE=ON \
-DWITH_OPUS=ON \
-DWITH_WEBVIEW=OFF \
-DWITH_FAAD2=OFF \
-DWITH_FAAC=OFF \
-DWITH_INTERNAL_RC4=ON \
-DWITH_INTERNAL_MD4=ON \
-DWITH_INTERNAL_MD5=ON \
-DCHANNEL_RDPEAR=OFF \
-DWITH_FDK_AAC=ON \
-DWITH_JSONC_REQUIRED=ON
cmake --build freerdp
cmake --install freerdp
# remove unused stuff from bin
find "$INSTALL" -name "*.a" -exec rm -f {} \;
find "$INSTALL" -name "*.la" -exec rm -f {} \;
find "$INSTALL" -name sdl2-config -exec rm -f {} \;
fix_rpath "$INSTALL/lib"
fix_rpath "$INSTALL/bin" "$INSTALL/lib" ""
# move files in place
cd $INSTALL
mv lib $LIBDIR
mv bin $BINDIR
# update RPATH
for LIB in $(find $LIBDIR -type f -name "*.dylib"); do
replace_rpath $LIB
done
for BIN in $(find $BINDIR -type f); do
replace_rpath $BIN
done
# clean up unused data
rm -rf "$INSTALL/include"
rm -rf "$INSTALL/share"
rm -rf "$INSTALL/bin"
rm -rf "$INSTALL/$LIBDIR/cmake"
rm -rf "$INSTALL/$LIBDIR/pkgconfig"
# TODO: Create remaining files required

37
third_party/FreeRDP/scripts/cmake-format.sh vendored Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash -e
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
SRC_PATH="${SCRIPT_PATH}/.."
FORMAT_ARG="--check"
REST_ARGS=$@
if [ $# -ne 0 ]; then
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "usage: $0 [options] [file, file, ...]"
echo "\t--check.-c ... run format check only, no files changed (default)"
echo "\t--format,-f ... format files in place"
echo "\t--help,-h ... print this help"
exit 1
fi
if [ "$1" = "--check" ] || [ "$1" = "-c" ]; then
FORMAT_ARG="--check"
REST_ARGS="${@:2}"
fi
if [ "$1" = "--format" ] || [ "$1" = "-f" ]; then
FORMAT_ARG="-i"
REST_ARGS="${@:2}"
fi
fi
if [ ! -n "$REST_ARGS" ]; then
CMAKE_FILES=$(find ${SRC_PATH} -name "*.cmake" -o -name "CMakeLists.txt")
CMAKE_CI_FILES=$(find ${SRC_PATH}/ci -name "*.txt")
fi
for FILE in $CMAKE_FILES $CMAKE_CI_FILES $REST_ARGS; do
echo "processing file $FILE..."
cmake-format -c "$SCRIPT_PATH/cmake-format.yml" $FORMAT_ARG $FILE
done

View File

@@ -0,0 +1,245 @@
_help_parse: Options affecting listfile parsing
parse:
_help_additional_commands:
- Specify structure for custom cmake functions
additional_commands:
foo:
flags:
- BAR
- BAZ
kwargs:
HEADERS: '*'
SOURCES: '*'
DEPENDS: '*'
_help_override_spec:
- Override configurations per-command where available
override_spec: {}
_help_vartags:
- Specify variable tags.
vartags: []
_help_proptags:
- Specify property tags.
proptags: []
_help_format: Options affecting formatting.
format:
_help_disable:
- Disable formatting entirely, making cmake-format a no-op
disable: false
_help_line_width:
- How wide to allow formatted cmake files
line_width: 120
_help_tab_size:
- How many spaces to tab for indent
tab_size: 2
_help_use_tabchars:
- If true, lines are indented using tab characters (utf-8
- 0x09) instead of <tab_size> space characters (utf-8 0x20).
- In cases where the layout would require a fractional tab
- character, the behavior of the fractional indentation is
- governed by <fractional_tab_policy>
use_tabchars: false
_help_fractional_tab_policy:
- If <use_tabchars> is True, then the value of this variable
- indicates how fractional indentions are handled during
- whitespace replacement. If set to 'use-space', fractional
- indentation is left as spaces (utf-8 0x20). If set to
- '`round-up` fractional indentation is replaced with a single'
- tab character (utf-8 0x09) effectively shifting the column
- to the next tabstop
fractional_tab_policy: use-space
_help_max_subgroups_hwrap:
- If an argument group contains more than this many sub-groups
- (parg or kwarg groups) then force it to a vertical layout.
max_subgroups_hwrap: 16
_help_max_pargs_hwrap:
- If a positional argument group contains more than this many
- arguments, then force it to a vertical layout.
max_pargs_hwrap: 6
_help_max_rows_cmdline:
- If a cmdline positional group consumes more than this many
- lines without nesting, then invalidate the layout (and nest)
max_rows_cmdline: 2
_help_separate_ctrl_name_with_space:
- If true, separate flow control names from their parentheses
- with a space
separate_ctrl_name_with_space: false
_help_separate_fn_name_with_space:
- If true, separate function names from parentheses with a
- space
separate_fn_name_with_space: false
_help_dangle_parens:
- If a statement is wrapped to more than one line, than dangle
- the closing parenthesis on its own line.
dangle_parens: true
_help_dangle_align:
- If the trailing parenthesis must be 'dangled' on its on
- 'line, then align it to this reference: `prefix`: the start'
- 'of the statement, `prefix-indent`: the start of the'
- 'statement, plus one indentation level, `child`: align to'
- the column of the arguments
dangle_align: prefix
_help_min_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is smaller than this amount, then force reject
- nested layouts.
min_prefix_chars: 4
_help_max_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is larger than the tab width by more than this
- amount, then force reject un-nested layouts.
max_prefix_chars: 10
_help_max_lines_hwrap:
- If a candidate layout is wrapped horizontally but it exceeds
- this many lines, then reject the layout.
max_lines_hwrap: 6
_help_line_ending:
- What style line endings to use in the output.
line_ending: unix
_help_command_case:
- Format command names consistently as 'lower' or 'upper' case
command_case: canonical
_help_keyword_case:
- Format keywords consistently as 'lower' or 'upper' case
keyword_case: unchanged
_help_always_wrap:
- A list of command names which should always be wrapped
always_wrap: []
_help_enable_sort:
- If true, the argument lists which are known to be sortable
- will be sorted lexicographicall
enable_sort: true
_help_autosort:
- If true, the parsers may infer whether or not an argument
- list is sortable (without annotation).
autosort: false
_help_require_valid_layout:
- By default, if cmake-format cannot successfully fit
- everything into the desired linewidth it will apply the
- last, most aggressive attempt that it made. If this flag is
- True, however, cmake-format will print error, exit with non-
- zero status code, and write-out nothing
require_valid_layout: false
_help_layout_passes:
- A dictionary mapping layout nodes to a list of wrap
- decisions. See the documentation for more information.
layout_passes: {}
_help_markup: Options affecting comment reflow and formatting.
markup:
_help_bullet_char:
- What character to use for bulleted lists
bullet_char: '*'
_help_enum_char:
- What character to use as punctuation after numerals in an
- enumerated list
enum_char: .
_help_first_comment_is_literal:
- If comment markup is enabled, don't reflow the first comment
- block in each listfile. Use this to preserve formatting of
- your copyright/license statements.
first_comment_is_literal: false
_help_literal_comment_pattern:
- If comment markup is enabled, don't reflow any comment block
- which matches this (regex) pattern. Default is `None`
- (disabled).
literal_comment_pattern: null
_help_fence_pattern:
- Regular expression to match preformat fences in comments
- default= ``r'^\s*([`~]{3}[`~]*)(.*)$'``
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
_help_ruler_pattern:
- Regular expression to match rulers in comments default=
- '``r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''``'
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
_help_explicit_trailing_pattern:
- If a comment line matches starts with this pattern then it
- is explicitly a trailing comment for the preceding argument.
- Default is '#<'
explicit_trailing_pattern: '#<'
_help_hashruler_min_length:
- If a comment line starts with at least this many consecutive
- hash characters, then don't lstrip() them off. This allows
- for lazy hash rulers where the first hash char is not
- separated by space
hashruler_min_length: 10
_help_canonicalize_hashrulers:
- If true, then insert a space between the first hash char and
- remaining hash chars in a hash ruler, and normalize its
- length to fill the column
canonicalize_hashrulers: true
_help_enable_markup:
- enable comment markup parsing and reflow
enable_markup: false
_help_lint: Options affecting the linter
lint:
_help_disabled_codes:
- a list of lint codes to disable
disabled_codes: []
_help_function_pattern:
- regular expression pattern describing valid function names
function_pattern: '[0-9a-z_]+'
_help_macro_pattern:
- regular expression pattern describing valid macro names
macro_pattern: '[0-9A-Z_]+'
_help_global_var_pattern:
- regular expression pattern describing valid names for
- variables with global (cache) scope
global_var_pattern: '[A-Z][0-9A-Z_]+'
_help_internal_var_pattern:
- regular expression pattern describing valid names for
- variables with global scope (but internal semantic)
internal_var_pattern: _[A-Z][0-9A-Z_]+
_help_local_var_pattern:
- regular expression pattern describing valid names for
- variables with local scope
local_var_pattern: '[a-z][a-z0-9_]+'
_help_private_var_pattern:
- regular expression pattern describing valid names for
- privatedirectory variables
private_var_pattern: _[0-9a-z_]+
_help_public_var_pattern:
- regular expression pattern describing valid names for public
- directory variables
public_var_pattern: '[A-Z][0-9A-Z_]+'
_help_argument_var_pattern:
- regular expression pattern describing valid names for
- function/macro arguments and loop variables.
argument_var_pattern: '[a-z][a-z0-9_]+'
_help_keyword_pattern:
- regular expression pattern describing valid names for
- keywords used in functions or macros
keyword_pattern: '[A-Z][0-9A-Z_]+'
_help_max_conditionals_custom_parser:
- In the heuristic for C0201, how many conditionals to match
- within a loop in before considering the loop a parser.
max_conditionals_custom_parser: 2
_help_min_statement_spacing:
- Require at least this many newlines between statements
min_statement_spacing: 1
_help_max_statement_spacing:
- Require no more than this many newlines between statements
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50
_help_encode: Options affecting file encoding
encode:
_help_emit_byteorder_mark:
- If true, emit the unicode byte-order mark (BOM) at the start
- of the file
emit_byteorder_mark: false
_help_input_encoding:
- Specify the encoding of the input file. Defaults to utf-8
input_encoding: utf-8
_help_output_encoding:
- Specify the encoding of the output file. Defaults to utf-8.
- Note that cmake only claims to support utf-8 so be careful
- when using anything else
output_encoding: utf-8
_help_misc: Miscellaneous configurations options.
misc:
_help_per_command:
- A dictionary containing any per-command configuration
- overrides. Currently only `command_case` is supported.
per_command: {}

View File

@@ -0,0 +1,30 @@
nin
pres
ptd
statics
inout
ontext
clen
usera
fom
fle
parm
tolen
psuh
larg
varn
wight
resizeable
wan
bre
sur
numer
requestor
addin
nome
manuel
shs
udo
wheight
emac
leadin

16
third_party/FreeRDP/scripts/codespell.sh vendored Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash -x
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
# ignore the following regular expressions:
#
# 1. All words consisting of only 2 characters (too many issues with variable names)
# 2. Every word of the form 'pEvent', e.g. variable prefixed with p for pointer
# 3. Every word prefixed by e.g. '\tSome text', e.g. format string escapes
codespell --version
codespell \
-I "$SCRIPT_PATH/codespell.ignore" \
-S ".git,*.ai,*.svg,*.rtf,*/assets/de_*,*/res/values-*,*/protocols/xdg*,*/test/*,*/external/*" \
--ignore-regex "\b[a-zA-Z][a-zA-Z]\b|\bp[A-Z].*|\\\\[a-z][a-zA-Z].*" \
--count $SCRIPT_PATH/..

View File

@@ -0,0 +1,77 @@
#!/bin/bash -e
function run {
"$@"
RES=$?
if [[ $RES -ne 0 ]]; then
echo "[ERROR] $@ returned $RES" >&2
exit 1
fi
}
if [ -z ${TAG:-} ]; then
echo "No TAG set - trying to detect"
TAG=$(git describe --tags)
echo "Is the TAG ${TAG} ok (YES|NO)?"
read answ
case "$answ" in
YES)
:
;;
*)
echo 'stopping here'
exit 1
;;
esac
fi
function create_hash {
NAME=$1
run md5sum ${NAME} >${NAME}.md5
run sha1sum ${NAME} >${NAME}.sha1
run sha256sum ${NAME} >${NAME}.sha256
run sha512sum ${NAME} >${NAME}.sha512
}
function create_tar {
ARGS=$1
EXT=$2
TAG=$3
NAME=freerdp-${TAG}${EXT}
run tar $ARGS ${NAME} freerdp-${TAG}
create_hash ${NAME}
}
TMPDIR=$(mktemp -d -t release-${TAG}-XXXXXXXXXX)
run git archive --prefix=freerdp-${TAG}/ --format=tar.gz -o ${TMPDIR}/freerdp-${TAG}.tar.gz ${TAG}
run tar xzvf ${TMPDIR}/freerdp-${TAG}.tar.gz -C ${TMPDIR}
run echo ${TAG} >${TMPDIR}/freerdp-${TAG}/.source_version
pushd .
cd $TMPDIR
create_tar czf .tar.gz ${TAG}
create_tar cvjSf .tar.bz2 ${TAG}
create_tar cfJ .tar.xz ${TAG}
ZIPNAME=freerdp-${TAG}.zip
run zip -r ${ZIPNAME} freerdp-${TAG}
create_hash ${ZIPNAME}
popd
# Sign the release tarballs
for EXT in tar.gz tar.bz2 tar.xz zip; do
run gpg --local-user 0xA49454A3FC909FD5 --sign --armor --output ${TMPDIR}/freerdp-${TAG}.${EXT}.asc --detach-sig ${TMPDIR}/freerdp-${TAG}.${EXT}
done
run mv ${TMPDIR}/freerdp-${TAG}.tar* .
run mv ${TMPDIR}/freerdp-${TAG}.zip* .
run rm -rf ${TMPDIR}
# Verify the release tarball signatures
for EXT in tar.gz tar.bz2 tar.xz zip; do
run gpg --verify freerdp-${TAG}.${EXT}.asc
done
exit 0

View File

@@ -0,0 +1,129 @@
#!/bin/env python3
#
# This is a helper script that fetches the current language and keyboard tables
# and writes the result to a C compatible struct.
#
import os
import sys
import requests
import numpy as np
import traceback
from bs4 import BeautifulSoup
from bs4 import element
intro = '''/* This file is auto generated from
*
* https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings
*
* please do not edit but use ./scripts/fetch_language_identifiers.py to regenerate!
*/
'''
def parse_html(text):
soup = BeautifulSoup(text, 'html.parser')
table = soup.find("table")
head = table.find('thead').find('tr')
headers = []
for th in head:
if type(th) == element.Tag:
headers += th
body = table.find('tbody')
languages = []
for tr in body:
if type(tr) == element.Tag:
entry = []
for th in tr:
if type(th) == element.Tag:
if th.string:
entry += [th.string]
else:
entry += ['']
languages += [entry]
return [headers, languages]
def is_base(num, base):
try:
v = int(num, base)
return True
except ValueError:
return False
def padhexa(v):
s = hex(v)
return '0x' + s[2:].zfill(8)
def write_struct(fp, struct, name, url, base, inv = False, typemap = None):
li = requests.get(url)
if li.status_code != requests.codes.ok:
print('Could not fetch ' + str(url) + ', response code ' + str(li.status_code))
sys.exit(1)
headers, languages = parse_html(li.text)
fp.write('const ' + str(struct) + ' ' + str(name) + '[] =\n')
fp.write('{\n')
fp.write('/* ')
for h in headers:
fp.write('\t[')
fp.write(h)
fp.write(']\t')
fp.write('*/\n')
last = [None] * 32
for language in languages:
fp.write('\t{ ')
line = ''
pos = 0
for e in language:
try:
v = int(e, base=base)
switcher = {
0: padhexa(v),
2: bin(v),
8: oct(v),
10: str(v),
16: padhexa(v)
}
h = str(switcher.get(base))
if h != "None":
last[pos] = h
if inv:
line = h + ', ' + line
else:
line += h + ', '
except ValueError:
if typemap and typemap[pos] != str:
line += str(last[pos]) + ',\t'
else:
if e == "":
line += '"' + str(last[pos]) + '",\t'
else:
line += '"' + e + '",\t'
if e != "None":
last[pos] = str(e)
pos = pos + 1
fp.write(line[:-2] + '},\n')
fp.write('};\n')
fp.write('\n')
def update_lang_identifiers(fp):
# [Language identifier] [Primary language] [Prim. lang. identifier] [Prim. lang. symbol] [Sublanguage] [Sublang. identifier] [Sublang. symbol]
write_struct(fp, 'LanguageIdentifier', 'language_identifiers', 'https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings', 16, False, [int, str, int, str, str, int, str])
def update_code_pages(fp):
write_struct(fp, 'CodePage', 'code_pages', 'https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers', 10)
def update_input_locales(fp):
write_struct(fp, 'KeyboardIdentifier', 'keyboard_identifiers', 'https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc766503(v=ws.10)', 0)
write_struct(fp, 'RDP_KEYBOARD_LAYOUT', 'RDP_KEYBOARD_LAYOUT_TABLE', 'https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values', 16, True)
try:
with open('language_identifiers.c', 'w') as fp:
fp.write(intro)
update_lang_identifiers(fp)
update_code_pages(fp)
update_input_locales(fp)
except:
print('exception cought')
traceback.print_exc()

View File

@@ -0,0 +1,56 @@
#!/bin/bash
#
# This script tries to pull gprof profiling information generated by aFreeRDP
# from the target using adb and generating human readable profiling data from
# it.
#
# Any arguments supplied to the script will be appended to adb.
#
# Requirements:
# - ANDROID_SDK is set to the android SDK directory or adb is in path.
#
if [ -d $ANDROID_SDK ]; then
ADB=$ANDROID_SDK/platform-tools/adb
else
ADB=`which adb`
fi
GCC=@CMAKE_C_COMPILER@
GPROF=${GCC/gcc/gprof}
LIB=@PROJECT_BINARY_DIR@/client/Android/FreeRDPCore/jni/armeabi-v7a/libfreerdp-android.so
if [ ! -f $LIB ]; then
echo "Missing libfreerdp-android.so"
echo "Please build the project first."
exit -1
fi
if [ ! -f $GPROF ]; then
echo "gprof could not be found at $GPROF."
echo "Please assure, that you are using a GCC based android toolchain."
exit -2
fi
if [ ! -f $ADB ] || [ ! -x $ADB ]; then
echo "adb could not be found."
echo "assure, that either ANDROID_SDK is set to the path of your android SDK"
echo "or that adb is in path."
exit -3
fi
# Do the actual work in a temporary directory.
SRC=`mktemp -d`
cd $SRC
$ADB $@ pull /sdcard/gmon.out
if [ ! -f gmon.out ]; then
echo "Could not pull profiling information from device!"
RC=-4
else
echo "Pulled profiling information from device, starting conversion..."
$GPROF $LIB -PprofCount -QprofCount -P__gnu_mcount_nc -Q__gnu_mcount_nc
RC=0
fi
rm -rf $SRC
exit $RC

View File

@@ -0,0 +1,15 @@
[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
exe_wrapper = 'wine64'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[properties]
sysroot = '/usr/x86_64-w64-mingw32'

290
third_party/FreeRDP/scripts/mingw.sh vendored Executable file
View File

@@ -0,0 +1,290 @@
#!/bin/bash -xe
#
# mingw build script
#
# TODO: Replace with CMake FetchContent
# https://cmake.org/cmake/help/latest/module/FetchContent.html
#
SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}")
SCRIPT_PATH=$(realpath "$SCRIPT_PATH")
SRC_BASE="$SCRIPT_PATH/../build-mingw/src"
BUILD_BASE="$SCRIPT_PATH/../build-mingw/build"
INSTALL_BASE="$SCRIPT_PATH/../build-mingw/install"
CLEAN=0
CLONE=1
DEPS=1
BUILD=1
FFMPEG=0
OPENH264=0
ARG_SHARED=1
ARG_STATIC=0
CMAKE_DEFAULT_FLAGS=""
ARG_SHARED_MESON="-Ddefault_library=shared"
ARG_SHARED_FFMPEG="--disable-static --enable-shared"
for i in "$@"; do
case $i in
-b | --no-build)
BUILD=0
;;
-c | --no-clone)
CLONE=0
;;
--clean-first)
CLEAN=1
;;
-d | --no-deps)
DEPS=0
;;
-f | --with-ffmpeg)
FFMPEG=1
;;
-o | --with-openh264)
OPENH264=1
;;
-s | --static)
ARG_SHARED=0
ARG_STATIC=1
CMAKE_DEFAULT_FLAGS="-static -static-libgcc -static-libstdc++"
ARG_SHARED_MESON="-Ddefault_library=static"
ARG_SHARED_FFMPEG=""
;;
*)
# unknown option
echo "unknown option '$i', quit"
echo "usage:\n\t$0 [-b|--no-build] [-c|--no-clone] [-d|--no-deps] [-f|--with-ffmpeg] [-o|--with-openh264] [-s|--static] [--clean-first]"
exit 1
;;
esac
done
ARG_COMPILED_RES=1
if [ $ARG_SHARED -ne 0 ]; then
ARG_COMPILED_RES=0
fi
if [ $CLEAN -ne 0 ]; then
rm -rf "$BUILD_BASE"
rm -rf "$INSTALL_BASE"
fi
function do_clone {
version=$1
url=$2
dir=$3
if [ -d "$dir" ]; then
(
cd "$dir"
git fetch --all
git clean -xdf
git reset --hard $version
git checkout $version
git submodule update --init --recursive
)
else
git clone --depth 1 --shallow-submodules --recurse-submodules -b $version $url $dir
fi
}
function do_download {
url=$1
file=$2
hash=$3
dir=$4
if [ ! -f $file ]; then
if command -v curl 2>&1 >/dev/null; then
curl -o $file $url/$file
elif command -v wget 2>&1 >/dev/null; then
wget -O $file $url/$file
else
echo "Could not find wget or curl, exiting"
exit 1
fi
fi
if [ ! -f $file.sha256sum ]; then
echo "$hash $file" >$file.sha256sum
fi
sha256sum -c $file.sha256sum
if [ -d $dir ]; then
rm -rf $dir
fi
mkdir $dir
tar xf $file --strip-components=1 -C $dir
}
function do_cmake_build {
cmake \
-GNinja \
-DCMAKE_TOOLCHAIN_FILE="$SCRIPT_PATH/mingw64.cmake" \
-DCMAKE_PREFIX_PATH="$INSTALL_BASE/lib/cmake;$INSTALL_BASE/lib;$INSTALL_BASE" \
-DCMAKE_MODULE_PATH="$INSTALL_BASE/lib/cmake;$INSTALL_BASE/lib;$INSTALL_BASE" \
-DCMAKE_INSTALL_PREFIX="$INSTALL_BASE" \
-DBUILD_SHARED_LIBS=$ARG_SHARED \
-DCMAKE_EXE_LINKER_FLAGS="$CMAKE_DEFAULT_FLAGS" \
-B "$1" \
${@:2}
cmake --build "$1"
cmake --install "$1"
}
mkdir -p "$SRC_BASE"
mkdir -p "$BUILD_BASE"
cd "$SRC_BASE"
if [ $CLONE -ne 0 ]; then
do_clone v1.3.1 https://github.com/madler/zlib.git zlib
do_clone uriparser-1.0.0 https://github.com/uriparser/uriparser.git uriparser
do_clone json-c-0.18-20240915 https://github.com/json-c/json-c.git json-c
do_clone release-3.2.28 https://github.com/libsdl-org/SDL.git SDL
if [ $FFMPEG -ne 0 ]; then
do_clone n8.0.1 https://github.com/FFmpeg/FFmpeg.git FFmpeg
fi
if [ $OPENH264 -ne 0 ]; then
do_clone v2.6.0 https://github.com/cisco/openh264.git openh264
fi
do_clone v1.0.29-0 https://github.com/libusb/libusb-cmake.git libusb-cmake
do_clone release-3.2.4 https://github.com/libsdl-org/SDL_image.git SDL_image
do_clone release-3.2.2 https://github.com/libsdl-org/SDL_ttf.git SDL_ttf
do_clone v2.0.3 https://github.com/mstorsjo/fdk-aac.git fdk-aac
do_clone v1.6 https://gitlab.xiph.org/xiph/opus.git opus
do_download https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ libressl-4.2.1.tar.gz 6d5c2f58583588ea791f4c8645004071d00dfa554a5bf788a006ca1eb5abd70b libressl
fi
if [ $BUILD -eq 0 ]; then
exit 0
fi
if [ $DEPS -ne 0 ]; then
do_cmake_build \
"$BUILD_BASE/libressl" \
-S libressl \
-DLIBRESSL_APPS=OFF \
-DLIBRESSL_TESTS=OFF
do_cmake_build \
"$BUILD_BASE/zlib" \
-S zlib \
-DZLIB_BUILD_EXAMPLES=OFF
do_cmake_build \
"$BUILD_BASE/uriparser" \
-S uriparser \
-DURIPARSER_BUILD_TOOLS=OFF \
-DURIPARSER_BUILD_DOCS=OFF \
-DURIPARSER_BUILD_TESTS=OFF
do_cmake_build \
"$BUILD_BASE/json-c" \
-S json-c \
-DBUILD_APPS=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=$ARG_SHARED \
-DBUILD_STATIC_LIBS=$ARG_STATIC
do_cmake_build \
"$BUILD_BASE/SDL" \
-S SDL \
-DSDL_TEST=OFF \
-DSDL_TESTS=OFF \
-DSDL_STATIC_PIC=ON
do_cmake_build \
"$BUILD_BASE/SDL_ttf" \
-S SDL_ttf \
-DSDLTTF_HARFBUZZ=ON \
-DSDLTTF_FREETYPE=ON \
-DSDLTTF_VENDORED=ON \
-DFT_DISABLE_ZLIB=OFF \
-DSDLTTF_SAMPLES=OFF \
-DSDLTTF_PLUTOSVG=OFF
do_cmake_build \
"$BUILD_BASE/SDL_image" \
-S SDL_image \
-DSDLIMAGE_SAMPLES=OFF \
-DSDLIMAGE_DEPS_SHARED=$ARG_SHARED
do_cmake_build \
"$BUILD_BASE/libusb-cmake" \
-S libusb-cmake \
-DLIBUSB_BUILD_EXAMPLES=OFF \
-DLIBUSB_BUILD_TESTING=OFF \
-DLIBUSB_ENABLE_DEBUG_LOGGING=OFF
do_cmake_build \
"$BUILD_BASE/fdk-aac" \
-S fdk-aac \
-DBUILD_PROGRAMS=OFF
do_cmake_build \
"$BUILD_BASE/opus" \
-S opus \
-DOPUS_BUILD_SHARED_LIBRARY=$ARG_SHARED
# TODO: This takes ages to compile, disable
if [ $FFMPEG -ne 0 ]; then
(
cd "$BUILD_BASE"
mkdir -p FFmpeg
cd FFmpeg
"$SRC_BASE/FFmpeg/configure" \
--arch=x86_64 \
--target-os=mingw64 \
--cross-prefix=x86_64-w64-mingw32- \
--disable-programs \
--disable-doc \
--prefix="$INSTALL_BASE" $ARG_SHARED_FFMPEG
make -j
make -j install
)
fi
if [ $OPENH264 -ne 0 ]; then
(
meson setup --cross-file "$SCRIPT_PATH/mingw-meson.conf" \
-Dprefix="$INSTALL_BASE" \
-Db_pie=true \
-Db_lto=true \
-Dbuildtype=release \
-Dtests=disabled \
$ARG_SHARED_MESON \
-Dcpp_link_args="$CMAKE_DEFAULT_FLAGS" \
-Dcpp_args="$CMAKE_DEFAULT_FLAGS" \
"$BUILD_BASE/openh264" \
openh264
ninja -C "$BUILD_BASE/openh264"
ninja -C "$BUILD_BASE/openh264" install
)
fi
fi
do_cmake_build \
"$BUILD_BASE/freerdp" \
-S "$SCRIPT_PATH/.." \
-DWITHOUT_FREERDP_3x_DEPRECATED=ON \
-DWITH_SERVER=ON \
-DWITH_SHADOW=OFF \
-DWITH_PLATFORM_SERVER=OFF \
-DWITH_SAMPLE=ON \
-DWITH_PLATFORM_SERVER=OFF \
-DUSE_UNWIND=OFF \
-DSDL_USE_COMPILED_RESOURCES=$ARG_COMPILED_RES \
-DWITH_SDL_IMAGE_DIALOGS=ON \
-DWITH_SDL_LINK_SHARED=$ARG_SHARED \
-DWITH_CLIENT_SDL2=OFF \
-DWITH_SWSCALE=$FFMPEG \
-DWITH_FFMPEG=$FFMPEG \
-DWITH_SIMD=ON \
-DWITH_OPENH264=$OPENH264 \
-DWITH_WEBVIEW=OFF \
-DWITH_LIBRESSL=ON \
-DWITH_OPUS=ON \
-DWITH_JSONC_REQUIRED=ON \
-DWITH_FDK_AAC=ON \
-DWITH_MANPAGES=OFF

View File

@@ -0,0 +1,41 @@
set(CMAKE_SYSTEM_NAME Windows CACHE STRING "toolchain default")
set(CMAKE_SYSTEM_PROCESSOR amd64 CACHE STRING "toolchain default")
# https://github.com/meganz/mingw-std-threads
#
# we simply compile with the POSIX C++ primitives, but faster is using the wrapper
set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc-posix CACHE STRING "toolchain default")
set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++-posix CACHE STRING "toolchain default")
set(CMAKE_RC_COMPILER_INIT /usr/bin/x86_64-w64-mingw32-windres CACHE STRING "toolchain default")
set(CMAKE_RC_COMPILER /usr/bin/x86_64-w64-mingw32-windres CACHE STRING "toolchain default")
set(CMAKE_AR /usr/bin/x86_64-w64-mingw32-gcc-ar-posix CACHE STRING "toolchain default")
set(CMAKE_C_COMPILER_AR /usr/bin/x86_64-w64-mingw32-gcc-ar-posix CACHE STRING "toolchain default")
set(CMAKE_CXX_COMPILER_AR /usr/bin/x86_64-w64-mingw32-gcc-ar-posix CACHE STRING "toolchain default")
set(CMAKE_RANLIB /usr/bin/x86_64-w64-mingw32-gcc-ranlib-posix CACHE STRING "toolchain default")
set(CMAKE_C_COMPILER_RANLIB /usr/bin/x86_64-w64-mingw32-gcc-ranlib-posix CACHE STRING "toolchain default")
set(CMAKE_CXX_COMPILER_RANLIB /usr/bin/x86_64-w64-mingw32-gcc-ranlib-posix CACHE STRING "toolchain default")
set(CMAKE_LINKER /usr/bin/x86_64-w64-mingw32-ld-posix CACHE STRING "toolchain default")
set(CMAKE_NM /usr/bin/x86_64-w64-mingw32-nm-posix CACHE STRING "toolchain default")
set(CMAKE_READELF /usr/bin/x86_64-w64-mingw32-readelf CACHE STRING "toolchain default")
set(CMAKE_OBJCOPY /usr/bin/x86_64-w64-mingw32-objcopy CACHE STRING "toolchain default")
set(CMAKE_OBJDUMP /usr/bin/x86_64-w64-mingw32-objdump CACHE STRING "toolchain default")
set(CMAKE_SYSROOT /usr/x86_64-w64-mingw32 CACHE STRING "toolchain default")
#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "toolchain default")
#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE STRING "toolchain default")
#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE STRING "toolchain default")
#set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY CACHE STRING "toolchain default")
set(CMAKE_WINDOWS_VERSION "WIN10" CACHE STRING "toolchain default")
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "toolchain default")
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON CACHE BOOL "toolchain default")
set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "toolchain default")
set(THREADS_PREFER_PTHREAD_FLAG ON CACHE BOOL "toolchain default")
# mingw does not support C11
#
# https://stackoverflow.com/questions/52239644/mingw-w64-c11-threads-h-not-found
add_compile_definitions(__STDC_NO_THREADS__)
add_compile_definitions(__STDC_NO_ATOMICS__)

View File

@@ -0,0 +1,69 @@
#!/usr/bin/python
#
# A script to convert blob from the MS spec to array of byte to use in unitary tests
#
# 00000000 c7 01 00 01 20 54 e2
# 00000008 c7 01 00 01 20 54 e2
# taken from the spec, will give:
# 0xc7, 0x01, 0x00, 0x01, 0x20, 0x54, 0xe2,
# 0xc7, 0x01, 0x00, 0x01, 0x20, 0x54, 0xe2,
#
# Notes:
# * the script reads the two first lines to detect the number of items per lines, so you need a blob with at least 2 lines
# * the script detects if items are hex values by searching for + or -
#
# sample usage:
# $ python scripts/specBytesToCode.py < image.txt > image.c
# then go edit image.c and paste that in your code
import sys
def getOffset(l):
token = l.split(' ')[0]
return int(token, 16)
def isHex(l):
return l.find('+') == -1 and l.find('-') == -1
if __name__ == '__main__':
lines = []
itemPerLine = 16
doHex = True
# parse the offset to know how many items per line we have
l1 = sys.stdin.readline().strip()
l2 = sys.stdin.readline().strip()
itemsPerLine = getOffset(l2) - getOffset(l1)
#
doHex = isHex(l1)
for l in [l1, l2] + sys.stdin.readlines():
# 00000000 c7 01 00 01 20 54 e2 cc 00 jh.kjkjhkhk
l = l.strip() # in case we have spaces before the offset
pos = l.find(' ')
l = l[pos+1:]
items = []
tokens = l.strip().split(' ')
ntokens = 0
for t in tokens:
if not t: # empty token
continue
if ntokens == itemPerLine:
break
item = ''
if doHex:
item += '0x'
item += t
items.append(item)
ntokens += 1
lines.append(', '.join(items))
print(",\n".join(lines))

View File

@@ -0,0 +1,914 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard API test program
*
* This simple program can be used to trigger calls for (almost) the
* entire SCARD API.
* Compile on windows, connect with FreeRDP via RDP with smartcard
* redirection enabled and run this test program on the windows
* machine.
*
* Copyright 2020 Armin Novak <armin.novak@thincast.com>
* Copyright 2020 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
#include <codecvt>
#include <comdef.h>
#include <winscard.h>
static const WCHAR* listW[] = { nullptr, L"SCard$AllReaders\000", L"SCard$DefaultReaders\000",
L"SCard$LocalReaders\000", L"SCard$SystemReaders\000" };
static const char* listA[] = { nullptr, "SCard$AllReaders\000", "SCard$DefaultReaders\000",
"SCard$LocalReaders\000", "SCard$SystemReaders\000" };
static std::string scope2str(DWORD scope)
{
switch (scope)
{
case SCARD_SCOPE_USER:
return "SCARD_SCOPE_USER";
case SCARD_SCOPE_TERMINAL:
return "SCARD_SCOPE_TERMINAL";
case SCARD_SCOPE_SYSTEM:
return "SCARD_SCOPE_SYSTEM";
default:
return "UNKNOWN";
}
}
static std::string err2str(LONG code)
{
switch (code)
{
case ERROR_BROKEN_PIPE:
return "ERROR_BROKEN_PIPE";
case SCARD_E_BAD_SEEK:
return "SCARD_E_BAD_SEEK";
case SCARD_E_CANCELLED:
return "SCARD_E_CANCELLED";
case SCARD_E_CANT_DISPOSE:
return "SCARD_E_CANT_DISPOSE";
case SCARD_E_CARD_UNSUPPORTED:
return "SCARD_E_CARD_UNSUPPORTED";
case SCARD_E_CERTIFICATE_UNAVAILABLE:
return "SCARD_E_CERTIFICATE_UNAVAILABLE";
case SCARD_E_COMM_DATA_LOST:
return "SCARD_E_COMM_DATA_LOST";
case SCARD_E_DIR_NOT_FOUND:
return "SCARD_E_DIR_NOT_FOUND";
case SCARD_E_DUPLICATE_READER:
return "SCARD_E_DUPLICATE_READER";
case SCARD_E_FILE_NOT_FOUND:
return "SCARD_E_FILE_NOT_FOUND";
case SCARD_E_ICC_CREATEORDER:
return "SCARD_E_ICC_CREATEORDER";
case SCARD_E_ICC_INSTALLATION:
return "SCARD_E_ICC_INSTALLATION";
case SCARD_E_INSUFFICIENT_BUFFER:
return "SCARD_E_INSUFFICIENT_BUFFER";
case SCARD_E_INVALID_ATR:
return "SCARD_E_INVALID_ATR";
case SCARD_E_INVALID_CHV:
return "SCARD_E_INVALID_CHV";
case SCARD_E_INVALID_HANDLE:
return "SCARD_E_INVALID_HANDLE";
case SCARD_E_INVALID_PARAMETER:
return "SCARD_E_INVALID_PARAMETER";
case SCARD_E_INVALID_TARGET:
return "SCARD_E_INVALID_TARGET";
case SCARD_E_INVALID_VALUE:
return "SCARD_E_INVALID_VALUE";
case SCARD_E_NO_ACCESS:
return "SCARD_E_NO_ACCESS";
case SCARD_E_NO_DIR:
return "SCARD_E_NO_DIR";
case SCARD_E_NO_FILE:
return "SCARD_E_NO_FILE";
case SCARD_E_NO_KEY_CONTAINER:
return "SCARD_E_NO_KEY_CONTAINER";
case SCARD_E_NO_MEMORY:
return "SCARD_E_NO_MEMORY";
case SCARD_E_NO_PIN_CACHE:
return "SCARD_E_NO_PIN_CACHE";
case SCARD_E_NO_READERS_AVAILABLE:
return "SCARD_E_NO_READERS_AVAILABLE";
case SCARD_E_NO_SERVICE:
return "SCARD_E_NO_SERVICE";
case SCARD_E_NO_SMARTCARD:
return "SCARD_E_NO_SMARTCARD";
case SCARD_E_NO_SUCH_CERTIFICATE:
return "SCARD_E_NO_SUCH_CERTIFICATE";
case SCARD_E_NOT_READY:
return "SCARD_E_NOT_READY";
case SCARD_E_NOT_TRANSACTED:
return "SCARD_E_NOT_TRANSACTED";
case SCARD_E_PCI_TOO_SMALL:
return "SCARD_E_PCI_TOO_SMALL";
case SCARD_E_PIN_CACHE_EXPIRED:
return "SCARD_E_PIN_CACHE_EXPIRED";
case SCARD_E_PROTO_MISMATCH:
return "SCARD_E_PROTO_MISMATCH";
case SCARD_E_READ_ONLY_CARD:
return "SCARD_E_READ_ONLY_CARD";
case SCARD_E_READER_UNAVAILABLE:
return "SCARD_E_READER_UNAVAILABLE";
case SCARD_E_READER_UNSUPPORTED:
return "SCARD_E_READER_UNSUPPORTED";
case SCARD_E_SERVER_TOO_BUSY:
return "SCARD_E_SERVER_TOO_BUSY";
case SCARD_E_SERVICE_STOPPED:
return "SCARD_E_SERVICE_STOPPED";
case SCARD_E_SHARING_VIOLATION:
return "SCARD_E_SHARING_VIOLATION";
case SCARD_E_SYSTEM_CANCELLED:
return "SCARD_E_SYSTEM_CANCELLED";
case SCARD_E_TIMEOUT:
return "SCARD_E_TIMEOUT";
case SCARD_E_UNEXPECTED:
return "SCARD_E_UNEXPECTED";
case SCARD_E_UNKNOWN_CARD:
return "SCARD_E_UNKNOWN_CARD";
case SCARD_E_UNKNOWN_READER:
return "SCARD_E_UNKNOWN_READER";
case SCARD_E_UNKNOWN_RES_MNG:
return "SCARD_E_UNKNOWN_RES_MNG";
case SCARD_E_UNSUPPORTED_FEATURE:
return "SCARD_E_UNSUPPORTED_FEATURE";
case SCARD_E_WRITE_TOO_MANY:
return "SCARD_E_WRITE_TOO_MANY";
case SCARD_F_COMM_ERROR:
return "SCARD_F_COMM_ERROR";
case SCARD_F_INTERNAL_ERROR:
return "SCARD_F_INTERNAL_ERROR";
case SCARD_F_UNKNOWN_ERROR:
return "SCARD_F_UNKNOWN_ERROR";
case SCARD_F_WAITED_TOO_LONG:
return "SCARD_F_WAITED_TOO_LONG";
case SCARD_P_SHUTDOWN:
return "SCARD_P_SHUTDOWN";
case SCARD_S_SUCCESS:
return "SCARD_S_SUCCESS";
case SCARD_W_CANCELLED_BY_USER:
return "SCARD_W_CANCELLED_BY_USER";
case SCARD_W_CACHE_ITEM_NOT_FOUND:
return "SCARD_W_CACHE_ITEM_NOT_FOUND";
case SCARD_W_CACHE_ITEM_STALE:
return "SCARD_W_CACHE_ITEM_STALE";
case SCARD_W_CACHE_ITEM_TOO_BIG:
return "SCARD_W_CACHE_ITEM_TOO_BIG";
case SCARD_W_CARD_NOT_AUTHENTICATED:
return "SCARD_W_CARD_NOT_AUTHENTICATED";
case SCARD_W_CHV_BLOCKED:
return "SCARD_W_CHV_BLOCKED";
case SCARD_W_EOF:
return "SCARD_W_EOF";
case SCARD_W_REMOVED_CARD:
return "SCARD_W_REMOVED_CARD";
case SCARD_W_RESET_CARD:
return "SCARD_W_RESET_CARD";
case SCARD_W_SECURITY_VIOLATION:
return "SCARD_W_SECURITY_VIOLATION";
case SCARD_W_UNPOWERED_CARD:
return "SCARD_W_UNPOWERED_CARD";
case SCARD_W_UNRESPONSIVE_CARD:
return "SCARD_W_UNRESPONSIVE_CARD";
case SCARD_W_UNSUPPORTED_CARD:
return "SCARD_W_UNSUPPORTED_CARD";
case SCARD_W_WRONG_CHV:
return "SCARD_W_WRONG_CHV";
default:
return "UNKNOWN";
}
}
static std::wstring err2wstr(LONG code)
{
auto str = err2str(code);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(str);
}
static bool test_valid(SCARDCONTEXT context)
{
auto rc = SCardIsValidContext(context);
if (rc)
std::cerr << "SCardIsValidContext failed with " << err2str(rc) << std::endl;
return true;
}
static bool test_list_readers_a(SCARDCONTEXT context)
{
for (auto cur : listA)
{
LPSTR mszReaders = nullptr;
DWORD chReaders = SCARD_AUTOALLOCATE;
auto rc = SCardListReadersA(context, cur, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
if (!cur)
{
cur = "NULL";
}
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardListReadersA [" << cur << "] failed with " << err2str(rc)
<< std::endl;
}
else
{
auto start = mszReaders;
auto end = &mszReaders[chReaders];
std::cout << "SCardListReadersA [" << cur << "] " << chReaders << " [";
while (start < end)
{
std::cout << start << ", ";
start += strnlen(start, chReaders) + 2;
}
std::cout << "]" << std::endl;
}
SCardFreeMemory(context, mszReaders);
}
return true;
}
static bool test_list_readers_w(SCARDCONTEXT context)
{
for (auto cur : listW)
{
LPWSTR mszReaders = nullptr;
DWORD chReaders = SCARD_AUTOALLOCATE;
auto rc =
SCardListReadersW(context, cur, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
if (!cur)
{
cur = L"NULL";
}
if (rc != SCARD_S_SUCCESS)
{
std::wcerr << L"SCardListReadersW [" << cur << L"] failed with " << err2wstr(rc)
<< std::endl;
}
else
{
auto start = mszReaders;
auto end = &mszReaders[chReaders];
std::wcout << L"SCardListReadersW [" << cur << L"] " << chReaders << L" [";
while (start < end)
{
std::wcout << start << L", ";
start += wcsnlen(start, chReaders) + 2;
}
std::wcout << L"]" << std::endl;
}
SCardFreeMemory(context, mszReaders);
}
return true;
}
static bool test_list_reader_groups_a(SCARDCONTEXT context)
{
LPSTR mszReaders = nullptr;
DWORD chReaders = SCARD_AUTOALLOCATE;
auto rc = SCardListReaderGroupsA(context, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardListReaderGroupsA failed with " << err2str(rc) << std::endl;
}
else
{
auto start = mszReaders;
auto end = &mszReaders[chReaders];
std::cout << "SCardListReaderGroupsA " << chReaders << " [";
while (start < end)
{
std::cout << start << ", ";
start += strnlen(start, chReaders) + 2;
}
std::cout << "]" << std::endl;
}
SCardFreeMemory(context, mszReaders);
return true;
}
static bool test_list_reader_groups_w(SCARDCONTEXT context)
{
LPWSTR mszReaders = nullptr;
DWORD chReaders = SCARD_AUTOALLOCATE;
auto rc = SCardListReaderGroupsW(context, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
if (rc != SCARD_S_SUCCESS)
{
std::wcerr << L"SCardListReaderGroupsW failed with " << err2wstr(rc) << std::endl;
}
else
{
auto start = mszReaders;
auto end = &mszReaders[chReaders];
std::wcout << L"SCardListReaderGroupsW " << chReaders << L" [";
while (start < end)
{
std::wcout << start << L", ";
start += wcsnlen(start, chReaders) + 2;
}
std::wcout << L"]" << std::endl;
}
SCardFreeMemory(context, mszReaders);
return true;
}
static bool test_introduce_forget_reader_groups_a(SCARDCONTEXT context)
{
LPSTR group = "somefancygroup";
auto rc = SCardIntroduceReaderGroupA(context, group);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardIntroduceReaderGroupA failed with " << err2str(rc) << std::endl;
return false;
}
else
{
rc = SCardForgetReaderGroupA(context, group);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardForgetReaderGroupA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
}
static bool test_introduce_forget_reader_groups_w(SCARDCONTEXT context)
{
LPWSTR group = L"somefancygroup";
auto rc = SCardIntroduceReaderGroupW(context, group);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardIntroduceReaderGroupW failed with " << err2str(rc) << std::endl;
return false;
}
else
{
rc = SCardForgetReaderGroupW(context, group);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardForgetReaderGroupW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
}
static bool test_introduce_forget_reader_a(SCARDCONTEXT context)
{
LPSTR reader = "somefancygroup";
LPSTR device = "otherfancy";
auto rc = SCardIntroduceReaderA(context, reader, device);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardIntroduceReaderA failed with " << err2str(rc) << std::endl;
return false;
}
else
{
rc = SCardForgetReaderA(context, reader);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardForgetReaderA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
}
static bool test_introduce_forget_reader_w(SCARDCONTEXT context)
{
LPWSTR reader = L"somefancygroup";
LPWSTR device = L"otherfancy";
auto rc = SCardIntroduceReaderW(context, reader, device);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardIntroduceReaderW failed with " << err2str(rc) << std::endl;
return false;
}
else
{
rc = SCardForgetReaderW(context, reader);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardForgetReaderW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
}
static bool test_list_cards_a(SCARDCONTEXT context)
{
DWORD chCards = SCARD_AUTOALLOCATE;
LPSTR mszCards = nullptr;
auto rc =
SCardListCardsA(context, nullptr, nullptr, 0, reinterpret_cast<LPSTR>(&mszCards), &chCards);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardListCardsA failed with " << err2str(rc) << std::endl;
}
else
{
auto start = mszCards;
auto end = &mszCards[chCards];
std::cout << "SCardListCardsA " << chCards << " [";
while (start < end)
{
std::cout << start << ", ";
start += strnlen(start, chCards) + 2;
}
std::cout << "]" << std::endl;
}
return true;
}
static bool test_list_cards_w(SCARDCONTEXT context)
{
DWORD chCards = SCARD_AUTOALLOCATE;
LPWSTR mszCards = nullptr;
auto rc = SCardListCardsW(context, nullptr, nullptr, 0, reinterpret_cast<LPWSTR>(&mszCards),
&chCards);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardListCardsW failed with " << err2str(rc) << std::endl;
}
else
{
auto start = mszCards;
auto end = &mszCards[chCards];
std::cout << "SCardListCardsW " << chCards << " [";
while (start < end)
{
std::wcout << start << L", ";
start += wcsnlen(start, chCards) + 2;
}
std::cout << "]" << std::endl;
}
return true;
}
static bool test_cache_a(SCARDCONTEXT context)
{
BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const DWORD wdatalen = sizeof(wdata);
BYTE data[32] = {};
DWORD datalen = sizeof(data);
LPSTR name = "testdata";
UUID id = {};
auto rc = SCardWriteCacheA(context, &id, 0, name, wdata, wdatalen);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardWriteCacheA failed with " << err2str(rc) << std::endl;
return false;
}
rc = SCardReadCacheA(context, &id, 0, name, data, &datalen);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardReadCacheA failed with " << err2str(rc) << std::endl;
return false;
}
if (wdatalen != datalen)
{
std::cerr << "SCardWriteCacheA wrote " << wdatalen << "bytes, SCardReadCacheA read "
<< datalen << "bytes" << std::endl;
return false;
}
if (memcmp(wdata, data, wdatalen) != 0)
{
std::cerr << "SCardWriteCacheA / SCardReadCacheA data corruption detected" << std::endl;
return false;
}
return true;
}
static bool test_cache_w(SCARDCONTEXT context)
{
BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const DWORD wdatalen = sizeof(wdata);
BYTE data[32] = {};
DWORD datalen = sizeof(data);
LPWSTR name = L"testdata";
UUID id = {};
auto rc = SCardWriteCacheW(context, &id, 0, name, wdata, wdatalen);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardWriteCacheW failed with " << err2str(rc) << std::endl;
return false;
}
rc = SCardReadCacheW(context, &id, 0, name, data, &datalen);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardReadCacheW failed with " << err2str(rc) << std::endl;
return false;
}
if (wdatalen != datalen)
{
std::cerr << "SCardReadCacheW wrote " << wdatalen << "bytes, SCardReadCacheW read "
<< datalen << "bytes" << std::endl;
return false;
}
if (memcmp(wdata, data, wdatalen) != 0)
{
std::cerr << "SCardReadCacheW / SCardReadCacheW data corruption detected" << std::endl;
return false;
}
return true;
}
static bool test_reader_icon_a(SCARDCONTEXT context)
{
LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
LPBYTE pbIcon = nullptr;
DWORD cbIcon = SCARD_AUTOALLOCATE;
auto rc = SCardGetReaderIconA(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
SCardFreeMemory(context, pbIcon);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetReaderIconA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_reader_icon_w(SCARDCONTEXT context)
{
LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
LPBYTE pbIcon = nullptr;
DWORD cbIcon = SCARD_AUTOALLOCATE;
auto rc = SCardGetReaderIconW(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
SCardFreeMemory(context, pbIcon);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetReaderIconW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_locate_cards_a(SCARDCONTEXT context)
{
LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
SCARD_READERSTATEA rgReaderStates[16] = {};
auto rc = SCardLocateCardsA(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardLocateCardsA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_locate_cards_w(SCARDCONTEXT context)
{
LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
SCARD_READERSTATEW rgReaderStates[16] = {};
auto rc = SCardLocateCardsW(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardLocateCardsW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_locate_cards_by_atr_a(SCARDCONTEXT context)
{
SCARD_READERSTATEA rgReaderStates[16] = {};
SCARD_ATRMASK rgAtrMasks[16] = {};
auto rc = SCardLocateCardsByATRA(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
ARRAYSIZE(rgReaderStates));
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardLocateCardsByATRA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_locate_cards_by_atr_w(SCARDCONTEXT context)
{
SCARD_READERSTATEW rgReaderStates[16] = {};
SCARD_ATRMASK rgAtrMasks[16] = {};
auto rc = SCardLocateCardsByATRW(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
ARRAYSIZE(rgReaderStates));
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardLocateCardsByATRW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_devicetype_id_a(SCARDCONTEXT context)
{
BYTE data[32] = {};
LPSTR name = "testdata";
DWORD type;
auto rc = SCardGetDeviceTypeIdA(context, name, &type);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetDeviceTypeIdA failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_devicetype_id_w(SCARDCONTEXT context)
{
BYTE data[32] = {};
LPWSTR name = L"testdata";
DWORD type;
auto rc = SCardGetDeviceTypeIdW(context, name, &type);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
return false;
}
return true;
}
static bool test_transmitcount(SCARDHANDLE handle)
{
BYTE data[32] = {};
LPWSTR name = L"testdata";
DWORD count;
auto rc = SCardGetTransmitCount(handle, &count);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetTransmitCount failed with " << err2str(rc) << std::endl;
return false;
}
std::cout << "SCardGetTransmitCount() " << count << std::endl;
return true;
}
static bool test_status_a(SCARDHANDLE handle)
{
BYTE data[32] = {};
LPWSTR name = L"testdata";
DWORD count;
/*
auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
if (rc != SCARD_S_SUCCESS) {
std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
return false;
}
*/
return true;
}
static bool test_status_w(SCARDHANDLE handle)
{
BYTE data[32] = {};
LPWSTR name = L"testdata";
DWORD count;
/*
auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
if (rc != SCARD_S_SUCCESS) {
std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
return false;
}
*/
return true;
}
static bool test_get_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
{
DWORD attrlen = SCARD_AUTOALLOCATE;
LPBYTE attr = nullptr;
auto rc =
SCardGetAttrib(handle, SCARD_ATTR_ATR_STRING, reinterpret_cast<LPBYTE>(&attr), &attrlen);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardGetAttrib failed with " << err2str(rc) << std::endl;
return false;
}
std::cout << "SCardGetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
SCardFreeMemory(context, attr);
return true;
}
static bool test_set_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
{
DWORD attrlen = SCARD_AUTOALLOCATE;
BYTE attr[] = "0123456789";
auto rc = SCardSetAttrib(handle, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST, attr, ARRAYSIZE(attr));
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardSetAttrib failed with " << err2str(rc) << std::endl;
return false;
}
std::cout << "SCardSetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
SCardFreeMemory(context, attr);
return true;
}
int main()
{
std::cout << "Hello World!" << std::endl;
try
{
auto scopes = { SCARD_SCOPE_USER, SCARD_SCOPE_SYSTEM };
for (auto scope : scopes)
{
SCARDCONTEXT context;
auto rc = SCardEstablishContext(scope, nullptr, nullptr, &context);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] failed with "
<< err2str(rc) << std::endl;
}
else
{
std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] success"
<< std::endl;
test_valid(context);
test_list_reader_groups_a(context);
test_list_reader_groups_w(context);
test_list_readers_a(context);
test_list_readers_w(context);
test_list_cards_a(context);
test_list_cards_w(context);
test_introduce_forget_reader_groups_a(context);
test_introduce_forget_reader_groups_w(context);
test_introduce_forget_reader_a(context);
test_introduce_forget_reader_w(context);
// TODO: Introduce/Remove reader to group
test_locate_cards_a(context);
test_locate_cards_w(context);
test_locate_cards_by_atr_a(context);
test_locate_cards_by_atr_w(context);
test_cache_a(context);
test_cache_w(context);
test_reader_icon_a(context);
test_reader_icon_w(context);
test_devicetype_id_a(context);
test_devicetype_id_w(context);
// TODO: statuschange
// TODO: begin/end transaction
// TODO: state
// TODO: transmit
// TODO: control
{
DWORD protocol;
SCARDHANDLE handle = 0;
LPSTR mszReaders;
DWORD chReaders = SCARD_AUTOALLOCATE;
LONG status = SCardListReadersA(
context, nullptr, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
if (status == SCARD_S_SUCCESS)
status = SCardConnectA(context, mszReaders, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
&handle, &protocol);
SCardFreeMemory(context, mszReaders);
if (status != SCARD_S_SUCCESS)
{
std::cerr << "SCardConnectA ["
<< "] failed with " << err2str(status) << std::endl;
}
else
{
test_status_a(handle);
test_status_w(handle);
test_get_attrib(context, handle);
test_set_attrib(context, handle);
test_transmitcount(handle);
status = SCardDisconnect(handle, 0);
if (status)
{
std::cerr << "SCardDisconnect ["
<< "] failed with " << err2str(status) << std::endl;
}
}
}
{
DWORD protocol;
SCARDHANDLE handle = 0;
LPWSTR mszReaders;
DWORD chReaders = SCARD_AUTOALLOCATE;
LONG status = SCardListReadersW(
context, nullptr, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
if (status == SCARD_S_SUCCESS)
status = SCardConnectW(context, mszReaders, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
&handle, &protocol);
SCardFreeMemory(context, mszReaders);
if (status != SCARD_S_SUCCESS)
{
std::cerr << "SCardConnectW ["
<< "] failed with " << err2str(status) << std::endl;
}
else
{
test_status_a(handle);
test_status_w(handle);
test_get_attrib(context, handle);
test_set_attrib(context, handle);
test_transmitcount(handle);
status = SCardDisconnect(handle, 0);
if (status)
{
std::cerr << "SCardDisconnect ["
<< "] failed with " << err2str(status) << std::endl;
}
}
}
rc = SCardReleaseContext(context);
if (rc != SCARD_S_SUCCESS)
{
std::cerr << "SCardReleaseContext [" << scope2str(scope) << "] failed with "
<< err2str(rc) << std::endl;
}
}
}
}
catch (...)
{
std::cerr << "exception!!!!" << std::endl;
}
return 0;
}

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python3
"""
Get the toolchains path
https://proandroiddev.com/tutorial-compile-openssl-to-1-1-1-for-android-application-87137968fee
"""
import argparse
import atexit
import inspect
import os
import shutil
import stat
import sys
import textwrap
def get_host_tag_or_die():
"""Return the host tag for this platform. Die if not supported."""
if sys.platform.startswith('linux'):
return 'linux-x86_64'
elif sys.platform == 'darwin':
return 'darwin-x86_64'
elif sys.platform == 'win32' or sys.platform == 'cygwin':
host_tag = 'windows-x86_64'
if not os.path.exists(os.path.join(NDK_DIR, 'prebuilt', host_tag)):
host_tag = 'windows'
return host_tag
sys.exit('Unsupported platform: ' + sys.platform)
def get_toolchain_path_or_die(ndk, host_tag):
"""Return the toolchain path or die."""
toolchain_path = os.path.join(ndk, 'toolchains/llvm/prebuilt',
host_tag, 'bin')
if not os.path.exists(toolchain_path):
sys.exit('Could not find toolchain: {}'.format(toolchain_path))
return toolchain_path
def main():
"""Program entry point."""
parser = argparse.ArgumentParser(description='Optional app description')
parser.add_argument('--ndk', required=True,
help='The NDK Home directory')
args = parser.parse_args()
host_tag = get_host_tag_or_die()
toolchain_path = get_toolchain_path_or_die(args.ndk, host_tag)
print(toolchain_path)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,42 @@
#!/usr/bin/env python3
import os
import urllib.request
import xml.etree.ElementTree as ET
name = os.path.realpath(__file__)
base = os.path.normpath(os.path.join(os.path.dirname(name), '..'))
rname = os.path.relpath(name, base)
zfile = os.path.join(base, 'winpr/libwinpr/timezone/WindowsZones.c')
#url = 'https://raw.githubusercontent.com/unicode-org/cldr/latest/common/supplemental/windowsZones.xml'
url = 'https://raw.githubusercontent.com/unicode-org/cldr/main/common/supplemental/windowsZones.xml'
try:
with urllib.request.urlopen(url) as response:
xml = response.read()
root = ET.fromstring(xml)
entries = []
for child in root.iter('mapZone'):
tzid = child.get('type')
windows = child.get('other')
entries += ['\t{ "' + windows + '", "' + tzid + '" },\n']
entries.sort()
with open(zfile, 'w') as f:
f.write('/*\n')
f.write(' * Automatically generated with ' + str(rname) + '\n')
f.write(' */\n')
f.write('\n')
f.write('#include "WindowsZones.h"\n')
f.write('\n')
f.write('const WINDOWS_TZID_ENTRY WindowsTimeZoneIdTable[] =\n')
f.write('{\n')
for entry in entries:
f.write(entry)
f.write('};\n')
f.write('\n');
f.write('const size_t WindowsTimeZoneIdTableNrElements = ARRAYSIZE(WindowsTimeZoneIdTable);\n')
except Exception as e:
print('----------------------------------------------------')
print(str(e))
print('----------------------------------------------------')

74
third_party/FreeRDP/scripts/xcode.sh vendored Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# may now be legacy; 2 stage cmake no longer needed
# Xcode generated files directory
XCODE_PROJ_DIR=xcode
# MacFreeRDP client directory
CLIENT_MAC_DIR=./client/Mac/
pushd .
GEN='Xcode'
# Build settings
ARCH=-DCMAKE_OSX_ARCHITECTURES="${CMAKE_OSX_ARCHITECTURES:-i386;x86_64}"
BUILDTYPE=-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:Debug}"
MANPAGES=-DWITH_MANPAGES="${WITHMANPAGES:NO}"
# Run cmake for FreeRDP and MacFreeRDP
mkdir ${XCODE_PROJ_DIR} >/dev/null 2>&1
pushd ${XCODE_PROJ_DIR}
cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../
popd
mkdir ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR} >/dev/null 2>&1
pushd ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR}
cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../
popd
# Check for errors; otherwise, ask for compile.
if [ "$?" -ne 0 ]; then
echo "CMake failed. Please check error messages"
popd >/dev/null
exit
else
popd
while true; do
echo -n "Compile FreeRDP? (y or n) - (y recommended for MacFreeRDP compilation):"
read CONFIRM
case $CONFIRM in
y | Y | YES | yes | Yes)
pushd ./${XCODE_PROJ_DIR}
xcodebuild
popd
break
;;
n | N | no | NO | No)
echo OK - you entered $CONFIRM
break
;;
*) echo Please enter only y or n ;;
esac
done
echo "SUCCESS!"
while true; do
echo -n "Open Xcode projects now? (y or n):"
read CONFIRM
case $CONFIRM in
y | Y | YES | yes | Yes)
open ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR}/MacFreeRDP.xcodeproj
open ./${XCODE_PROJ_DIR}/FreeRDP.xcodeproj
break
;;
n | N | no | NO | No)
echo OK - $CONFIRM
break
;;
*) echo Please enter only y or n ;;
esac
done
echo -n "NOTE: Dragging FreeRDP project from finder onto the MacFreeRDP project in Xcode
will enable code stepping from MacFreeRDP into FreeRDP.
"
fi

303
third_party/FreeRDP/scripts/xkb.pl vendored Executable file
View File

@@ -0,0 +1,303 @@
#!/usr/bin/perl
# FreeRDP: A Remote Desktop Protocol Implementation
# XKB database conversion script
# Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Description:
# Script to export XKB configuration files to keycode -> virtual key code keymaps that are
# easy to use in FreeRDP. This makes keymap maintenance easier to make as all bugs can
# simply be reported to the XKB Configuration Database project, and then this script can
# be used to export newer (and fixed) version of the XKB Configuration Database.
use Cwd;
my %sym2virt = (
"AE00" => "VK_TILDE",
"AE01" => "VK_KEY_1",
"AE02" => "VK_KEY_2",
"AE03" => "VK_KEY_3",
"AE04" => "VK_KEY_4",
"AE05" => "VK_KEY_5",
"AE06" => "VK_KEY_6",
"AE07" => "VK_KEY_7",
"AE08" => "VK_KEY_8",
"AE09" => "VK_KEY_9",
"AE10" => "VK_KEY_0",
"AE11" => "VK_OEM_MINUS",
"AE12" => "VK_OEM_PLUS",
"AD01" => "VK_KEY_Q",
"AD02" => "VK_KEY_W",
"AD03" => "VK_KEY_E",
"AD04" => "VK_KEY_R",
"AD05" => "VK_KEY_T",
"AD06" => "VK_KEY_Y",
"AD07" => "VK_KEY_U",
"AD08" => "VK_KEY_I",
"AD09" => "VK_KEY_O",
"AD10" => "VK_KEY_P",
"AD11" => "VK_OEM_4",
"AD12" => "VK_OEM_6",
"AC01" => "VK_KEY_A",
"AC02" => "VK_KEY_S",
"AC03" => "VK_KEY_D",
"AC04" => "VK_KEY_F",
"AC05" => "VK_KEY_G",
"AC06" => "VK_KEY_H",
"AC07" => "VK_KEY_J",
"AC08" => "VK_KEY_K",
"AC09" => "VK_KEY_L",
"AC10" => "VK_OEM_1",
"AC11" => "VK_OEM_7",
"AC12" => "VK_OEM_5",
"AB00" => "VK_LSHIFT",
"AB01" => "VK_KEY_Z",
"AB02" => "VK_KEY_X",
"AB03" => "VK_KEY_C",
"AB04" => "VK_KEY_V",
"AB05" => "VK_KEY_B",
"AB06" => "VK_KEY_N",
"AB07" => "VK_KEY_M",
"AB08" => "VK_OEM_COMMA",
"AB09" => "VK_OEM_PERIOD",
"AB10" => "VK_OEM_2",
"AB11" => "VK_ABNT_C1",
"FK01" => "VK_F1",
"FK02" => "VK_F2",
"FK03" => "VK_F3",
"FK04" => "VK_F4",
"FK05" => "VK_F5",
"FK06" => "VK_F6",
"FK07" => "VK_F7",
"FK08" => "VK_F8",
"FK09" => "VK_F9",
"FK10" => "VK_F10",
"FK11" => "VK_F11",
"FK12" => "VK_F12",
"FK13" => "VK_F13",
"FK14" => "VK_F14",
"FK15" => "VK_F15",
"FK16" => "VK_F16",
"FK17" => "VK_F17",
"FK18" => "VK_F18",
"FK19" => "VK_F19",
"FK20" => "VK_F20",
"FK21" => "VK_F21",
"FK22" => "VK_F22",
"FK23" => "VK_F23",
"FK24" => "VK_F24",
"KP0" => "VK_NUMPAD0",
"KP1" => "VK_NUMPAD1",
"KP2" => "VK_NUMPAD2",
"KP3" => "VK_NUMPAD3",
"KP4" => "VK_NUMPAD4",
"KP5" => "VK_NUMPAD5",
"KP6" => "VK_NUMPAD6",
"KP7" => "VK_NUMPAD7",
"KP8" => "VK_NUMPAD8",
"KP9" => "VK_NUMPAD9",
"KPDV" => "VK_DIVIDE",
"KPMU" => "VK_MULTIPLY",
"KPSU" => "VK_SUBTRACT",
"KPAD" => "VK_ADD",
"KPDL" => "VK_DECIMAL",
"KPEN" => "VK_RETURN",
"RTRN" => "VK_RETURN",
"SPCE" => "VK_SPACE",
"BKSP" => "VK_BACK",
"BKSL" => "VK_OEM_5",
"LSGT" => "VK_OEM_102",
"ESC" => "VK_ESCAPE",
"TLDE" => "VK_OEM_3",
"CAPS" => "VK_CAPITAL",
"TAB" => "VK_TAB",
"LFSH" => "VK_LSHIFT",
"RTSH" => "VK_RSHIFT",
"LCTL" => "VK_LCONTROL",
"RCTL" => "VK_RCONTROL",
"LWIN" => "VK_LWIN",
"RWIN" => "VK_RWIN",
"LALT" => "VK_LMENU",
"RALT" => "VK_RMENU",
"COMP" => "VK_APPS",
"MENU" => "VK_APPS",
"UP" => "VK_UP",
"DOWN" => "VK_DOWN",
"LEFT" => "VK_LEFT",
"RGHT" => "VK_RIGHT",
"INS" => "VK_INSERT",
"DELE" => "VK_DELETE",
"PGUP" => "VK_PRIOR",
"PGDN" => "VK_NEXT",
"HOME" => "VK_HOME",
"END" => "VK_END",
"PAUS" => "VK_PAUSE",
"NMLK" => "VK_NUMLOCK",
"SCLK" => "VK_SCROLL",
# This page helps understanding the keys that follow:
# http://www.stanford.edu/class/cs140/projects/pintos/specs/kbd/scancodes-7.html
"KANJ" => "VK_KANJI",
"HANJ" => "VK_HANJA",
"MUHE" => "VK_NONCONVERT",
"HIRA" => "VK_KANA",
"PRSC" => "VK_SNAPSHOT",
"KPF1" => "VK_NUMLOCK",
"KPF2" => "VK_DIVIDE",
"KPF3" => "VK_MULTIPLY",
"KPF4" => "VK_SUBTRACT",
"KPCO" => "VK_ADD",
"HELP" => "VK_HELP",
"SELE" => "VK_SELECT",
# We can ignore LDM (Lock Down Modifier)
# What are LCMP/RCMP?
# DO, FIND?
);
my $inDir;
my $outDir;
if(@ARGV < 1) {
$inDir = getcwd() . "/";
$outDir = $inDir;
} elsif(@ARGV == 1) {
$inDir = $ARGV[0];
$outDir = getcwd() . "/";
} elsif(@ARGV == 2) {
$inDir = $ARGV[0];
$outDir = $ARGV[1];
} else {
print "Error: Too many arguments\n" .
"Usage:\n" .
"perl xkb.pl <XKB Directory>\n" .
"perl xkb.pl <XKB Directory> <Output Directory>\n\n" .
"In Linux, the XKB directory usually is /usr/share/X11/xkb/\n" .
"The latest version of XKB can always be downloaded at:\n" .
"http://freedesktop.org/wiki/Software/XKeyboardConfig\n";
exit 0;
}
open("SPEC", $inDir . "xkeyboard-config.spec");
$xkbVersion = "";
while($line = <SPEC>) {
if($line =~ m/Version:\s+(.\..)/) {
$xkbVersion = "version $1";
}
}
# Create directory if it does not exists
if(not -e $outDir) {
mkdir $outDir or die("Error: Can't create directory $outDir\n");
}
open("KCD", $inDir . "keycodes/keycodes.dir") or die("Error: Can't open $inDir" . "keycodes/keycodes.dir\n");
$previousFile = "";
while($line = <KCD>) {
if($line =~ m/........ -------- (.+)\((.+)\)/) {
if($1 ne $previousFile) {
push(@keymapFiles, $1);
$previousFile = $1;
}
}
}
close("KCD");
foreach $keymapFile (@keymapFiles) {
print "File $keymapFile:\n";
@directories = split(/\//, $keymapFile);
splice(@directories, @directories - 1, 1);
if(@directories > 0) {
$directory = $outDir;
for($i = 0; $i < @directories; $i++) {
$directory .= $directories[$i] . "/";
if(not -e $directory) {
mkdir $directory or die("Can't create directory $directory\n");
}
}
}
open("IN", $inDir . "keycodes/" . $keymapFile);
open("OUT", ">" . "$outDir" . $keymapFile);
print OUT "# This file was generated with xkb.pl\n";
print OUT "# and is based on the X Keyboard Configuration Database $xkbVersion\n";
print OUT "# Please use xkb.pl to re-export newer versions of XKB\n";
print OUT "\n\n";
while($line = <IN>) {
if($line =~ m/xkb_keycodes \"(\w+)\"/) {
print "Exporting \"$1\"\n";
print OUT "keyboard \"$1\"";
while($line = <IN>) {
if($line =~ m/include\W+\"(.+)\"/) {
print OUT "\n: extends \"$1\"";
last;
} else {
last;
}
}
print OUT "\n{\n";
while($line = <IN>) {
if($line =~ m/<(\w{1,4})>\W+=\W+(\w+);/) {
if($sym2virt{$1} ne undef) {
$vkcode = $sym2virt{$1};
print OUT "\t$vkcode";
if(length($vkcode) < 8) {
print OUT "\t";
}
print OUT "\t<$2>\n";
} else {
# If undef, then this symbolic key code is
# missing from the sym2virt hash table
# print "\t$1\t$2\n";
}
} elsif($line =~ m/};/) {
print OUT "};\n\n";
last;
}
}
}
}
close("IN");
close("OUT");
}