diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index ce93dadd..bba5b61e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: Feature request description: Suggest an idea for this project title: "Feature: " -labels: [ "enhancement", "P5" ] +labels: [ "enh", "P4" ] assignees: - "squid233" body: diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fd3b2392..0d65a039 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -7,7 +7,12 @@ name: Java CI with Gradle -on: [ push, pull_request, workflow_dispatch ] +on: + push: + branches: + - main + pull_request: + workflow_dispatch: jobs: build: diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml new file mode 100644 index 00000000..b125370c --- /dev/null +++ b/.github/workflows/javadoc.yml @@ -0,0 +1,34 @@ +name: Javadoc + +on: [ release, workflow_dispatch ] + +jobs: + build: + strategy: + matrix: + java: [ + 22-ea + ] + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + java-version: | + ${{ matrix.java }} + 21 + distribution: 'temurin' + - name: Grant execute permission for gradlew + if: ${{ runner.os != 'Windows' }} + run: chmod +x gradlew + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + - name: Execute Gradle build + run: ./gradlew aggregateJavadoc + - name: Capture Javadoc + uses: actions/upload-artifact@v4 + with: + name: javadoc + path: build/docs/javadoc/ diff --git a/build.gradle.kts b/build.gradle.kts index 4c957697..48e8493c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -135,7 +135,6 @@ artifactNameMap.forEach { (subprojectName, artifactName) -> // temporary maven repositories maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") } maven { url = uri("https://s01.oss.sonatype.org/content/repositories/releases") } - maven { url = uri("https://maven.aliyun.com/repository/central") } } val compileOnly by configurations diff --git a/doc/notes/0.x/0.1.0.md b/doc/notes/0.x/0.1.0.md index a468d616..db87bdc5 100644 --- a/doc/notes/0.x/0.1.0.md +++ b/doc/notes/0.x/0.1.0.md @@ -4,7 +4,7 @@ _Not Released Yet_ This version includes the following features: -- GLFW 3.3.9 +- GLFW 3.4 - OpenGL 1.0 ~ 4.6 functions and constants - OpenGL extension functions - OpenGL Loader diff --git a/gradle.properties b/gradle.properties index 0a81762d..02323763 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,5 +18,5 @@ jdkEnablePreview=true jdkEarlyAccessDoc=jdk22 kotlinTargetJdkVersion=21 -overrunMarshalVersion=0.1.0-alpha.21-jdk22 +overrunMarshalVersion=0.1.0-alpha.23-jdk22 overrunPlatformVersion=1.0.0 diff --git a/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java b/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java index 59b60714..b0ff75bb 100644 --- a/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java +++ b/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java @@ -16,8 +16,12 @@ package overrungl; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; import java.util.Objects; import java.util.function.Consumer; +import java.util.jar.Manifest; /** * Constants of OverrunGL. @@ -33,7 +37,7 @@ public final class OverrunGL { /** * The version of GLFW native libraries. */ - public static final String GLFW_VERSION = "3.3.9.0"; + public static final String GLFW_VERSION = "3.4.0.0"; /** * The version of NFD native libraries. */ @@ -49,6 +53,24 @@ private OverrunGL() { //no instance } + /** + * {@return the actual version of OverrunGL from the jar file} + */ + public static String actualVersion() { + try { + final URL url = ((URLClassLoader) OverrunGL.class.getClassLoader()).findResource("META-INF/MANIFEST.MF"); + if (url == null) { + return VERSION; + } + try (InputStream stream = url.openStream()) { + final String value = new Manifest(stream).getMainAttributes().getValue("Implementation-Version"); + return value != null ? value : VERSION; + } + } catch (Exception e) { + return VERSION; + } + } + /** * Sets the API logger. * diff --git a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java index 6f2f404e..4685cf39 100644 --- a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java +++ b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java @@ -22,10 +22,7 @@ import overrungl.OverrunGL; import java.io.IOException; -import java.lang.foreign.Arena; -import java.lang.foreign.Linker; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.SymbolLookup; +import java.lang.foreign.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; @@ -51,6 +48,10 @@ public final class RuntimeHelper { public static final MemoryLayout LONG = CANONICAL_LAYOUTS.get("long"), SIZE_T = CANONICAL_LAYOUTS.get("size_t"), WCHAR_T = CANONICAL_LAYOUTS.get("wchar_t"); + /** + * Is {@code size_t} of {@code long}? + */ + public static final boolean SIZE_T_LONG = SIZE_T instanceof ValueLayout.OfLong; /** * constructor diff --git a/modules/overrungl.core/src/main/java/overrungl/util/MemoryUtil.java b/modules/overrungl.core/src/main/java/overrungl/util/MemoryUtil.java index 130e16c1..2d823de7 100644 --- a/modules/overrungl.core/src/main/java/overrungl/util/MemoryUtil.java +++ b/modules/overrungl.core/src/main/java/overrungl/util/MemoryUtil.java @@ -22,11 +22,11 @@ import java.lang.foreign.*; import java.lang.invoke.MethodHandle; -import java.util.Objects; import static java.lang.foreign.FunctionDescriptor.of; import static java.lang.foreign.ValueLayout.ADDRESS; import static overrungl.internal.RuntimeHelper.SIZE_T; +import static overrungl.internal.RuntimeHelper.SIZE_T_LONG; /** * The standard-C memory allocator. @@ -121,7 +121,8 @@ public static void checkAlignment(long alignment) throws IllegalArgumentExceptio */ public static MemorySegment malloc(long size) { try { - final MemorySegment seg = ((MemorySegment) m_malloc.invokeExact(size)).reinterpret(size); + final MemorySegment seg = (SIZE_T_LONG ? (MemorySegment) m_malloc.invokeExact(size) : (MemorySegment) m_malloc.invokeExact(Math.toIntExact(size))) + .reinterpret(size); if (DEBUG) DebugAllocator.track(seg.address(), size); return seg; } catch (Throwable e) { @@ -155,7 +156,8 @@ public static MemorySegment malloc(MemoryLayout layout) { public static MemorySegment calloc(long number, long size) { try { long byteSize = number * size; - final MemorySegment seg = ((MemorySegment) m_calloc.invokeExact(number, size)).reinterpret(byteSize); + final MemorySegment seg = (SIZE_T_LONG ? (MemorySegment) m_calloc.invokeExact(number, size) : (MemorySegment) m_calloc.invokeExact(Math.toIntExact(number), Math.toIntExact(size))) + .reinterpret(byteSize); if (DEBUG) DebugAllocator.track(seg.address(), byteSize); return seg; } catch (Throwable e) { @@ -215,9 +217,9 @@ public static MemorySegment realloc(@Nullable MemorySegment memblock, long size) oldSize = DebugAllocator.untrack(ptr); } try { - MemorySegment segment = ((MemorySegment) m_realloc.invokeExact( - Objects.requireNonNullElse(memblock, MemorySegment.NULL), - size)).reinterpret(size); + final MemorySegment mem = memblock != null ? memblock : MemorySegment.NULL; + MemorySegment segment = (SIZE_T_LONG ? (MemorySegment) m_realloc.invokeExact(mem, size) : (MemorySegment) m_realloc.invokeExact(mem, Math.toIntExact(size))) + .reinterpret(size); if (DEBUG) { if (!isNullptr(segment)) { DebugAllocator.track(segment.address(), size); @@ -270,7 +272,7 @@ public static void free(@Nullable MemorySegment memblock) { */ public static MemorySegment memcpy(MemorySegment dest, MemorySegment src, long count) { try { - final var _ = (MemorySegment) m_memcpy.invokeExact(dest, src, count); + final var _ = SIZE_T_LONG ? (MemorySegment) m_memcpy.invokeExact(dest, src, count) : (MemorySegment) m_memcpy.invokeExact(dest, src, Math.toIntExact(count)); return dest; } catch (Throwable e) { throw new AssertionError("should not reach here", e); @@ -295,7 +297,7 @@ public static MemorySegment memcpy(MemorySegment dest, MemorySegment src, long c */ public static MemorySegment memmove(MemorySegment dest, MemorySegment src, long count) { try { - final var _ = (MemorySegment) m_memmove.invokeExact(dest, src, count); + final var _ = SIZE_T_LONG ? (MemorySegment) m_memmove.invokeExact(dest, src, count) : (MemorySegment) m_memmove.invokeExact(dest, src, Math.toIntExact(count)); return dest; } catch (Throwable e) { throw new AssertionError("should not reach here", e); @@ -318,7 +320,7 @@ public static MemorySegment memmove(MemorySegment dest, MemorySegment src, long */ public static MemorySegment memset(MemorySegment dest, int c, long count) { try { - final var _ = (MemorySegment) m_memset.invokeExact(dest, c, count); + final var _ = SIZE_T_LONG ? (MemorySegment) m_memset.invokeExact(dest, c, count) : (MemorySegment) m_memset.invokeExact(dest, c, Math.toIntExact(count)); return dest; } catch (Throwable e) { throw new AssertionError("should not reach here", e); diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java index 6bfbf956..91a30d24 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFW.java @@ -31,6 +31,7 @@ import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.invoke.MethodHandles; +import java.nio.charset.StandardCharsets; import static java.lang.foreign.ValueLayout.*; import static overrungl.glfw.Handles.*; @@ -58,13 +59,13 @@ public interface GLFW extends DirectAccess { *
* This is incremented when features are added to the API, but it remains backward-compatible. */ - int VERSION_MINOR = 3; + int VERSION_MINOR = 4; /** * The revision number of the GLFW header. *
* This is incremented when a bug fix release is made that does not contain any API changes. */ - int VERSION_REVISION = 9; + int VERSION_REVISION = 0; /** * One. @@ -407,7 +408,7 @@ public interface GLFW extends DirectAccess { * *
* Some pre-installed Windows graphics drivers do not support OpenGL. AMD only @@ -473,6 +474,69 @@ public interface GLFW extends DirectAccess { * Application programmer error. Fix the offending call. */ int NO_WINDOW_CONTEXT = 0x0001000A; + /** + * The specified cursor shape is not available. + *
+ * The specified standard cursor shape is not available, either because the + * current platform cursor theme does not provide it or because it is not + * available on the platform. + *
+ * The requested feature is not provided by the platform, so GLFW is unable to + * implement it. The documentation for each function notes if it could emit + * this error. + *
+ * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ + int FEATURE_UNAVAILABLE = 0x0001000C; + /** + * The requested feature is not implemented for the platform. + *
+ * The requested feature has not yet been implemented in GLFW for this platform. + *
+ * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ + int FEATURE_UNIMPLEMENTED = 0x0001000D; + /** + * Platform unavailable or no matching platform was found. + *
+ * If emitted during initialization, no matching platform was found. If the + * {@link #PLATFORM} init hint was set to {@link #ANY_PLATFORM}, GLFW could not detect any of + * the platforms supported by this library binary, except for the Null platform. If the + * init hint was set to a specific platform, it is either not supported by this library + * binary or GLFW was not able to detect it. + *
+ * If emitted by a native access function, GLFW was initialized for a different platform + * than the function is for. + * + *
+ * Failure to detect a specific platform may have the same cause as above or be because + * support for that platform was not compiled in. Call {@link #platformSupported} to + * check whether a specific platform is supported by a library binary. + */ + int PLATFORM_UNAVAILABLE = 0x0001000E; /** *
* This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11. * On platforms like macOS the resolution of the framebuffer is changed independently of the window size. + *
+ * This hint only has an effect on platforms where screen coordinates can be scaled relative to pixel coordinates, + * such as macOS and Wayland. + * On platforms like Windows and X11 the framebuffer and window content area sizes always map 1:1. + *
+ * This is the new name, introduced in GLFW 3.4. + * The older {@link #COCOA_RETINA_FRAMEBUFFER} name is also available for compatibility. + * Both names modify the same hint value.
* Forward-compatibility is described in detail in the OpenGL Reference Manual. * - *
* Debug contexts for OpenGL and OpenGL ES are described in detail * by the GL_KHR_debug extension. + *
+ * Note
+ * {@code CONTEXT_DEBUG} is the new name introduced in GLFW 3.4.
+ * The older {@code OPENGL_DEBUG_CONTEXT} name is also available for compatibility.
*
+ * This is an alias for the + * {@link #SCALE_FRAMEBUFFER} window hint for + * compatibility with earlier versions. + *
* If you wish to implement mouse motion based camera controls or other input schemes * that require unlimited mouse movement, set the cursor mode to {@code CURSOR_DISABLED}. - * {@snippet lang = java: - * GLFW.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_DISABLED); - * } + *
{@code glfw.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_DISABLED);}* This will hide the cursor and lock it to the specified window. GLFW will then take care of all the details of cursor re-centering * and offset calculation and providing the application with a virtual cursor position. This virtual position is provided normally * via both the cursor position callback and through polling. @@ -778,22 +898,27 @@ public interface GLFW extends DirectAccess { * Note
* If you only wish the cursor to become hidden when it is over a window but still want it to behave normally, * set the cursor mode to {@code CURSOR_HIDDEN}. - * {@snippet lang = java: - * GLFW.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_HIDDEN); - * } + *
{@code glfw.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_HIDDEN);}* This mode puts no limit on the motion of the cursor. + * + *
+ * If you wish the cursor to be visible but confined to the content area of the window, set the cursor mode to {@code CURSOR_CAPTURED}. + *
{@code glfw.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_CAPTURED);}+ * The cursor will behave normally inside the content area but will not be able to leave unless the window loses focus. + * *
* To exit out of either of these special modes, restore the {@code CURSOR_NORMAL} cursor mode. - * {@snippet lang = java: - * GLFW.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_NORMAL); - * } + *
{@code glfw.setInputMode(window, GLFW.CURSOR, GLFW.CURSOR_NORMAL);}+ * If the cursor was disabled, this will move it back to its last visible position. */ int CURSOR_NORMAL = 0x00034001, CURSOR_HIDDEN = 0x00034002, - CURSOR_DISABLED = 0x00034003; + CURSOR_DISABLED = 0x00034003, + CURSOR_CAPTURED = 0x00034004; int ANY_RELEASE_BEHAVIOR = 0; int RELEASE_BEHAVIOR_FLUSH = 0x00035001; @@ -803,11 +928,21 @@ public interface GLFW extends DirectAccess { int EGL_CONTEXT_API = 0x00036002; int OSMESA_CONTEXT_API = 0x00036003; + int ANGLE_PLATFORM_TYPE_NONE = 0x00037001, + ANGLE_PLATFORM_TYPE_OPENGL = 0x00037002, + ANGLE_PLATFORM_TYPE_OPENGLES = 0x00037003, + ANGLE_PLATFORM_TYPE_D3D9 = 0x00037004, + ANGLE_PLATFORM_TYPE_D3D11 = 0x00037005, + ANGLE_PLATFORM_TYPE_VULKAN = 0x00037007, + ANGLE_PLATFORM_TYPE_METAL = 0x00037008; + int WAYLAND_PREFER_LIBDECOR = 0x00038001; int WAYLAND_DISABLE_LIBDECOR = 0x00038002; + int ANY_POSITION = 0x80000000; + /** - * The regular arrow cursor. + * The regular arrow cursor shape. */ int ARROW_CURSOR = 0x00036001; /** @@ -815,21 +950,88 @@ public interface GLFW extends DirectAccess { */ int IBEAM_CURSOR = 0x00036002; /** - * The crosshair shape. + * The crosshair cursor shape. */ int CROSSHAIR_CURSOR = 0x00036003; /** - * The hand shape. + * The pointing hand cursor shape. + */ + int POINTING_HAND_CURSOR = 0x00036004; + /** + * The horizontal resize/move arrow shape. + *
+ * The horizontal resize/move arrow shape. This is usually a horizontal + * double-headed arrow. + */ + int RESIZE_EW_CURSOR = 0x00036005; + /** + * The vertical resize/move arrow shape. + *
+ * The vertical resize/move arrow shape. This is usually a horizontal + * double-headed arrow. */ - int HAND_CURSOR = 0x00036004; + int RESIZE_NS_CURSOR = 0x00036006; /** - * The horizontal resize arrow shape. + * The top-left to bottom-right diagonal resize/move arrow shape. + *
+ * The top-left to bottom-right diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + *
+ * The top-right to bottom-left diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + *
+ * The omni-directional resize cursor/move shape. This is usually either + * a combined horizontal and vertical double-headed arrow or a grabbing hand. */ - int VRESIZE_CURSOR = 0x00036006; + int RESIZE_ALL_CURSOR = 0x00036009; + /** + * The operation-not-allowed shape. + *
+ * The operation-not-allowed shape. This is usually a circle with a diagonal + * line through it. + *
+ * This is an alias for compatibility with earlier versions. + */ + int HRESIZE_CURSOR = RESIZE_EW_CURSOR, + VRESIZE_CURSOR = RESIZE_NS_CURSOR, + HAND_CURSOR = POINTING_HAND_CURSOR; int CONNECTED = 0x00040001; int DISCONNECTED = 0x00040002; @@ -840,6 +1042,27 @@ public interface GLFW extends DirectAccess { * Possible values are {@link #TRUE} and {@link #FALSE}. */ int JOYSTICK_HAT_BUTTONS = 0x00050001; + /** + * {@code ANGLE_PLATFORM_TYPE} specifies the platform type (rendering backend) to request when using OpenGL ES and EGL via ANGLE. + * If the requested platform type is unavailable, ANGLE will use its default. + * Possible values are one of {@code ANGLE_PLATFORM_TYPE_NONE}, {@code ANGLE_PLATFORM_TYPE_OPENGL}, + * {@code ANGLE_PLATFORM_TYPE_OPENGLES}, {@code ANGLE_PLATFORM_TYPE_D3D9}, + * {@code ANGLE_PLATFORM_TYPE_D3D11}, {@code ANGLE_PLATFORM_TYPE_VULKAN} + * and {@code ANGLE_PLATFORM_TYPE_METAL}. + *
+ * The ANGLE platform type is specified via the {@code EGL_ANGLE_platform_angle} extension. + * This extension is not used if this hint is {@code ANGLE_PLATFORM_TYPE_NONE}, which is the default value. + */ + int ANGLE_PLATFORM_TYPE = 0x00050002; + /** + * {@code PLATFORM} specifies the platform to use for windowing and input. + * Possible values are {@code ANY_PLATFORM}, {@code PLATFORM_WIN32}, + * {@code PLATFORM_COCOA}, {@code PLATFORM_WAYLAND}, + * {@code PLATFORM_X11} and {@code PLATFORM_NULL}. + * The default value is {@code ANY_PLATFORM}, + * which will choose any platform the library includes support for except for the Null backend. + */ + int PLATFORM = 0x00050003; /** *
@@ -860,6 +1093,18 @@ public interface GLFW extends DirectAccess { */ int WAYLAND_LIBDECOR = 0x00053001; + /** + * Hint value that enables automatic platform selection. + *
+ * Hint value for {@link #PLATFORM} that enables automatic platform selection. + */ + int ANY_PLATFORM = 0x00060000, + PLATFORM_WIN32 = 0x00060001, + PLATFORM_COCOA = 0x00060002, + PLATFORM_WAYLAND = 0x00060003, + PLATFORM_X11 = 0x00060004, + PLATFORM_NULL = 0x00060005; + /** * Don't care value. */ @@ -886,10 +1131,52 @@ static String getErrorString(int errorCode) { case PLATFORM_ERROR -> "PLATFORM_ERROR"; case FORMAT_UNAVAILABLE -> "FORMAT_UNAVAILABLE"; case NO_WINDOW_CONTEXT -> "NO_WINDOW_CONTEXT"; + case CURSOR_UNAVAILABLE -> "CURSOR_UNAVAILABLE"; + case FEATURE_UNAVAILABLE -> "FEATURE_UNAVAILABLE"; + case FEATURE_UNIMPLEMENTED -> "FEATURE_UNIMPLEMENTED"; + case PLATFORM_UNAVAILABLE -> "PLATFORM_UNAVAILABLE"; default -> RuntimeHelper.unknownToken(errorCode); }; } + /** + * Converts the given platform code to a debug string. + *
+ * This method is created by OverrunGL and does not belong to the original GLFW library. + * + * @param platformCode the platform code. + * @return the platform string. + */ + static String getPlatformDebugString(int platformCode) { + return switch (platformCode) { + case PLATFORM_WIN32 -> "PLATFORM_WIN32"; + case PLATFORM_COCOA -> "PLATFORM_COCOA"; + case PLATFORM_WAYLAND -> "PLATFORM_WAYLAND"; + case PLATFORM_X11 -> "PLATFORM_X11"; + case PLATFORM_NULL -> "PLATFORM_NULL"; + default -> RuntimeHelper.unknownToken(platformCode); + }; + } + + /** + * Converts the given platform code to a readable string. + *
+ * This method is created by OverrunGL and does not belong to the original GLFW library. + * + * @param platformCode the platform code. + * @return the platform string. + */ + static String getPlatformString(int platformCode) { + return switch (platformCode) { + case PLATFORM_WIN32 -> "Win32"; + case PLATFORM_COCOA -> "Cocoa"; + case PLATFORM_WAYLAND -> "Wayland"; + case PLATFORM_X11 -> "X11"; + case PLATFORM_NULL -> "Null"; + default -> RuntimeHelper.unknownToken(platformCode); + }; + } + /** * Initializes the GLFW library. *
@@ -903,19 +1190,49 @@ static String getErrorString(int errorCode) { *
* Additional calls to this function after successful initialization but before * termination will return {@code true} immediately. + *
+ * The {@link #PLATFORM} init hint controls which platforms are considered during + * initialization. This also depends on which platforms the library was compiled to + * support. * * @return {@code true} if successful, or {@code false} if an * error occurred. - * @glfw.errors Possible errors include {@link #PLATFORM_ERROR}. - * @glfw.remark macOS: This function will change the current directory of the + * @glfw.errors Possible errors include {@link #PLATFORM_UNAVAILABLE} and {@link #PLATFORM_ERROR}. + * @glfw.remark
+ * This function will create the main menu and dock icon for the + * application. If GLFW finds a {@code MainMenu.nib} it is loaded and assumed to + * contain a menu bar. Otherwise a minimal menu bar is created manually with + * common commands like Hide, Quit and About. The About entry opens a minimal + * about dialog with information from the application's bundle. The menu bar + * and dock icon can be disabled entirely with the {@link #COCOA_MENUBAR} init + * hint. + *
+ * To use the default allocator, call this function with a {@link MemorySegment#NULL} argument. + *
+ * If you specify an allocator struct, every member must be a valid function + * pointer. If any member is {@link MemorySegment#NULL}, this function will emit + * {@link #INVALID_VALUE} and the init allocator will be unchanged. + *
+ * The functions in the allocator must fulfil a number of requirements. See the + * documentation for {@link GLFWAllocateFun}, {@link GLFWReallocateFun} and + * {@link GLFWDeallocateFun} for details. + * + * @param allocator The allocator to use at the next initialization, or + * {@link MemorySegment#NULL} to use the default one. + * @glfw.errors Possible errors include {@link #INVALID_VALUE}. + * @glfw.pointer_lifetime The specified allocator is copied before this function + * returns. + * @glfw.thread_safety This function must only be called from the main thread. + * @see #init + */ + @Entrypoint("glfwInitAllocator") + void ninitAllocator(MemorySegment allocator); + + /** + * Sets the init allocator to the desired value. + * + * @param allocator The allocator to use at the next initialization, or + * {@code null} to use the default one. + * @see #ninitAllocator(MemorySegment) + */ + @Entrypoint("glfwInitAllocator") + void initAllocator(@Nullable GLFWAllocator allocator); + /** * Retrieves the version of the GLFW library. *
@@ -1026,13 +1377,17 @@ default Triplet.OfInt getVersion() { *
* This function returns the compile-time generated * version string - * of the GLFW library binary. It describes the version, platform, compiler and any platform-specific + * of the GLFW library binary. + * It describes the version, platforms, compiler and any platform or operating system specific * compile-time options. It should not be confused with the OpenGL or OpenGL * ES version string, queried with {@code GL.getString}. *
* Do not use the version string to parse the GLFW library version. The * {@link #ngetVersion getVersion} function provides the version of the running library * binary in numerical format. + *
+ * Do not use the version string to parse what platforms are supported. The
+ * {@link #platformSupported} function lets you query platform support.
*
* @return The ASCII encoded GLFW version string.
* @glfw.errors None.
@@ -1097,7 +1452,7 @@ default Tuple2.OfObjInt
+ * This function returns the platform that was selected during initialization. The
+ * returned value will be one of {@code PLATFORM_WIN32}, {@code PLATFORM_COCOA},
+ * {@code PLATFORM_WAYLAND}, {@code PLATFORM_X11} or {@code PLATFORM_NULL}.
+ *
+ * @return The currently selected platform, or zero if an error occurred.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}.
+ * @glfw.thread_safety This function may be called from any thread.
+ * @see #platformSupported
+ */
+ @Entrypoint("glfwGetPlatform")
+ int getPlatform();
+
+ /**
+ * Returns whether the library includes support for the specified platform.
+ *
+ * This function returns whether the library was compiled with support for the specified
+ * platform. The platform must be one of {@link #PLATFORM_WIN32}, {@link #PLATFORM_COCOA},
+ * {@link #PLATFORM_WAYLAND}, {@link #PLATFORM_X11} or {@link #PLATFORM_NULL}.
+ *
+ * @param platform The platform to query.
+ * @return {@code true} if the platform is supported, or {@code false} otherwise.
+ * @glfw.errors Possible errors include {@link #INVALID_ENUM}.
+ * @glfw.remark This function may be called before {@link #init}.
+ * @glfw.thread_safety This function may be called from any thread.
+ * @see #getPlatform
+ */
+ @Convert(Type.INT)
+ @Entrypoint("glfwPlatformSupported")
+ boolean platformSupported(int platform);
+
/**
* Returns the currently connected monitors.
*
@@ -1251,7 +1639,7 @@ default Pair.OfInt getMonitorPos(MemorySegment monitor) {
* This function returns the position, in screen coordinates, of the upper-left
* corner of the work area of the specified monitor along with the work area
* size in screen coordinates. The work area is defined as the area of the
- * monitor not occluded by the operating system task bar where present. If no
+ * monitor not occluded by the window system task bar where present. If no
* task bar exists then the work area is the monitor resolution in screen
* coordinates.
*
@@ -1311,7 +1699,7 @@ default Quad.OfInt getMonitorWorkarea(MemorySegment monitor) {
* This function returns the size, in millimetres, of the display area of the
* specified monitor.
*
- * Some systems do not provide accurate monitor size information, either
+ * Some platforms do not provide accurate monitor size information, either
* because the monitor
* EDID
* data is incorrect or because the driver does not report it accurately.
@@ -1382,6 +1770,8 @@ default Pair.OfInt getMonitorPhysicalSize(MemorySegment monitor) {
* @param yscale Where to store the y-axis content scale, or {@link MemorySegment#NULL NULL}.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
* {@link #PLATFORM_ERROR}.
+ * @glfw.remark Wayland: Fractional scaling information is not yet available for
+ * monitors, so this function only returns integer content scales.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #ngetWindowContentScale(MemorySegment, MemorySegment, MemorySegment) getWindowContentScale
*/
@@ -1549,7 +1939,7 @@ default MemorySegment setMonitorCallback(@Nullable GLFWMonitorFun callback) {
/**
* Returns the available video modes for the specified monitor.
*
- * @param monitor The monitor to query.
+ * @param monitor The monitor to query.
* @return An array of video modes, or {@code null} if an
* error occurred.
* @see #ngetVideoModes(MemorySegment, MemorySegment) ngetVideoModes
@@ -1621,10 +2011,10 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
*
* @param monitor The monitor whose gamma ramp to set.
* @param gamma The desired exponent.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
- * {@link #INVALID_VALUE} and {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, {@link #INVALID_VALUE},
+ * {@link #PLATFORM_ERROR} and {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark Wayland: Gamma handling is a privileged protocol, this function
- * will thus never be implemented and emits {@link #PLATFORM_ERROR}.
+ * will thus never be implemented and emits {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
*/
@Entrypoint("glfwSetGamma")
@@ -1638,10 +2028,10 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
* @param monitor The monitor to query.
* @return The current gamma ramp, or {@link MemorySegment#NULL NULL} if an
* error occurred.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
- * {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, {@link #PLATFORM_ERROR}
+ * and {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark Wayland: Gamma handling is a privileged protocol, this function
- * will thus never be implemented and emits {@link #PLATFORM_ERROR} while
+ * will thus never be implemented and emits {@link #FEATURE_UNAVAILABLE} while
* returning {@link MemorySegment#NULL NULL}.
* @glfw.pointer_lifetime The returned structure and its arrays are allocated and
* freed by GLFW. You should not free them yourself. They are valid until the
@@ -1681,15 +2071,15 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
*
* @param monitor The monitor whose gamma ramp to set.
* @param ramp The gamma ramp to use.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
- * {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, {@link #PLATFORM_ERROR}
+ * and {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark The size of the specified gamma ramp should match the size of the
* current ramp for that monitor.
*
* Windows: The gamma ramp size must be 256.
*
* Wayland: Gamma handling is a privileged protocol, this function
- * will thus never be implemented and emits {@link #PLATFORM_ERROR}.
+ * will thus never be implemented and emits {@link #FEATURE_UNAVAILABLE}.
* @glfw.pointer_lifetime The specified gamma ramp is copied before this function
* returns.
* @glfw.thread_safety This function must only be called from the main thread.
@@ -1873,82 +2263,81 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
* error occurred.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
* {@link #INVALID_ENUM}, {@link #INVALID_VALUE}, {@link #API_UNAVAILABLE},
- * {@link #VERSION_UNAVAILABLE}, {@link #FORMAT_UNAVAILABLE} and
- * {@link #PLATFORM_ERROR}.
- * @glfw.remark Windows: Window creation will fail if the Microsoft GDI software
+ * {@link #VERSION_UNAVAILABLE}, {@link #FORMAT_UNAVAILABLE},
+ * {@link #NO_WINDOW_CONTEXT} and {@link #PLATFORM_ERROR}.
+ * @glfw.remark
+ *
- * Windows: If the executable has an icon resource named {@code GLFW_ICON}, it
+ * If the executable has an icon resource named {@code GLFW_ICON}, it
* will be set as the initial icon for the window. If no such icon is present,
* the {@code IDI_APPLICATION} icon will be used instead. To set a different icon,
* see {@link #nsetWindowIcon(MemorySegment, int, MemorySegment) setWindowIcon}.
*
- * Windows: The context to share resources with must not be current on
+ * The context to share resources with must not be current on
* any other thread.
- *
- * macOS: The OS only supports forward-compatible core profile contexts
- * for OpenGL versions 3.2 and later. Before creating an OpenGL context of
- * version 3.2, or later you must set the
- * {@link #OPENGL_FORWARD_COMPAT} and
- * {@link #OPENGL_PROFILE} hints accordingly.
+ *
- * macOS: The GLFW window has no icon, as it is not a document
+ * The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon.
* For more information on bundles, see the
* Bundle Programming Guide
* in the Mac Developer Library.
*
- * macOS: The first time a window is created the menu bar is created.
+ * The first time a window is created the menu bar is created.
* If GLFW finds a {@code MainMenu.nib} it is loaded and assumed to contain a menu
* bar. Otherwise, a minimal menu bar is created manually with common commands
* like Hide, Quit and About. The "About" entry opens a minimal about dialog
* with information from the application's bundle. Menu bar creation can be
* disabled entirely with the {@link #COCOA_MENUBAR} init hint.
*
- * macOS: On OS X 10.10 and later the window frame will not be rendered
+ * On OS X 10.10 and later the window frame will not be rendered
* at full resolution on Retina displays unless the
- * {@link #COCOA_RETINA_FRAMEBUFFER}
+ * {@link #SCALE_FRAMEBUFFER}
* hint is {@link #TRUE} and the {@code NSHighResolutionCapable} key is enabled in the
* application bundle's {@code Info.plist}. For more information, see
* High Resolution Guidelines for OS X
- * in the Mac Developer Library. The GLFW test and example programs use
- * a custom {@code Info.plist} template for this, which can be found as
- * {@code CMake/MacOSXBundleInfo.plist.in} in the source tree.
+ * in the Mac Developer Library. The GLFW test and example programs use a custom {@code Info.plist}
+ * template for this, which can be found as {@code CMake/Info.plist.in} in the source tree.
*
- * macOS: When activating frame autosaving with
+ * When activating frame autosaving with
* {@link #COCOA_FRAME_NAME}, the specified
* window size and position may be overridden by previously saved values.
- *
+ *
- * X11: Due to the asynchronous nature of X11, it may take a moment for
+ * Due to the asynchronous nature of X11, it may take a moment for
* a window to reach its requested state. This means you may not be able to
* query the final size, position or other attributes directly after window
* creation.
*
- * X11: The class part of the {@code WM_CLASS} window property will by
+ * The class part of the {@code WM_CLASS} window property will by
* default be set to the window title passed to this function. The instance
* part will use the contents of the {@code RESOURCE_NAME} environment variable, if
* present and not empty, or fall back to the window title. Set the
* {@link #X11_CLASS_NAME} and
* {@link #X11_INSTANCE_NAME} window hints to
* override this.
- *
- * Wayland: Compositors should implement the xdg-decoration protocol
- * for GLFW to decorate the window properly. If this protocol isn't
- * supported, or if the compositor prefers client-side decorations, a very
- * simple fallback frame will be drawn using the wp_viewporter protocol. A
- * compositor can still emit close, maximize or fullscreen events, using for
- * instance a keybind mechanism. If neither of these protocols is supported,
- * the window won't be decorated.
- *
- * Wayland: A full screen window will not attempt to change the mode,
- * no matter what the requested size or refresh rate.
- *
- * Wayland: Screensaver inhibition requires the idle-inhibit protocol
- * to be implemented in the user's compositor.
+ *
+ * This function returns the window title, encoded as UTF-8, of the specified
+ * window. This is the title set previously by {@link #ncreateWindow createWindow}
+ * or {@link #nsetWindowTitle setWindowTitle}.
+ *
+ * @param window The window to query.
+ * @return The UTF-8 encoded window title, or {@code null} if an
+ * error occurred.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}.
+ * @glfw.remark The returned title is currently a copy of the title last set by
+ * {@link #ncreateWindow createWindow} or {@link #nsetWindowTitle setWindowTitle}.
+ * It does not include any
+ * additional text which may be appended by the platform or another program.
+ * @glfw.pointer_lifetime The returned string is allocated and freed by GLFW. You
+ * should not free it yourself. It is valid until the next call to
+ * {@code getWindowTitle} or {@link #nsetWindowTitle setWindowTitle}, or until the library is
+ * terminated.
+ * @glfw.thread_safety This function must only be called from the main thread.
+ * @see #nsetWindowTitle(MemorySegment, MemorySegment) setWindowTitle
+ */
+ @Entrypoint("glfwGetWindowTitle")
+ MemorySegment ngetWindowTitle(MemorySegment window);
+
+ /**
+ * Returns the title of the specified window.
+ *
+ * @param window The window to query.
+ * @return The UTF-8 encoded window title, or {@code null} if an
+ * error occurred.
+ * @see #ngetWindowTitle(MemorySegment)
+ */
+ @Entrypoint("glfwGetWindowTitle")
+ @SizedSeg(Unmarshal.STR_SIZE)
+ String getWindowTitle(MemorySegment window);
+
/**
* Sets the title of the specified window.
*
@@ -2039,6 +2465,7 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
* @glfw.remark macOS: The window title will not be updated until the next time you
* process events.
* @glfw.thread_safety This function must only be called from the main thread.
+ * @see #ngetWindowTitle(MemorySegment) getWindowTitle
*/
@Entrypoint("glfwSetWindowTitle")
void nsetWindowTitle(MemorySegment window, MemorySegment title);
@@ -2075,18 +2502,19 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
* @param images The images to create the icon from. This is ignored if
* count is zero.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
- * {@link #INVALID_VALUE} and {@link #PLATFORM_ERROR}.
+ * {@link #INVALID_VALUE}, {@link #PLATFORM_ERROR} and
+ * {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.pointer_lifetime The specified image data is copied before this function
* returns.
- * @glfw.remark macOS: The GLFW window has no icon, as it is not a document
- * window, so this function does nothing. The dock icon will be the same as
+ * @glfw.remark macOS: Regular windows do not have icons on macOS. This function
+ * will emit {@link #FEATURE_UNAVAILABLE}. The dock icon will be the same as
* the application bundle's icon. For more information on bundles, see the
* Bundle Programming Guide
* in the Mac Developer Library.
*
* Wayland: There is no existing protocol to change an icon, the
* window will thus inherit the one defined in the application's desktop file.
- * This function always emits {@link #PLATFORM_ERROR}.
+ * This function will emit {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
*/
@Entrypoint("glfwSetWindowIcon")
@@ -2138,11 +2566,11 @@ default void setWindowIcon(MemorySegment window, @Nullable GLFWImage images) {
* the content area, or {@link MemorySegment#NULL NULL}.
* @param ypos Where to store the y-coordinate of the upper-left corner of
* the content area, or {@link MemorySegment#NULL NULL}.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
- * {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
+ * {@link #PLATFORM_ERROR} and {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark Wayland: There is no way for an application to retrieve the global
- * position of its windows, this function will always emit
- * {@link #PLATFORM_ERROR}.
+ * position of its windows. This function will emit
+ * {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #setWindowPos(MemorySegment, int, int) setWindowPos
*/
@@ -2193,11 +2621,11 @@ default Pair.OfInt getWindowPos(MemorySegment window) {
* @param window The window to query.
* @param xpos The x-coordinate of the upper-left corner of the content area.
* @param ypos The y-coordinate of the upper-left corner of the content area.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
- * {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
+ * {@link #PLATFORM_ERROR} and {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark Wayland: There is no way for an application to set the global
- * position of its windows, this function will always emit
- * {@link #PLATFORM_ERROR}.
+ * position of its windows. This function will emit
+ * {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #ngetWindowPos(MemorySegment, MemorySegment, MemorySegment) getWindowPos
*/
@@ -2355,8 +2783,6 @@ default Pair.OfInt getWindowSize(MemorySegment window) {
* content area.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
* {@link #PLATFORM_ERROR}.
- * @glfw.remark Wayland: A full screen window will not attempt to change the mode,
- * no matter what the requested size.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #ngetWindowSize(MemorySegment, MemorySegment, MemorySegment) getWindowSize
* @see #setWindowMonitor(MemorySegment, MemorySegment, int, int, int, int, int) setWindowMonitor
@@ -2500,7 +2926,7 @@ default Quad.OfInt getWindowFrameSize(MemorySegment window) {
* regardless of their DPI and scaling settings. This relies on the system DPI
* and scaling settings being somewhat correct.
*
- * On systems where each monitors can have its own content scale, the window
+ * On platforms where each monitors can have its own content scale, the window
* content scale will depend on which monitor the system considers the window
* to be on.
*
@@ -2580,8 +3006,10 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
*
* @param window The window to set the opacity for.
* @param opacity The desired opacity of the specified window.
- * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
- * {@link #PLATFORM_ERROR}.
+ * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}
+ * {@link #PLATFORM_ERROR} and {@link #FEATURE_UNAVAILABLE} (see remarks).
+ * @glfw.remark Wayland: There is no way to set an opacity factor for a window.
+ * This function will emit {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #getWindowOpacity(MemorySegment) getWindowOpacity
*/
@@ -2602,6 +3030,9 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
* @param window The window to iconify.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
* {@link #PLATFORM_ERROR}.
+ * @glfw.remark Wayland: Once a window is iconified, {@link #restoreWindow} won’t
+ * be able to restore it. This is a design decision of the xdg-shell
+ * protocol.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #restoreWindow(MemorySegment) restoreWindow
* @see #maximizeWindow(MemorySegment) maximizeWindow
@@ -2712,8 +3143,8 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
* @param window The window to give input focus.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and
* {@link #PLATFORM_ERROR}.
- * @glfw.remark Wayland: It is not possible for an application to bring its windows
- * to front, this function will always emit {@link #PLATFORM_ERROR}.
+ * @glfw.remark Wayland: The compositor will likely ignore focus requests unless
+ * another window created by the same application already has input focus.
* @glfw.thread_safety This function must only be called from the main thread.
*/
@Entrypoint("glfwFocusWindow")
@@ -2796,9 +3227,6 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
*
* Wayland: The desired window position is ignored, as there is no way
* for an application to set this property.
- *
- * Wayland: Setting the window to full screen will not attempt to
- * change the mode, no matter what the requested size or refresh rate.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #getWindowMonitor(MemorySegment) getWindowMonitor
* @see #setWindowSize(MemorySegment, int, int) setWindowSize
@@ -2844,8 +3272,9 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
* The supported attributes are {@link #DECORATED},
* {@link #RESIZABLE},
* {@link #FLOATING},
- * {@link #AUTO_ICONIFY} and
- * {@link #FOCUS_ON_SHOW}.
+ * {@link #AUTO_ICONIFY},
+ * {@link #FOCUS_ON_SHOW} and
+ * {@link #MOUSE_PASSTHROUGH}.
*
* Some of these attributes are ignored for full screen windows. The new
* value will take effect if the window is later made windowed.
@@ -2857,9 +3286,13 @@ default Pair.OfFloat getWindowContentScale(MemorySegment window) {
* @param attrib A supported window attribute.
* @param value {@code true} of {@code false}.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED},
- * {@link #INVALID_ENUM}, {@link #INVALID_VALUE} and {@link #PLATFORM_ERROR}.
+ * {@link #INVALID_ENUM}, {@link #INVALID_VALUE}, {@link #PLATFORM_ERROR} and
+ * {@link #FEATURE_UNAVAILABLE} (see remarks).
* @glfw.remark Calling {@link #getWindowAttrib} will always return the latest
* value, even if that value is ignored by the current mode of the window.
+ *
+ * Wayland: The {@link #FLOATING} window attribute is
+ * not supported. Setting this will emit {@link #FEATURE_UNAVAILABLE}.
* @glfw.thread_safety This function must only be called from the main thread.
* @see #getWindowAttrib(MemorySegment, int) getWindowAttrib
*/
@@ -3112,8 +3545,6 @@ default MemorySegment setWindowFocusCallback(MemorySegment window, @Nullable GLF
* For more information about the callback parameters, see the
* {@link GLFWWindowIconifyFun function pointer type}.
* @glfw.errors Possible errors include {@link #NOT_INITIALIZED}.
- * @glfw.remark Wayland: The XDG-shell protocol has no event for iconification, so
- * this callback will never be called.
* @glfw.thread_safety This function must only be called from the main thread.
*/
@Entrypoint("glfwSetWindowIconifyCallback")
@@ -3406,6 +3837,8 @@ default MemorySegment setWindowContentScaleCallback(MemorySegment window, @Nulla
*
+ *
* @glfw.thread_safety This function must only be called from the main thread.
* @see #destroyWindow
*/
@@ -2026,6 +2415,43 @@ default GLFWVidMode.Value getVideoMode(MemorySegment monitor) {
@Entrypoint("glfwSetWindowShouldClose")
void setWindowShouldClose(MemorySegment window, @Convert(Type.INT) boolean value);
+ /**
+ * Returns the title of the specified window.
+ *
* If the mode is {@code STICKY_KEYS}, the value must be either {@link #TRUE} to @@ -3432,7 +3865,7 @@ default MemorySegment setWindowContentScaleCallback(MemorySegment window, @Nulla * If the mode is {@code RAW_MOUSE_MOTION}, the value must be either {@link #TRUE} * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is * disabled, or {@link #FALSE} to disable it. If raw motion is not supported, - * attempting to set this will emit {@link #PLATFORM_ERROR}. Call + * attempting to set this will emit {@link #FEATURE_UNAVAILABLE}. Call * {@link #rawMouseMotionSupported} to check for support. * * @param window The window whose input mode to set. @@ -3441,7 +3874,8 @@ default MemorySegment setWindowContentScaleCallback(MemorySegment window, @Nulla * {@code RAW_MOUSE_MOTION}. * @param value The new value of the specified input mode. * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, - * {@link #INVALID_ENUM} and {@link #PLATFORM_ERROR}. + * {@link #INVALID_ENUM}, {@link #PLATFORM_ERROR} and + * {@link #FEATURE_UNAVAILABLE} (see above). * @glfw.thread_safety This function must only be called from the main thread. * @see #getInputMode(MemorySegment, int) getInputMode */ @@ -3711,10 +4145,10 @@ default Pair.OfDouble getCursorPos(MemorySegment window) { * content area. * @param ypos The desired y-coordinate, relative to the top edge of the * content area. - * @glfw.errors Possible errors include {@link #NOT_INITIALIZED} and - * {@link #PLATFORM_ERROR}. + * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, + * {@link #PLATFORM_ERROR} and {@link #FEATURE_UNAVAILABLE} (see remarks). * @glfw.remark Wayland: This function will only work when the cursor mode is - * {@link #CURSOR_DISABLED}, otherwise it will do nothing. + * {@link #CURSOR_DISABLED}, otherwise it will emit {@link #FEATURE_UNAVAILABLE}. * @glfw.thread_safety This function must only be called from the main thread. * @see #ngetCursorPos(MemorySegment, MemorySegment, MemorySegment) getCursorPos */ @@ -3768,15 +4202,41 @@ default Pair.OfDouble getCursorPos(MemorySegment window) { /** * Creates a cursor with a standard shape. *
- * Returns a cursor with a standard shape, - * that can be set for a window with {@link #setCursor}. + * Returns a cursor with a standard shape, that can be set for a window with + * {@link #setCursor}. The images for these cursors come from the system + * cursor theme and their exact appearance will vary between platforms. + *
+ * Most of these shapes are guaranteed to exist on every supported platform but + * a few may not be present. See the table below for details. + *
Cursor shape | Windows | macOS | X11 | Wayland |
---|---|---|---|---|
{@link #ARROW_CURSOR} | Yes | Yes | Yes | Yes |
{@link #IBEAM_CURSOR} | Yes | Yes | Yes | Yes |
{@link #CROSSHAIR_CURSOR} | Yes | Yes | Yes | Yes |
{@link #POINTING_HAND_CURSOR} | Yes | Yes | Yes | Yes |
{@link #RESIZE_EW_CURSOR} | Yes | Yes | Yes | Yes |
{@link #RESIZE_NS_CURSOR} | Yes | Yes | Yes | Yes |
{@link #RESIZE_NWSE_CURSOR} | Yes | Yes1 | Maybe2 | Maybe2 |
{@link #RESIZE_NESW_CURSOR} | Yes | Yes1 | Maybe2 | Maybe2 |
{@link #RESIZE_ALL_CURSOR} | Yes | Yes | Yes | Yes |
{@link #NOT_ALLOWED_CURSOR} | Yes | Yes | Maybe2 | Maybe2 |
* The resolution of the timer is system dependent, but is usually on the order * of a few micro- or nanoseconds. It uses the highest-resolution monotonic - * time source on each supported platform. + * time source on each operating system. * * @return The current time, in seconds, or zero if an * error occurred. @@ -4910,7 +5377,7 @@ default String getClipboardString() { * @glfw.errors Possible errors include {@link #NOT_INITIALIZED}, * {@link #NO_CURRENT_CONTEXT} and {@link #PLATFORM_ERROR}. * @glfw.remark This function is not called during context creation, leaving the - * swap interval set to whatever is the default on that platform. This is done + * swap interval set to whatever is the default for that API. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * @glfw.remark Some GPU drivers do not honor the requested swap interval, either @@ -5084,7 +5551,7 @@ default String getClipboardString() { MemorySegment pExt = ngetRequiredInstanceExtensions(pCount); final int count = pCount.get(JAVA_INT, 0); if (count == 0) return null; - return Unmarshal.unmarshalAsStringArray(pExt.reinterpret(ADDRESS.scale(0L, count))); + return Unmarshal.unmarshalAsStringArray(pExt.reinterpret(ADDRESS.scale(0L, count)), StandardCharsets.US_ASCII); } } } diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocateFun.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocateFun.java new file mode 100644 index 00000000..59ff1257 --- /dev/null +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocateFun.java @@ -0,0 +1,128 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrungl.glfw; + +import overrun.marshal.Upcall; +import overrungl.internal.RuntimeHelper; +import overrungl.util.MemoryUtil; + +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +/** + * The function pointer type for memory allocation callbacks. + *
+ * This is the function pointer type for memory allocation callbacks. A memory
+ * allocation callback function has the following signature:
+ * {@snippet lang = java:
+ * MemorySegment functionName(long size, MemorySegment user); // @link regex="functionName" target="#invoke"
+ * }
+ *
+ * @author squid233
+ * @see GLFWAllocator
+ * @since 0.1.0
+ */
+@FunctionalInterface
+public interface GLFWAllocateFun extends Upcall {
+ /**
+ * The type of the upcall.
+ */
+ Type
+ * This function must support being called during {@link GLFW#init} but before the library is
+ * flagged as initialized, as well as during {@link GLFW#terminate} after the library is no
+ * longer flagged as initialized.
+ *
+ * Any memory allocated via this function will be deallocated via the same allocator
+ * during library termination or earlier.
+ *
+ * Any memory allocated via this function must be suitably aligned for any object type.
+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the
+ * same as what {@link MemoryUtil#malloc} provides. If you are using C11 or later, this is the value of
+ * {@code alignof(max_align_t)}.
+ *
+ * The size will always be greater than zero. Allocations of size zero are filtered out
+ * before reaching the custom allocator.
+ *
+ * If this function returns {@link MemorySegment#NULL}, GLFW will emit {@link GLFW#OUT_OF_MEMORY}.
+ *
+ * This function must not call any GLFW function.
+ *
+ * @param size The minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated memory block, or {@link MemorySegment#NULL} if an
+ * error occurred.
+ * @glfw.pointer_lifetime The returned memory block must be valid at least until it
+ * is deallocated.
+ * @glfw.reentrancy This function should not call any GLFW function.
+ * @glfw.thread_safety This function must support being called from any thread that calls GLFW
+ * functions.
+ */
+ MemorySegment invoke(long size, MemorySegment user);
+
+ /**
+ * Integer version of {@link #invoke(long, MemorySegment)}
+ *
+ * @param size The minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated memory block, or {@link MemorySegment#NULL} if an
+ * error occurred.
+ */
+ default MemorySegment invoke_int(int size, MemorySegment user) {
+ return invoke(size, user);
+ }
+
+ /**
+ * Downcall version of {@link #invoke(long, MemorySegment)}
+ *
+ * @param stub the upcall stub
+ * @param size The minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated memory block, or {@link MemorySegment#NULL} if an
+ * error occurred.
+ */
+ static MemorySegment invoke(MemorySegment stub, long size, MemorySegment user) {
+ try {
+ return (MemorySegment) TYPE.downcallTarget().invokeExact(stub, size, user);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Wraps the given upcall stub to this function.
+ *
+ * @param stub the upcall stub
+ * @return the function instance
+ */
+ static GLFWAllocateFun wrap(MemorySegment stub) {
+ return (size, user) -> invoke(stub, size, user);
+ }
+
+ @Override
+ default MemorySegment stub(Arena arena) {
+ return TYPE.of(arena, this);
+ }
+}
diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocator.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocator.java
new file mode 100644
index 00000000..4dd1e564
--- /dev/null
+++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWAllocator.java
@@ -0,0 +1,102 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Overrun Organization
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ */
+
+package overrungl.glfw;
+
+import overrun.marshal.struct.Struct;
+import overrun.marshal.struct.StructHandle;
+
+import java.lang.foreign.*;
+
+/**
+ * Custom heap memory allocator.
+ *
+ * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it
+ * to {@link GLFW#initAllocator} before initializing the library.
+ *
+ * @author squid233
+ * @see GLFW#initAllocator
+ * @since 0.1.0
+ */
+public final class GLFWAllocator extends Struct {
+ /**
+ * The layout of this struct.
+ */
+ public static final StructLayout LAYOUT = MemoryLayout.structLayout(
+ ValueLayout.ADDRESS.withName("allocate"),
+ ValueLayout.ADDRESS.withName("reallocate"),
+ ValueLayout.ADDRESS.withName("deallocate"),
+ ValueLayout.ADDRESS.withName("user")
+ );
+ /**
+ * The memory allocation function. See {@link GLFWAllocateFun} for details about
+ * allocation function.
+ */
+ public static final StructHandle.Upcall
+ * This is the function pointer type for memory deallocation callbacks.
+ * A memory deallocation callback function has the following signature:
+ * {@snippet lang = java:
+ * void functionName(MemorySegment block, MemorySegment user); // @link regex="functionName" target="#invoke"
+ * }
+ *
+ * @author squid233
+ * @see GLFWAllocator
+ * @since 0.1.0
+ */
+@FunctionalInterface
+public interface GLFWDeallocateFun extends Upcall {
+ /**
+ * The type of the upcall.
+ */
+ Type
+ * This function must support being called during {@link GLFW#init} but before the library is
+ * flagged as initialized, as well as during {@link GLFW#terminate} after the library is no
+ * longer flagged as initialized.
+ *
+ * The block address will never be {@link MemorySegment#NULL}. Deallocations of {@link MemorySegment#NULL} are filtered out
+ * before reaching the custom allocator.
+ *
+ * If this function returns {@link MemorySegment#NULL}, GLFW will emit {@link GLFW#OUT_OF_MEMORY}.
+ *
+ * This function must not call any GLFW function.
+ *
+ * @param block The address of the memory block to deallocate.
+ * @param user The user-defined pointer from the allocator.
+ * @glfw.pointer_lifetime The specified memory block will not be accessed by GLFW
+ * after this function is called.
+ * @glfw.reentrancy This function should not call any GLFW function.
+ * @glfw.thread_safety This function must support being called from any thread that calls GLFW
+ * functions.
+ */
+ void invoke(MemorySegment block, MemorySegment user);
+
+ /**
+ * Downcall version of {@link #invoke(MemorySegment, MemorySegment)}
+ *
+ * @param stub the upcall stub
+ * @param block The address of the memory block to deallocate.
+ * @param user The user-defined pointer from the allocator.
+ */
+ static void invoke(MemorySegment stub, MemorySegment block, MemorySegment user) {
+ try {
+ TYPE.downcallTarget().invokeExact(stub, block, user);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Wraps the given upcall stub to this function.
+ *
+ * @param stub the upcall stub
+ * @return the function instance
+ */
+ static GLFWDeallocateFun wrap(MemorySegment stub) {
+ return (block, user) -> invoke(stub, block, user);
+ }
+
+ @Override
+ default MemorySegment stub(Arena arena) {
+ return TYPE.of(arena, this);
+ }
+}
diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWErrorFun.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWErrorFun.java
index e691b158..a3ea748b 100644
--- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWErrorFun.java
+++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWErrorFun.java
@@ -22,10 +22,9 @@
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
-import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
-import static java.lang.foreign.ValueLayout.*;
+import static java.lang.foreign.ValueLayout.JAVA_INT;
/**
* This is the function pointer type for error callbacks. An error callback
@@ -46,7 +45,7 @@ public interface GLFWErrorFun extends Upcall {
/**
* The type.
*/
- Type
+ * This is the function pointer type for memory reallocation callbacks.
+ * A memory reallocation callback function has the following signature:
+ * {@snippet lang = java:
+ * MemorySegment functionName(MemorySegment block, long size, MemorySegment user); // @link regex="functionName" target="#invoke"
+ * }
+ *
+ * @author squid233
+ * @see GLFWAllocator
+ * @since 0.1.0
+ */
+@FunctionalInterface
+public interface GLFWReallocateFun extends Upcall {
+ /**
+ * The type of the upcall.
+ */
+ Type
+ * This function must support being called during {@link GLFW#init} but before the library is
+ * flagged as initialized, as well as during {@link GLFW#terminate} after the library is no
+ * longer flagged as initialized.
+ *
+ * Any memory allocated via this function will be deallocated via the same allocator
+ * during library termination or earlier.
+ *
+ * Any memory allocated via this function must be suitably aligned for any object type.
+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the
+ * same as what {@link MemoryUtil#realloc} provides. If you are using C11 or later, this is the value of
+ * {@code alignof(max_align_t)}.
+ *
+ * The block address will never be {@code NULL} and the size will always be greater than zero.
+ * Reallocations of a block to size zero are converted into deallocations before reaching
+ * the custom allocator. Reallocations of {@code NULL} to a non-zero size are converted into
+ * regular allocations before reaching the custom allocator.
+ *
+ * If this function returns {@link MemorySegment#NULL}, GLFW will emit {@link GLFW#OUT_OF_MEMORY}.
+ *
+ * This function must not call any GLFW function.
+ *
+ * @param block The address of the memory block to reallocate.
+ * @param size The new minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated or resized memory block, or
+ * {@link MemorySegment#NULL} if an error occurred.
+ * @glfw.pointer_lifetime The returned memory block must be valid at least until it
+ * is deallocated.
+ * @glfw.reentrancy This function should not call any GLFW function.
+ * @glfw.thread_safety This function must support being called from any thread that calls GLFW
+ * functions.
+ */
+ MemorySegment invoke(MemorySegment block, long size, MemorySegment user);
+
+ /**
+ * Integer version of {@link #invoke(MemorySegment, long, MemorySegment)}
+ *
+ * @param block The address of the memory block to reallocate.
+ * @param size The new minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated or resized memory block, or
+ * {@link MemorySegment#NULL} if an error occurred.
+ */
+ default MemorySegment invoke_int(MemorySegment block, int size, MemorySegment user) {
+ return invoke(block, size, user);
+ }
+
+ /**
+ * Downcall version of {@link #invoke(MemorySegment, long, MemorySegment)}
+ *
+ * @param stub the upcall stub
+ * @param block The address of the memory block to reallocate.
+ * @param size The new minimum size, in bytes, of the memory block.
+ * @param user The user-defined pointer from the allocator.
+ * @return The address of the newly allocated or resized memory block, or
+ * {@link MemorySegment#NULL} if an error occurred.
+ */
+ static MemorySegment invoke(MemorySegment stub, MemorySegment block, long size, MemorySegment user) {
+ try {
+ return (MemorySegment) TYPE.downcallTarget().invokeExact(stub, block, size, user);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Wraps the given upcall stub to this function.
+ *
+ * @param stub the upcall stub
+ * @return the function instance
+ */
+ static GLFWReallocateFun wrap(MemorySegment stub) {
+ return (block, size, user) -> invoke(stub, block, size, user);
+ }
+
+ @Override
+ default MemorySegment stub(Arena arena) {
+ return TYPE.of(arena, this);
+ }
+}
diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java
index b2444a8f..119e88c4 100644
--- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java
+++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/GLFWVulkan.java
@@ -22,6 +22,7 @@
import overrun.marshal.gen.Entrypoint;
import overrun.marshal.gen.Ref;
import overrun.marshal.gen.Type;
+import overrungl.NativeType;
import java.lang.foreign.MemorySegment;
import java.lang.invoke.MethodHandles;
@@ -38,6 +39,40 @@ public interface GLFWVulkan extends DirectAccess {
*/
GLFWVulkan INSTANCE = Downcall.load(MethodHandles.lookup(), Handles.lookup);
+ /**
+ * Sets the desired Vulkan {@code vkGetInstanceProcAddr} function.
+ *
+ * This function sets the {@code vkGetInstanceProcAddr} function that GLFW will use for all
+ * Vulkan related entry point queries.
+ *
+ * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in
+ * a location where GLFW cannot find it through dynamic loading, or if you are still
+ * using the static library version of the loader.
+ *
+ * If set to {@link MemorySegment#NULL}, GLFW will try to load the Vulkan loader dynamically by its standard
+ * name and get this function from there. This is the default behavior.
+ *
+ * The standard name of the loader is {@code vulkan-1.dll} on Windows, {@code libvulkan.so.1} on
+ * Linux and other Unix-like systems and {@code libvulkan.1.dylib} on macOS. If your code is
+ * also loading it via these names then you probably don't need to use this function.
+ *
+ * The function address you set is never reset by GLFW, but it only takes effect during
+ * initialization. Once GLFW has been initialized, any updates will be ignored until the
+ * library is terminated and initialized again.
+ *
+ * @param loader The address of the function to use, or {@link MemorySegment#NULL}.
+ * Loader function signature
+ *
@@ -161,14 +196,25 @@ public interface GLFWVulkan extends DirectAccess {
* {@link GLFW#vulkanSupported() vulkanSupported} and
* {@link GLFW#ngetRequiredInstanceExtensions(MemorySegment) getRequiredInstanceExtensions} should
* eliminate almost all occurrences of these errors.
- *
+ *
- * macOS: This function creates and sets a {@code CAMetalLayer} instance for
+ * This function creates and sets a {@code CAMetalLayer} instance for
* the window content view, which is required for MoltenVK to function.
+ *
+ * For more information about this function,
+ * see the Vulkan Registry.
+ * @glfw.errors None.
+ * @glfw.remark This function may be called before {@link GLFW#init}.
+ * @glfw.thread_safety This function must only be called from the main thread.
+ * @see GLFW#init
+ */
+ @Entrypoint("glfwInitVulkanLoader")
+ void initVulkanLoader(@NativeType("PFN_vkGetInstanceProcAddr") MemorySegment loader);
+
/**
* Returns the address of the specified Vulkan instance function.
* PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name)
+ *
* @glfw.thread_safety This function may be called from any thread. For
* synchronization details of Vulkan objects, see the Vulkan specification.
* @see GLFW#ngetRequiredInstanceExtensions(MemorySegment) getRequiredInstanceExtensions
diff --git a/modules/overrungl.nfd/src/main/java/overrungl/nfd/NFD.java b/modules/overrungl.nfd/src/main/java/overrungl/nfd/NFD.java
index 52bd75ef..76c36fef 100644
--- a/modules/overrungl.nfd/src/main/java/overrungl/nfd/NFD.java
+++ b/modules/overrungl.nfd/src/main/java/overrungl/nfd/NFD.java
@@ -643,7 +643,7 @@ default NFDResult openDialogU8(String[] outPath, NFDU8FilterItem filterList, Str
Marshal.marshal(stack, defaultPath));
if (result == NFDResult.OKAY) {
final MemorySegment path = seg.get(Unmarshal.STR_LAYOUT, 0);
- outPath[0] = path.getString(0L);
+ outPath[0] = Unmarshal.unmarshalAsString(path);
freePathU8(path);
}
return result;
@@ -736,7 +736,7 @@ default NFDResult saveDialogU8(String[] outPath, NFDU8FilterItem filterList, Str
Marshal.marshal(stack, defaultName));
if (result == NFDResult.OKAY) {
final MemorySegment path = seg.get(Unmarshal.STR_LAYOUT, 0);
- outPath[0] = path.getString(0L);
+ outPath[0] = Unmarshal.unmarshalAsString(path);
freePathU8(path);
}
return result;
@@ -777,7 +777,7 @@ default NFDResult pickFolderU8(String[] outPath, String defaultPath) {
final NFDResult result = npickFolderU8(seg, Marshal.marshal(stack, defaultPath));
if (result == NFDResult.OKAY) {
final MemorySegment path = seg.get(Unmarshal.STR_LAYOUT, 0);
- outPath[0] = path.getString(0L);
+ outPath[0] = Unmarshal.unmarshalAsString(path);
freePathU8(path);
}
return result;
@@ -825,7 +825,7 @@ default NFDResult pathSetGetPathU8(@NativeType("const nfdpathset_t*") MemorySegm
final NFDResult result = npathSetGetPathU8(pathSet, index, seg);
if (result == NFDResult.OKAY) {
final MemorySegment path = seg.get(Unmarshal.STR_LAYOUT, 0);
- outPath[0] = path.getString(0L);
+ outPath[0] = Unmarshal.unmarshalAsString(path);
pathSetFreePathU8(path);
}
return result;
@@ -870,7 +870,7 @@ default NFDResult pathSetEnumNextU8(@NativeType("nfdpathsetenum_t*") MemorySegme
if (result == NFDResult.OKAY) {
final MemorySegment path = seg.get(Unmarshal.STR_LAYOUT, 0);
if (!Unmarshal.isNullPointer(path)) {
- outPath[0] = path.getString(0L);
+ outPath[0] = Unmarshal.unmarshalAsString(path);
pathSetFreePathU8(path);
}
}
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL20C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL20C.java
index 93873157..be4e4232 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL20C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL20C.java
@@ -215,7 +215,7 @@ default void getActiveAttrib(SegmentAllocator allocator, int program, int index,
Unmarshal.copy(pLen, length);
Unmarshal.copy(pSz, size);
Unmarshal.copy(pType, type);
- name[0] = pName.getString(0);
+ name[0] = Unmarshal.unmarshalAsString(pName);
}
@Entrypoint("glGetActiveUniform")
@@ -223,17 +223,9 @@ default void getActiveUniform(int program, int index, int bufSize, MemorySegment
throw new ContextException();
}
- @Skip
+ @Entrypoint("glGetActiveUniform")
default void getActiveUniform(SegmentAllocator allocator, int program, int index, int bufSize, @Ref int @Nullable [] length, @Ref int[] size, @Ref int[] type, @Ref String[] name) {
- var pLen = Marshal.marshal(allocator, length);
- var pSz = Marshal.marshal(allocator, size);
- var pType = Marshal.marshal(allocator, type);
- var pName = allocator.allocate(JAVA_BYTE, bufSize);
- getActiveUniform(program, index, bufSize, pLen, pSz, pType, pName);
- Unmarshal.copy(pLen, length);
- Unmarshal.copy(pSz, size);
- Unmarshal.copy(pType, type);
- name[0] = pName.getString(0);
+ throw new ContextException();
}
@Entrypoint("glGetAttachedShaders")
@@ -268,7 +260,7 @@ default String getProgramInfoLog(int program, int bufSize, @Ref int @Nullable []
var pLog = stack.allocate(JAVA_BYTE, bufSize);
getProgramInfoLog(program, bufSize, pLen, pLog);
Unmarshal.copy(pLen, length);
- return pLog.getString(0);
+ return Unmarshal.unmarshalAsString(pLog);
}
}
@@ -308,7 +300,7 @@ default String getShaderInfoLog(int shader, int bufSize, @Ref int @Nullable [] l
var pLog = stack.allocate(JAVA_BYTE, bufSize);
getShaderInfoLog(shader, bufSize, pLen, pLog);
Unmarshal.copy(pLen, length);
- return pLog.getString(0);
+ return Unmarshal.unmarshalAsString(pLog);
}
}
@@ -329,7 +321,7 @@ default String getShaderSource(int shader, int bufSize, @Ref int @Nullable [] le
var pSrc = stack.allocate(JAVA_BYTE, bufSize);
getShaderSource(shader, bufSize, pLen, pSrc);
Unmarshal.copy(pLen, length);
- return pSrc.getString(0);
+ return Unmarshal.unmarshalAsString(pSrc);
}
}
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL30C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL30C.java
index 55bcd06e..01e20e10 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL30C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL30C.java
@@ -672,17 +672,9 @@ default void getTransformFeedbackVarying(int program, int index, int bufSize, Me
throw new ContextException();
}
- @Skip
+ @Entrypoint("glGetTransformFeedbackVarying")
default void getTransformFeedbackVarying(SegmentAllocator allocator, int program, int index, int bufSize, @Ref int @Nullable [] length, @Ref int[] size, @Ref int[] type, @Ref String[] name) {
- var pLen = Marshal.marshal(allocator, length);
- var pSz = Marshal.marshal(allocator, size);
- var pType = Marshal.marshal(allocator, type);
- var pName = allocator.allocate(JAVA_BYTE, bufSize);
- getTransformFeedbackVarying(program, index, bufSize, pLen, pSz, pType, pName);
- Unmarshal.copy(pLen, length);
- Unmarshal.copy(pSz, size);
- Unmarshal.copy(pType, type);
- name[0] = pName.getString(0);
+ throw new ContextException();
}
@Entrypoint("glGetUniformuiv")
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL31C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL31C.java
index 809f9ac8..ebdd273e 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL31C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL31C.java
@@ -146,7 +146,7 @@ default String getActiveUniformBlockName(int program, int uniformBlockIndex, int
final MemorySegment length = stack.ints(0);
var pName = stack.allocate(ValueLayout.JAVA_BYTE, bufSize);
getActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, pName);
- return pName.reinterpret(length.get(ValueLayout.JAVA_INT, 0L) + 1).getString(0);
+ return Unmarshal.unmarshalAsString(pName.reinterpret(length.get(ValueLayout.JAVA_INT, 0L) + 1));
}
}
@@ -171,7 +171,7 @@ default String getActiveUniformName(int program, int uniformIndex, int bufSize)
final MemorySegment length = stack.ints(0);
var pName = stack.allocate(ValueLayout.JAVA_BYTE, bufSize);
getActiveUniformName(program, uniformIndex, bufSize, length, pName);
- return pName.reinterpret(length.get(ValueLayout.JAVA_INT, 0L) + 1).getString(0);
+ return Unmarshal.unmarshalAsString(pName.reinterpret(length.get(ValueLayout.JAVA_INT, 0L) + 1));
}
}
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL40C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL40C.java
index fed58cba..0687281f 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL40C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL40C.java
@@ -251,7 +251,7 @@ default String getActiveSubroutineName(int program, int shaderType, int index, i
final MemorySegment length = stack.ints(0);
var seg = stack.allocate(JAVA_BYTE, bufSize);
getActiveSubroutineName(program, shaderType, index, bufSize, length, seg);
- return seg.reinterpret(length.get(JAVA_INT, 0L) + 1).getString(0);
+ return Unmarshal.unmarshalAsString(seg.reinterpret(length.get(JAVA_INT, 0L) + 1));
}
}
@@ -266,7 +266,7 @@ default String getActiveSubroutineUniformName(int program, int shaderType, int i
final MemorySegment length = stack.ints(0);
var seg = stack.allocate(JAVA_BYTE, bufSize);
getActiveSubroutineUniformName(program, shaderType, index, bufSize, length, seg);
- return seg.reinterpret(length.get(JAVA_INT, 0L) + 1).getString(0);
+ return Unmarshal.unmarshalAsString(seg.reinterpret(length.get(JAVA_INT, 0L) + 1));
}
}
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL41C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL41C.java
index 8805c54b..41482b31 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL41C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL41C.java
@@ -232,7 +232,7 @@ default void getProgramPipelineInfoLog(SegmentAllocator allocator, int pipeline,
var pi = allocator.allocate(JAVA_BYTE, bufSize);
getProgramPipelineInfoLog(pipeline, bufSize, pl, pi);
Unmarshal.copy(pl, length);
- infoLog[0] = pi.getString(0);
+ infoLog[0] = Unmarshal.unmarshalAsString(pi);
}
@Skip
@@ -240,7 +240,7 @@ default String getProgramPipelineInfoLog(SegmentAllocator allocator, int pipelin
final int sz = getProgramPipelineiv(pipeline, GL20C.INFO_LOG_LENGTH);
var pi = allocator.allocate(JAVA_BYTE, sz);
getProgramPipelineInfoLog(pipeline, sz, MemorySegment.NULL, pi);
- return pi.getString(0);
+ return Unmarshal.unmarshalAsString(pi);
}
@Entrypoint("glGetProgramPipelineiv")
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL43C.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL43C.java
index 45676a81..dbefc237 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL43C.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GL43C.java
@@ -464,7 +464,7 @@ default String getObjectLabel(SegmentAllocator allocator, int identifier, int na
var pLen = Marshal.marshal(allocator, length);
getObjectLabel(identifier, name, bufSize, seg, pLen);
Unmarshal.copy(pLen, length);
- return seg.getString(0);
+ return Unmarshal.unmarshalAsString(seg);
}
@Skip
@@ -488,7 +488,7 @@ default String getObjectPtrLabel(SegmentAllocator allocator, MemorySegment ptr,
var pLen = Marshal.marshal(allocator, length);
getObjectPtrLabel(ptr, bufSize, seg, pLen);
Unmarshal.copy(pLen, length);
- return seg.getString(0);
+ return Unmarshal.unmarshalAsString(seg);
}
@Skip
@@ -556,7 +556,7 @@ default String getProgramResourceName(SegmentAllocator allocator, int program, i
var pLen = Marshal.marshal(allocator, length);
getProgramResourceName(program, programInterface, index, bufSize, pLen, seg);
Unmarshal.copy(pLen, length);
- return seg.getString(0);
+ return Unmarshal.unmarshalAsString(seg);
}
@Skip
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLDebugProc.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLDebugProc.java
index 99a39641..789f29ae 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLDebugProc.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLDebugProc.java
@@ -16,6 +16,7 @@
package overrungl.opengl;
+import overrun.marshal.Unmarshal;
import overrun.marshal.Upcall;
import java.lang.foreign.Arena;
@@ -50,7 +51,7 @@ public interface GLDebugProc extends Upcall {
void invoke(int source, int type, int id, int severity, String message, MemorySegment userParam);
default void ninvoke(int source, int type, int id, int severity, int length, MemorySegment message, MemorySegment userParam) {
- invoke(source, type, id, severity, message.reinterpret(length + 1).getString(0), userParam);
+ invoke(source, type, id, severity, Unmarshal.unmarshalAsString(message.reinterpret(length + 1)), userParam);
}
@Override
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLFinder.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLFinder.java
index 4c96a83a..4b079421 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLFinder.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/GLFinder.java
@@ -27,6 +27,7 @@
import java.lang.invoke.MethodHandle;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -56,7 +57,7 @@ static Pair.OfInt findCoreGL(GLLoadFunc load) {
String version;
try {
- version = ((MemorySegment) glGetString.invokeExact(GL.VERSION)).getString(0L);
+ version = Unmarshal.unmarshalAsString((MemorySegment) glGetString.invokeExact(GL.VERSION));
} catch (Throwable e) {
throw new RuntimeException(e);
}
@@ -87,7 +88,8 @@ static boolean getExtensions(GLLoadFunc load,
return false;
}
try {
- Collections.addAll(list, ((MemorySegment) glGetString.invokeExact(GL.EXTENSIONS)).getString(0L).split("\\s+"));
+ Collections.addAll(list, Objects.requireNonNull(Unmarshal.unmarshalAsString((MemorySegment) glGetString.invokeExact(GL.EXTENSIONS)))
+ .split("\\s+"));
return true;
} catch (Throwable e) {
throw new RuntimeException(e);
@@ -128,7 +130,7 @@ static boolean getExtensions(GLLoadFunc load,
} catch (Throwable e) {
throw new RuntimeException(e);
}
- list.add(glStrTmp.getString(0L));
+ list.add(Unmarshal.unmarshalAsString(glStrTmp));
}
return true;
diff --git a/modules/overrungl.opengl/src/main/java/overrungl/opengl/ext/amd/GLDebugProcAMD.java b/modules/overrungl.opengl/src/main/java/overrungl/opengl/ext/amd/GLDebugProcAMD.java
index 40c9b4d5..3b894708 100644
--- a/modules/overrungl.opengl/src/main/java/overrungl/opengl/ext/amd/GLDebugProcAMD.java
+++ b/modules/overrungl.opengl/src/main/java/overrungl/opengl/ext/amd/GLDebugProcAMD.java
@@ -16,6 +16,7 @@
package overrungl.opengl.ext.amd;
+import overrun.marshal.Unmarshal;
import overrun.marshal.Upcall;
import java.lang.foreign.Arena;
@@ -49,7 +50,7 @@ public interface GLDebugProcAMD extends Upcall {
void invoke(int id, int category, int severity, String message, MemorySegment userParam);
default void ninvoke(int id, int category, int severity, int length, MemorySegment message, MemorySegment userParam) {
- invoke(id, category, severity, message.reinterpret(length + 1).getString(0), userParam);
+ invoke(id, category, severity, Unmarshal.unmarshalAsString(message.reinterpret(length + 1)), userParam);
}
@Override