Squashed 'third_party/pi/' content from commit d981de122
git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
This commit is contained in:
20
packages/tui/native/darwin/README.md
Normal file
20
packages/tui/native/darwin/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Darwin native prebuilds
|
||||
|
||||
Build both macOS architectures from the repository root:
|
||||
|
||||
```sh
|
||||
npm --prefix packages/tui run build:native:darwin
|
||||
```
|
||||
|
||||
The build uses macOS 11.0 as the arm64 deployment target and macOS 10.15 as the x86_64 deployment target. On macOS, `build.sh` finds Apple clang and the active macOS SDK through `xcrun`. Either an Intel or Apple Silicon host can build both outputs.
|
||||
|
||||
A non-macOS host needs a complete Darwin cross-toolchain, including a macOS SDK and a Mach-O linker. For example, an osxcross installation can be selected with `CC` and `SDKROOT`:
|
||||
|
||||
```sh
|
||||
CC=/path/to/osxcross/clang SDKROOT=/path/to/MacOSX.sdk \
|
||||
npm --prefix packages/tui run build:native:darwin
|
||||
```
|
||||
|
||||
The SDK must be obtained and used in accordance with Apple's license. Plain Linux or Windows clang is not enough because the addon includes and links CoreGraphics.
|
||||
|
||||
Zig is not used here because it does not provide the Apple SDK or CoreGraphics framework stubs. It therefore does not make this build SDK-independent, and its clang driver does not currently handle this Mach-O bundle recipe as a drop-in replacement for Apple clang.
|
||||
62
packages/tui/native/darwin/build.sh
Executable file
62
packages/tui/native/darwin/build.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source_file="$script_dir/src/darwin-modifiers.c"
|
||||
|
||||
if [[ -n "${CC:-}" ]]; then
|
||||
compiler="$CC"
|
||||
elif [[ "$(uname -s)" == "Darwin" ]] && command -v xcrun >/dev/null 2>&1; then
|
||||
compiler="$(xcrun --find clang)"
|
||||
else
|
||||
compiler="clang"
|
||||
fi
|
||||
|
||||
if ! command -v "$compiler" >/dev/null 2>&1; then
|
||||
echo "Darwin C compiler not found: $compiler" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sdk_flags=()
|
||||
if [[ -n "${SDKROOT:-}" ]]; then
|
||||
if [[ ! -d "$SDKROOT" ]]; then
|
||||
echo "SDKROOT does not exist: $SDKROOT" >&2
|
||||
exit 1
|
||||
fi
|
||||
sdk_flags=(-isysroot "$SDKROOT" "-F$SDKROOT/System/Library/Frameworks")
|
||||
elif [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
sdkroot="$(xcrun --sdk macosx --show-sdk-path)"
|
||||
sdk_flags=(-isysroot "$sdkroot" "-F$sdkroot/System/Library/Frameworks")
|
||||
fi
|
||||
|
||||
temporary_dir="$(mktemp -d "${TMPDIR:-/tmp}/pi-tui-darwin.XXXXXX")"
|
||||
trap 'rm -rf "$temporary_dir"' EXIT
|
||||
|
||||
build() {
|
||||
local arch="$1"
|
||||
local target="$2"
|
||||
local output_dir="$script_dir/prebuilds/darwin-$arch"
|
||||
local temporary_output="$temporary_dir/darwin-$arch/darwin-modifiers.node"
|
||||
|
||||
mkdir -p "$(dirname "$temporary_output")"
|
||||
"$compiler" \
|
||||
-std=c11 \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-O2 \
|
||||
"--target=$target" \
|
||||
"${sdk_flags[@]}" \
|
||||
-bundle \
|
||||
-undefined dynamic_lookup \
|
||||
-framework CoreGraphics \
|
||||
"$source_file" \
|
||||
-o "$temporary_output"
|
||||
|
||||
mkdir -p "$output_dir"
|
||||
install -m 755 "$temporary_output" "$output_dir/darwin-modifiers.node"
|
||||
echo "Built $output_dir/darwin-modifiers.node"
|
||||
}
|
||||
|
||||
build arm64 arm64-apple-macos11.0
|
||||
build x64 x86_64-apple-macos10.15
|
||||
BIN
packages/tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node
Executable file
BIN
packages/tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node
Executable file
Binary file not shown.
BIN
packages/tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node
Executable file
BIN
packages/tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node
Executable file
Binary file not shown.
70
packages/tui/native/darwin/src/darwin-modifiers.c
Normal file
70
packages/tui/native/darwin/src/darwin-modifiers.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NAPI_AUTO_LENGTH ((size_t)-1)
|
||||
|
||||
typedef void* napi_env;
|
||||
typedef void* napi_value;
|
||||
typedef void* napi_callback_info;
|
||||
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
|
||||
typedef int (*napi_create_function_fn)(napi_env, const char*, size_t, napi_callback, void*, napi_value*);
|
||||
typedef int (*napi_set_named_property_fn)(napi_env, napi_value, const char*, napi_value);
|
||||
typedef int (*napi_get_boolean_fn)(napi_env, bool, napi_value*);
|
||||
typedef int (*napi_get_cb_info_fn)(napi_env, napi_callback_info, size_t*, napi_value*, napi_value*, void**);
|
||||
typedef int (*napi_get_value_string_utf8_fn)(napi_env, napi_value, char*, size_t, size_t*);
|
||||
|
||||
static void* node_symbol(const char* name) {
|
||||
return dlsym(RTLD_DEFAULT, name);
|
||||
}
|
||||
|
||||
static CGEventFlags modifier_mask_for_name(const char* name) {
|
||||
if (strcmp(name, "shift") == 0) return kCGEventFlagMaskShift;
|
||||
if (strcmp(name, "command") == 0) return kCGEventFlagMaskCommand;
|
||||
if (strcmp(name, "control") == 0) return kCGEventFlagMaskControl;
|
||||
if (strcmp(name, "option") == 0) return kCGEventFlagMaskAlternate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static napi_value is_modifier_pressed(napi_env env, napi_callback_info info) {
|
||||
napi_get_cb_info_fn napi_get_cb_info = (napi_get_cb_info_fn)node_symbol("napi_get_cb_info");
|
||||
napi_get_value_string_utf8_fn napi_get_value_string_utf8 = (napi_get_value_string_utf8_fn)node_symbol("napi_get_value_string_utf8");
|
||||
napi_get_boolean_fn napi_get_boolean = (napi_get_boolean_fn)node_symbol("napi_get_boolean");
|
||||
|
||||
bool pressed = false;
|
||||
if (napi_get_cb_info && napi_get_value_string_utf8) {
|
||||
size_t argc = 1;
|
||||
napi_value args[1] = {0};
|
||||
if (napi_get_cb_info(env, info, &argc, args, 0, 0) == 0 && argc >= 1 && args[0]) {
|
||||
char name[16] = {0};
|
||||
size_t copied = 0;
|
||||
if (napi_get_value_string_utf8(env, args[0], name, sizeof(name), &copied) == 0) {
|
||||
CGEventFlags mask = modifier_mask_for_name(name);
|
||||
if (mask != 0) {
|
||||
CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
|
||||
pressed = (flags & mask) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
napi_value result = 0;
|
||||
if (napi_get_boolean) napi_get_boolean(env, pressed, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) napi_value napi_register_module_v1(napi_env env, napi_value exports) {
|
||||
napi_create_function_fn napi_create_function = (napi_create_function_fn)node_symbol("napi_create_function");
|
||||
napi_set_named_property_fn napi_set_named_property = (napi_set_named_property_fn)node_symbol("napi_set_named_property");
|
||||
|
||||
napi_value fn = 0;
|
||||
if (napi_create_function &&
|
||||
napi_set_named_property &&
|
||||
napi_create_function(env, "isModifierPressed", NAPI_AUTO_LENGTH, is_modifier_pressed, 0, &fn) == 0) {
|
||||
napi_set_named_property(env, exports, "isModifierPressed", fn);
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
Reference in New Issue
Block a user