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
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
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;
}
+153
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
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)
+292
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
+36
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"
+36
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"
+40
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"
+309
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
}
+217
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
+204
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"
+60
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
+83
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/
+36
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"
+36
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
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
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
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
+245
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: {}
+30
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
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/..
+77
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
+129
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()
+56
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
+15
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
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
+41
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__)
+69
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))
+914
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;
}
+49
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()
+42
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
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
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");
}