From ebc810a4d81053f7d2803d2d34e1aea252b7ead2 Mon Sep 17 00:00:00 2001
From: monkuous <84319635+monkuous@users.noreply.github.com>
Date: Sat, 15 Nov 2025 23:22:35 +0100
Subject: [PATCH] lwjgl3: add port
---
patches/lwjgl3/jinx-working-patch.patch | 3814 +++++++++++++++++++++++
recipes/lwjgl3 | 46 +
source-recipes/lwjgl3 | 8 +
3 files changed, 3868 insertions(+)
create mode 100644 patches/lwjgl3/jinx-working-patch.patch
create mode 100644 recipes/lwjgl3
create mode 100644 source-recipes/lwjgl3
diff --git a/patches/lwjgl3/jinx-working-patch.patch b/patches/lwjgl3/jinx-working-patch.patch
new file mode 100644
index 00000000..e2924a29
--- /dev/null
+++ b/patches/lwjgl3/jinx-working-patch.patch
@@ -0,0 +1,3814 @@
+diff -urN --no-dereference lwjgl3-clean/build.xml lwjgl3-workdir/build.xml
+--- lwjgl3-clean/build.xml
++++ lwjgl3-workdir/build.xml
+@@ -1181,6 +1181,7 @@
+
+
+
++
+
+
+
+@@ -1221,6 +1222,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1288,6 +1292,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1306,6 +1313,7 @@
+
+
+
++
+
+
+
+@@ -1333,6 +1341,7 @@
+
+
+
++
+
+
+
+@@ -1557,6 +1566,10 @@
+
+
+
++
++
++
++
+
+
+
+@@ -1583,6 +1596,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1628,6 +1644,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1653,6 +1672,7 @@
+
+
+
++
+
+
+
+@@ -1678,6 +1698,7 @@
+
+
+
++
+
+
+
+@@ -1693,6 +1714,7 @@
+
+
+
++
+
+
+
+@@ -1728,6 +1750,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1758,6 +1783,10 @@
+
+
+
++
++
++
++
+
+
+
+@@ -1781,6 +1810,9 @@
+
+
+
++
++
++
+
+
+
+@@ -1810,6 +1842,8 @@
+
+
+
++
++
+
+
+
+@@ -1829,6 +1863,7 @@
+
+
+
++
+
+
+
+@@ -1848,6 +1883,7 @@
+
+
+
++
+
+
+
+diff -urN --no-dereference lwjgl3-clean/config/astral/build.xml lwjgl3-workdir/config/astral/build.xml
+--- lwjgl3-clean/config/astral/build.xml 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/config/astral/build.xml
+@@ -0,0 +1,482 @@
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -urN --no-dereference lwjgl3-clean/config/astral/version.script lwjgl3-workdir/config/astral/version.script
+--- lwjgl3-clean/config/astral/version.script 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/config/astral/version.script
+@@ -0,0 +1,9 @@
++LWJGL {
++ # Expose symbols required by the JVM
++ global:
++ *org_lwjgl_*;
++ JNI_On*;
++
++ # Hide everything else
++ local: *;
++};
+diff -urN --no-dereference lwjgl3-clean/config/build-definitions.xml lwjgl3-workdir/config/build-definitions.xml
+--- lwjgl3-clean/config/build-definitions.xml
++++ lwjgl3-workdir/config/build-definitions.xml
+@@ -120,10 +120,14 @@
+
+
+
++
++
++
+
+
+
+
++
+
+
+
+@@ -131,6 +135,7 @@
+
+
+
++
+
+
+
+diff -urN --no-dereference lwjgl3-clean/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt lwjgl3-workdir/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
+--- lwjgl3-clean/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
++++ lwjgl3-workdir/modules/generator/src/main/kotlin/org/lwjgl/generator/Modules.kt
+@@ -55,6 +55,11 @@
+ "Contains bindings to native APIs specific to the Windows operating system.",
+ CallingConvention.STDCALL
+ ),
++ CORE_ASTRAL(
++ "core.astral",
++ "org.lwjgl.system.astral",
++ "Contains bindings to native APIs specific to the Astral operating system."
++ ),
+
+ ASSIMP(
+ "assimp",
+@@ -988,4 +993,4 @@
+ }
+ }
+
+-fun String.dependsOn(vararg modules: Module): String? = if (modules.any { it.enabled }) this else null
+\ No newline at end of file
++fun String.dependsOn(vararg modules: Module): String? = if (modules.any { it.enabled }) this else null
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/main/c/astral/AstralConfig.h lwjgl3-workdir/modules/lwjgl/core/src/main/c/astral/AstralConfig.h
+--- lwjgl3-clean/modules/lwjgl/core/src/main/c/astral/AstralConfig.h 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/main/c/astral/AstralConfig.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++
++#include
++#include
++
++#define DISABLE_WARNINGS() \
++ _Pragma("GCC diagnostic push") \
++ _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
++
++#define ENABLE_WARNINGS() \
++ _Pragma("GCC diagnostic pop")
++
++// JNIEXPORT_CRITICAL & CRITICAL are used as a workaround for JDK-8167409 on applicable functions.
++#define JNIEXPORT_CRITICAL static
++#define CRITICAL(function) _JavaCritical_##function
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/main/c/common_tools.h lwjgl3-workdir/modules/lwjgl/core/src/main/c/common_tools.h
+--- lwjgl3-clean/modules/lwjgl/core/src/main/c/common_tools.h
++++ lwjgl3-workdir/modules/lwjgl/core/src/main/c/common_tools.h
+@@ -13,6 +13,9 @@
+ #ifdef LWJGL_MACOS
+ #include "macOSConfig.h"
+ #endif
++#ifdef LWJGL_ASTRAL
++ #include "AstralConfig.h"
++#endif
+
+ DISABLE_WARNINGS()
+ #include
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/APIUtil.java lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/APIUtil.java
+--- lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/APIUtil.java
++++ lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/APIUtil.java
+@@ -9,6 +9,7 @@
+ import org.lwjgl.system.linux.*;
+ import org.lwjgl.system.macosx.*;
+ import org.lwjgl.system.windows.*;
++import org.lwjgl.system.astral.*;
+
+ import javax.annotation.*;
+ import java.io.*;
+@@ -128,6 +129,8 @@
+ return new LinuxLibrary(name);
+ case MACOSX:
+ return MacOSXLibrary.create(name);
++ case ASTRAL:
++ return new AstralLibrary(name);
+ default:
+ throw new IllegalStateException();
+ }
+@@ -669,4 +672,4 @@
+ public static void apiClosureRet(long ret, float __result) { memPutFloat(ret, __result); }
+ public static void apiClosureRet(long ret, double __result) { memPutDouble(ret, __result); }
+
+-}
+\ No newline at end of file
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java
+--- lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java
++++ lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java
+@@ -47,6 +47,18 @@
+
+ return System.mapLibraryName(name);
+ }
++ },
++ ASTRAL("Astral", "astral") {
++ private final Pattern SO = Pattern.compile("(?:^|/)lib\\w+[.]so(?:[.]\\d+)*$");
++
++ @Override
++ String mapLibraryName(String name) {
++ if (SO.matcher(name).find()) {
++ return name;
++ }
++
++ return System.mapLibraryName(name);
++ }
+ };
+
+ /** The architectures supported by LWJGL. */
+@@ -87,6 +99,8 @@
+ current = LINUX;
+ } else if (osName.startsWith("Mac OS X") || osName.startsWith("Darwin")) {
+ current = MACOSX;
++ } else if (osName.startsWith("Astral")) {
++ current = ASTRAL;
+ } else {
+ throw new LinkageError("Unknown platform: " + osName);
+ }
+@@ -169,4 +183,4 @@
+ }
+ }
+
+-}
+\ No newline at end of file
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/astral/AstralLibrary.java lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/astral/AstralLibrary.java
+--- lwjgl3-clean/modules/lwjgl/core/src/main/java/org/lwjgl/system/astral/AstralLibrary.java 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/main/java/org/lwjgl/system/astral/AstralLibrary.java
+@@ -0,0 +1,54 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package org.lwjgl.system.astral;
++
++import org.lwjgl.system.*;
++
++import javax.annotation.*;
++import java.nio.*;
++
++import static org.lwjgl.system.MemoryStack.*;
++import static org.lwjgl.system.MemoryUtil.*;
++import static org.lwjgl.system.astral.DynamicLinkLoader.*;
++
++/** Implements a {@link SharedLibrary} on the Astral OS. */
++public class AstralLibrary extends SharedLibrary.Default {
++
++ public AstralLibrary(String name) {
++ this(name, loadLibrary(name));
++ }
++
++ public AstralLibrary(String name, long handle) {
++ super(name, handle);
++ }
++
++ private static long loadLibrary(String name) {
++ long handle;
++ try (MemoryStack stack = stackPush()) {
++ handle = dlopen(stack.UTF8(name), RTLD_LAZY | RTLD_LOCAL);
++ }
++ if (handle == NULL) {
++ throw new UnsatisfiedLinkError("Failed to dynamically load library: " + name + "(error = " + dlerror() + ")");
++ }
++ return handle;
++ }
++
++ @Nullable
++ @Override
++ public String getPath() {
++ return SharedLibraryUtil.getLibraryPath(address());
++ }
++
++ @Override
++ public long getFunctionAddress(ByteBuffer functionName) {
++ return dlsym(address(), functionName);
++ }
++
++ @Override
++ public void free() {
++ dlclose(address());
++ }
++
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/LinuxTypes.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/LinuxTypes.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/LinuxTypes.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/LinuxTypes.kt
+@@ -0,0 +1,156 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral
++
++import org.lwjgl.generator.*
++
++val __u8 = typedef(uint8_t, "__u8")
++val __u16 = typedef(uint16_t, "__u16")
++val __u32 = typedef(uint32_t, "__u32")
++val __u64 = typedef(uint64_t, "__u64")
++
++val __s32 = typedef(int32_t, "__s32")
++val __s64 = typedef(int64_t, "__s64")
++
++val ssize_t = IntegerType("ssize_t", PrimitiveMapping.POINTER)
++
++val mode_t = typedef(unsigned_int, "mode_t")
++val off_t = typedef(int64_t, "off_t")
++val pid_t = typedef(int, "pid_t")
++val pthread_t = typedef(unsigned_long_int, "pthread_t")
++val socklen_t = typedef(uint32_t, "socklen_t")
++
++val cpu_set_t = "cpu_set_t".opaque
++val sigset_t = "sigset_t".opaque
++
++val flock = struct(Module.CORE_ASTRAL, "Flock", nativeName = "flock64") {
++ short("l_type", "type of lock").links("#F_RDLCK #F_WRLCK #F_UNLCK")
++ short("l_whence", "where {@code l_start} is relative to (like {@code lseek})")
++ off_t("l_start", "offset where the lock begins")
++ off_t("l_len", "size of the locked area; zero means until EOF")
++ pid_t("l_pid", "process holding the lock")
++}
++
++val f_owner_ex = struct(Module.CORE_ASTRAL, "FOwnerEx", nativeName = "f_owner_ex") {
++ int("type", "")
++ pid_t("pid", "")
++}
++
++// fcntl.h
++
++val open_how = struct(Module.CORE_ASTRAL, "OpenHow", nativeName = "struct open_how") {
++ documentation =
++ """
++ Arguments for how {@code openat2(2)} should open the target path.
++
++ If only {@code flags} and {@code @}mode are non-zero, then {@code openat2(2)} operates very similarly to {@code openat(2)}.
++
++ However, unlike {@code openat(2)}, unknown or invalid bits in {@code flags} result in {@code -EINVAL} rather than being silently ignored. {@code mode}
++ must be zero unless one of #O_CREAT, #O_TMPFILE are set.
++ """
++
++ __u64("flags", "")
++ __u64("mode", "")
++ __u64("resolve", "")
++}
++
++// fs.h
++
++val __kernel_rwf_t = typedef(int, "__kernel_rwf_t")
++
++// sys/epoll.h
++
++val epoll_data_t = union(Module.CORE_ASTRAL, "EpollData", nativeName = "epoll_data_t") {
++ opaque_p("ptr", "")
++ int("fd", "")
++ uint32_t("u32", "")
++ uint64_t("u64", "")
++}
++
++val epoll_event = struct(Module.CORE_ASTRAL, "EpollEvent", nativeName = "struct epoll_event") {
++ uint32_t("events", "epoll events")
++ epoll_data_t("data", "user data variable")
++}
++
++// sys/uio.h
++
++val iovec = struct(Module.CORE_ASTRAL, "IOVec", nativeName = "struct iovec") {
++ Check("iov_len")..nullable..void.p("iov_base", "starting address")
++ size_t("iov_len", "number of bytes to transfer")
++}
++
++// sys/socket.h
++
++val msghdr = struct(Module.CORE_ASTRAL, "Msghdr", nativeName = "struct msghdr") {
++ void.p("msg_name", "address to send to/receive from")
++ AutoSize("msg_name")..socklen_t("msg_namelen", "length of {@code address} data")
++
++ iovec.p("msg_iov", "vector of data to send/receive into")
++ AutoSize("msg_iov")..size_t("msg_iovlen", "number of elements in the vector")
++
++ void.p("msg_control", "ancillary data (eg BSD filedesc passing)")
++ AutoSize("msg_control")..size_t("msg_controllen", "ancillary data buffer length")
++
++ int("msg_flags", "flags on received message")
++}
++
++val sockaddr = struct(Module.CORE_ASTRAL, "Sockaddr", nativeName = "struct sockaddr") {
++ documentation = "Structure describing a generic socket address."
++
++ typedef(unsigned_short, "sa_family_t")("sa_family", "address family and length")
++ char("sa_data", "address data")[14]
++}
++
++val cmsghdr = struct(Module.CORE_ASTRAL, "CMsghdr", nativeName = "struct cmsghdr") {
++ socklen_t("cmsg_len", "data byte count, including header")
++ int("cmsg_level", "originating protocol")
++ int("cmsg_type", "protocol-specific type")
++ char("cmsg_data", "")[0]
++}
++
++// sys/stat.h
++
++val stat = "struct stat".opaque // TODO:
++
++val statx_timestamp = struct(Module.CORE_ASTRAL, "StatxTimestamp", nativeName = "struct statx_timestamp") {
++ documentation = "Timestamp structure for the timestamps in {@code struct statx}."
++
++ __s64("tv_sec", "the number of seconds before (negative) or after (positive) {@code 00:00:00 1st January 1970 UTC}")
++ __u32("tv_nsec", "a number of nanoseconds (0..999,999,999) after the {@code tv_sec} time")
++ __s32("__reserved", "in case we need a yet finer resolution").private()
++}
++
++val statx = struct(Module.CORE_ASTRAL, "Statx", nativeName = "struct statx") {
++ __u32("stx_mask", "what results were written [uncond]")
++ __u32("stx_blksize", "preferred general I/O size [uncond]")
++ __u64("stx_attributes", "flags conveying information about the file [uncond]")
++ __u32("stx_nlink", "number of hard links")
++ __u32("stx_uid", "user ID of owner")
++ __u32("stx_gid", "group ID of owner")
++ __u16("stx_mode", "file mode")
++ __u16("__spare0", "")[1].private()
++ __u64("stx_ino", "{@code inode} number")
++ __u64("stx_size", "file size")
++ __u64("stx_blocks", "number of 512-byte blocks allocated")
++ __u64("stx_attributes_mask", "mask to show what's supported in {@code stx_attributes}")
++ statx_timestamp("stx_atime", "last access time")
++ statx_timestamp("stx_btime", "file creation time")
++ statx_timestamp("stx_ctime", "last attribute change time")
++ statx_timestamp("stx_mtime", "last data modification time ")
++ __u32("stx_rdev_major", "device ID of special file [if bdev/cdev]")
++ __u32("stx_rdev_minor", "")
++ __u32("stx_dev_major", "ID of device containing file [uncond]")
++ __u32("stx_dev_minor", "")
++ __u64("stx_mnt_id", "")
++ __u64("__spare2", "").private()
++ __u64("__spare3", "spare space for future expansion")[12].private()
++}
++
++// time_types.h
++
++val __kernel_timespec = struct(Module.CORE_ASTRAL, "KernelTimespec", nativeName = "struct __kernel_timespec") {
++ int64_t("tv_sec", "seconds")
++ long_long("tv_nsec", "nanoseconds")
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/WaylandTypes.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/WaylandTypes.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/WaylandTypes.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/WaylandTypes.kt
+@@ -0,0 +1,11 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral
++
++import org.lwjgl.generator.*
++
++val wl_display = "struct wl_display".opaque
++val wl_output = "struct wl_output".opaque
++val wl_surface = "struct wl_surface".opaque
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/XEvents.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/XEvents.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/XEvents.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/XEvents.kt
+@@ -0,0 +1,470 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral
++
++import org.lwjgl.generator.*
++
++val XAnyEvent = struct(Module.CORE_ASTRAL, "XAnyEvent") {
++ documentation = "Generic X event."
++
++ int("type", "the event type constant name that uniquely identifies it")
++ unsigned_long("serial", "# of last request processed by server")
++ Bool("send_event", "true if this came from an #XSendEvent() request")
++ Display.p("display", "{@code Display} the event was read from")
++ Window("window", "window it reported relative to")
++}
++
++val XKeyEvent = struct(Module.CORE_ASTRAL, "XKeyEvent") {
++ documentation = "Key event."
++
++ int("type", "the event type").links("#KeyPress #KeyRelease")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ Window("root", "root window that the event occurred on")
++ Window("subwindow", "child window")
++ Time("time", "milliseconds ")
++ int("x", "pointer x coordinate in event window")
++ int("y", "pointer y coordinate in event window")
++ int("x_root", "x coordinate relative to {@code root}")
++ int("y_root", "y coordinate relative to {@code root}")
++ unsigned_int("state", "key mask")
++ unsigned_int("keycode", "detail")
++ Bool("same_screen", "same screen flag")
++}
++
++val XEvent = union(Module.CORE_ASTRAL, "XEvent", mutable = false) {
++ documentation = "This union is defined so Xlib can always use the same sized event structure internally, to avoid memory fragmentation."
++
++ int("type", "")
++
++ XAnyEvent("xany", "")
++ XKeyEvent("xkey", "")
++ struct(Module.CORE_ASTRAL, "XButtonEvent") {
++ documentation = "Button event."
++
++ int("type", "the event type").links("#ButtonPress #ButtonRelease")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ XKeyEvent copy "root"
++ XKeyEvent copy "subwindow"
++ XKeyEvent copy "time"
++ XKeyEvent copy "x"
++ XKeyEvent copy "y"
++ XKeyEvent copy "x_root"
++ XKeyEvent copy "y_root"
++ unsigned_int("state", "button mask")
++ unsigned_int("button", "detail")
++ XKeyEvent copy "same_screen"
++ }("xbutton", "")
++ struct(Module.CORE_ASTRAL, "XMotionEvent") {
++ documentation = "Motion event."
++
++ int("type", "the event type").links("#MotionNotify")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ XKeyEvent copy "root"
++ XKeyEvent copy "subwindow"
++ XKeyEvent copy "time"
++ XKeyEvent copy "x"
++ XKeyEvent copy "y"
++ XKeyEvent copy "x_root"
++ XKeyEvent copy "y_root"
++ unsigned_int("state", "key or button mask")
++ char("is_hint", "detail")
++ Bool("same_screen", "same screen flag")
++ }("xmotion", "")
++ struct(Module.CORE_ASTRAL, "XCrossingEvent") {
++ documentation = ""
++
++ int("type", "of event")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ XKeyEvent copy "root"
++ XKeyEvent copy "subwindow"
++ XKeyEvent copy "time"
++ XKeyEvent copy "x"
++ XKeyEvent copy "y"
++ XKeyEvent copy "x_root"
++ XKeyEvent copy "y_root"
++ int("mode", "").links("#NotifyNormal #NotifyGrab #NotifyUngrab")
++ int("detail", "")
++ int("same_screen", "same screen flag")
++ int("focus", "boolean focus")
++ unsigned_int("state", "key or button mask")
++ }("xcrossing", "")
++ struct(Module.CORE_ASTRAL, "XFocusChangeEvent") {
++ documentation = ""
++
++ int("type", "").links("#FocusIn #FocusOut")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("mode", "").links("#NotifyNormal #NotifyWhileGrabbed #NotifyGrab #NotifyUngrab")
++ int("detail", "").links(
++ "#NotifyAncestor #NotifyVirtual #NotifyInferior #NotifyNonlinear #NotifyNonlinearVirtual #NotifyPointer #NotifyPointerRoot #NotifyDetailNone"
++ )
++ }("xfocus", "")
++ struct(Module.CORE_ASTRAL, "XExposeEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("x", "")
++ int("y", "")
++ int("width", "")
++ int("height", "")
++ int("count", "if non-zero, at least this many more")
++ }("xexpose", "")
++ struct(Module.CORE_ASTRAL, "XGraphicsExposeEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Drawable("drawable", "")
++ int("x", "")
++ int("y", "")
++ int("width", "")
++ int("height", "")
++ int("count", "if non-zero, at least this many more")
++ int("major_code", "core is {@code CopyArea} or {@code CopyPlane}")
++ int("minor_code", "not defined in the core")
++ }("xgraphicsexpose", "")
++ struct(Module.CORE_ASTRAL, "XNoExposeEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Drawable("drawable", "")
++ int("major_code", "core is {@code CopyArea} or {@code CopyPlane}")
++ int("minor_code", "not defined in the core")
++ }("xnoexpose", "")
++ struct(Module.CORE_ASTRAL, "XVisibilityEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("state", "visibility state")
++ }("xvisibility", "")
++ struct(Module.CORE_ASTRAL, "XCreateWindowEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("parent", "parent of the window")
++ Window("window", "window id of window created")
++ int("x", "window location")
++ int("y", "window location")
++ int("width", "size of window")
++ int("height", "size of window")
++ int("border_width", "border width")
++ int("override_redirect", "creation should be overridden")
++ }("xcreatewindow", "")
++ struct(Module.CORE_ASTRAL, "XDestroyWindowEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ }("xdestroywindow", "")
++ struct(Module.CORE_ASTRAL, "XUnmapEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ int("from_configure", "")
++ }("xunmap", "")
++ struct(Module.CORE_ASTRAL, "XMapEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ int("override_redirect", "boolean, is override set...")
++ }("xmap", "")
++ struct(Module.CORE_ASTRAL, "XMapRequestEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("parent", "")
++ Window("window", "")
++ }("xmaprequest", "")
++ struct(Module.CORE_ASTRAL, "XReparentEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ Window("parent", "")
++ int("x", "")
++ int("y", "")
++ int("override_redirect", "")
++ }("xreparent", "")
++ struct(Module.CORE_ASTRAL, "XConfigureEvent") {
++ documentation = "Motion event."
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("x", "")
++ int("y", "")
++ int("width", "")
++ int("height", "")
++ int("border_width", "")
++ Window("above", "")
++ Bool("override_redirect", "")
++ }("xconfigure", "")
++ struct(Module.CORE_ASTRAL, "XGravityEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ int("x", "")
++ int("y", "")
++ }("xgravity", "")
++ struct(Module.CORE_ASTRAL, "XResizeRequestEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("width", "")
++ int("height", "")
++ }("xresizerequest", "")
++ struct(Module.CORE_ASTRAL, "XConfigureRequestEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("parent", "")
++ Window("window", "")
++ int("x", "")
++ int("y", "")
++ int("width", "")
++ int("height", "")
++ int("border_width", "")
++ Window("above", "")
++ int("detail", "").links("#Above #Below #TopIf #BottomIf #Opposite")
++ unsigned_long("value_mask", "")
++ }("xconfigurerequest", "")
++ struct(Module.CORE_ASTRAL, "XCirculateEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("event", "")
++ Window("window", "")
++ int("place", "").links("#PlaceOnTop #PlaceOnBottom")
++ }("xcirculate", "")
++ struct(Module.CORE_ASTRAL, "XCirculateRequestEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("parent", "")
++ Window("window", "")
++ int("place", "").links("#PlaceOnTop #PlaceOnBottom")
++ }("xcirculaterequest", "")
++ struct(Module.CORE_ASTRAL, "XPropertyEvent") {
++ documentation = "Property event."
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ Atom("atom", "")
++ Time("time", "")
++ int("state", "").links("#PropertyNewValue #PropertyDelete")
++ }("xproperty", "")
++ struct(Module.CORE_ASTRAL, "XSelectionClearEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ Atom("selection", "")
++ Time("time", "")
++ }("xselectionclear", "")
++ struct(Module.CORE_ASTRAL, "XSelectionRequestEvent") {
++ documentation = "SelectionRequest event structure."
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("owner", "")
++ Window("requestor", "")
++ Atom("selection", "")
++ Atom("target", "")
++ Atom("property", "")
++ Time("time", "")
++ }("xselectionrequest", "")
++ struct(Module.CORE_ASTRAL, "XSelectionEvent") {
++ documentation = "Selection event structure."
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ Window("requestor", "")
++ Atom("selection", "")
++ Atom("target", "")
++ Atom("property", "atom or #None")
++ Time("time", "")
++ }("xselection", "")
++ struct(Module.CORE_ASTRAL, "XColormapEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ Colormap("colormap", "colormap or #None")
++ int("new", "")
++ int("state", "").links("#ColormapInstalled #ColormapUninstalled")
++ }("xcolormap", "")
++ struct(Module.CORE_ASTRAL, "XClientMessageEvent") {
++ documentation =
++ """
++ Client message event.
++
++ The {@code message_type} member is set to an atom that indicates how the data should be interpreted by the receiving client. The {@code format}
++ member is set to 8, 16, or 32 and specifies whether the data should be viewed as a list of bytes, shorts, or longs. The {@code data} member is a
++ union that contains the members {@code b}, {@code s}, and {@code l}. The {@code b}, {@code s}, and {@code l} members represent data of twenty 8-bit
++ values, ten 16-bit values, and five 32-bit values. Particular message types might not make use of all these values. The X server places no
++ interpretation on the values in the {@code window}, {@code message_type}, or {@code data} members.
++ """
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ Atom("message_type", "")
++ int("format", "")
++ struct {
++ char("b", "")[20]
++ short("s", "")[10]
++ long("l", "")[5]
++ }("data", "")
++ }("xclient", "")
++ struct(Module.CORE_ASTRAL, "XMappingEvent") {
++ documentation = ""
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ int("request", "").links("#MappingModifier #MappingKeyboard #MappingPointer")
++ int("first_keycode", "first keycode")
++ int("count", "defines range of change w. {@code first_keycode}")
++ }("xmapping", "")
++ struct(Module.CORE_ASTRAL, "XErrorEvent") {
++ documentation = "Error event."
++
++ int("type", "")
++ Display.p("display", "display the event was read from")
++ XID("resourceid", "resource id")
++ unsigned_long("serial", "serial number of failed request")
++ unsigned_char("error_code", "error code of failed request")
++ unsigned_char("request_code", "major op-code of failed request")
++ unsigned_char("minor_code", "minor op-code of failed request")
++ }("xerror", "")
++ struct(Module.CORE_ASTRAL, "XKeymapEvent") {
++ documentation = "Generated on {@code EnterWindow} and {@code FocusIn} when {@code KeyMapState} selected."
++
++ int("type", "")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ XAnyEvent copy "window"
++ char("key_vector", "")[32]
++ }("xkeymap", "")
++ struct(Module.CORE_ASTRAL, "XGenericEvent") {
++ documentation = "GenericEvent. This event is the standard event for all newer extensions."
++
++ int("type", "of event").links("#GenericEvent")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ int("extension", "major opcode of extension that caused the event")
++ int("evtype", "actual event type")
++ }("xgeneric", "")
++ struct(Module.CORE_ASTRAL, "XGenericEventCookie") {
++ documentation = "Additional information for an {@code XGenericEvent}."
++
++ int("type", "of event").links("#GenericEvent")
++ XAnyEvent copy "serial"
++ XAnyEvent copy "send_event"
++ XAnyEvent copy "display"
++ int("extension", "major opcode of extension that caused the event")
++ int("evtype", "actual event type")
++ unsigned_int("cookie", "")
++ void.p("data", "")
++ }("xcookie", "")
++
++ long.padding(24)
++}
++
++val XTimeCoord = struct(Module.CORE_ASTRAL, "XTimeCoord", mutable = false) {
++ Time("time", "the time, in milliseconds")
++ short("x", "the x coordinate of the pointer relative to the origin of the specified window")
++ short("y", "the y coordinate of the pointer relative to the origin of the specified window")
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/XTypes.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/XTypes.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/XTypes.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/XTypes.kt
+@@ -0,0 +1,79 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral
++
++import org.lwjgl.generator.*
++
++val Bool = typedef(intb, "Bool")
++val Status = typedef(int, "Status")
++
++val XID = typedef(unsigned_long, "XID")
++val Mask = typedef(unsigned_long, "Mask")
++val Atom = typedef(unsigned_long, "Atom")
++val VisualID = typedef(unsigned_long, "VisualID")
++val Time = typedef(unsigned_long, "Time")
++
++val Colormap = typedef(XID, "Colormap")
++val Cursor = typedef(XID, "Cursor")
++val Drawable = typedef(XID, "Drawable")
++val Font = typedef(XID, "Font")
++val Pixmap = typedef(XID, "Pixmap")
++val Window = typedef(XID, "Window")
++
++val Display = "Display".opaque // Display is a struct, but should be treated as an opaque type by apps
++val DISPLAY = Parameter(Display.p, "display", "the connection to the X server") // This is here so that GLX extensions can use it
++
++val Visual = struct(Module.CORE_ASTRAL, "Visual") {
++ documentation = "Visual structure; contains information about colormapping possible."
++
++ nullable..opaque_p("ext_data", "")
++ VisualID("visualid", "")
++ int("class", "")
++ unsigned_long("red_mask", "")
++ unsigned_long("green_mask", "")
++ unsigned_long("blue_mask", "")
++ int("bits_per_rgb", "")
++ int("map_entries", "")
++}
++
++val XVisualInfo = struct(Module.CORE_ASTRAL, "XVisualInfo") {
++ documentation = "Information used by the visual utility routines to find desired visual type from the many visuals a display may support."
++
++ Visual.p("visual", "")
++ VisualID("visualid", "")
++ int("screen", "")
++ int("depth", "")
++ int("class", "")
++ unsigned_long("red_mask", "")
++ unsigned_long("green_mask", "")
++ unsigned_long("blue_mask", "")
++ int("colormap_size", "")
++ int("bits_per_rgb", "")
++}
++
++val XSetWindowAttributes = struct(Module.CORE_ASTRAL, "XSetWindowAttributes") {
++ documentation = "Data structure for setting window attributes."
++
++ Pixmap("background_pixmap", "")
++ unsigned_long("background_pixel", "")
++ Pixmap("border_pixmap", "")
++ unsigned_long("border_pixel", "")
++ int("bit_gravity", "")
++ int("win_gravity", "")
++ int("backing_store", "")
++ unsigned_long("backing_planes", "")
++ unsigned_long("backing_pixel", "")
++ Bool("save_under", "")
++ long("event_mask", "")
++ long("do_not_propagate_mask", "")
++ Bool("override_redirect", "")
++ Colormap("colormap", "")
++ Cursor("cursor", "")
++}
++
++// --------------- Xrandr.h ---------------
++
++val RROutput = typedef(XID, "RROutput")
++val RRCrtc = typedef(XID, "RRCrtc")
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/DynamicLinkLoader.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/DynamicLinkLoader.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/DynamicLinkLoader.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/DynamicLinkLoader.kt
+@@ -0,0 +1,90 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import org.lwjgl.generator.*
++
++val dlfcn = "DynamicLinkLoader".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport("")
++
++ documentation = "Native bindings to <dlfcn.h>."
++
++ val Modes = IntConstant(
++ "The {@code mode} argument to #dlopen() contains one of the following.",
++
++ "RTLD_LAZY"..0x00001,
++ "RTLD_NOW"..0x00002,
++ "RTLD_BINDING_MASK"..0x3,
++ "RTLD_NOLOAD"..0x00004,
++ "RTLD_DEEPBIND"..0x00008
++ ).javaDocLinks + " #RTLD_GLOBAL #RTLD_LOCAL #RTLD_NODELETE"
++
++ IntConstant(
++ """
++ If the following bit is set in the {@code mode} argument to #dlopen(), the symbols of the loaded object and its dependencies are made visible as
++ if the object were linked directly into the program.
++ """,
++
++ "RTLD_GLOBAL"..0x00100
++ )
++
++ IntConstant(
++ """
++ Unix98 demands the following flag which is the inverse to #RTLD_GLOBAL. The implementation does this by default and so we can define the value
++ to zero.
++ """,
++
++ "RTLD_LOCAL".."0"
++ )
++
++ IntConstant(
++ "Do not delete object when closed.",
++
++ "RTLD_NODELETE"..0x01000
++ )
++
++ opaque_p(
++ "dlopen",
++ """
++ Loads the dynamic library file named by the null-terminated string {@code filename} and returns an opaque "handle" for the dynamic library. If
++ {@code filename} is #NULL, then the returned handle is for the main program.
++ """,
++
++ nullable..charUTF8.const.p("filename", "the name of the dynamic library to open, or #NULL"),
++ int("mode", "a bitfield", Modes, LinkMode.BITFIELD)
++ )
++
++ charUTF8.p(
++ "dlerror",
++ """
++ Returns a human readable string describing the most recent error that occurred from #dlopen(), #dlsym() or #dlclose() since
++ the last call to {@code dlerror()}. It returns #NULL if no errors have occurred since initialization or since it was last called.
++ """,
++ void()
++ )
++
++ opaque_p(
++ "dlsym",
++ """
++ Takes a "handle" of a dynamic library returned by #dlopen() and the null-terminated symbol name, returning the address where that symbol is loaded
++ into memory. If the symbol is not found, in the specified library or any of the libraries that were automatically loaded by #dlopen() when that
++ library was loaded, {@code dlsym()} returns #NULL.
++ """,
++
++ opaque_p("handle", "the dynamic library handle"),
++ charASCII.const.p("name", "the symbol name")
++ )
++
++ int(
++ "dlclose",
++ """
++ Decrements the reference count on the dynamic library handle handle. If the reference count drops to zero and no other loaded libraries use symbols in
++ it, then the dynamic library is unloaded.
++ """,
++
++ opaque_p("handle", "the dynamic library to close")
++ )
++
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/X11.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/X11.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/X11.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/X11.kt
+@@ -0,0 +1,718 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import org.lwjgl.generator.*
++import core.astral.*
++
++val X11 = "X11".nativeClass(
++ Module.CORE_ASTRAL,
++ nativeSubPath = "astral",
++ binding = simpleBinding(Module.CORE_ASTRAL, "X11", libraryExpression = "null, \"libX11.so.6\", \"libX11.so\"")
++) {
++ documentation = "Native bindings to libX11."
++
++ IntConstant(
++ "Boolean values",
++
++ "True".."1",
++ "False".."0"
++ )
++
++ IntConstant(
++ "RESERVED RESOURCE AND CONSTANT DEFINITIONS",
++
++ "None".."0",
++ "ParentRelative".."1",
++ "CopyFromParent".."0",
++ "PointerWindow".."0",
++ "InputFocus".."1",
++ "PointerRoot".."1",
++ "AnyPropertyType".."0",
++ "AnyKey".."0",
++ "AnyButton".."0",
++ "AllTemporary".."0",
++ "CurrentTime".."0",
++ "NoSymbol".."0"
++ )
++
++ IntConstant(
++ "ERROR CODES",
++
++ "Success".."0",
++ "BadRequest".."1",
++ "BadValue".."2",
++ "BadWindow".."3",
++ "BadPixmap".."4",
++ "BadAtom".."5",
++ "BadCursor".."6",
++ "BadFont".."7",
++ "BadMatch".."8",
++ "BadDrawable".."9",
++ "BadAccess".."10",
++ "BadAlloc".."11",
++ "BadColor".."12",
++ "BadGC".."13",
++ "BadIDChoice".."14",
++ "BadName".."15",
++ "BadLength".."16",
++ "BadImplementation".."17",
++ "FirstExtensionError".."128",
++ "LastExtensionError".."255"
++ )
++
++ IntConstant(
++ "Window attributes for CreateWindow and ChangeWindowAttributes",
++
++ "CWBackPixmap".."1 << 0",
++ "CWBackPixel".."1 << 1",
++ "CWBorderPixmap".."1 << 2",
++ "CWBorderPixel".."1 << 3",
++ "CWBitGravity".."1 << 4",
++ "CWWinGravity".."1 << 5",
++ "CWBackingStore".."1 << 6",
++ "CWBackingPlanes".."1 << 7",
++ "CWBackingPixel".."1 << 8",
++ "CWOverrideRedirect".."1 << 9",
++ "CWSaveUnder".."1 << 10",
++ "CWEventMask".."1 << 11",
++ "CWDontPropagate".."1 << 12",
++ "CWColormap".."1 << 13",
++ "CWCursor".."1 << 14"
++ )
++
++ IntConstant(
++ "Input Event Masks. Used as event-mask window attribute and as arguments to Grab requests. Not to be confused with event names.",
++
++ "NoEventMask".."0",
++ "KeyPressMask".."1 << 0",
++ "KeyReleaseMask".."1 << 1",
++ "ButtonPressMask".."1 << 2",
++ "ButtonReleaseMask".."1 << 3",
++ "EnterWindowMask".."1 << 4",
++ "LeaveWindowMask".."1 << 5",
++ "PointerMotionMask".."1 << 6",
++ "PointerMotionHintMask".."1 << 7",
++ "Button1MotionMask".."1 << 8",
++ "Button2MotionMask".."1 << 9",
++ "Button3MotionMask".."1 << 10",
++ "Button4MotionMask".."1 << 11",
++ "Button5MotionMask".."1 << 12",
++ "ButtonMotionMask".."1 << 13",
++ "KeymapStateMask".."1 << 14",
++ "ExposureMask".."1 << 15",
++ "VisibilityChangeMask".."1 << 16",
++ "StructureNotifyMask".."1 << 17",
++ "ResizeRedirectMask".."1 << 18",
++ "SubstructureNotifyMask".."1 << 19",
++ "SubstructureRedirectMask".."1 << 20",
++ "FocusChangeMask".."1 << 21",
++ "PropertyChangeMask".."1 << 22",
++ "ColormapChangeMask".."1 << 23",
++ "OwnerGrabButtonMask".."1 << 24"
++ )
++
++ IntConstant(
++ """
++ Event names. Used in "type" field in {@code XEvent} structures. Not to be confused with event masks above. They start from 2 because 0 and 1 are reserved in
++ the protocol for errors and replies.
++ """,
++
++ "KeyPress".."2",
++ "KeyRelease".."3",
++ "ButtonPress".."4",
++ "ButtonRelease".."5",
++ "MotionNotify".."6",
++ "EnterNotify".."7",
++ "LeaveNotify".."8",
++ "FocusIn".."9",
++ "FocusOut".."10",
++ "KeymapNotify".."11",
++ "Expose".."12",
++ "GraphicsExpose".."13",
++ "NoExpose".."14",
++ "VisibilityNotify".."15",
++ "CreateNotify".."16",
++ "DestroyNotify".."17",
++ "UnmapNotify".."18",
++ "MapNotify".."19",
++ "MapRequest".."20",
++ "ReparentNotify".."21",
++ "ConfigureNotify".."22",
++ "ConfigureRequest".."23",
++ "GravityNotify".."24",
++ "ResizeRequest".."25",
++ "CirculateNotify".."26",
++ "CirculateRequest".."27",
++ "PropertyNotify".."28",
++ "SelectionClear".."29",
++ "SelectionRequest".."30",
++ "SelectionNotify".."31",
++ "ColormapNotify".."32",
++ "ClientMessage".."33",
++ "MappingNotify".."34",
++ "GenericEvent".."35",
++ "LASTEvent".."36"
++ )
++
++ IntConstant(
++ "Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, state in various key-, mouse-, and button-related events.",
++
++ "ShiftMask".."1<<0",
++ "LockMask".."1<<1",
++ "ControlMask".."1<<2",
++ "Mod1Mask".."1<<3",
++ "Mod2Mask".."1<<4",
++ "Mod3Mask".."1<<5",
++ "Mod4Mask".."1<<6",
++ "Mod5Mask".."1<<7"
++ )
++
++ IntConstant(
++ "modifier names. Used to build a SetModifierMapping request or to read a GetModifierMapping request. These correspond to the masks defined above.",
++
++ "ShiftMapIndex".."0",
++ "LockMapIndex".."1",
++ "ControlMapIndex".."2",
++ "Mod1MapIndex".."3",
++ "Mod2MapIndex".."4",
++ "Mod3MapIndex".."5",
++ "Mod4MapIndex".."6",
++ "Mod5MapIndex".."7"
++ )
++
++ IntConstant(
++ "button masks. Used in same manner as Key masks above. Not to be confused with button names below.",
++
++ "Button1Mask".."1<<8",
++ "Button2Mask".."1<<9",
++ "Button3Mask".."1<<10",
++ "Button4Mask".."1<<11",
++ "Button5Mask".."1<<12",
++ "AnyModifier".."1<<15"
++ )
++
++ IntConstant(
++ """
++ button names. Used as arguments to GrabButton and as detail in ButtonPress and ButtonRelease events. Not to be confused with button masks above. Note
++ that 0 is already defined above as "AnyButton".
++ """,
++
++ "Button1".."1",
++ "Button2".."2",
++ "Button3".."3",
++ "Button4".."4",
++ "Button5".."5"
++ )
++
++ IntConstant(
++ "Notify modes",
++
++ "NotifyNormal".."0",
++ "NotifyGrab".."1",
++ "NotifyUngrab".."2",
++ "NotifyWhileGrabbed".."3",
++ "NotifyHint".."1"
++ )
++
++ IntConstant(
++ "Notify detail",
++
++ "NotifyAncestor".."0",
++ "NotifyVirtual".."1",
++ "NotifyInferior".."2",
++ "NotifyNonlinear".."3",
++ "NotifyNonlinearVirtual".."4",
++ "NotifyPointer".."5",
++ "NotifyPointerRoot".."6",
++ "NotifyDetailNone".."7"
++ )
++
++ IntConstant(
++ "Visibility notify",
++
++ "VisibilityUnobscured".."0",
++ "VisibilityPartiallyObscured".."1",
++ "VisibilityFullyObscured".."2"
++ )
++
++ IntConstant(
++ "Circulation request",
++
++ "PlaceOnTop".."0",
++ "PlaceOnBottom".."1"
++ )
++
++ IntConstant(
++ "Property notification",
++
++ "PropertyNewValue".."0",
++ "PropertyDelete".."1"
++ )
++
++ IntConstant(
++ "Color Map notification",
++
++ "ColormapUninstalled".."0",
++ "ColormapInstalled".."1"
++ )
++
++ IntConstant(
++ "GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes",
++
++ "GrabModeSync".."0",
++ "GrabModeAsync".."1"
++ )
++
++ IntConstant(
++ "GrabPointer, GrabKeyboard reply status",
++
++ "GrabSuccess".."0",
++ "AlreadyGrabbed".."1",
++ "GrabInvalidTime".."2",
++ "GrabNotViewable".."3",
++ "GrabFrozen".."4"
++ )
++
++ IntConstant(
++ "AllowEvents modes",
++
++ "AsyncPointer".."0",
++ "SyncPointer".."1",
++ "ReplayPointer".."2",
++ "AsyncKeyboard".."3",
++ "SyncKeyboard".."4",
++ "ReplayKeyboard".."5",
++ "AsyncBoth".."6",
++ "SyncBoth".."7"
++ )
++
++ IntConstant(
++ "For #XCreateColormap().",
++
++ "AllocNone".."0",
++ "AllocAll".."1"
++ )
++
++ IntConstant(
++ "Used in XSetInputFocus(), XGetInputFocus().",
++
++ "RevertToNone".."None",
++ "RevertToPointerRoot".."PointerRoot",
++ "RevertToParent".."2"
++ )
++
++ IntConstant(
++ "Window classes used by #XCreateWindow().",
++
++ "InputOutput".."1",
++ "InputOnly".."2"
++ )
++
++ IntConstant(
++ "SCREEN SAVER STUFF",
++
++ "DontPreferBlanking".."0",
++ "PreferBlanking".."1",
++ "DefaultBlanking".."2",
++ "DisableScreenSaver".."0",
++ "DisableScreenInterval".."0",
++ "DontAllowExposures".."0",
++ "AllowExposures".."1",
++ "DefaultExposures".."2",
++ "ScreenSaverReset".."0",
++ "ScreenSaverActive".."1"
++ )
++
++ IntConstant(
++ "Property modes",
++
++ "PropModeReplace".."0",
++ "PropModePrepend".."1",
++ "PropModeAppend".."2"
++ )
++
++ IntConstant(
++ "graphics functions, as in GC.alu",
++
++ "GXclear"..0x0,
++ "GXand"..0x1,
++ "GXandReverse"..0x2,
++ "GXcopy"..0x3,
++ "GXandInverted"..0x4,
++ "GXnoop"..0x5,
++ "GXxor"..0x6,
++ "GXor"..0x7,
++ "GXnor"..0x8,
++ "GXequiv"..0x9,
++ "GXinvert"..0xa,
++ "GXorReverse"..0xb,
++ "GXcopyInverted"..0xc,
++ "GXorInverted"..0xd,
++ "GXnand"..0xe,
++ "GXset"..0xf
++ )
++
++ IntConstant(
++ "LineStyle",
++
++ "LineSolid".."0",
++ "LineOnOffDash".."1",
++ "LineDoubleDash".."2"
++ )
++
++ IntConstant(
++ "capStyle",
++
++ "CapNotLast".."0",
++ "CapButt".."1",
++ "CapRound".."2",
++ "CapProjecting".."3"
++ )
++
++ IntConstant(
++ "joinStyle",
++
++ "JoinMiter".."0",
++ "JoinRound".."1",
++ "JoinBevel".."2"
++ )
++
++ IntConstant(
++ "fillStyle",
++
++ "FillSolid".."0",
++ "FillTiled".."1",
++ "FillStippled".."2",
++ "FillOpaqueStippled".."3"
++ )
++
++ IntConstant(
++ "fillRule",
++
++ "EvenOddRule".."0",
++ "WindingRule".."1"
++ )
++
++ IntConstant(
++ "subwindow mode",
++
++ "ClipByChildren".."0",
++ "IncludeInferiors".."1"
++ )
++
++ IntConstant(
++ "SetClipRectangles ordering",
++
++ "Unsorted".."0",
++ "YSorted".."1",
++ "YXSorted".."2",
++ "YXBanded".."3"
++ )
++
++ IntConstant(
++ "CoordinateMode for drawing routines",
++
++ "CoordModeOrigin".."0",
++ "CoordModePrevious".."1"
++ )
++
++ IntConstant(
++ "Polygon shapes",
++
++ "Complex".."0",
++ "Nonconvex".."1",
++ "Convex".."2"
++ )
++
++ IntConstant(
++ "Arc modes for PolyFillArc",
++
++ "ArcChord".."0",
++ "ArcPieSlice".."1"
++ )
++
++ IntConstant(
++ "GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into GC.stateChanges",
++
++ "GCFunction".."1<<0",
++ "GCPlaneMask".."1<<1",
++ "GCForeground".."1<<2",
++ "GCBackground".."1<<3",
++ "GCLineWidth".."1<<4",
++ "GCLineStyle".."1<<5",
++ "GCCapStyle".."1<<6",
++ "GCJoinStyle".."1<<7",
++ "GCFillStyle".."1<<8",
++ "GCFillRule".."1<<9",
++ "GCTile".."1<<10",
++ "GCStipple".."1<<11",
++ "GCTileStipXOrigin".."1<<12",
++ "GCTileStipYOrigin".."1<<13",
++ "GCFont".."1<<14",
++ "GCSubwindowMode".."1<<15",
++ "GCGraphicsExposures".."1<<16",
++ "GCClipXOrigin".."1<<17",
++ "GCClipYOrigin".."1<<18",
++ "GCClipMask".."1<<19",
++ "GCDashOffset".."1<<20",
++ "GCDashList".."1<<21",
++ "GCArcMode".."1<<22",
++ "GCLastBit".."22"
++ )
++
++ IntConstant(
++ "",
++
++ "Above".."0",
++ "Below".."1",
++ "TopIf".."2",
++ "BottomIf".."3",
++ "Opposite".."4"
++ )
++
++ IntConstant(
++ "",
++
++ "MappingModifier".."0",
++ "MappingKeyboard".."1",
++ "MappingPointer".."2"
++ )
++
++ val DISPLAY = Display.p("display", "the connection to the X server")
++ val WINDOW = Window("w", "the window")
++ //val DRAWABLE = Drawable("d", "the drawable")
++
++ Display.p(
++ "XOpenDisplay",
++ """
++ Returns a Display structure that serves as the connection to the X server and that contains all the information about that X server. {@code XOpenDisplay}
++ connects your application to the X server through TCP or DECnet communications protocols, or through some local inter-process communication protocol.
++ If the hostname is a host machine name and a single colon (:) separates the hostname and display number, {@code XOpenDisplay} connects using TCP streams.
++ If the hostname is not specified, Xlib uses whatever it believes is the fastest transport. If the hostname is a host machine name and a double colon
++ (::) separates the hostname and display number, {@code XOpenDisplay} connects using DECnet. A single X server can support any or all of these transport
++ mechanisms simultaneously. A particular Xlib implementation can support many more of these transport mechanisms.
++ """,
++
++ nullable..charASCII.const.p(
++ "display_name",
++ """
++ the hardware display name, which determines the display and communications domain to be used. On a POSIX-conformant system, if the
++ {@code display_name} is #NULL, it defaults to the value of the DISPLAY environment variable.
++ """
++ )
++ )
++
++ void(
++ "XCloseDisplay",
++ """
++ Closes the connection to the X server for the display specified in the {@code Display} structure and destroys all windows, resource IDs (Window, Font,
++ Pixmap, Colormap, Cursor, and GContext), or other resources that the client has created on this display, unless the close-down mode of the resource has
++ been changed (see {@code XSetCloseDownMode()}). Therefore, these windows, resource IDs, and other resources should never be referenced again or an error will
++ be generated. Before exiting, you should call {@code XCloseDisplay()} explicitly so that any pending errors are reported as {@code XCloseDisplay()}
++ performs a final {@code XSync()} operation.
++ """,
++
++ DISPLAY
++ )
++
++ int(
++ "XDefaultScreen",
++ "Returns a pointer to the default screen.",
++
++ DISPLAY
++ )
++
++ Window(
++ "XRootWindow",
++ "Returns the root window of the specified screen.",
++
++ DISPLAY,
++ int("screen_number", "the appropriate screen number on the host server")
++ )
++
++ Colormap(
++ "XCreateColormap",
++ """
++ Creates a colormap of the specified visual type for the screen on which the specified window resides and returns the colormap ID associated with it.
++ Note that the specified window is only used to determine the screen.
++ """,
++
++ DISPLAY,
++ WINDOW,
++ Visual.p("visual", "a visual type supported on the screen. If the visual type is not one supported by the screen, a {@code BadMatch} error results."),
++ int("alloc", "the colormap entries to be allocated. You can pass AllocNone or AllocAll.")
++ )
++
++ int(
++ "XFreeColormap",
++ """
++ Deletes the association between the {@code colormap} resource ID and the {@code colormap} and frees the {@code colormap} storage. However, this function
++ has no effect on the default colormap for a screen. If the specified {@code colormap} is an installed map for a screen, it is uninstalled. If the
++ specified {@code colormap} is defined as the {@code colormap} for a window, {@code XFreeColormap()} changes the colormap associated with the window to
++ #None and generates a {@code ColormapNotify} event. X does not define the colors displayed for a window with a colormap of #None.
++ """,
++
++ DISPLAY,
++ Colormap("colormap", "the colormap to destroy")
++ )
++
++ Window(
++ "XCreateWindow",
++ """
++ Creates an unmapped subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a
++ {@code CreateNotify }event. The created window is placed on top in the stacking order with respect to siblings.
++
++ The coordinate system has the X axis horizontal and the Y axis vertical with the origin [0, 0] at the upper-left corner. Coordinates are integral, in
++ terms of pixels, and coincide with pixel centers. Each window and pixmap has its own coordinate system. For a window, the origin is inside the border at
++ the inside, upper-left corner.
++
++ The x and y coordinates are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders.
++
++ The width and height are the created window's inside dimensions and do not include the created window's borders.
++ """,
++
++ DISPLAY,
++ Window("parent", "the parent window"),
++ int("x", "the window x-coordinate"),
++ int("y", "the window y-coordinate"),
++ unsigned_int("width", "the window width"),
++ unsigned_int("height", "the window height"),
++ unsigned_int("border_width", "the border width"),
++ int("depth", "the window's depth. A depth of #CopyFromParent means the depth is taken from the parent."),
++ unsigned_int("windowClass", "the created window's class", "#InputOutput #InputOnly #CopyFromParent"),
++ Visual.p("visual", "the visual type. A visual of #CopyFromParent means the visual type is taken from the parent."),
++ unsigned_long(
++ "valuemask",
++ """
++ which window attributes are defined in the attributes argument. This mask is the bitwise inclusive OR of the valid attribute mask bits. If
++ {@code valuemask} is zero, the attributes are ignored and are not referenced.
++ """
++ ),
++ XSetWindowAttributes.p("attributes", "the structure from which the values (as specified by the value mask) are to be taken")
++ )
++
++ int(
++ "XDestroyWindow",
++ """
++ Destroys the specified window as well as all of its subwindows and causes the X server to generate a {@code DestroyNotify} event for each window. The
++ window should never be referenced again. If the window specified by the {@code w} argument is mapped, it is unmapped automatically. The ordering of the
++ {@code DestroyNotify} events is such that for any given window being destroyed, {@code DestroyNotify} is generated on any inferiors of the window before
++ being generated on the window itself. The ordering among siblings and across subhierarchies is not otherwise constrained. If the window you specified is
++ a root window, no windows are destroyed. Destroying a mapped window will generate {@code Expose} events on other windows that were obscured by the
++ window being destroyed.
++ """,
++
++ DISPLAY,
++ WINDOW
++ )
++
++ int(
++ "XFree",
++ "Free in-memory data that was created by an Xlib function.",
++
++ MultiType(PointerMapping.DATA_POINTER)..Unsafe..void.p("data", "the data that is to be freed")
++ )
++
++ Status(
++ "XSendEvent",
++ """
++ The {@code XSendEvent} function identifies the destination window, determines which clients should receive the specified events, and ignores any active
++ grabs. This function requires you to pass an event mask. This function uses the {@code w} argument to identify the destination window as follows:
++ ${ul(
++ "If {@code w} is {@code PointerWindow}, the destination window is the window that contains the pointer.",
++ """
++ If {@code w} is {@code InputFocus} and if the focus window contains the pointer, the destination window is the window that contains the pointer;
++ otherwise, the destination window is the focus window.
++ """
++ )}
++
++ To determine which clients should receive the specified events, {@code XSendEvent} uses the propagate argument as follows:
++ ${ul(
++ """
++ If {@code event_mask} is the empty set, the event is sent to the client that created the destination window. If that client no longer exists, no
++ event is sent.
++ """,
++ """
++ If {@code propagate} is #False, the event is sent to every client selecting on destination any of the event types in the {@code event_mask}
++ argument.
++ """,
++ """
++ If {@code propagate} is #True and no clients have selected on destination any of the event types in event-mask, the destination is replaced with
++ the closest ancestor of destination for which some client has selected a type in event-mask and for which no intervening window has that type in
++ its do-not-propagate-mask. If no such window exists or if the window is an ancestor of the focus window and #InputFocus was originally specified as
++ the destination, the event is not sent to any clients. Otherwise, the event is reported to every client selecting on the final destination any of
++ the types specified in {@code event_mask}.
++ """
++ )}
++
++ The event in the {@code XEvent} structure must be one of the core events or one of the events defined by an extension (or a #BadValue error results) so
++ that the X server can correctly byte-swap the contents as necessary. The contents of the event are otherwise unaltered and unchecked by the X server
++ except to force {@code send_event} to #True in the forwarded event and to set the serial number in the event correctly; therefore these fields and the
++ display field are ignored by {@code XSendEvent}.
++
++ {@code XSendEvent} returns zero if the conversion to wire protocol format failed and returns nonzero otherwise. {@code XSendEvent} can generate
++ #BadValue and #BadWindow errors.
++
++ The server may retain the recent history of the pointer motion and do so to a finer granularity than is reported by #MotionNotify events. The
++ #XGetMotionEvents() function makes this history available.
++ """,
++
++ DISPLAY,
++ Window("w", "specifies the window the event is to be sent to"),
++ Bool("propagate", "specifies a {@code Boolean} value"),
++ long("event_mask", "specifies the event mask"),
++ XEvent.p("event_send", "specifies the event that is to be sent")
++ )
++
++ unsigned_long(
++ "XDisplayMotionBufferSize",
++ "",
++
++ DISPLAY
++ )
++
++ XTimeCoord.p(
++ "XGetMotionEvents",
++ """
++ The {@code XGetMotionEvents} function returns all events in the motion history buffer that fall between the specified start and stop times, inclusive,
++ and that have coordinates that lie within the specified window (including its borders) at its present placement.
++
++ If the server does not support motion history, if the start time is later than the stop time, or if the start time is in the future, no events are
++ returned; {@code XGetMotionEvents} returns #NULL. If the stop time is in the future, it is equivalent to specifying #CurrentTime.
++ {@code XGetMotionEvents} can generate a #BadWindow error.
++ """,
++
++ DISPLAY,
++ Window("w" ,""),
++ Time("start", ""),
++ Time("stop", ""),
++ AutoSizeResult..Check(1)..int.p("nevents_return", "")
++ )
++
++ Bool(
++ "XTranslateCoordinates",
++ """
++ Translates window coordinates.
++
++ If {@code XTranslateCoordinates} returns #True, it takes the {@code src_x} and {@code src_y} coordinates relative to the source window's origin and
++ returns these coordinates to {@code dest_x_return} and {@code dest_y_return} relative to the destination window's origin. If
++ {@code XTranslateCoordinates} returns #False, {@code src_w} and {@code dest_w} are on different screens, and {@code dest_x_return} and
++ {@code dest_y_return} are zero. If the coordinates are contained in a mapped child of {@code dest_w}, that child is returned to {@code child_return}.
++ Otherwise, {@code child_return} is set to #None.
++
++ {@code XTranslateCoordinates} can generate a #BadWindow error.
++ """,
++
++ DISPLAY,
++ Window("src_w", "specifies the source window"),
++ Window("dest_w", "specifies the destination window"),
++ int("src_x", "specifies the x coordinate within the source window"),
++ int("src_y", "specifies the x coordinate within the source window"),
++ Check(1)..int.p("dest_x_return", "returns the x coordinate within the destination window"),
++ Check(1)..int.p("dest_y_return", "returns the y coordinate within the destination window"),
++ Check(1)..Window.p("child_return", "returns the child if the coordinates are contained in a mapped child of the destination window")
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/fcntl.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/fcntl.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/fcntl.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/fcntl.kt
+@@ -0,0 +1,760 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val fcntl = "FCNTL".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++ documentation = "Native bindings to <fcntl.h>."
++
++ EnumConstant(
++ "",
++
++ "O_ACCMODE".enum("", "00000003"),
++ "O_RDONLY".enum("", "00000000"),
++ "O_WRONLY".enum("", "00000001"),
++ "O_RDWR".enum("", "00000002"),
++
++ "O_APPEND".enum(
++ """
++ The file is opened in append mode.
++
++ Before each {@code write(2)}, the file offset is positioned at the end of the file, as if with {@code lseek(2)}. {@code O_APPEND} may lead to
++ corrupted files on NFS file systems if more than one process appends data to a file at once. This is because NFS does not support appending to a
++ file, so the client kernel has to simulate it, which can't be done without a race condition.
++ """,
++ "00002000"
++ ),
++ "O_ASYNC".enum(
++ """
++ Enable signal-driven I/O: generate a signal ({@code SIGIO} by default, but this can be changed via {@code fcntl(2)}) when input or output becomes
++ possible on this file descriptor.
++
++ This feature is only available for terminals, pseudoterminals, sockets, and (since Linux 2.6) pipes and FIFOs. See {@code fcntl(2)} for further
++ details.
++ """,
++ "020000"
++ ),
++ "O_CLOEXEC".enum(
++ """
++ Enable the close-on-exec flag for the new file descriptor.
++
++ Specifying this flag permits a program to avoid additional {@code fcntl(2) F_SETFD} operations to set the {@code FD_CLOEXEC} flag. Additionally,
++ use of this flag is essential in some multithreaded programs since using a separate {@code fcntl(2) F_SETFD} operation to set the
++ {@code FD_CLOEXEC} flag does not suffice to avoid race conditions where one thread opens a file descriptor at the same time as another thread does
++ a {@code fork(2)} plus {@code execve(2)}.
++ """,
++ "02000000"
++ ),
++ "O_CREAT".enum(
++ """
++ If the file does not exist it will be created.
++
++ The owner (user ID) of the file is set to the effective user ID of the process. The group ownership (group ID) is set either to the effective group
++ ID of the process or to the group ID of the parent directory (depending on file system type and mount options, and the mode of the parent
++ directory, see the mount options {@code bsdgroups} and {@code sysvgroups} described in {@code mount(8)}).
++ """,
++ "00000100"
++ ),
++ "O_DIRECT".enum(
++ """
++ Try to minimize cache effects of the I/O to and from this file.
++
++ In general this will degrade performance, but it is useful in special situations, such as when applications do their own caching. File I/O is done
++ directly to/from user-space buffers. The {@code O_DIRECT} flag on its own makes an effort to transfer data synchronously, but does not give the
++ guarantees of the {@code O_SYNC} flag that data and necessary metadata are transferred. To guarantee synchronous I/O, {@code O_SYNC} must be used
++ in addition to {@code O_DIRECT}.
++
++ A semantically similar (but deprecated) interface for block devices is described in {@code raw(8)}.
++ """,
++ "040000"
++ ),
++ "O_DIRECTORY".enum(
++ """
++ If pathname is not a directory, cause the open to fail.
++
++ This flag is Linux-specific, and was added in kernel version 2.1.126, to avoid denial-of-service problems if {@code opendir(3)} is called on a FIFO
++ or tape device, but should not be used outside of the implementation of {@code opendir(3)}.
++ """,
++ "0200000"
++ ),
++ "O_DSYNC".enum("""""", "00010000"),
++ "O_EXCL".enum(
++ """
++ Ensure that this call creates the file: if this flag is specified in conjunction with {@code O_CREAT}, and pathname already exists, then
++ {@code open()} will fail.
++
++ When these two flags are specified, symbolic links are not followed: if {@code pathname} is a symbolic link, then {@code open()} fails regardless
++ of where the symbolic link points to.
++
++ In general, the behavior of {@code O_EXCL} is undefined if it is used without {@code O_CREAT}. There is one exception: on Linux 2.6 and later,
++ {@code O_EXCL} can be used without {@code O_CREAT} if {@code pathname} refers to a block device. If the block device is in use by the system (e.g.,
++ mounted), {@code open()} fails with the error {@code EBUSY}.
++
++ On NFS, {@code O_EXCL} is only supported when using NFSv3 or later on kernel 2.6 or later. In NFS environments where {@code O_EXCL} support is not
++ provided, programs that rely on it for performing locking tasks will contain a race condition. Portable programs that want to perform atomic file
++ locking using a lockfile, and need to avoid reliance on NFS support for {@code O_EXCL}, can create a unique file on the same file system (e.g.,
++ incorporating hostname and PID), and use {@code link(2)} to make a link to the lockfile. If {@code link(2)} returns 0, the lock is successful.
++ Otherwise, use {@code stat(2)} on the unique file to check if its link count has increased to 2, in which case the lock is also successful.
++ """,
++ "00000200"
++ ),
++ "O_LARGEFILE".enum(
++ """
++ (LFS) Allow files whose sizes cannot be represented in an {@code off_t} (but can be represented in an {@code off64_t}) to be opened.
++
++ The {@code _LARGEFILE64_SOURCE} macro must be defined (before including any header files) in order to obtain this definition. Setting the
++ {@code _FILE_OFFSET_BITS} feature test macro to 64 (rather than using {@code O_LARGEFILE}) is the preferred method of accessing large files on
++ 32-bit systems (see {@code feature_test_macros(7)}).
++ """,
++ "00100000"
++ ),
++ "O_NOATIME".enum(
++ """
++ Do not update the file last access time ({@code st_atime} in the {@code inode}) when the file is {@code read(2)}.
++
++ This flag is intended for use by indexing or backup programs, where its use can significantly reduce the amount of disk activity. This flag may not
++ be effective on all file systems. One example is NFS, where the server maintains the access time.
++ """,
++ "01000000"
++ ),
++ "O_NOCTTY".enum(
++ """
++ If {@code pathname} refers to a terminal device --see {@code tty(4)}-- it will not become the process's controlling terminal even if the process
++ does not have one.
++ """,
++ "00000400"
++ ),
++ "O_NOFOLLOW".enum(
++ """
++ If {@code pathname} is a symbolic link, then the open fails.
++
++ This is a FreeBSD extension, which was added to Linux in version 2.1.126. Symbolic links in earlier components of the {@code pathname} will still
++ be followed.
++ """,
++ "00400000"
++ ),
++ "O_NONBLOCK".enum(
++ """
++ When possible, the file is opened in nonblocking mode.
++
++ Neither the {@code open()} nor any subsequent operations on the file descriptor which is returned will cause the calling process to wait. For the
++ handling of FIFOs (named pipes), see also {@code fifo(7)}. For a discussion of the effect of {@code O_NONBLOCK} in conjunction with mandatory file
++ locks and with file leases, see {@code fcntl(2)}.
++ """,
++ "00004000"
++ ),
++ "O_NDELAY".enum("""""", "O_NONBLOCK"),
++ "O_PATH".enum("""""", "010000000"),
++ "O_SYNC".enum(
++ """
++ The file is opened for synchronous I/O.
++
++ Any {@code write(2)}s on the resulting file descriptor will block the calling process until the data has been physically written to the underlying
++ hardware.
++ """,
++ "04010000"
++ ),
++ "O_TMPFILE".enum("""""", "020000000 | O_DIRECTORY"),
++ "O_TRUNC".enum(
++ """
++ If the file already exists and is a regular file and the open mode allows writing (i.e., is {@code O_RDWR} or {@code O_WRONLY}) it will be
++ truncated to length 0.
++
++ If the file is a FIFO or terminal device file, the {@code O_TRUNC} flag is ignored. Otherwise the effect of {@code O_TRUNC} is unspecified.
++ """,
++ "00001000"
++ ),
++ )
++
++ EnumConstant(
++ "File types encoded in type {@code mode_t}.",
++
++ "S_IFMT".enum("Type of file.", "00170000"),
++ "S_IFBLK".enum("Block special.", "0060000"),
++ "S_IFCHR".enum("Character special.", "0020000"),
++ "S_IFIFO".enum("FIFO special.", "0010000"),
++ "S_IFREG".enum("Regular.", "0100000"),
++ "S_IFDIR".enum("Directory.", "0040000"),
++ "S_IFLNK".enum("Symbolic link.", "0120000"),
++ "S_IFSOCK".enum("Socket.", "0140000")
++ )
++
++ val ModeBits = EnumConstant(
++ "File mode bits encoded in type {@code mode_t}.",
++
++ "S_IRWXU".enum("Read, write, execute/search by owner.", "0700"),
++ "S_IRUSR".enum("Read permission, owner.", "0400"),
++ "S_IWUSR".enum("Write permission, owner.", "0200"),
++ "S_IXUSR".enum("Execute/search permission, owner.", "0100"),
++ "S_IRWXG".enum("Read, write, execute/search by group.", "070"),
++ "S_IRGRP".enum("Read permission, group.", "040"),
++ "S_IWGRP".enum("Write permission, group.", "020"),
++ "S_IXGRP".enum("Execute/search permission, group.", "010"),
++ "S_IRWXO".enum("Read, write, execute/search by others.", "07"),
++ "S_IROTH".enum("Read permission, others.", "04"),
++ "S_IWOTH".enum("Write permission, others.", "02"),
++ "S_IXOTH".enum("Execute/search permission, others.", "01"),
++ "S_ISUID".enum("Set-user-ID on execution.", "04000"),
++ "S_ISGID".enum("Set-group-ID on execution.", "02000"),
++ "S_ISVTX".enum("On directories, restricted deletion flag.", "01000")
++ ).javaDocLinks
++
++ val commands = EnumConstant(
++ "#fcntl() commands.",
++
++ "F_DUPFD".enum(
++ """
++ Duplicate the file descriptor {@code fd} using the lowest-numbered available file descriptor greater than or equal to {@code arg}.
++
++ This is different from {@code dup2(2)}, which uses exactly the file descriptor specified.
++
++ On success, the new file descriptor is returned.
++
++ See {@code dup(2)} for further details.
++ """,
++ "0"
++ ),
++ "F_GETFD".enum("Return (as the function result) the file descriptor flags; {@code arg} is ignored.", "1"),
++ "F_SETFD".enum("Set the file descriptor flags to the value specified by {@code arg}.", "2"),
++ "F_GETFL".enum("Return (as the function result) the file access mode and the file status flags; {@code arg} is ignored.", "3"),
++ "F_SETFL".enum(
++ """
++ Set the file status flags to the value specified by {@code arg}.
++
++ File access mode (#O_RDONLY, #O_WRONLY, #O_RDWR) and file creation flags (i.e., #O_CREAT, #O_EXCL, #O_NOCTTY, #O_TRUNC) in {@code arg} are ignored.
++ On Linux, this command can change only the #O_APPEND, #O_ASYNC, #O_DIRECT, #O_NOATIME, and #O_NONBLOCK flags. It is not possible to change the
++ #O_DSYNC and #O_SYNC flags; see BUGS, below.
++ """,
++ "4"
++ ),
++ "F_GETLK".enum(
++ """
++ On input to this call, lock describes a lock we would like to place on the file.
++
++ If the lock could be placed, {@code fcntl()} does not actually place it, but returns #F_UNLCK in the {@code l_type} field of lock and leaves the
++ other fields of the structure unchanged.
++
++ If one or more incompatible locks would prevent this lock being placed, then {@code fcntl()} returns details about one of those locks in the
++ {@code l_type}, {@code l_whence}, {@code l_start}, and {@code l_len} fields of lock. If the conflicting lock is a traditional (process-associated)
++ record lock, then the {@code l_pid} field is set to the {@code PID} of the process holding that lock. If the conflicting lock is an open file
++ description lock, then {@code l_pid} is set to -1. Note that the returned information may already be out of date by the time the caller inspects
++ it.
++ """,
++ "5"
++ ),
++ "F_SETLK".enum(
++ """
++ Acquire a lock (when {@code l_type} is #F_RDLCK or #F_WRLCK) or release a lock (when {@code l_type} is #F_UNLCK) on the bytes specified by the
++ {@code l_whence}, {@code l_start}, and {@code l_len} fields of lock.
++
++ If a conflicting lock is held by another process, this call returns -1 and sets {@code errno} to {@code EACCES} or {@code EAGAIN}. (The error
++ returned in this case differs across implementations, so POSIX requires a portable application to check for both errors.)
++ """,
++ "8"
++ ),
++ "F_SETLKW".enum(
++ """
++ As for #F_SETLK, but if a conflicting lock is held on the file, then wait for that lock to be released.
++
++ If a signal is caught while waiting, then the call is interrupted and (after the signal handler has returned) returns immediately (with return
++ value -1 and errno set to {@code EINTR}; see {@code signal(7)}).
++ """,
++ "7"
++ ),
++ "F_SETOWN".enum(
++ """
++ Set the process ID or process group ID that will receive {@code SIGIO} and {@code SIGURG} signals for events on the file descriptor {@code fd}.
++
++ The target process or process group ID is specified in {@code arg}. A process ID is specified as a positive value; a process group ID is specified
++ as a negative value. Most commonly, the calling process specifies itself as the owner (that is, {@code arg} is specified as {@code getpid(2)}).
++
++ As well as setting the file descriptor owner, one must also enable generation of signals on the file descriptor. This is done by using the
++ {@code fcntl()} #F_SETFL command to set the #O_ASYNC file status flag on the file descriptor. Subsequently, a {@code SIGIO} signal is sent whenever
++ input or output becomes possible on the file descriptor. The {@code fcntl()} #F_SETSIG command can be used to obtain delivery of a signal other
++ than {@code SIGIO}.
++
++ Sending a signal to the owner process (group) specified by {@code F_SETOWN} is subject to the same permissions checks as are described for
++ {@code kill(2)}, where the sending process is the one that employs {@code F_SETOWN} (but see BUGS below). If this permission check fails, then the
++ signal is silently discarded. Note: The {@code F_SETOWN} operation records the caller's credentials at the time of the {@code fcntl()} call, and it
++ is these saved credentials that are used for the permission checks.
++
++ If the file descriptor {@code fd} refers to a socket, {@code F_SETOWN} also selects the recipient of {@code SIGURG} signals that are delivered when
++ out-of-band data arrives on that socket. ({@code SIGURG} is sent in any situation where {@code select(2)} would report the socket as having an
++ "exceptional condition".)
++
++ The following was true in 2.6.x kernels up to and including kernel 2.6.11:
++
++ If a nonzero value is given to #F_SETSIG in a multithreaded process running with a threading library that supports thread groups (e.g., NPTL), then
++ a positive value given to {@code F_SETOWN} has a different meaning: instead of being a process ID identifying a whole process, it is a thread ID
++ identifying a specific thread within a process. Consequently, it may be necessary to pass {@code F_SETOWN} the result of {@code gettid(2)} instead
++ of {@code getpid(2)} to get sensible results when {@code F_SETSIG} is used. (In current Linux threading implementations, a main thread's thread ID
++ is the same as its process ID. This means that a single-threaded program can equally use {@code gettid(2)} or {@code getpid(2)} in this scenario.)
++ Note, however, that the statements in this paragraph do not apply to the {@code SIGURG} signal generated for out-of-band data on a socket: this
++ signal is always sent to either a process or a process group, depending on the value given to {@code F_SETOWN}.
++
++ The above behavior was accidentally dropped in Linux 2.6.12, and won't be restored. From Linux 2.6.32 onward, use #F_SETOWN_EX to target
++ {@code SIGIO} and {@code SIGURG} signals at a particular thread.
++ """,
++ "8"
++ ),
++ "F_GETOWN".enum(
++ """
++ Return (as the function result) the process ID or process group ID currently receiving {@code SIGIO} and {@code SIGURG} signals for events on file
++ descriptor {@code fd}.
++
++ Process IDs are returned as positive values; process group IDs are returned as negative values (but see BUGS below). {@code arg} is ignored.
++ """,
++ "9"
++ ),
++ "F_SETSIG".enum(
++ """
++ Set the signal sent when input or output becomes possible to the value given in {@code arg}.
++
++ A value of zero means to send the default {@code SIGIO} signal. Any other value (including {@code SIGIO}) is the signal to send instead, and in
++ this case additional info is available to the signal handler if installed with {@code SA_SIGINFO}.
++
++ By using {@code F_SETSIG} with a nonzero value, and setting {@code SA_SIGINFO} for the signal handler (see {@code sigaction(2)}), extra information
++ about I/O events is passed to the handler in a {@code siginfo_t} structure. If the {@code si_code} field indicates the source is {@code SI_SIGIO},
++ the {@code si_fd} field gives the file descriptor associated with the event. Otherwise, there is no indication which file descriptors are pending,
++ and you should use the usual mechanisms ({@code select(2)}, {@code poll(2)}, {@code read(2)} with {@code O_NONBLOCK} set etc.) to determine which
++ file descriptors are available for I/O.
++
++ Note that the file descriptor provided in {@code si_fd} is the one that was specified during the {@code F_SETSIG} operation. This can lead to an
++ unusual corner case. If the file descriptor is duplicated ({@code dup(2)} or similar), and the original file descriptor is closed, then I/O events
++ will continue to be generated, but the {@code si_fd} field will contain the number of the now closed file descriptor.
++
++ By selecting a real time signal (value ≥ {@code SIGRTMIN}), multiple I/O events may be queued using the same signal numbers. (Queuing is
++ dependent on available memory.) Extra information is available if {@code SA_SIGINFO} is set for the signal handler, as above.
++
++ Note that Linux imposes a limit on the number of real-time signals that may be queued to a process (see {@code getrlimit(2)} and {@code signal(7)})
++ and if this limit is reached, then the kernel reverts to delivering {@code SIGIO}, and this signal is delivered to the entire process rather than
++ to a specific thread.
++ """,
++ "10"
++ ),
++ "F_GETSIG".enum(
++ """
++ Return (as the function result) the signal sent when input or output becomes possible.
++
++ A value of zero means {@code SIGIO} is sent. Any other value (including {@code SIGIO}) is the signal sent instead, and in this case additional info
++ is available to the signal handler if installed with {@code SA_SIGINFO}. {@code arg} is ignored.
++ """,
++ "11"
++ ),
++ "F_SETOWN_EX".enum(
++ """
++ This operation performs a similar task to #F_SETOWN. It allows the caller to direct I/O availability signals to a specific thread, process, or
++ process group.
++
++ The caller specifies the target of signals via {@code arg}, which is a pointer to a ##FOwnerEx structure. The type field has one of the following
++ values, which define how pid is interpreted: #F_OWNER_TID, #F_OWNER_PID, #F_OWNER_PGRP.
++ """,
++ "15"
++ ),
++ "F_GETOWN_EX".enum(
++ """
++ Return the current file descriptor owner settings as defined by a previous #F_SETOWN_EX operation.
++
++ The information is returned in the ##FOwnerEx structure pointed to by {@code arg}.
++
++ The type field will have one of the values #F_OWNER_TID, #F_OWNER_PID, or #F_OWNER_PGRP. The {@code pid} field is a positive integer representing a
++ thread ID, process ID, or process group ID. See #F_SETOWN_EX for more details.
++ """,
++ "16"
++ ),
++ "F_OFD_GETLK".enum(
++ """
++ On input to this call, {@code lock} describes an open file description lock we would like to place on the file.
++
++ If the lock could be placed, {@code fcntl()} does not actually place it, but returns #F_UNLCK in the {@code l_type} field of {@code lock} and
++ leaves the other fields of the structure unchanged. If one or more incompatible locks would prevent this lock being placed, then details about one
++ of these locks are returned via {@code lock}, as described above for #F_GETLK.
++ """,
++ "36"
++ ),
++ "F_OFD_SETLK".enum(
++ """
++ Acquire an open file description lock (when {@code l_type} is #F_RDLCK or #F_WRLCK) or release an open file description lock (when {@code l_type}
++ is #F_UNLCK) on the bytes specified by the {@code l_whence}, {@code l_start}, and {@code l_len} fields of {@code lock}.
++
++ If a conflicting lock is held by another process, this call returns -1 and sets {@code errno} to {@code EAGAIN}.
++ """,
++ "37"
++ ),
++ "F_OFD_SETLKW".enum(
++ """
++ As for #F_OFD_SETLK, but if a conflicting lock is held on the file, then wait for that lock to be released.
++
++ If a signal is caught while waiting, then the call is interrupted and (after the signal handler has returned) returns immediately (with return
++ value -1 and {@code errno} set to {@code EINTR}; see {@code signal(7)}).
++ """,
++ "38"
++ ),
++ "F_SETLEASE".enum(
++ "Set or remove a file lease according to which of the following values is specified in the integer {@code arg}: #F_RDLCK, #F_WRLCK, #F_UNLCK",
++ "1024"
++ ),
++ "F_GETLEASE".enum(
++ """
++ Indicates what type of lease is associated with the file descriptor {@code fd} by returning either #F_RDLCK, #F_WRLCK, or #F_UNLCK, indicating,
++ respectively, a read lease, a write lease, or no lease. {@code arg} is ignored.
++ """,
++ "1025"
++ ),
++ "F_NOTIFY".enum(
++ """
++ (Linux 2.4 onward) Provide notification when the directory referred to by {@code fd} or any of the files that it contains is changed.
++
++ The events to be notified are specified in {@code arg}, which is a bit mask specified by ORing together zero or more of the following bits:
++ #DN_ACCESS, #DN_MODIFY, #DN_CREATE, #DN_DELETE, #DN_RENAME, #DN_ATTRIB
++
++ (In order to obtain these definitions, the {@code _GNU_SOURCE} feature test macro must be defined before including any header files.)
++
++ Directory notifications are normally "one-shot", and the application must reregister to receive further notifications. Alternatively, if
++ #DN_MULTISHOT is included in {@code arg}, then notification will remain in effect until explicitly removed.
++
++ A series of {@code F_NOTIFY} requests is cumulative, with the events in {@code arg} being added to the set already monitored. To disable
++ notification of all events, make an {@code F_NOTIFY} call specifying {@code arg} as 0.
++
++ Notification occurs via delivery of a signal. The default signal is {@code SIGIO}, but this can be changed using the #F_SETSIG command to
++ {@code fcntl()}. (Note that {@code SIGIO} is one of the nonqueuing standard signals; switching to the use of a real-time signal means that multiple
++ notifications can be queued to the process.) In the latter case, the signal handler receives a {@code siginfo_t} structure as its second argument
++ (if the handler was established using {@code SA_SIGINFO}) and the {@code si_fd} field of this structure contains the file descriptor which
++ generated the notification (useful when establishing notification on multiple directories).
++
++ Especially when using {@code DN_MULTISHOT}, a real time signal should be used for notification, so that multiple notifications can be queued.
++
++ NOTE: New applications should use the {@code inotify} interface (available since kernel 2.6.13), which provides a much superior interface for
++ obtaining notifications of filesystem events. See {@code inotify(7)}.
++ """,
++ "1026"
++ ),
++ "F_SETPIPE_SZ".enum(
++ """
++ Change the capacity of the pipe referred to by {@code fd} to be at least {@code arg} bytes.
++
++ An unprivileged process can adjust the pipe capacity to any value between the system page size and the limit defined in
++ {@code /proc/sys/fs/pipe-max-size} (see {@code proc(5)}). Attempts to set the pipe capacity below the page size are silently rounded up to the page
++ size. Attempts by an unprivileged process to set the pipe capacity above the limit in {@code /proc/sys/fs/pipe-max-size} yield the error
++ {@code EPERM}; a privileged process ({@code CAP_SYS_RESOURCE}) can override the limit.
++
++ When allocating the buffer for the pipe, the kernel may use a capacity larger than {@code arg}, if that is convenient for the implementation. (In
++ the current implementation, the allocation is the next higher power-of-two page-size multiple of the requested size.) The actual capacity (in
++ bytes) that is set is returned as the function result.
++
++ Attempting to set the pipe capacity smaller than the amount of buffer space currently used to store data produces the error {@code EBUSY}.
++
++ Note that because of the way the pages of the pipe buffer are employed when data is written to the pipe, the number of bytes that can be written
++ may be less than the nominal size, depending on the size of the writes.
++ """,
++ "1031"
++ ),
++ "F_GETPIPE_SZ".enum("Return (as the function result) the capacity of the pipe referred to by {@code fd}.", "1032"
++ ),
++ "F_ADD_SEALS".enum(
++ """
++ Add the seals given in the bit-mask argument {@code arg} to the set of seals of the {@code inode} referred to by the file descriptor {@code fd}.
++
++ Seals cannot be removed again. Once this call succeeds, the seals are enforced by the kernel immediately. If the current set of seals includes
++ #F_SEAL_SEAL (see below), then this call will be rejected with {@code EPERM}. Adding a seal that is already set is a no-op, in case
++ {@code F_SEAL_SEAL} is not set already. In order to place a seal, the file descriptor {@code fd} must be writable.
++ """,
++ "1033"
++ ),
++ "F_GET_SEALS".enum(
++ """
++ Return (as the function result) the current set of seals of the {@code inode} referred to by {@code fd}.
++
++ If no seals are set, 0 is returned. If the file does not support sealing, -1 is returned and {@code errno} is set to {@code EINVAL}.
++ """,
++ "1034"
++ ),
++ "F_GET_RW_HINT".enum("Returns the value of the read/write hint associated with the underlying {@code inode} referred to by {@code fd}.", "1035"),
++ "F_SET_RW_HINT".enum(
++ """
++ Sets the read/write hint value associated with the underlying {@code inode} referred to by {@code fd}.
++
++ This hint persists until either it is explicitly modified or the underlying filesystem is unmounted.
++ """,
++ "1036"
++ ),
++ "F_GET_FILE_RW_HINT".enum("Returns the value of the read/write hint associated with the open file description referred to by {@code fd}.", "1037"),
++ "F_SET_FILE_RW_HINT".enum("Sets the read/write hint value associated with the open file description referred to by {@code fd}.", "1038"),
++ "F_DUPFD_CLOEXEC".enum(
++ """
++ As for #F_DUPFD, but additionally set the close-on-exec flag for the duplicate file descriptor.
++
++ Specifying this flag permits a program to avoid an additional {@code fcntl()} #F_SETFD operation to set the #FD_CLOEXEC flag. For an explanation of
++ why this flag is useful, see the description of #O_CLOEXEC in {@code open(2)}.
++ """,
++ "1030"
++ )
++ ).javaDocLinks
++
++ IntConstant("", "FD_CLOEXEC".."1")
++
++ EnumConstant(
++ "For posix #fcntl() and {@code l_type} field of an ##Flock for {@code lockf()}.",
++
++ "F_RDLCK".enum(
++ """
++ Take out a read lease.
++
++ This will cause the calling process to be notified when the file is opened for writing or is truncated. A read lease can be placed only on a file
++ descriptor that is opened read-only.
++ """,
++ "0"
++ ),
++ "F_WRLCK".enum(
++ """
++ Take out a write lease.
++
++ This will cause the caller to be notified when the file is opened for reading or writing or is truncated. A write lease may be placed on a file
++ only if there are no other open file descriptors for the file.
++ """,
++ "1"
++ ),
++ "F_UNLCK".enum("Remove our lease from the file.", "2"),
++ "F_EXLCK".enum("", "4"),
++ "F_SHLCK".enum("", "8")
++ )
++
++ EnumConstant(
++ "##FOwnerEx{@code ::type} values.",
++
++ "F_OWNER_TID".enum(
++ """
++ Send the signal to the thread whose thread ID (the value returned by a call to {@code clone(2)} or {@code gettid(2)}) is specified in {@code pid}.
++ """,
++ "0"
++ ),
++ "F_OWNER_PID".enum(" Send the signal to the process whose ID is specified in {@code pid}.", "1"),
++ "F_OWNER_PGRP".enum(
++ """
++ Send the signal to the process group whose ID is specified in {@code pid}.
++
++ (Note that, unlike with #F_SETOWN, a process group ID is specified as a positive value here.)
++ """,
++ "2"
++ )
++ )
++
++ EnumConstant(
++ "",
++
++ "LOCK_SH".enum("shared lock", "1"),
++ "LOCK_EX".enum("exclusive lock", "2"),
++ "LOCK_NB".enum("or'd with one of the above to prevent blocking", "4"),
++ "LOCK_UN".enum("remove lock", "8"),
++ "LOCK_MAND".enum("This is a mandatory flock...", "32"),
++ "LOCK_READ".enum("which allows concurrent read operations", "64"),
++ "LOCK_WRITE".enum("which allows concurrent write operations", "128"),
++ "LOCK_RW".enum("which allows concurrent read & writes ops", "192")
++ )
++
++ EnumConstant(
++ "",
++
++ "DN_ACCESS".enum("A file was accessed ({@code read(2)}, {@code pread(2)}, {@code readv(2)}, and similar).", 0x00000001),
++ "DN_MODIFY".enum(
++ "A file was modified ({@code write(2)}, {@code pwrite(2)}, {@code writev(2)}, {@code truncate(2)}, {@code ftruncate(2)}, and similar).",
++ 0x00000002
++ ),
++ "DN_CREATE".enum(
++ """
++ A file was created ({@code open(2)}, {@code creat(2)}, {@code mknod(2)}, {@code mkdir(2)}, {@code link(2)}, {@code symlink(2)}, {@code rename(2)}
++ into this directory).
++ """,
++ 0x00000004
++ ),
++ "DN_DELETE".enum("A file was unlinked ({@code unlink(2)}, {@code rename(2)} to another directory, {@code rmdir(2)}).", 0x00000008),
++ "DN_RENAME".enum("A file was renamed within this directory ({@code rename(2)}).", 0x00000010),
++ "DN_ATTRIB".enum(
++ "The attributes of a file were changed ({@code chown(2)}, {@code chmod(2)}, {@code utime(2)}, {@code utimensat(2)}, and similar).",
++ 0x00000020
++ ),
++ "DN_MULTISHOT".enum("Don't remove notifier", "0x80000000")
++ )
++
++ EnumConstant(
++ "",
++
++ "F_SEAL_SEAL".enum(
++ """
++ If this seal is set, any further call to {@code fcntl()} with #F_ADD_SEALS fails with the error {@code EPERM}.
++
++ Therefore, this seal prevents any modifications to the set of seals itself. If the initial set of seals of a file includes {@code F_SEAL_SEAL},
++ then this effectively causes the set of seals to be constant and locked.
++ """,
++ "0x0001"
++ ),
++ "F_SEAL_SHRINK".enum(
++ """
++ If this seal is set, the file in question cannot be reduced in size.
++
++ This affects {@code open(2)} with the #O_TRUNC flag as well as {@code truncate(2)} and {@code ftruncate(2)}. Those calls fail with {@code EPERM} if
++ you try to shrink the file in question. Increasing the file size is still possible.
++ """,
++ "0x0002"
++ ),
++ "F_SEAL_GROW".enum(
++ """
++ If this seal is set, the size of the file in question cannot be increased.
++
++ This affects {@code write(2)} beyond the end of the file, {@code truncate(2)}, {@code ftruncate(2)}, and {@code fallocate(2)}. These calls fail
++ with {@code EPERM} if you use them to increase the file size. If you keep the size or shrink it, those calls still work as expected.
++ """,
++ "0x0004"
++ ),
++ "F_SEAL_WRITE".enum(
++ """
++ If this seal is set, you cannot modify the contents of the file.
++
++ Note that shrinking or growing the size of the file is still possible and allowed. Thus, this seal is normally used in combination with one of the
++ other seals. This seal affects {@code write(2)} and {@code fallocate(2)} (only in combination with the {@code FALLOC_FL_PUNCH_HOLE} flag). Those
++ calls fail with {@code EPERM} if this seal is set. Furthermore, trying to create new shared, writable memory-mappings via {@code mmap(2)} will also
++ fail with {@code EPERM}.
++
++ Using the #F_ADD_SEALS operation to set the {@code F_SEAL_WRITE} seal fails with {@code EBUSY} if any writable, shared mapping exists. Such
++ mappings must be unmapped before you can add this seal. Furthermore, if there are any asynchronous I/O operations ({@code io_submit(2)}) pending on
++ the file, all outstanding writes will be discarded.
++ """,
++ "0x0008"
++ ),
++ "F_SEAL_FUTURE_WRITE".enum(
++ """
++ The effect of this seal is similar to #F_SEAL_WRITE, but the contents of the file can still be modified via shared writable mappings that were
++ created prior to the seal being set.
++
++ Any attempt to create a new writable mapping on the file via {@code mmap(2)} will fail with {@code EPERM}. Likewise, an attempt to write to the
++ file via {@code write(2)} will fail with {@code EPERM}.
++
++ Using this seal, one process can create a memory buffer that it can continue to modify while sharing that buffer on a "read-only" basis with other
++ processes.
++
++ (since Linux 5.1)
++ """,
++ "0x0010"
++ )
++ )
++
++ EnumConstant(
++ "",
++
++ "RWH_WRITE_LIFE_NOT_SET".enum("No specific hint has been set. This is the default value.", "0"),
++ "RWH_WRITE_LIFE_NONE".enum("No specific write lifetime is associated with this file or {@code inode}."),
++ "RWH_WRITE_LIFE_SHORT".enum("Data written to this {@code inode} or via this open file description is expected to have a short lifetime."),
++ "RWH_WRITE_LIFE_MEDIUM".enum(
++ """
++ Data written to this {@code inode} or via this open file description is expected to have a lifetime longer than data written with
++ #RWH_WRITE_LIFE_SHORT.
++ """
++ ),
++ "RWH_WRITE_LIFE_LONG".enum(
++ """
++ Data written to this {@code inode} or via this open file description is expected to have a lifetime longer than data written with
++ #RWH_WRITE_LIFE_MEDIUM.
++ """
++ ),
++ "RWH_WRITE_LIFE_EXTREME".enum(
++ """
++ Data written to this {@code inode} or via this open file description is expected to have a lifetime longer than data written with
++ #RWH_WRITE_LIFE_LONG.
++ """
++ )
++ )
++
++ SaveErrno..int(
++ "open",
++ """
++ Given a {@code pathname} for a file, {@code open()} returns a file descriptor, a small, nonnegative integer for use in subsequent system calls
++ ({@code read(2)}, {@code write(2)}, {@code lseek(2)}, {@code fcntl(2)}, etc.).
++
++ The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.
++ """,
++
++ charUTF8.const.p("pathname", ""),
++ int("flags", ""),
++ mode_t("mode", "", ModeBits, LinkMode.BITFIELD),
++
++ returnDoc = "the new file descriptor, or -1 if an error occurred (in which case, {@code errno} is set appropriately)."
++ )
++
++ SaveErrno..int(
++ "openat",
++ """
++ The {@code openat()} system call operates in exactly the same way as {@code open(2)}, except for the differences described in this manual page.
++
++ If the pathname given in {@code pathname} is relative, then it is interpreted relative to the directory referred to by the file descriptor
++ {@code dirfd} (rather than relative to the current working directory of the calling process, as is done by {@code open(2)} for a relative pathname).
++
++ If {@code pathname} is relative and {@code dirfd} is the special value {@code AT_FDCWD}, then pathname is interpreted relative to the current working
++ directory of the calling process (like {@code open(2)}).
++
++ If {@code pathname} is absolute, then {@code dirfd} is ignored.
++ """,
++
++ int("dirfd", ""),
++ charUTF8.const.p("pathname", ""),
++ int("flags", ""),
++ mode_t("mode", "", ModeBits, LinkMode.BITFIELD),
++
++ returnDoc = "a new file descriptor on success. On error, -1 is returned and {@code errno} is set to indicate the error."
++ )
++
++ SaveErrno..int(
++ "creat",
++ """
++ Equivalent to {@code open()} with {@code flags} equal to {@code O_CREAT|O_WRONLY|O_TRUNC}.
++ """,
++
++ charUTF8.const.p("pathname", ""),
++ mode_t("mode", "", ModeBits, LinkMode.BITFIELD)
++ )
++
++ SaveErrno..int(
++ "fcntl",
++ """
++ Performs one of the operations determined by {@code cmd} on the open file descriptor {@code fd}.
++
++ {@code fcntl()} can take an optional third argument. Whether or not this argument is required is determined by {@code cmd}. The required argument type
++ is indicated in parentheses after each {@code cmd} name (in most cases, the required type is {@code int}, and we identify the argument using the name
++ {@code arg}), or {@code void} is specified if the argument is not required.
++
++ LWJGL note: Use #fcntli() or #fcntlp() to pass a third argument of the appropriate type.
++
++ Certain of the operations below are supported only since a particular Linux kernel version. The preferred method of checking whether the host kernel
++ supports a particular operation is to invoke {@code fcntl()} with the desired {@code cmd} value and then test whether the call failed with
++ {@code EINVAL}, indicating that the kernel does not recognize this value.
++ """,
++
++ int("fd", ""),
++ int("cmd", "", commands)
++ )
++
++ SaveErrno..NativeName("fcntl")..int(
++ "fcntli",
++ "#fcntl() overload that takes a third argument of type {@code int}.",
++
++ int("fd", ""),
++ int("cmd", "", commands),
++ int("arg", "")
++ )
++
++ SaveErrno..NativeName("fcntl")..int(
++ "fcntlp",
++ "#fcntl() overload that takes a third argument of type {@code void *}.",
++
++ int("fd", ""),
++ int("cmd", "", commands),
++ opaque_p("arg", "")
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/mman.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/mman.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/mman.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/mman.kt
+@@ -0,0 +1,280 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val mman = "MMAN".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++ documentation = "Native bindings to <sys/mman.h>."
++
++ LongConstant(
++ "Return value of #mmap() in case of an error.",
++
++ "MAP_FAILED".."-1L"
++ )
++
++ EnumConstant(
++ """
++ The {@code prot} argument describes the desired memory protection of the mapping (and must not conflict with the open mode of the file).
++
++ It is either {@code PROT_NONE} or the bitwise OR of one or more of the following flags.
++ """,
++
++ "PROT_EXEC".enum("Pages may be executed.", "0x4"),
++ "PROT_READ".enum("Pages may be read.", "0x1"),
++ "PROT_WRITE".enum("Pages may be written.", "0x2"),
++ "PROT_NONE".enum("Pages may not be accessed.", "0x0"),
++ "PROT_GROWSDOWN".enum("Extend change to start of {@code growsdown} vma ({@code mprotect} only).", "0x01000000"),
++ "PROT_GROWSUP".enum("Extend change to start of {@code growsup} vma ({@code mprotect} only).", "0x02000000")
++ )
++
++ EnumConstant(
++ """
++ The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried
++ through to the underlying file.
++
++ This behavior is determined by including exactly one of the following values in {@code flags}.
++ """,
++
++ "MAP_SHARED".enum(
++ """
++ Share this mapping.
++
++ Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to the
++ underlying file. (To precisely control when updates are carried through to the underlying file requires the use of {@code msync(2)}.)
++ """,
++ "0x01"
++ ),
++ "MAP_SHARED_VALIDATE".enum(
++ """
++ This flag provides the same behavior as #MAP_SHARED except that {@code MAP_SHARED} mappings ignore unknown flags in {@code flags}.
++
++ By contrast, when creating a mapping using {@code MAP_SHARED_VALIDATE}, the kernel verifies all passed flags are known and fails the mapping with
++ the error {@code EOPNOTSUPP} for unknown flags. This mapping type is also required to be able to use some mapping flags (e.g., {@code MAP_SYNC}).
++ """,
++ "0x03"
++ ),
++ "MAP_PRIVATE".enum(
++ """
++ Create a private copy-on-write mapping.
++
++ Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is
++ unspecified whether changes made to the file after the #mmap() call are visible in the mapped region.
++ """,
++ "0x02"
++ )
++ )
++
++ IntConstant("", "MAP_HUGE_SHIFT".."26")
++ IntConstant("", "MAP_HUGE_MASK".."0x3f")
++
++ EnumConstant(
++ "",
++
++ "MAP_32BIT".enum(
++ """
++ Put the mapping into the first 2 Gigabytes of the process address space.
++
++ This flag is supported only on x86-64, for 64-bit programs. It was added to allow thread stacks to be allocated somewhere in the first 2 GB of
++ memory, so as to improve context-switch performance on some early 64-bit processors. Modern x86-64 processors no longer have this performance
++ problem, so use of this flag is not required on those systems. The {@code MAP_32BIT} flag is ignored when #MAP_FIXED is set.
++ """,
++ "0x40"
++ ),
++ "MAP_ANONYMOUS".enum(
++ """
++ The mapping is not backed by any file; its contents are initialized to zero.
++
++ The {@code fd} argument is ignored; however, some implementations require {@code fd} to be -1 if {@code MAP_ANONYMOUS} (or #MAP_ANON) is specified,
++ and portable applications should ensure this. The {@code offset} argument should be zero. The use of {@code MAP_ANONYMOUS} in conjunction with
++ {@code MAP_SHARED} is supported on Linux only since kernel 2.4.
++ """,
++ "0x20"
++ ),
++ "MAP_ANON".enum("Synonym for MAP_ANONYMOUS; provided for compatibility with other implementations.", "MAP_ANONYMOUS"),
++ "MAP_DENYWRITE".enum(
++ """
++ This flag is ignored.
++
++ (Long ago —Linux 2.0 and earlier— it signaled that attempts to write to the underlying file should fail with {@code ETXTBSY}. But this was a source
++ of denial-of-service attacks.)
++ """,
++ "0x00800"
++ ),
++ "MAP_EXECUTABLE".enum("This flag is ignored.", "0x01000"),
++ "MAP_FILE".enum("Compatibility flag. Ignored.", "0"),
++ "MAP_FIXED".enum(
++ """
++ Don't interpret {@code addr} as a hint: place the mapping at exactly that address.
++
++ {@code addr} must be suitably aligned: for most architectures a multiple of the page size is sufficient; however, some architectures may impose
++ additional restrictions. If the memory region specified by {@code addr} and {@code length} overlaps pages of any existing mapping(s), then the
++ overlapped part of the existing mapping(s) will be discarded. If the specified address cannot be used, #mmap() will fail.
++
++ Software that aspires to be portable should use the {@code MAP_FIXED} flag with care, keeping in mind that the exact layout of a process's memory
++ mappings is allowed to change significantly between kernel versions, C library versions, and operating system releases. Carefully read the
++ discussion of this flag in NOTES!
++ """,
++ "0x10"
++ ),
++ "MAP_FIXED_NOREPLACE".enum(
++ """
++ This flag provides behavior that is similar to #MAP_FIXED with respect to the {@code addr} enforcement, but differs in that
++ {@code MAP_FIXED_NOREPLACE} never clobbers a preexisting mapped range.
++
++ If the requested range would collide with an existing mapping, then this call fails with the error {@code EEXIST}. This flag can therefore be used
++ as a way to atomically (with respect to other threads) attempt to map an address range: one thread will succeed; all others will report failure.
++
++ Note that older kernels which do not recognize the {@code MAP_FIXED_NOREPLACE} flag will typically (upon detecting a collision with a preexisting
++ mapping) fall back to a "non-{@code MAP_FIXED}" type of behavior: they will return an address that is different from the requested address.
++ Therefore, backward-compatible software should check the returned address against the requested address.
++
++ (since Linux 4.17)
++ """,
++ "0x100000"
++ ),
++ "MAP_GROWSDOWN".enum(
++ """
++ This flag is used for stacks. It indicates to the kernel virtual memory system that the mapping should extend downward in memory.
++
++ The return address is one page lower than the memory area that is actually created in the process's virtual address space. Touching an address in
++ the "guard" page below the mapping will cause the mapping to grow by a page. This growth can be repeated until the mapping grows to within a page
++ of the high end of the next lower mapping, at which point touching the "guard" page will result in a {@code SIGSEGV} signal.
++ """,
++ "0x00100"
++ ),
++ "MAP_HUGETLB".enum(
++ """
++ Allocate the mapping using "huge" pages.
++
++ See the Linux kernel source file {@code Documentation/admin-guide/mm/hugetlbpage.rst} for further information, as well as NOTES, below.
++
++ (since Linux 2.6.32)
++ """,
++ "0x40000"
++ ),
++ "MAP_HUGE_2MB".enum(
++ """
++ Used in conjunction with #MAP_HUGETLB to select alternative {@code hugetlb} page sizes (respectively, 2 MB and 1 GB) on systems that support
++ multiple {@code hugetlb} page sizes.
++
++ More generally, the desired huge page size can be configured by encoding the base-2 logarithm of the desired page size in the six bits at the
++ offset #MAP_HUGE_SHIFT. (A value of zero in this bit field provides the default huge page size; the default huge page size can be discovered via
++ the {@code Hugepagesize} field exposed by {@code /proc/meminfo}.) Thus, the above two constants are defined as:
++ ${codeBlock("""
++\#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
++\#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)""")}
++
++ The range of huge page sizes that are supported by the system can be discovered by listing the subdirectories in {@code /sys/kernel/mm/hugepages}.
++
++ (since Linux 3.8)
++ """,
++ "21 << MAP_HUGE_SHIFT"
++ ),
++ "MAP_HUGE_1GB".enum("See #MAP_HUGE_2MB.", "30 << MAP_HUGE_SHIFT"),
++ "MAP_LOCKED".enum(
++ """
++
++ """,
++ "0x02000"
++ ),
++ "MAP_NONBLOCK".enum(
++ """
++
++ """,
++ "0x10000"
++ ),
++ "MAP_NORESERVE".enum(
++ """
++
++ """,
++ "0x04000"
++ ),
++ "MAP_POPULATE".enum(
++ """
++
++ """,
++ "0x08000"
++ ),
++ "MAP_STACK".enum(
++ """
++
++ """,
++ "0x20000"
++ ),
++ "MAP_SYNC".enum(
++ """
++
++ """,
++ "0x80000"
++ ),
++ "MAP_UNINITIALIZED".enum(
++ """
++
++ """,
++ "0x4000000"
++ )
++ )
++
++ SaveErrno..opaque_p(
++ "mmap",
++ """
++ Creates a new mapping in the virtual address space of the calling process.
++
++ The starting address for the new mapping is specified in {@code addr}. The {@code length} argument specifies the length of the mapping (which must be
++ greater than 0).
++
++ If {@code addr} is #NULL, then the kernel chooses the (page-aligned) address at which to create the mapping; this is the most portable method of
++ creating a new mapping. If {@code addr} is not #NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the kernel will
++ pick a nearby page boundary (but always above or equal to the value specified by {@code /proc/sys/vm/mmap_min_addr}) and attempt to create the mapping
++ there. If another mapping already exists there, the kernel picks a new address that may or may not depend on the hint. The address of the new mapping
++ is returned as the result of the call.
++
++ The contents of a file mapping (as opposed to an anonymous mapping; see {@code MAP_ANONYMOUS} below), are initialized using {@code length} bytes
++ starting at offset {@code offset} in the file (or other object) referred to by the file descriptor {@code fd}. {@code offset} must be a multiple of the
++ page size as returned by {@code sysconf(_SC_PAGE_SIZE)}.
++
++ After the {@code mmap()} call has returned, the file descriptor, {@code fd}, can be closed immediately without invalidating the mapping.
++ """,
++
++ nullable..opaque_p("addr", ""),
++ size_t("length", ""),
++ int(
++ "prot",
++ "describes the desired memory protection of the mapping (and must not conflict with the open mode of the file)",
++ "PROT_\\w+", LinkMode.BITFIELD
++ ),
++ int("flags", "", "MAP_\\w+", LinkMode.BITFIELD),
++ int("fd", ""),
++ off_t("offset", ""),
++
++ returnDoc =
++ "on success, returns a pointer to the mapped area. On error, the value #MAP_FAILED is returned, and {@code errno} is set to indicate the error."
++ )
++
++ SaveErrno..int(
++ "munmap",
++ """
++ Deletes the mappings for the specified address range, and causes further references to addresses within the range to generate invalid memory
++ references.
++
++ The region is also automatically unmapped when the process is terminated. On the other hand, closing the file descriptor does not unmap the region.
++
++ The address {@code addr} must be a multiple of the page size (but {@code length} need not be). All pages containing a part of the indicated range are
++ unmapped, and subsequent references to these pages will generate {@code SIGSEGV}. It is not an error if the indicated range does not contain any mapped
++ pages.
++ """,
++
++ void.p("addr", ""),
++ AutoSize("addr")..size_t("length", ""),
++
++ returnDoc = "on success, returns 0. On failure, it returns -1, and {@code errno} is set to indicate the error (probably to {@code EINVAL})."
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/pthread.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/pthread.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/pthread.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/pthread.kt
+@@ -0,0 +1,20 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val pthread = "PThread".nativeClass(Module.CORE_ASTRAL, prefixMethod = "pthread_", nativeSubPath = "astral") {
++ nativeImport("")
++ documentation = "Native bindings to <pthread.h>."
++
++ pthread_t(
++ "self",
++ "",
++
++ void()
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/socket.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/socket.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/socket.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/socket.kt
+@@ -0,0 +1,41 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val socket = "Socket".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++ documentation = "Native bindings to <sys/socket.h>."
++
++ // TODO:
++
++ EnumConstant(
++ "The following constants should be used for the second parameter of {@code shutdown}.",
++
++ "SHUT_RD".enum("No more receptions.", "0"),
++ "SHUT_WR".enum("No more transmissions."),
++ "SHUT_RDWR".enum("No more receptions or transmissions.")
++ )
++
++ SaveErrno..int(
++ "socket",
++ """
++ Create a new socket of type {@code __type} in domain {@code __domain}, using protocol {@code __protocol}.
++
++ If {@code __protocol} is zero, one is chosen automatically.
++ """,
++
++ int("__domain", ""),
++ int("__type", ""),
++ int("__protocol", ""),
++
++ returnDoc = "a file descriptor for the new socket, or -1 for errors"
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/stat.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/stat.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/stat.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/stat.kt
+@@ -0,0 +1,34 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val sys_stat_h = "Stat".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++ documentation = "Native bindings to <sys/stat.h>."
++
++ // TODO:
++
++ SaveErrno..int(
++ "stat",
++ "",
++
++ charUTF8.const.p("__file", ""),
++ stat.p("__buf", "")
++ )
++
++ SaveErrno..int(
++ "fstat",
++ "",
++
++ int("__fd", ""),
++ stat.p("__buf", "")
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/uio.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/uio.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/uio.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/uio.kt
+@@ -0,0 +1,115 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val uio = "UIO".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++ documentation = "Native bindings to <sys/uio.h>."
++
++ // TODO:
++
++ IntConstant("", "UIO_FASTIOV".."8")
++ IntConstant("", "UIO_MAXIOV".."1024")
++
++ EnumConstant(
++ "Flags for {@code preadv2}/{@code pwritev2}.",
++
++ "RWF_HIPRI".enum("High priority request.", 0x00000001),
++ "RWF_DSYNC".enum("per-IO #O_DSYNC", 0x00000002),
++ "RWF_SYNC".enum("per-IO #O_SYNC", 0x00000004),
++ "RWF_NOWAIT".enum("per-IO nonblocking mode", 0x00000008),
++ "RWF_APPEND".enum("per-IO #O_APPEND", 0x00000010),
++ )
++
++ SaveErrno..ssize_t(
++ "readv",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", "")
++ )
++
++ SaveErrno..ssize_t(
++ "writev",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", "")
++ )
++
++ SaveErrno..ssize_t(
++ "preadv",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", ""),
++ off_t("__offset", "")
++ )
++
++ SaveErrno..ssize_t(
++ "pwritev",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", ""),
++ off_t("__offset", "")
++ )
++
++ /*SaveErrno..ssize_t(
++ "preadv2",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", ""),
++ off_t("__offset", ""),
++ int("__flags", "")
++ )*/
++
++ /*SaveErrno..ssize_t(
++ "pwritev2",
++ "",
++
++ int("__fd", ""),
++ iovec.const.p("__iovec", ""),
++ int("__count", ""),
++ off_t("__offset", ""),
++ int("__flags", "")
++ )*/
++
++ SaveErrno..ssize_t(
++ "process_vm_readv",
++ "Read from another process' address space.",
++
++ pid_t("__pid", ""),
++ iovec.const.p("__lvec", ""),
++ unsigned_long_int("__liovcnt", ""),
++ iovec.const.p("__rvec", ""),
++ unsigned_long_int("__riovcnt", ""),
++ unsigned_long_int("__flags", "")
++ )
++
++ SaveErrno..ssize_t(
++ "process_vm_writev",
++ "Write to another process' address space.",
++
++ pid_t("__pid", ""),
++ iovec.const.p("__lvec", ""),
++ unsigned_long_int("__liovcnt", ""),
++ iovec.const.p("__rvec", ""),
++ unsigned_long_int("__riovcnt", ""),
++ unsigned_long_int("__flags", "")
++ )
++}
+\ No newline at end of file
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/unistd.kt lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/unistd.kt
+--- lwjgl3-clean/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/unistd.kt 1970-01-01 01:00:00.000000000 +0100
++++ lwjgl3-workdir/modules/lwjgl/core/src/templates/kotlin/core/astral/templates/unistd.kt
+@@ -0,0 +1,73 @@
++/*
++ * Copyright LWJGL. All rights reserved.
++ * License terms: https://www.lwjgl.org/license
++ */
++package core.astral.templates
++
++import core.astral.*
++import org.lwjgl.generator.*
++
++val unistd = "UNISTD".nativeClass(Module.CORE_ASTRAL, nativeSubPath = "astral") {
++ nativeImport(
++ "",
++ ""
++ )
++
++ documentation = "Native bindings to <unistd.h>."
++
++ EnumConstant(
++ "",
++
++ "_SC_OPEN_MAX".enum("", "4"),
++ "_SC_PAGE_SIZE".enum("", "30"),
++ "_SC_IOV_MAX".enum("", "60")
++ )
++
++ SaveErrno..int(
++ "close",
++ """
++
++ """,
++
++ int("fd", "")
++ )
++
++ SaveErrno..long(
++ "sysconf",
++ """
++
++ """,
++
++ int("name", "")
++ )
++
++ SaveErrno..ssize_t(
++ "read",
++ "",
++
++ int("fd", ""),
++ void.p("buf", ""),
++ AutoSize("buf")..size_t("count", "")
++ )
++
++ pid_t(
++ "getpid",
++ "",
++
++ void()
++ )
++
++ pid_t(
++ "getppid",
++ "",
++
++ void()
++ )
++
++ pid_t(
++ "gettid",
++ "",
++
++ void()
++ )
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/openal/src/main/java/org/lwjgl/openal/ALC.java lwjgl3-workdir/modules/lwjgl/openal/src/main/java/org/lwjgl/openal/ALC.java
+--- lwjgl3-clean/modules/lwjgl/openal/src/main/java/org/lwjgl/openal/ALC.java
++++ lwjgl3-workdir/modules/lwjgl/openal/src/main/java/org/lwjgl/openal/ALC.java
+@@ -64,6 +64,7 @@
+ switch (Platform.get()) {
+ case LINUX:
+ case MACOSX:
++ case ASTRAL:
+ libName = "openal";
+ break;
+ case WINDOWS:
+@@ -350,4 +351,4 @@
+
+ }
+
+-}
+\ No newline at end of file
++}
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/opengl/src/main/java/org/lwjgl/opengl/GL.java lwjgl3-workdir/modules/lwjgl/opengl/src/main/java/org/lwjgl/opengl/GL.java
+--- lwjgl3-clean/modules/lwjgl/opengl/src/main/java/org/lwjgl/opengl/GL.java
++++ lwjgl3-workdir/modules/lwjgl/opengl/src/main/java/org/lwjgl/opengl/GL.java
+@@ -98,6 +98,7 @@
+ SharedLibrary GL;
+ switch (Platform.get()) {
+ case LINUX:
++ case ASTRAL:
+ GL = Library.loadNative(GL.class, "org.lwjgl.opengl", Configuration.OPENGL_LIBRARY_NAME, "libGLX.so.0", "libGL.so.1", "libGL.so");
+ break;
+ case MACOSX:
+diff -urN --no-dereference lwjgl3-clean/modules/lwjgl/remotery/src/main/c/Remotery.h lwjgl3-workdir/modules/lwjgl/remotery/src/main/c/Remotery.h
+--- lwjgl3-clean/modules/lwjgl/remotery/src/main/c/Remotery.h
++++ lwjgl3-workdir/modules/lwjgl/remotery/src/main/c/Remotery.h
+@@ -130,7 +130,7 @@
+ // Platform identification
+ #if defined(_WINDOWS) || defined(_WIN32)
+ #define RMT_PLATFORM_WINDOWS
+-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
++#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__astral__)
+ #define RMT_PLATFORM_LINUX
+ #define RMT_PLATFORM_POSIX
+ #elif defined(__APPLE__)
diff --git a/recipes/lwjgl3 b/recipes/lwjgl3
new file mode 100644
index 00000000..1db7724f
--- /dev/null
+++ b/recipes/lwjgl3
@@ -0,0 +1,46 @@
+name=lwjgl3
+revision=1
+from_source=lwjgl3
+imagedeps="build-essential zip unzip file ant openjdk-8-jdk"
+hostdeps="xgcc xbinutils libstdc++-v3 pkgconfig autoconf"
+deps="base cups freetype fontconfig libpng libjpeg-turbo zlib libx11 libxext libxi libxrandr libxrender libxt libxtst xorgproto libiconv libffi libxcursor libxxf86vm openjdk17 glfw openal"
+allow_network=yes
+
+configure() {
+ cp -rp "${source_dir}/." .
+}
+
+_call_ant() {
+ JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 ant \
+ -Dgcc.prefix=x86_64-astral- \
+ -Dbuild.arch=x64 \
+ -Dplatform=astral \
+ -Djni.headers="${sysroot_dir}/usr/lib/jvm/java-17/include" \
+ -Dbinding.nfd=false \
+ -Dbinding.tootle=false \
+ -Dbinding.remotery=false \
+ -Dbinding.assimp=false \
+ -Dbinding.bgfx=false \
+ -Dbinding.harfbuzz=false \
+ -Dbinding.hwloc=false \
+ -Dbinding.ktx=false \
+ -Dbinding.openvr=false \
+ -Dbinding.openxr=false \
+ -Dbinding.opus=false \
+ -Dbinding.shaderc=false \
+ -Dbinding.spvc=false \
+ -Dbinding.nanovg=false \
+ -Djavadoc.skip=true \
+ "$@"
+}
+
+build() {
+ _call_ant compile-templates generate compile
+ _call_ant -Dbuild.offline=true compile-native
+ yes | _call_ant -Dbuild.offline=true release
+}
+
+package() {
+ mkdir -vp "${dest_dir}${prefix}/share/lwjgl3"
+ find bin/RELEASE -type f -name '*.jar' ! -name '*-sources.jar' -exec cp '{}' "${dest_dir}${prefix}/share/lwjgl3" ';'
+}
diff --git a/source-recipes/lwjgl3 b/source-recipes/lwjgl3
new file mode 100644
index 00000000..5f6266a6
--- /dev/null
+++ b/source-recipes/lwjgl3
@@ -0,0 +1,8 @@
+name=lwjgl3
+version=3.3.3
+source_method=tarball
+tarball_url="https://github.com/LWJGL/lwjgl3/archive/refs/tags/${version}.tar.gz"
+tarball_sha512=739a8bcadc0b4008326b9a90fcbc90076308baa0e38649454b8747187611d355d454e4c0396d1a9f4ea3c1ac515ec8f7ae0ff6607fb0dab825d035c6a83873b7
+prepare() {
+ true
+}