diff --git a/kernel-src/arch/x86-64/context.c b/kernel-src/arch/x86-64/context.c new file mode 100644 index 00000000..42f175d9 --- /dev/null +++ b/kernel-src/arch/x86-64/context.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#define XCR0_X87 (1ull << 0) +#define XCR0_SSE (1ull << 1) +#define XCR0_AVX (1ull << 2) +#define XCR0_AVX512 (7ull << 5) + +#define XCR0_MASK (XCR0_AVX512 | XCR0_AVX | XCR0_SSE | XCR0_X87) + +static enum { + FXSAVE, + XSAVE, + XSAVEOPT, +} xsave_method; +size_t arch_xsave_size; +static uint64_t xcr0_value; +static scache_t *xsave_cache; + +typedef struct { + uint16_t fcw; + uint16_t fsw; + uint8_t ftw; + uint8_t reserved1; + uint16_t fop; + uint64_t fip; + uint64_t fdp; + uint32_t mxcsr; + uint32_t mxcsr_mask; + struct { + uint64_t data[2]; + } mm[8]; + struct { + uint64_t data[2]; + } xmm[16]; + uint64_t reserved2[6]; + uint64_t unused[6]; +} fxsave_area_t; + +void arch_extracontext_detect(void) { + if (!arch_xsave_size) { + if (cpuid_base_max_leaf() >= 0x0d) { + xsave_method = XSAVE; + + cpuid_results_t results; + cpuid_with_ecx(0x0d, 0, &results); + xcr0_value = ((uint64_t)results.edx << 32) | results.eax; + xcr0_value &= XCR0_MASK; + } else { + xsave_method = FXSAVE; + arch_xsave_size = 512; + } + } + + if (xsave_method == FXSAVE) return; + + size_t cr4; + asm volatile("mov %%cr4, %0" : "=r" (cr4)); + cr4 |= (1u << 18); + asm volatile("mov %0, %%cr4" :: "r" (cr4)); + + uint32_t low = xcr0_value; + uint32_t high = xcr0_value >> 32; + asm volatile("xsetbv" :: "a" (low), "d" (high), "c" (0u)); + + if (!arch_xsave_size) { + // after xsetbv ebx is updated to the size of the context for the enabled features + cpuid_results_t results; + cpuid_with_ecx(0x0d, 0, &results); + arch_xsave_size = results.ebx; + + cpuid_with_ecx(0x0d, 1, &results); + if (results.eax & 1) xsave_method = XSAVEOPT; + } +} + +int arch_extracontext_init(extracontext_t *context) { + if (!xsave_cache) { + xsave_cache = slab_newcache(arch_xsave_size, xsave_method == FXSAVE ? 16 : 64, NULL, NULL); + __assert(xsave_cache); + } + + context->xsave = slab_allocate(xsave_cache); + if (!context->xsave) return 1; + + // all sse exceptions masked + // initialise the x87 FPU state as it would be after the FNINIT instruction + memset(context->xsave, 0, arch_xsave_size); + fxsave_area_t *area = context->xsave; + area->mxcsr = 0x1f80; + area->fcw = 0x37f; + + return 0; +} + +void arch_extracontext_free(extracontext_t *context) { + slab_free(xsave_cache, context->xsave); +} + +void arch_extracontext_save(extracontext_t *context) { + context->gsbase = rdmsr(MSR_KERNELGSBASE); + context->fsbase = rdmsr(MSR_FSBASE); + + switch (xsave_method) { + case FXSAVE: asm("fxsaveq %0" ::"m"(*(char(*)[arch_xsave_size])context->xsave) : "memory"); break; + case XSAVE: asm("xsaveq %0" ::"m"(*(char(*)[arch_xsave_size])context->xsave), "d"(-1), "a"(-1) : "memory"); break; + case XSAVEOPT: asm("xsaveoptq %0" ::"m"(*(char(*)[arch_xsave_size])context->xsave), "d"(-1), "a"(-1) : "memory"); break; + } +} + +void arch_extracontext_load(extracontext_t *context) { + wrmsr(MSR_KERNELGSBASE, context->gsbase); + wrmsr(MSR_FSBASE, context->fsbase); + + switch (xsave_method) { + case FXSAVE: asm("fxrstorq %0" ::"m"(*(char(*)[arch_xsave_size])context->xsave) : "memory"); break; + case XSAVE: + case XSAVEOPT: asm("xrstorq %0" ::"m"(*(char(*)[arch_xsave_size])context->xsave), "d"(-1), "a"(-1) : "memory"); break; + } +} + +void arch_extracontext_copy(extracontext_t *dst, const extracontext_t *src) { + // XXX is this behavior correct? ucontext doesnt seem to save it on linux and so it will not be saved + dst->gsbase = src->gsbase; + dst->fsbase = src->fsbase; + memcpy(dst->xsave, src->xsave, arch_xsave_size); +} diff --git a/kernel-src/arch/x86-64/cpu.c b/kernel-src/arch/x86-64/cpu.c index ccdae38e..75559e75 100644 --- a/kernel-src/arch/x86-64/cpu.c +++ b/kernel-src/arch/x86-64/cpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #define EFER_SYSCALLENABLE 1 @@ -251,6 +252,7 @@ static void arch_early(void) { arch_idt_reload(); interrupt_register(0xfd, (void *)infinite_loop, NULL, IPL_IGNORE); dpc_init(); + arch_extracontext_detect(); } INIT_ROUTINE_DEFINE(arch_early, INIT_ROUTINE_FLAGS_NONE, arch_early) diff --git a/kernel-src/arch/x86-64/smp.c b/kernel-src/arch/x86-64/smp.c index 82fd65a1..29ebaef8 100644 --- a/kernel-src/arch/x86-64/smp.c +++ b/kernel-src/arch/x86-64/smp.c @@ -8,6 +8,7 @@ #include #include #include +#include DEFINE_KERNEL_ARGUMENT(nosmp, bool); @@ -35,6 +36,7 @@ static void cpuwakeup(struct limine_smp_info *info) { arch_idt_reload(); interrupt_register(0xfd, (void *)cpuwakeuphalt, NULL, IPL_IGNORE); dpc_init(); + arch_extracontext_detect(); arch_mmu_apswitch(); vmm_apinit(); diff --git a/kernel-src/include/kernel/elf.h b/kernel-src/include/kernel/elf.h index 8ff64f01..467081fe 100644 --- a/kernel-src/include/kernel/elf.h +++ b/kernel-src/include/kernel/elf.h @@ -27,6 +27,7 @@ #define AT_PHDR 3 #define AT_PHENT 4 #define AT_PHNUM 5 +#define AT_PAGESZ 6 #define AT_ENTRY 9 #define AT_SECURE 23 #define AT_EXECFN 31 @@ -43,6 +44,7 @@ typedef struct { auxv64_t entry; auxv64_t execfn; auxv64_t secure; + auxv64_t pagesz; auxv64_t null; } auxv64list_t; diff --git a/kernel-src/include/x86-64/arch/context.h b/kernel-src/include/x86-64/arch/context.h index fda9ca5c..66a4a021 100644 --- a/kernel-src/include/x86-64/arch/context.h +++ b/kernel-src/include/x86-64/arch/context.h @@ -41,10 +41,11 @@ typedef struct { typedef struct { uint64_t gsbase; uint64_t fsbase; - __attribute__((aligned(16))) uint8_t fx[512]; - uint32_t mxcsr; + void *xsave; } extracontext_t; +extern size_t arch_xsave_size; + #define CTX_INIT(x,u,interrupts) \ if (u) { \ (x)->cs = 0x23; \ @@ -55,15 +56,6 @@ typedef struct { } \ (x)->rflags = interrupts ? 0x200 : 0; -// all sse exceptions masked -// initialise the x87 FPU state as it would be after the FNINIT instruction -#define CTX_XINIT(x, u) {\ - (x)->mxcsr = 0x1f80; \ - *((uint16_t *)&(x)->fx[0]) = 0x37f; \ - *((uint16_t *)&(x)->fx[2]) = 0; \ - (x)->fx[4] = 0; \ - } - #define CTX_SP(x) (x)->rsp #define CTX_IP(x) (x)->rip #define CTX_RET(x) (x)->rax @@ -81,43 +73,36 @@ typedef struct { void arch_context_switch(context_t *context); int arch_context_saveandcall(void (*fn)(context_t *context, void *argument), void *stack, void *argument); +void arch_extracontext_detect(void); + +int arch_extracontext_init(extracontext_t *context); +void arch_extracontext_free(extracontext_t *context); +void arch_extracontext_save(extracontext_t *context); +void arch_extracontext_load(extracontext_t *context); +void arch_extracontext_copy(extracontext_t *dst, const extracontext_t *src); + #include // kernelgsbase is set as user because they'll be swapped in the context switch #define ARCH_CONTEXT_SWITCHTHREAD(x) \ current_cpu()->ist.rsp0 = (uint64_t)(x)->kernelstacktop; \ - wrmsr(MSR_KERNELGSBASE, (x)->extracontext.gsbase); \ - wrmsr(MSR_FSBASE, (x)->extracontext.fsbase); \ - asm("fxrstor (%%rax)" : : "a"(&(x)->extracontext.fx[0])); \ - asm("ldmxcsr (%%rax)" : : "a"(&(x)->extracontext.mxcsr)); \ + arch_extracontext_load(&(x)->extracontext); \ arch_context_switch(&thread->context); #define ARCH_CONTEXT_THREADSAVE(t, c) \ memcpy(&(t)->context, c, sizeof(context_t)); \ - (t)->extracontext.gsbase = rdmsr(MSR_KERNELGSBASE); \ - (t)->extracontext.fsbase = rdmsr(MSR_FSBASE); \ - asm("fxsave (%%rax)" : : "a"(&(t)->extracontext.fx[0])); \ - asm("stmxcsr (%%rax)" : : "a"(&(t)->extracontext.mxcsr)); + arch_extracontext_save(&(t)->extracontext); #define ARCH_CONTEXT_THREADLOAD(t, c) \ memcpy(c, &(t)->context, sizeof(context_t)); \ current_cpu()->ist.rsp0 = (uint64_t)(t)->kernelstacktop; \ - wrmsr(MSR_KERNELGSBASE, (t)->extracontext.gsbase); \ - wrmsr(MSR_FSBASE, (t)->extracontext.fsbase); \ - asm("fxrstor (%%rax)" : : "a"(&(t)->extracontext.fx[0])); \ - asm("ldmxcsr (%%rax)" : : "a"(&(t)->extracontext.mxcsr)); + arch_extracontext_load(&(t)->extracontext); #define ARCH_EXTRACONTEXT_LOAD(c) \ - wrmsr(MSR_KERNELGSBASE, (c)->gsbase); \ - wrmsr(MSR_FSBASE, (c)->fsbase); \ - asm("fxrstor (%%rax)" : : "a"(&(c)->fx[0])); \ - asm("ldmxcsr (%%rax)" : : "a"(&(c)->mxcsr)); + arch_extracontext_load(c); #define ARCH_EXTRACONTEXT_SAVE(c) \ - (c)->gsbase = rdmsr(MSR_KERNELGSBASE); \ - (c)->fsbase = rdmsr(MSR_FSBASE); \ - asm("fxsave (%%rax)" : : "a"(&(c)->fx[0])); \ - asm("stmxcsr (%%rax)" : : "a"(&(c)->mxcsr)); + arch_extracontext_save(c); #define ARCH_CONTEXT_INTSTATUS(x) ((x)->rflags & 0x200 ? true : false) #define ARCH_CONTEXT_ISUSER(x) ((x)->cs == 0x23) diff --git a/kernel-src/include/x86-64/arch/signal.h b/kernel-src/include/x86-64/arch/signal.h index bfc741bf..bdce15a5 100644 --- a/kernel-src/include/x86-64/arch/signal.h +++ b/kernel-src/include/x86-64/arch/signal.h @@ -56,9 +56,15 @@ typedef struct { context_t context; extracontext_t extracontext; siginfo_t siginfo; + uint8_t xsave[]; } sigframe_t; #define ARCH_SIGFRAME_GET_UCONTEXT_POINTER(x) (&(x)->uc_flags) +#define ARCH_SIGFRAME_SIZE (sizeof(sigframe_t) + arch_xsave_size) + +static inline void arch_sigframe_init(sigframe_t *sigframe) { + sigframe->extracontext.xsave = sigframe->xsave; +} static inline void arch_sigframe_prepare_mcontext(void *stack, sigframe_t *sigframe) { context_t *context = &sigframe->context; @@ -89,7 +95,8 @@ static inline void arch_sigframe_prepare_mcontext(void *stack, sigframe_t *sigfr gregs[MCONTEXT_REG_OLDMASK] = 0; gregs[MCONTEXT_REG_CR2] = context->cr2; - sigframe->mcontext.fpu_state_p = &((sigframe_t *)stack)->extracontext.fx; + extracontext->xsave = ((sigframe_t *)stack)->xsave; + sigframe->mcontext.fpu_state_p = extracontext->xsave; } static inline void arch_sigframe_get_context_from_mcontext(sigframe_t *sigframe) { diff --git a/kernel-src/io/tty.c b/kernel-src/io/tty.c index a13703df..1f283898 100644 --- a/kernel-src/io/tty.c +++ b/kernel-src/io/tty.c @@ -385,6 +385,13 @@ int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cre size_t len = min(strlen(tty->name) + 1, TTY_NAME_MAX); return USERCOPY_POSSIBLY_TO_USER(arg, tty->name, len); } + case FIONREAD: { + MUTEX_ACQUIRE(&tty->readmutex); + int count = RINGBUFFER_DATACOUNT(&tty->readbuffer); + MUTEX_RELEASE(&tty->readmutex); + int status = USERCOPY_POSSIBLY_TO_USER(arg, &count, sizeof(count)); + return status; + } default: return ENOTTY; } diff --git a/kernel-src/sys/elf.c b/kernel-src/sys/elf.c index 484b841d..6d7c142e 100644 --- a/kernel-src/sys/elf.c +++ b/kernel-src/sys/elf.c @@ -163,11 +163,13 @@ int elf_load(vnode_t *vnode, void *base, void **entry, char **interpreter, auxv6 auxv64->phent.type = AT_PHENT; auxv64->entry.type = AT_ENTRY; auxv64->secure.type = AT_SECURE; + auxv64->pagesz.type = AT_PAGESZ; auxv64->secure.val = 0; // set later by whoever called elf_load auxv64->phnum.val = header.phcount; auxv64->phent.val = header.phsize; auxv64->entry.val = header.entry + (uintptr_t)base; + auxv64->pagesz.val = PAGE_SIZE; *entry = (void *)(header.entry + (uintptr_t)base); __assert(header.phsize == sizeof(elfph64_t)); diff --git a/kernel-src/sys/signal.c b/kernel-src/sys/signal.c index e2c6ede0..e0475993 100644 --- a/kernel-src/sys/signal.c +++ b/kernel-src/sys/signal.c @@ -540,7 +540,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin // get where in memory to put the frame #if ARCH_SIGNAL_STACK_GROWS_DOWNWARDS == 1 void *stack = altstack ? (void *)((uintptr_t)altstack + thread->signals.stack.size) : (void *)CTX_SP(context); - stack = (void *)((((uintptr_t)stack - ARCH_SIGNAL_REDZONE_SIZE - sizeof(sigframe_t)) & ~0xfl) - 0x8); + stack = (void *)((((uintptr_t)stack - ARCH_SIGNAL_REDZONE_SIZE - ARCH_SIGFRAME_SIZE) & ~0xfl) - 0x8); #else #error unsupported #endif @@ -553,35 +553,36 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin } // configure stack frame - sigframe_t sigframe; - sigframe.restorer = action->restorer; + sigframe_t *sigframe = __builtin_alloca(ARCH_SIGFRAME_SIZE); + arch_sigframe_init(sigframe); + sigframe->restorer = action->restorer; if (altstack) { - memcpy(&sigframe.oldstack, &thread->signals.stack, sizeof(stack_t)); + memcpy(&sigframe->oldstack, &thread->signals.stack, sizeof(stack_t)); memset(&thread->signals.stack, 0, sizeof(stack_t)); } else { - memset(&sigframe.oldstack, 0, sizeof(stack_t)); + memset(&sigframe->oldstack, 0, sizeof(stack_t)); } if (thread->signals.hasreturnmask) { // if we were waiting in signal_suspend, push the old mask into the return frame // of the first signal and set it to not act this way the next check - memcpy(&sigframe.oldmask, &thread->signals.returnmask, sizeof(sigset_t)); + memcpy(&sigframe->oldmask, &thread->signals.returnmask, sizeof(sigset_t)); thread->signals.hasreturnmask = false; } else { // else, just push the current mask - memcpy(&sigframe.oldmask, &thread->signals.mask, sizeof(sigset_t)); + memcpy(&sigframe->oldmask, &thread->signals.mask, sizeof(sigset_t)); } - memcpy(&sigframe.context, context, sizeof(context_t)); - memcpy(&sigframe.extracontext, &thread->extracontext, sizeof(extracontext_t)); + memcpy(&sigframe->context, context, sizeof(context_t)); + arch_extracontext_copy(&sigframe->extracontext, &thread->extracontext); - arch_sigframe_prepare_mcontext(stack, &sigframe); + arch_sigframe_prepare_mcontext(stack, sigframe); - memset(&sigframe.siginfo, 0, sizeof(siginfo_t)); + memset(&sigframe->siginfo, 0, sizeof(siginfo_t)); if (signal == SIGSEGV) - sigframe.siginfo.__si_fields.__sigfault.si_addr = CTX_TRAP_ADDR(context); + sigframe->siginfo.__si_fields.__sigfault.si_addr = CTX_TRAP_ADDR(context); - if (usercopy_touser(stack, &sigframe, sizeof(sigframe_t))) { - printf("signal: bad user stack %p (altstack %p) handling signal %d trapno %lu\n", stack, altstack, signal, sigframe.mcontext.gregs[MCONTEXT_REG_TRAPNO]); + if (usercopy_touser(stack, sigframe, ARCH_SIGFRAME_SIZE)) { + printf("signal: bad user stack %p (altstack %p) handling signal %d trapno %lu\n", stack, altstack, signal, sigframe->mcontext.gregs[MCONTEXT_REG_TRAPNO]); THREAD_LEAVE(thread); PROCESS_LEAVE(proc); interrupt_set(true); diff --git a/kernel-src/sys/syscalls/sigreturn.c b/kernel-src/sys/syscalls/sigreturn.c index 8116e9fa..8b016c13 100644 --- a/kernel-src/sys/syscalls/sigreturn.c +++ b/kernel-src/sys/syscalls/sigreturn.c @@ -9,31 +9,26 @@ // this expects CTX_SP to be pointing to the signal frame __attribute__((noreturn)) void syscall_sigreturn(context_t *context) { - sigframe_t sigframe; - int error = usercopy_fromuser(&sigframe, (void *)CTX_SP(context), sizeof(sigframe_t)); - if (error || ARCH_CONTEXT_ISUSER(&sigframe.context) == false) { + sigframe_t *sigframe = __builtin_alloca(ARCH_SIGFRAME_SIZE); + int error = usercopy_fromuser(sigframe, (void *)CTX_SP(context), ARCH_SIGFRAME_SIZE); + if (error || ARCH_CONTEXT_ISUSER(&sigframe->context) == false) { printf("syscall_sigreturn: bad return stack or bad return information\n"); proc_terminate(SIGSEGV); } interrupt_set(false); - signal_altstack(current_thread(), &sigframe.oldstack, NULL); - signal_changemask(current_thread(), SIG_SETMASK, &sigframe.oldmask, NULL); + signal_altstack(current_thread(), &sigframe->oldstack, NULL); + signal_changemask(current_thread(), SIG_SETMASK, &sigframe->oldmask, NULL); - arch_sigframe_get_context_from_mcontext(&sigframe); + arch_sigframe_get_context_from_mcontext(sigframe); - __assert(ARCH_CONTEXT_ISUSER(&sigframe.context)); + __assert(ARCH_CONTEXT_ISUSER(&sigframe->context)); - #ifdef __x86_64__ - // XXX is this behavior correct? ucontext doesnt seem to save it on linux and so it will not be saved - sigframe.extracontext.gsbase = rdmsr(MSR_KERNELGSBASE); - sigframe.extracontext.fsbase = rdmsr(MSR_FSBASE); - #endif - memcpy(¤t_thread()->extracontext, &sigframe.extracontext, sizeof(extracontext_t)); + arch_extracontext_copy(¤t_thread()->extracontext, &sigframe->extracontext); ARCH_CONTEXT_THREADLOAD(current_thread(), context); interrupt_set(true); - arch_context_switch(&sigframe.context); + arch_context_switch(&sigframe->context); // if we were to return normally, CTX_RET and CTX_ERRNO would be corrupted, // so we will manually call arch_context_switch, which will jump to the right userland code diff --git a/kernel-src/sys/thread.c b/kernel-src/sys/thread.c index ca11b9a2..fdbb16f8 100644 --- a/kernel-src/sys/thread.c +++ b/kernel-src/sys/thread.c @@ -2,6 +2,7 @@ #include #include #include +#include static scache_t *thread_cache; @@ -17,8 +18,14 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v memset(thread, 0, sizeof(thread_t)); + if (arch_extracontext_init(&thread->extracontext)) { + slab_free(thread_cache, thread); + return NULL; + } + thread->kernelstack = vmm_map(NULL, kstacksize, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, NULL); if (thread->kernelstack == NULL) { + arch_extracontext_free(&thread->extracontext); slab_free(thread_cache, thread); return NULL; } @@ -37,7 +44,6 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v } CTX_INIT(&thread->context, proc != NULL, true); - CTX_XINIT(&thread->extracontext, proc != NULL); CTX_SP(&thread->context) = proc ? (ctxreg_t)ustack : (ctxreg_t)thread->kernelstacktop; CTX_IP(&thread->context) = (ctxreg_t)ip; SPINLOCK_INIT(thread->sleeplock); @@ -52,6 +58,7 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v void sched_destroythread(thread_t *thread) { vmm_unmap(thread->kernelstack, thread->kernelstacksize, 0); + arch_extracontext_free(&thread->extracontext); slab_free(thread_cache, thread); } diff --git a/patches/jna/jinx-working-patch.patch b/patches/jna/jinx-working-patch.patch new file mode 100644 index 00000000..c1ec1834 --- /dev/null +++ b/patches/jna/jinx-working-patch.patch @@ -0,0 +1,138 @@ +diff -urN --no-dereference jna-clean/build.xml jna-workdir/build.xml +--- jna-clean/build.xml ++++ jna-workdir/build.xml +@@ -939,6 +939,9 @@ + + + ++ ++ ++ + + + +diff -urN --no-dereference jna-clean/native/Makefile jna-workdir/native/Makefile +--- jna-clean/native/Makefile ++++ jna-workdir/native/Makefile +@@ -32,7 +32,7 @@ + # NDK_PLATFORM below or set it in your environment. + # + # The windows build requires a cygwin installation. The build will use MSVC +-# for compilation if cl.exe is found on the PATH, otherwise the build will fall ++# for compilation if cl.exe is found on the PATH, otherwise the build will fall + # back to mingw. + + # Systems which support POSIX signals may be able to support VM crash +@@ -118,7 +118,7 @@ + ALIBDIR=/usr/lib + ifeq ($(ARCH),arm) + PREFIX=arm-linux-androideabi- +-COPT+= -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -fstack-protector ++COPT+= -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -fstack-protector + HOST=arm-linux-eabi + else + ifeq ($(ARCH),armv7) +@@ -234,7 +234,7 @@ + ifeq ($(USE_MSVC),true) + # MS compiler + CC=$(FFI_SRC)/msvcc.sh +-CDEFINES+=-DHAVE_PROTECTION ++CDEFINES+=-DHAVE_PROTECTION + ifneq ($(DYNAMIC_LIBFFI),true) + CDEFINES+=-DUSE_STATIC_RTL + endif +@@ -396,13 +396,13 @@ + DARWIN_ARCH=$(ARCH) + ifeq ($(ARCH),aarch64) + DARWIN_ARCH=arm64 +-else ++else + ifeq ($(ARCH),x86-64) + DARWIN_ARCH=x86_64 + else + ifeq ($(ARCH),x86) + DARWIN_ARCH=x86 +-else ++else + endif + endif + endif +@@ -455,6 +455,19 @@ + LIBS= + endif + ++ifeq ($(OS),astral) ++PCFLAGS+=-fPIC ++CDEFINES+=-DHAVE_PROTECTION ++HOST_CONFIG=--host=x86_64-astral ++JAVA_INCLUDES+=-I"$(JAVA_HOME)/include/linux" ++ifeq ($(DYNAMIC_LIBFFI),true) ++LDFLAGS+=-Wl,-soname,$@ ++else ++# Ensure we bind to local libffi symbols ++LDFLAGS+=-Wl,-soname,$@,-Bsymbolic ++endif ++endif ++ + # Unfortunately, we have to use different libffi include files depending on + # the target, so we can't do a simple universal build on darwin. Do + # separate builds, then merge the results. +@@ -473,7 +486,7 @@ + cp $(LIBRARY) $(INSTALLDIR) + + ifeq ($(ARCH), amd64) +-$(DLLCB): dll-callback.c ++$(DLLCB): dll-callback.c + $(MINGW) -DDEFINE_CALLBACKS -c $< $(COUT) + endif + +@@ -505,7 +518,7 @@ + $(LD) $(LDFLAGS) $< $(TESTDEP) $(LIBS) + + ifneq ($(DYNAMIC_LIBFFI),true) +-$(FFI_LIB): ++$(FFI_LIB): + @mkdir -p $(FFI_BUILD) + @if [ ! -f $(FFI_SRC)/configure ]; then \ + echo "Generating configure"; \ +diff -urN --no-dereference jna-clean/src/com/sun/jna/Platform.java jna-workdir/src/com/sun/jna/Platform.java +--- jna-clean/src/com/sun/jna/Platform.java ++++ jna-workdir/src/com/sun/jna/Platform.java +@@ -42,6 +42,7 @@ + public static final int GNU = 9; + public static final int KFREEBSD = 10; + public static final int NETBSD = 11; ++ public static final int ASTRAL = 13; + + /** Whether read-only (final) fields within Structures are supported. */ + public static final boolean RO_FIELDS; +@@ -110,6 +111,9 @@ + else if (osName.equalsIgnoreCase("netbsd")) { + osType = NETBSD; + } ++ else if (osName.startsWith("Astral")) { ++ osType = ASTRAL; ++ } + else { + osType = UNSPECIFIED; + } +@@ -175,6 +179,9 @@ + public static final boolean iskFreeBSD() { + return osType == KFREEBSD; + } ++ public static final boolean isAstral() { ++ return osType == ASTRAL; ++ } + public static final boolean isX11() { + // TODO: check filesystem for /usr/X11 or some other X11-specific test + return !Platform.isWindows() && !Platform.isMac(); +@@ -341,6 +348,9 @@ + case Platform.KFREEBSD: + osPrefix = "kfreebsd-" + arch; + break; ++ case Platform.ASTRAL: ++ osPrefix = "astral-" + arch; ++ break; + default: + osPrefix = name.toLowerCase(); + int space = osPrefix.indexOf(" "); diff --git a/patches/libffi/jinx-working-patch.patch b/patches/libffi/jinx-working-patch.patch new file mode 100644 index 00000000..e5607993 --- /dev/null +++ b/patches/libffi/jinx-working-patch.patch @@ -0,0 +1,13 @@ +diff -urN --no-dereference libffi-clean/src/closures.c libffi-workdir/src/closures.c +--- libffi-clean/src/closures.c ++++ libffi-workdir/src/closures.c +@@ -139,6 +139,9 @@ + executable memory. */ + # define FFI_MMAP_EXEC_WRIT 1 + # endif ++# if defined(__astral__) ++# define FFI_MMAP_EXEC_WRIT 1 ++# endif + #endif + + #if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX 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/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index e73049cc..c0dea37e 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -551,9 +551,20 @@ index 5c57cf8..cb2d97f 100644 void tdestroy(void *root, void (*free_node)(void *)) { diff --git mlibc-clean/options/rtld/generic/main.cpp mlibc-workdir/options/rtld/generic/main.cpp -index b2db152..e6438fe 100644 +index b2db152..244ad4b 100644 --- mlibc-clean/options/rtld/generic/main.cpp +++ mlibc-workdir/options/rtld/generic/main.cpp +@@ -636,8 +636,8 @@ void *__dlapi_open(const char *file, int flags, void *returnAddress) { + // In order to know which RUNPATH / RPATH to process, we must find the calling object. + SharedObject *origin = initialRepository->findCaller(returnAddress); + if (!origin) { +- mlibc::panicLogger() << "rtld: unable to determine calling object of dlopen " +- << "(ra = " << returnAddress << ")" << frg::endlog; ++ // When we can't find the origin, assume it's the main executable (copies glibc behavior) ++ origin = executableSO; + } + + objectResult = initialRepository->requestObjectWithName(file, origin, newScope, !isGlobal, rts); @@ -681,6 +681,9 @@ void *__dlapi_open(const char *file, int flags, void *returnAddress) { } } diff --git a/recipes/glfw b/recipes/glfw new file mode 100644 index 00000000..9c55ef4c --- /dev/null +++ b/recipes/glfw @@ -0,0 +1,25 @@ +name=glfw +revision=1 +from_source=glfw +imagedeps="build-essential" +hostdeps="xgcc xbinutils cmake pkgconfig" +deps="base libx11 libxext libxi libxrandr libxrender libxt libxtst xorgproto libiconv libxcursor libxxf86vm libxinerama" + +configure() { + cmake \ + -DCMAKE_TOOLCHAIN_FILE=${base_dir}/util/cmake \ + -DCMAKE_INSTALL_PREFIX=${prefix} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DBUILD_SHARED_LIBS=ON \ + -DGLFW_BUILD_WAYLAND=OFF \ + ${source_dir} +} + +build() { + make -j${parallelism} +} + +package() { + DESTDIR=${dest_dir} make install +} diff --git a/recipes/jna b/recipes/jna new file mode 100644 index 00000000..e8d9964c --- /dev/null +++ b/recipes/jna @@ -0,0 +1,26 @@ +name=jna +revision=1 +from_source=jna +imagedeps="build-essential zip unzip file ant openjdk-8-jdk" +hostdeps="xgcc xbinutils" +deps="base openjdk17" + +configure() { + cp -rp "${source_dir}/." . +} + +build() { + JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 ant \ + -DCC=x86_64-astral-gcc \ + -Dos.prefix=linux-x86-64 \ + -Djre.arch=x86-64 \ + -Djdk.home="${sysroot_dir}/usr/lib/jvm/java-17" \ + -Dbuild-native=true \ + -Ddynlink.native=true \ + dist +} + +package() { + mkdir -p "${dest_dir}${prefix}/share/jna" + cp build/jna.jar "${dest_dir}${prefix}/share/jna" +} 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/recipes/openal b/recipes/openal new file mode 100644 index 00000000..b89e58b9 --- /dev/null +++ b/recipes/openal @@ -0,0 +1,23 @@ +name=openal +revision=1 +from_source=openal +imagedeps="build-essential cmake" +hostdeps="xgcc xbinutils libstdc++-v3 pkgconfig" +deps="base alsa-lib" + +configure() { + cmake \ + -DCMAKE_TOOLCHAIN_FILE=${base_dir}/util/cmake \ + -DCMAKE_INSTALL_PREFIX=${prefix} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_LIBDIR=lib \ + ${source_dir} +} + +build() { + make -j${parallelism} +} + +package() { + DESTDIR=${dest_dir} make install +} diff --git a/source-recipes/astral b/source-recipes/astral index 0ca2c64c..0343cfdc 100644 --- a/source-recipes/astral +++ b/source-recipes/astral @@ -10,7 +10,7 @@ prepare() { rm -f io/printf.c rm -f include/printf.h rm -rf flanterm - curl https://raw.githubusercontent.com/limine-bootloader/limine-protocol/refs/heads/trunk/include/limine.h > include/limine.h + curl https://raw.githubusercontent.com/limine-bootloader/limine-protocol/4607d68cbdbe653885937fb3178449588addb799/include/limine.h > include/limine.h pushd /tmp/ wget https://github.com/mpaland/printf/archive/refs/tags/v4.0.0.tar.gz tar -xf v4.0.0.tar.gz diff --git a/source-recipes/glfw b/source-recipes/glfw new file mode 100644 index 00000000..4153fbf0 --- /dev/null +++ b/source-recipes/glfw @@ -0,0 +1,8 @@ +name=glfw +version=3.4 +source_method=tarball +tarball_url="https://github.com/glfw/glfw/archive/refs/tags/${version}.tar.gz" +tarball_sha512=39ad7a4521267fbebc35d2ff0c389a56236ead5fa4bdff33db113bd302f70f5f2869ff4e6db1979512e1542813292dff5a482e94dfce231750f0746c301ae9ed +prepare() { + true +} diff --git a/source-recipes/jna b/source-recipes/jna new file mode 100644 index 00000000..52f89ecc --- /dev/null +++ b/source-recipes/jna @@ -0,0 +1,8 @@ +name=jna +version=5.13.0 +source_method=tarball +tarball_url="https://github.com/java-native-access/jna/archive/refs/tags/${version}.tar.gz" +tarball_sha512=aefd0becc03bb7fd753e8c5cdcbcb20f6d590125a5fb03048bef0024e826ab0254b750e22a8bb26bea38cc89262ad45e5030b666cb2c857b01b15a6a55379a0f +prepare() { + true +} 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 +} diff --git a/source-recipes/openal b/source-recipes/openal new file mode 100644 index 00000000..455b5cf0 --- /dev/null +++ b/source-recipes/openal @@ -0,0 +1,8 @@ +name=openal +version=1.21.0 +source_method=tarball +tarball_url="https://github.com/kcat/openal-soft/archive/refs/tags/openal-soft-${version}.tar.gz" +tarball_sha512=0c8159e25d9776469478c5ec577fd123c87822a22fc1da978b4e99a7fc1a5ed29ea2a53dc975cc311f72660114a7f8ab75fd9b080d93ac2a280b424c1c66d497 +prepare() { + true +}