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 { * *

Analysis

* The installed graphics driver does not support the requested - * API, or does not support it via the chosen context creation backend. + * API, or does not support it via the chosen context creation API. * Below are a few examples. *

* 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. + *

Analysis

+ * Platform or system settings limitation. Pick another + * standard cursor shape or create a + * custom cursor. + */ + int CURSOR_UNAVAILABLE = 0x0001000B; + /** + * The requested feature is not provided by 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. + *

Analysis

+ * Platform or platform version limitation. The error can be ignored + * unless the feature is critical to the application. + *

+ * 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. + *

Analysis

+ * An incomplete implementation of GLFW for this platform, hopefully + * fixed in a future release. The error can be ignored unless the feature is + * critical to the application. + *

+ * 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. + * + *

Analysis

+ * Failure to detect any platform usually only happens on non-macOS Unix + * systems, either when no window system is running or the program was run from + * a terminal that does not have the necessary environment variables. Fall back to + * a different platform if possible or notify the user that no usable platform was + * detected. + *

+ * 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; /** *

Window related hints

@@ -514,6 +578,27 @@ public interface GLFW extends DirectAccess { *

* 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. + *

  • {@link #SCALE_FRAMEBUFFER}: specifies whether the framebuffer should be resized based on + * content scale changes. + * This can be because of a global user settings change or because the window was moved to a monitor with different scale settings. + *

    + * 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.

  • + *
  • {@link #MOUSE_PASSTHROUGH}: specifies whether the window is transparent to mouse input, + * letting any mouse events pass through to whatever window is behind it. + * This is only supported for undecorated windows. + * Decorated windows with this enabled will behave differently between platforms. + * Possible values are {@link #TRUE} and {@link #FALSE}.
  • + *
  • {@link #POSITION_X} and {@link #POSITION_Y}: specify the desired initial position of the window. + * The window manager may modify or ignore these coordinates. + * If either or both of these hints are set to {@link #ANY_POSITION} + * then the window manager will position the window where it thinks the user will prefer it. + * Possible values are any valid screen coordinates and {@link #ANY_POSITION}.
  • * */ int FOCUSED = 0x00020001, @@ -527,7 +612,11 @@ public interface GLFW extends DirectAccess { CENTER_CURSOR = 0x00020009, TRANSPARENT_FRAMEBUFFER = 0x0002000A, FOCUS_ON_SHOW = 0x0002000C, - SCALE_TO_MONITOR = 0x0002200C; + MOUSE_PASSTHROUGH = 0x0002000D, + POSITION_X = 0x0002000E, + POSITION_Y = 0x0002000F, + SCALE_TO_MONITOR = 0x0002200C, + SCALE_FRAMEBUFFER = 0x0002200D; /** * HOVERED indicates whether the cursor is currently directly over the content area of the window, with no other windows between. @@ -644,11 +733,15 @@ public interface GLFW extends DirectAccess { *

    * Forward-compatibility is described in detail in the OpenGL Reference Manual. * - *

  • {@link #OPENGL_DEBUG_CONTEXT}: specifies whether the context should be created in debug mode, + *
  • {@link #CONTEXT_DEBUG}: specifies whether the context should be created in debug mode, * which may provide additional error and diagnostic reporting functionality. Possible values are {@link #TRUE} and {@link #FALSE}. *

    * 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. *

  • *
  • {@link #OPENGL_PROFILE}: specifies which OpenGL profile to create the context for. * Possible values are one of {@link #OPENGL_CORE_PROFILE} or {@link #OPENGL_COMPAT_PROFILE}, @@ -682,7 +775,8 @@ public interface GLFW extends DirectAccess { CONTEXT_VERSION_MINOR = 0x00022003, CONTEXT_ROBUSTNESS = 0x00022005, OPENGL_FORWARD_COMPAT = 0x00022006, - OPENGL_DEBUG_CONTEXT = 0x00022007, + CONTEXT_DEBUG = 0x00022007, + OPENGL_DEBUG_CONTEXT = CONTEXT_DEBUG, OPENGL_PROFILE = 0x00022008, CONTEXT_RELEASE_BEHAVIOR = 0x00022009, CONTEXT_NO_ERROR = 0x0002200A, @@ -696,8 +790,12 @@ public interface GLFW extends DirectAccess { /** *

    macOS specific window hints

    *