Replace mach-glfw with pkg/glfw (#6708)
Closes #6702 This removes our mach-glfw dependency and replaces it with an in-tree pkg/glfw that includes both the source for compiling glfw as well as the Zig bindings. This matches the pattern from our other packages. This is based on the upstream mach-glfw work and therefore includes the original license and copyright information. The reasoning is stated in the issue but to summarize for the commit: - mach-glfw is no longer maintained, so we have to take ownership - mach-glfw depended on some large blobs of header files to enable cross-compilation but this isn't something we actually care about, so we can (and do) drop the blobs - mach-glfw blobs were hosted on mach hosts. given mach-glfw is unmaintained, we can't rely on this hosting - mach-glfw relied on a "glfw" package which was owned by another person to be Zig 0.14 compatible, but we no longer need to rely on this - mach-glfw builds were outdated based on latest Zig practicespull/6712/head
commit
8eacde92e6
|
|
@ -5,6 +5,7 @@ vendor/** linguist-vendored
|
||||||
website/** linguist-documentation
|
website/** linguist-documentation
|
||||||
pkg/breakpad/vendor/** linguist-vendored
|
pkg/breakpad/vendor/** linguist-vendored
|
||||||
pkg/cimgui/vendor/** linguist-vendored
|
pkg/cimgui/vendor/** linguist-vendored
|
||||||
|
pkg/glfw/wayland-headers/** linguist-vendored
|
||||||
pkg/libintl/config.h linguist-generated=true
|
pkg/libintl/config.h linguist-generated=true
|
||||||
pkg/libintl/libintl.h linguist-generated=true
|
pkg/libintl/libintl.h linguist-generated=true
|
||||||
pkg/simdutf/vendor/** linguist-vendored
|
pkg/simdutf/vendor/** linguist-vendored
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,15 @@ jobs:
|
||||||
name: "Required Checks: Test"
|
name: "Required Checks: Test"
|
||||||
runs-on: namespace-profile-ghostty-sm
|
runs-on: namespace-profile-ghostty-sm
|
||||||
needs:
|
needs:
|
||||||
- build
|
|
||||||
- build-bench
|
- build-bench
|
||||||
|
- build-linux
|
||||||
- build-linux-libghostty
|
- build-linux-libghostty
|
||||||
- build-nix
|
- build-nix
|
||||||
- build-snap
|
- build-snap
|
||||||
- build-macos
|
- build-macos
|
||||||
- build-macos-matrix
|
- build-macos-matrix
|
||||||
- build-windows
|
- build-windows
|
||||||
|
- build-windows-cross
|
||||||
- test
|
- test
|
||||||
- test-gtk
|
- test-gtk
|
||||||
- test-sentry-linux
|
- test-sentry-linux
|
||||||
|
|
@ -48,52 +49,6 @@ jobs:
|
||||||
echo "One or more required build workflows failed: ${{ steps.status.outputs.results }}"
|
echo "One or more required build workflows failed: ${{ steps.status.outputs.results }}"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: ["namespace-profile-ghostty-md"]
|
|
||||||
|
|
||||||
target: [
|
|
||||||
aarch64-linux,
|
|
||||||
x86_64-linux,
|
|
||||||
x86-windows-gnu,
|
|
||||||
x86_64-windows-gnu,
|
|
||||||
# We don't support cross-compiling to macOS because the macOS build
|
|
||||||
# requires xcode due to the swift harness.
|
|
||||||
#aarch64-macos,
|
|
||||||
#x86_64-macos,
|
|
||||||
]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
needs: test
|
|
||||||
env:
|
|
||||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
|
||||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Cache
|
|
||||||
uses: namespacelabs/nscloud-cache-action@v1.2.0
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
/nix
|
|
||||||
/zig
|
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
|
||||||
- uses: cachix/install-nix-action@v30
|
|
||||||
with:
|
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
|
||||||
- uses: cachix/cachix-action@v15
|
|
||||||
with:
|
|
||||||
name: ghostty
|
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
|
||||||
|
|
||||||
# Cross-compile the binary. We always use static building for this
|
|
||||||
# because its the only way to access the headers.
|
|
||||||
- name: Test Build
|
|
||||||
run: nix develop -c zig build -Dapp-runtime=glfw -Dtarget=${{ matrix.target }}
|
|
||||||
|
|
||||||
build-bench:
|
build-bench:
|
||||||
# We build benchmarks on large because it uses ReleaseFast
|
# We build benchmarks on large because it uses ReleaseFast
|
||||||
runs-on: namespace-profile-ghostty-lg
|
runs-on: namespace-profile-ghostty-lg
|
||||||
|
|
@ -124,6 +79,39 @@ jobs:
|
||||||
- name: Build Benchmarks
|
- name: Build Benchmarks
|
||||||
run: nix develop -c zig build -Dapp-runtime=glfw -Demit-bench
|
run: nix develop -c zig build -Dapp-runtime=glfw -Demit-bench
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [namespace-profile-ghostty-md, namespace-profile-ghostty-md-arm64]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
needs: test
|
||||||
|
env:
|
||||||
|
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||||
|
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Cache
|
||||||
|
uses: namespacelabs/nscloud-cache-action@v1.2.0
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/nix
|
||||||
|
/zig
|
||||||
|
|
||||||
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
|
- uses: cachix/install-nix-action@v30
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v15
|
||||||
|
with:
|
||||||
|
name: ghostty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Test Build
|
||||||
|
run: nix develop -c zig build -Dapp-runtime=glfw
|
||||||
|
|
||||||
build-linux-libghostty:
|
build-linux-libghostty:
|
||||||
runs-on: namespace-profile-ghostty-md
|
runs-on: namespace-profile-ghostty-md
|
||||||
needs: test
|
needs: test
|
||||||
|
|
@ -373,6 +361,52 @@ jobs:
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: Get-Content -Path ".\build.log"
|
run: Get-Content -Path ".\build.log"
|
||||||
|
|
||||||
|
build-windows-cross:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: ["namespace-profile-ghostty-md"]
|
||||||
|
|
||||||
|
target: [
|
||||||
|
x86-windows-gnu,
|
||||||
|
x86_64-windows-gnu,
|
||||||
|
# We don't support cross-compiling to macOS or Linux because
|
||||||
|
# we require system libraries.
|
||||||
|
#aarch64-linux,
|
||||||
|
#x86_64-linux,
|
||||||
|
#aarch64-macos,
|
||||||
|
#x86_64-macos,
|
||||||
|
]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
needs: test
|
||||||
|
env:
|
||||||
|
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||||
|
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Cache
|
||||||
|
uses: namespacelabs/nscloud-cache-action@v1.2.0
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/nix
|
||||||
|
/zig
|
||||||
|
|
||||||
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
|
- uses: cachix/install-nix-action@v30
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v15
|
||||||
|
with:
|
||||||
|
name: ghostty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
# Cross-compile the binary. We always use static building for this
|
||||||
|
# because its the only way to access the headers.
|
||||||
|
- name: Test Build
|
||||||
|
run: nix develop -c zig build -Dapp-runtime=glfw -Dtarget=${{ matrix.target }}
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if: github.repository == 'ghostty-org/ghostty'
|
if: github.repository == 'ghostty-org/ghostty'
|
||||||
runs-on: namespace-profile-ghostty-md
|
runs-on: namespace-profile-ghostty-md
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,6 @@
|
||||||
.url = "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz",
|
.url = "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz",
|
||||||
.hash = "libxev-0.0.0-86vtc-ziEgDbLP0vihUn1MhsxNKY4GJEga6BEr7oyHpz",
|
.hash = "libxev-0.0.0-86vtc-ziEgDbLP0vihUn1MhsxNKY4GJEga6BEr7oyHpz",
|
||||||
},
|
},
|
||||||
.mach_glfw = .{
|
|
||||||
// mitchellh/mach-glfw
|
|
||||||
.url = "https://github.com/mitchellh/mach-glfw/archive/d84bc11b0601cdad71035a0e9cf21572d76aa0d2.zip",
|
|
||||||
.hash = "mach_glfw-0.2.0-EJSQm2M9BQCiYGTd9VcKjg2DhSD7WT4kS-MfX68ORRT_",
|
|
||||||
.lazy = true,
|
|
||||||
},
|
|
||||||
.vaxis = .{
|
.vaxis = .{
|
||||||
// rockorager/libvaxis
|
// rockorager/libvaxis
|
||||||
.url = "git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7",
|
.url = "git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7",
|
||||||
|
|
@ -62,6 +56,7 @@
|
||||||
.cimgui = .{ .path = "./pkg/cimgui" },
|
.cimgui = .{ .path = "./pkg/cimgui" },
|
||||||
.fontconfig = .{ .path = "./pkg/fontconfig" },
|
.fontconfig = .{ .path = "./pkg/fontconfig" },
|
||||||
.freetype = .{ .path = "./pkg/freetype" },
|
.freetype = .{ .path = "./pkg/freetype" },
|
||||||
|
.glfw = .{ .path = "./pkg/glfw" },
|
||||||
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell" },
|
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell" },
|
||||||
.harfbuzz = .{ .path = "./pkg/harfbuzz" },
|
.harfbuzz = .{ .path = "./pkg/harfbuzz" },
|
||||||
.highway = .{ .path = "./pkg/highway" },
|
.highway = .{ .path = "./pkg/highway" },
|
||||||
|
|
|
||||||
|
|
@ -91,54 +91,6 @@ in
|
||||||
hash = "sha256-oKZqA9d79jHnp/HsqJWQE33Ffn5Ee5G4VnlQepQuY4o=";
|
hash = "sha256-oKZqA9d79jHnp/HsqJWQE33Ffn5Ee5G4VnlQepQuY4o=";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "mach_glfw-0.2.0-EJSQm2M9BQCiYGTd9VcKjg2DhSD7WT4kS-MfX68ORRT_";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "mach_glfw";
|
|
||||||
url = "https://github.com/mitchellh/mach-glfw/archive/d84bc11b0601cdad71035a0e9cf21572d76aa0d2.zip";
|
|
||||||
hash = "sha256-Sh1DvCmawdN+a2JEhNP3wTX43/i5FDlDVOIx7Um/d0U=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "glfw-0.0.0-bOgnngiqGQCt5HJK25zx1lf9emPYDNtEuQPYmrTCdOoN";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "glfw";
|
|
||||||
url = "git+https://github.com/der-teufel-programming/glfw.git#206deaa2485703ac700d0f3020a8854282aecdbb";
|
|
||||||
hash = "sha256-GFeN4J4ZpKvQV8Gw6fxJ+KSpzzdjIYBbO/fTZ0Ooiuk=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "xcode_frameworks";
|
|
||||||
url = "https://pkg.machengine.org/xcode-frameworks/9a45f3ac977fd25dff77e58c6de1870b6808c4a7.tar.gz";
|
|
||||||
hash = "sha256-jWMT0p7klpkgX9GOUNAhrR2e6Ej7MobbqT5ZxJrNQoM=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "N-V-__8AAAIGzwDju1iAEUEqIbBeI3K4JhQ0vBdNzmETnIRQ";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "vulkan_headers";
|
|
||||||
url = "https://pkg.machengine.org/vulkan-headers/53e3ee66a78b97075863135b429956f225b149a5.tar.gz";
|
|
||||||
hash = "sha256-kXOn43ntsvxnufobQO0xfzg1cg0R97BmFOU3WRqFsH0=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "N-V-__8AAJfbCQBWPD1WA6AuYSk8LAIj4Bo_KY-2Br8NEIKT";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "wayland_headers";
|
|
||||||
url = "https://pkg.machengine.org/wayland-headers/7c53e7483c3cfb5c6780ae542c9f5cfa712a826a.tar.gz";
|
|
||||||
hash = "sha256-uGIvMyp+xR1jQXTDr6RqYl40Ukiw9l3fW1t6XpYztPY=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "N-V-__8AACbnQQDnnaLV79Xp3YtkU_g6nseVNOLiA7MzF2a4";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "x11_headers";
|
|
||||||
url = "https://pkg.machengine.org/x11-headers/29aefb525d5c08b05b0351e34b1623854a138c21.tar.gz";
|
|
||||||
hash = "sha256-UsbWkOmedS4ygY9C1g7OiPVnTcXzfGKdXImmztYAAiI=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "vaxis-0.1.0-BWNV_MHyCAARemSCSwwc3sA1etNgv7ge0BCIXspX6CZv";
|
name = "vaxis-0.1.0-BWNV_MHyCAARemSCSwwc3sA1etNgv7ge0BCIXspX6CZv";
|
||||||
path = fetchZigArtifact {
|
path = fetchZigArtifact {
|
||||||
|
|
@ -307,6 +259,14 @@ in
|
||||||
hash = "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU=";
|
hash = "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU=";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
name = "N-V-__8AADTkRwBjUvVwTLOnV96QhN0J5Nyg7YzvnISe-Eax";
|
||||||
|
path = fetchZigArtifact {
|
||||||
|
name = "glfw";
|
||||||
|
url = "https://github.com/glfw/glfw/archive/73948e6c0f15b1053cf74b7c4e6b04fd36e97e29.zip";
|
||||||
|
hash = "sha256-k7wBKiQpgxBhqHRwSEgZjmfncltlGG8BgY3FhyycM5E=";
|
||||||
|
};
|
||||||
|
}
|
||||||
{
|
{
|
||||||
name = "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr";
|
name = "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr";
|
||||||
path = fetchZigArtifact {
|
path = fetchZigArtifact {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
git+https://codeberg.org/atman/zg#4a002763419a34d61dcbb1f415821b83b9bf8ddc
|
git+https://codeberg.org/atman/zg#4a002763419a34d61dcbb1f415821b83b9bf8ddc
|
||||||
git+https://github.com/TUSF/zigimg#5102e09be233d372e9e05f4cb2ffbefba30bc1c0
|
|
||||||
git+https://github.com/der-teufel-programming/glfw.git#206deaa2485703ac700d0f3020a8854282aecdbb
|
|
||||||
git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7
|
git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7
|
||||||
git+https://github.com/rockorager/libvaxis/?ref=main#6a37605dde55898dcca4769dd3eb1e333959c209
|
git+https://github.com/rockorager/libvaxis/?ref=main#6a37605dde55898dcca4769dd3eb1e333959c209
|
||||||
|
git+https://github.com/TUSF/zigimg#5102e09be233d372e9e05f4cb2ffbefba30bc1c0
|
||||||
https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz
|
https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz
|
||||||
https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz
|
https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz
|
||||||
https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz
|
https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz
|
||||||
|
|
@ -27,14 +26,10 @@ https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d6
|
||||||
https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz
|
https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz
|
||||||
https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz
|
https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz
|
||||||
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
||||||
|
https://github.com/glfw/glfw/archive/73948e6c0f15b1053cf74b7c4e6b04fd36e97e29.zip
|
||||||
https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-11-16-1/ghostty-gobject-0.14.0-2025-03-11-16-1.tar.gz
|
https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-11-16-1/ghostty-gobject-0.14.0-2025-03-11-16-1.tar.gz
|
||||||
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/e21d5ffd19605741d0e3e19d7c5a8c6c25648673.tar.gz
|
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/e21d5ffd19605741d0e3e19d7c5a8c6c25648673.tar.gz
|
||||||
https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz
|
https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz
|
||||||
https://github.com/mitchellh/mach-glfw/archive/d84bc11b0601cdad71035a0e9cf21572d76aa0d2.zip
|
|
||||||
https://github.com/mitchellh/zig-objc/archive/3ab0d37c7d6b933d6ded1b3a35b6b60f05590a98.tar.gz
|
https://github.com/mitchellh/zig-objc/archive/3ab0d37c7d6b933d6ded1b3a35b6b60f05590a98.tar.gz
|
||||||
https://github.com/natecraddock/zf/archive/03176fcf23fda543cc02a8675e92c1fe3b1ee2eb.tar.gz
|
https://github.com/natecraddock/zf/archive/03176fcf23fda543cc02a8675e92c1fe3b1ee2eb.tar.gz
|
||||||
https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz
|
https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz
|
||||||
https://pkg.machengine.org/vulkan-headers/53e3ee66a78b97075863135b429956f225b149a5.tar.gz
|
|
||||||
https://pkg.machengine.org/wayland-headers/7c53e7483c3cfb5c6780ae542c9f5cfa712a826a.tar.gz
|
|
||||||
https://pkg.machengine.org/x11-headers/29aefb525d5c08b05b0351e34b1623854a138c21.tar.gz
|
|
||||||
https://pkg.machengine.org/xcode-frameworks/9a45f3ac977fd25dff77e58c6de1870b6808c4a7.tar.gz
|
|
||||||
|
|
|
||||||
|
|
@ -4,36 +4,6 @@
|
||||||
"url": "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz",
|
"url": "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz",
|
||||||
"hash": "sha256-oKZqA9d79jHnp/HsqJWQE33Ffn5Ee5G4VnlQepQuY4o="
|
"hash": "sha256-oKZqA9d79jHnp/HsqJWQE33Ffn5Ee5G4VnlQepQuY4o="
|
||||||
},
|
},
|
||||||
"mach_glfw-0.2.0-EJSQm2M9BQCiYGTd9VcKjg2DhSD7WT4kS-MfX68ORRT_": {
|
|
||||||
"name": "mach_glfw",
|
|
||||||
"url": "https://github.com/mitchellh/mach-glfw/archive/d84bc11b0601cdad71035a0e9cf21572d76aa0d2.zip",
|
|
||||||
"hash": "sha256-Sh1DvCmawdN+a2JEhNP3wTX43/i5FDlDVOIx7Um/d0U="
|
|
||||||
},
|
|
||||||
"glfw-0.0.0-bOgnngiqGQCt5HJK25zx1lf9emPYDNtEuQPYmrTCdOoN": {
|
|
||||||
"name": "glfw",
|
|
||||||
"url": "git+https://github.com/der-teufel-programming/glfw.git#206deaa2485703ac700d0f3020a8854282aecdbb",
|
|
||||||
"hash": "sha256-GFeN4J4ZpKvQV8Gw6fxJ+KSpzzdjIYBbO/fTZ0Ooiuk="
|
|
||||||
},
|
|
||||||
"N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms": {
|
|
||||||
"name": "xcode_frameworks",
|
|
||||||
"url": "https://pkg.machengine.org/xcode-frameworks/9a45f3ac977fd25dff77e58c6de1870b6808c4a7.tar.gz",
|
|
||||||
"hash": "sha256-jWMT0p7klpkgX9GOUNAhrR2e6Ej7MobbqT5ZxJrNQoM="
|
|
||||||
},
|
|
||||||
"N-V-__8AAAIGzwDju1iAEUEqIbBeI3K4JhQ0vBdNzmETnIRQ": {
|
|
||||||
"name": "vulkan_headers",
|
|
||||||
"url": "https://pkg.machengine.org/vulkan-headers/53e3ee66a78b97075863135b429956f225b149a5.tar.gz",
|
|
||||||
"hash": "sha256-kXOn43ntsvxnufobQO0xfzg1cg0R97BmFOU3WRqFsH0="
|
|
||||||
},
|
|
||||||
"N-V-__8AAJfbCQBWPD1WA6AuYSk8LAIj4Bo_KY-2Br8NEIKT": {
|
|
||||||
"name": "wayland_headers",
|
|
||||||
"url": "https://pkg.machengine.org/wayland-headers/7c53e7483c3cfb5c6780ae542c9f5cfa712a826a.tar.gz",
|
|
||||||
"hash": "sha256-uGIvMyp+xR1jQXTDr6RqYl40Ukiw9l3fW1t6XpYztPY="
|
|
||||||
},
|
|
||||||
"N-V-__8AACbnQQDnnaLV79Xp3YtkU_g6nseVNOLiA7MzF2a4": {
|
|
||||||
"name": "x11_headers",
|
|
||||||
"url": "https://pkg.machengine.org/x11-headers/29aefb525d5c08b05b0351e34b1623854a138c21.tar.gz",
|
|
||||||
"hash": "sha256-UsbWkOmedS4ygY9C1g7OiPVnTcXzfGKdXImmztYAAiI="
|
|
||||||
},
|
|
||||||
"vaxis-0.1.0-BWNV_MHyCAARemSCSwwc3sA1etNgv7ge0BCIXspX6CZv": {
|
"vaxis-0.1.0-BWNV_MHyCAARemSCSwwc3sA1etNgv7ge0BCIXspX6CZv": {
|
||||||
"name": "vaxis",
|
"name": "vaxis",
|
||||||
"url": "git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7",
|
"url": "git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7",
|
||||||
|
|
@ -139,6 +109,11 @@
|
||||||
"url": "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
|
"url": "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
|
||||||
"hash": "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU="
|
"hash": "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU="
|
||||||
},
|
},
|
||||||
|
"N-V-__8AADTkRwBjUvVwTLOnV96QhN0J5Nyg7YzvnISe-Eax": {
|
||||||
|
"name": "glfw",
|
||||||
|
"url": "https://github.com/glfw/glfw/archive/73948e6c0f15b1053cf74b7c4e6b04fd36e97e29.zip",
|
||||||
|
"hash": "sha256-k7wBKiQpgxBhqHRwSEgZjmfncltlGG8BgY3FhyycM5E="
|
||||||
|
},
|
||||||
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
|
||||||
"name": "gtk4_layer_shell",
|
"name": "gtk4_layer_shell",
|
||||||
"url": "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz",
|
"url": "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz",
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
harfbuzz,
|
harfbuzz,
|
||||||
libpng,
|
libpng,
|
||||||
libGL,
|
libGL,
|
||||||
|
libxkbcommon,
|
||||||
libX11,
|
libX11,
|
||||||
libXcursor,
|
libXcursor,
|
||||||
libXext,
|
libXext,
|
||||||
|
|
@ -83,6 +84,7 @@
|
||||||
glslang
|
glslang
|
||||||
spirv-cross
|
spirv-cross
|
||||||
|
|
||||||
|
libxkbcommon
|
||||||
libX11
|
libX11
|
||||||
libXcursor
|
libXcursor
|
||||||
libXi
|
libXi
|
||||||
|
|
@ -162,6 +164,7 @@ in
|
||||||
glslang
|
glslang
|
||||||
spirv-cross
|
spirv-cross
|
||||||
|
|
||||||
|
libxkbcommon
|
||||||
libX11
|
libX11
|
||||||
libXcursor
|
libXcursor
|
||||||
libXext
|
libXext
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,209 @@
|
||||||
|
//! Represents a cursor and provides facilities for setting cursor images.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const Image = @import("Image.zig");
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
const Cursor = @This();
|
||||||
|
|
||||||
|
ptr: *c.GLFWcursor,
|
||||||
|
|
||||||
|
/// Standard system cursor shapes.
|
||||||
|
///
|
||||||
|
/// These are the standard cursor shapes that can be requested from the platform (window system).
|
||||||
|
pub const Shape = enum(i32) {
|
||||||
|
/// The regular arrow cursor shape.
|
||||||
|
arrow = c.GLFW_ARROW_CURSOR,
|
||||||
|
|
||||||
|
/// The text input I-beam cursor shape.
|
||||||
|
ibeam = c.GLFW_IBEAM_CURSOR,
|
||||||
|
|
||||||
|
/// The crosshair cursor shape.
|
||||||
|
crosshair = c.GLFW_CROSSHAIR_CURSOR,
|
||||||
|
|
||||||
|
/// The pointing hand cursor shape.
|
||||||
|
///
|
||||||
|
/// NOTE: This supersedes the old `hand` enum.
|
||||||
|
pointing_hand = c.GLFW_POINTING_HAND_CURSOR,
|
||||||
|
|
||||||
|
/// The horizontal resize/move arrow shape.
|
||||||
|
///
|
||||||
|
/// The horizontal resize/move arrow shape. This is usually a horizontal double-headed arrow.
|
||||||
|
//
|
||||||
|
// NOTE: This supersedes the old `hresize` enum.
|
||||||
|
resize_ew = c.GLFW_RESIZE_EW_CURSOR,
|
||||||
|
|
||||||
|
/// The vertical resize/move arrow shape.
|
||||||
|
///
|
||||||
|
/// The vertical resize/move shape. This is usually a vertical double-headed arrow.
|
||||||
|
///
|
||||||
|
/// NOTE: This supersedes the old `vresize` enum.
|
||||||
|
resize_ns = c.GLFW_RESIZE_NS_CURSOR,
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// macos: This shape is provided by a private system API and may fail CursorUnavailable in the
|
||||||
|
/// future.
|
||||||
|
///
|
||||||
|
/// x11: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
///
|
||||||
|
/// wayland: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
resize_nwse = c.GLFW_RESIZE_NWSE_CURSOR,
|
||||||
|
|
||||||
|
/// The top-right to bottom-left diagonal resize/move arrow shape.
|
||||||
|
///
|
||||||
|
/// The top-right to bottom-left diagonal resize/move shape. This is usually a diagonal
|
||||||
|
/// double-headed arrow.
|
||||||
|
///
|
||||||
|
/// macos: This shape is provided by a private system API and may fail with CursorUnavailable
|
||||||
|
/// in the future.
|
||||||
|
///
|
||||||
|
/// x11: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
///
|
||||||
|
/// wayland: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
resize_nesw = c.GLFW_RESIZE_NESW_CURSOR,
|
||||||
|
|
||||||
|
/// The omni-directional resize/move cursor shape.
|
||||||
|
///
|
||||||
|
/// The omni-directional resize cursor/move shape. This is usually either a combined horizontal
|
||||||
|
/// and vertical double-headed arrow or a grabbing hand.
|
||||||
|
resize_all = c.GLFW_RESIZE_ALL_CURSOR,
|
||||||
|
|
||||||
|
/// The operation-not-allowed shape.
|
||||||
|
///
|
||||||
|
/// The operation-not-allowed shape. This is usually a circle with a diagonal line through it.
|
||||||
|
///
|
||||||
|
/// x11: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
///
|
||||||
|
/// wayland: This shape is provided by a newer standard not supported by all cursor themes.
|
||||||
|
not_allowed = c.GLFW_NOT_ALLOWED_CURSOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Creates a custom cursor.
|
||||||
|
///
|
||||||
|
/// Creates a new custom cursor image that can be set for a window with glfw.Cursor.set. The cursor
|
||||||
|
/// can be destroyed with glfwCursor.destroy. Any remaining cursors are destroyed by glfw.terminate.
|
||||||
|
///
|
||||||
|
/// The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits per channel with
|
||||||
|
/// the red channel first. They are arranged canonically as packed sequential rows, starting from
|
||||||
|
/// the top-left corner.
|
||||||
|
///
|
||||||
|
/// The cursor hotspot is specified in pixels, relative to the upper-left corner of the cursor
|
||||||
|
/// image. Like all other coordinate systems in GLFW, the X-axis points to the right and the Y-axis
|
||||||
|
/// points down.
|
||||||
|
///
|
||||||
|
/// @param[in] image The desired cursor image.
|
||||||
|
/// @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
|
||||||
|
/// @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
|
||||||
|
/// @return The handle of the created cursor.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError and glfw.ErrorCode.InvalidValue
|
||||||
|
/// null is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The specified image data is copied before this function returns.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: cursor_object, glfw.Cursor.destroy, glfw.Cursor.createStandard
|
||||||
|
pub inline fn create(image: Image, xhot: i32, yhot: i32) ?Cursor {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const img = image.toC();
|
||||||
|
if (c.glfwCreateCursor(&img, @as(c_int, @intCast(xhot)), @as(c_int, @intCast(yhot)))) |cursor| return Cursor{ .ptr = cursor };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a cursor with a standard shape.
|
||||||
|
///
|
||||||
|
/// Returns a cursor with a standard shape, that can be set for a window with glfw.Window.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 |
|
||||||
|
/// |------------------|---------|-----------------|-------------------|-------------------|
|
||||||
|
/// | `.arrow` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.ibeam` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.crosshair` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.pointing_hand` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.resize_ew` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.resize_ns` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.resize_nwse` | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup> |
|
||||||
|
/// | `.resize_nesw` | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup> |
|
||||||
|
/// | `.resize_all` | Yes | Yes | Yes | Yes |
|
||||||
|
/// | `.not_allowed` | Yes | Yes | Maybe<sup>2</sup> | Maybe<sup>2</sup> |
|
||||||
|
///
|
||||||
|
/// 1. This uses a private system API and may fail in the future.
|
||||||
|
/// 2. This uses a newer standard that not all cursor themes support.
|
||||||
|
///
|
||||||
|
/// If the requested shape is not available, this function emits a CursorUnavailable error
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError and glfw.ErrorCode.CursorUnavailable.
|
||||||
|
/// null is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: cursor_object, glfwCreateCursor
|
||||||
|
pub inline fn createStandard(shape: Shape) ?Cursor {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwCreateStandardCursor(@as(c_int, @intCast(@intFromEnum(shape))))) |cursor| return Cursor{ .ptr = cursor };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys a cursor.
|
||||||
|
///
|
||||||
|
/// This function destroys a cursor previously created with glfw.Cursor.create. Any remaining
|
||||||
|
/// cursors will be destroyed by glfw.terminate.
|
||||||
|
///
|
||||||
|
/// If the specified cursor is current for any window, that window will be reverted to the default
|
||||||
|
/// cursor. This does not affect the cursor mode.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @reentrancy This function must not be called from a callback.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: cursor_object, glfw.createCursor
|
||||||
|
pub inline fn destroy(self: Cursor) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwDestroyCursor(self.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "create" {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const image = try Image.init(allocator, 32, 32, 32 * 32 * 4);
|
||||||
|
defer image.deinit(allocator);
|
||||||
|
|
||||||
|
const cursor = glfw.Cursor.create(image, 0, 0);
|
||||||
|
if (cursor) |cur| cur.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "createStandard" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const cursor = glfw.Cursor.createStandard(.ibeam);
|
||||||
|
if (cursor) |cur| cur.destroy();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
//! Gamma ramp for monitors and related functions.
|
||||||
|
//!
|
||||||
|
//! It may be .owned (e.g. in the case of a gamma ramp initialized by you for passing into
|
||||||
|
//! glfw.Monitor.setGammaRamp) or not .owned (e.g. in the case of one gotten via
|
||||||
|
//! glfw.Monitor.getGammaRamp.) If it is .owned, deinit should be called to free the memory. It is
|
||||||
|
//! safe to call deinit even if not .owned.
|
||||||
|
//!
|
||||||
|
//! see also: monitor_gamma, glfw.Monitor.getGammaRamp
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
const mem = std.mem;
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const GammaRamp = @This();
|
||||||
|
|
||||||
|
red: []u16,
|
||||||
|
green: []u16,
|
||||||
|
blue: []u16,
|
||||||
|
owned: ?[]u16,
|
||||||
|
|
||||||
|
/// Initializes a new owned gamma ramp with the given array size and undefined values.
|
||||||
|
///
|
||||||
|
/// see also: glfw.Monitor.getGammaRamp
|
||||||
|
pub inline fn init(allocator: mem.Allocator, size: usize) !GammaRamp {
|
||||||
|
const buf = try allocator.alloc(u16, size * 3);
|
||||||
|
return GammaRamp{
|
||||||
|
.red = buf[size * 0 .. (size * 0) + size],
|
||||||
|
.green = buf[size * 1 .. (size * 1) + size],
|
||||||
|
.blue = buf[size * 2 .. (size * 2) + size],
|
||||||
|
.owned = buf,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns a GLFW / C gamma ramp into the nicer Zig type, and sets `.owned = false`.
|
||||||
|
///
|
||||||
|
/// The returned memory is valid for as long as the GLFW C memory is valid.
|
||||||
|
pub inline fn fromC(native: c.GLFWgammaramp) GammaRamp {
|
||||||
|
return GammaRamp{
|
||||||
|
.red = native.red[0..native.size],
|
||||||
|
.green = native.green[0..native.size],
|
||||||
|
.blue = native.blue[0..native.size],
|
||||||
|
.owned = null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns the nicer Zig type into a GLFW / C gamma ramp, for passing into GLFW C functions.
|
||||||
|
///
|
||||||
|
/// The returned memory is valid for as long as the Zig memory is valid.
|
||||||
|
pub inline fn toC(self: GammaRamp) c.GLFWgammaramp {
|
||||||
|
std.debug.assert(self.red.len == self.green.len);
|
||||||
|
std.debug.assert(self.red.len == self.blue.len);
|
||||||
|
return c.GLFWgammaramp{
|
||||||
|
.red = &self.red[0],
|
||||||
|
.green = &self.green[0],
|
||||||
|
.blue = &self.blue[0],
|
||||||
|
.size = @as(c_uint, @intCast(self.red.len)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deinitializes the memory using the allocator iff `.owned = true`.
|
||||||
|
pub inline fn deinit(self: GammaRamp, allocator: mem.Allocator) void {
|
||||||
|
if (self.owned) |buf| allocator.free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "conversion" {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
|
const ramp = try GammaRamp.init(allocator, 256);
|
||||||
|
defer ramp.deinit(allocator);
|
||||||
|
|
||||||
|
const glfw = ramp.toC();
|
||||||
|
_ = GammaRamp.fromC(glfw);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
//! Image data
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! This describes a single 2D image. See the documentation for each related function what the
|
||||||
|
//! expected pixel format is.
|
||||||
|
//!
|
||||||
|
//! see also: cursor_custom, window_icon
|
||||||
|
//!
|
||||||
|
//! It may be .owned (e.g. in the case of an image initialized by you for passing into glfw) or not
|
||||||
|
//! .owned (e.g. in the case of one gotten via glfw) If it is .owned, deinit should be called to
|
||||||
|
//! free the memory. It is safe to call deinit even if not .owned.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
const mem = std.mem;
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const Image = @This();
|
||||||
|
|
||||||
|
/// The width of this image, in pixels.
|
||||||
|
width: u32,
|
||||||
|
|
||||||
|
/// The height of this image, in pixels.
|
||||||
|
height: u32,
|
||||||
|
|
||||||
|
/// The pixel data of this image, arranged left-to-right, top-to-bottom.
|
||||||
|
pixels: []u8,
|
||||||
|
|
||||||
|
/// Whether or not the pixels data is owned by you (true) or GLFW (false).
|
||||||
|
owned: bool,
|
||||||
|
|
||||||
|
/// Initializes a new owned image with the given size and pixel_data_len of undefined .pixel values.
|
||||||
|
pub inline fn init(allocator: mem.Allocator, width: u32, height: u32, pixel_data_len: usize) !Image {
|
||||||
|
const buf = try allocator.alloc(u8, pixel_data_len);
|
||||||
|
return Image{
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.pixels = buf,
|
||||||
|
.owned = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns a GLFW / C image into the nicer Zig type, and sets `.owned = false`.
|
||||||
|
///
|
||||||
|
/// The length of pixel data must be supplied, as GLFW's image type does not itself describe the
|
||||||
|
/// number of bytes required per pixel / the length of the pixel data array.
|
||||||
|
///
|
||||||
|
/// The returned memory is valid for as long as the GLFW C memory is valid.
|
||||||
|
pub inline fn fromC(native: c.GLFWimage, pixel_data_len: usize) Image {
|
||||||
|
return Image{
|
||||||
|
.width = @as(u32, @intCast(native.width)),
|
||||||
|
.height = @as(u32, @intCast(native.height)),
|
||||||
|
.pixels = native.pixels[0..pixel_data_len],
|
||||||
|
.owned = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns the nicer Zig type into a GLFW / C image, for passing into GLFW C functions.
|
||||||
|
///
|
||||||
|
/// The returned memory is valid for as long as the Zig memory is valid.
|
||||||
|
pub inline fn toC(self: Image) c.GLFWimage {
|
||||||
|
return c.GLFWimage{
|
||||||
|
.width = @as(c_int, @intCast(self.width)),
|
||||||
|
.height = @as(c_int, @intCast(self.height)),
|
||||||
|
.pixels = &self.pixels[0],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deinitializes the memory using the allocator iff `.owned = true`.
|
||||||
|
pub inline fn deinit(self: Image, allocator: mem.Allocator) void {
|
||||||
|
if (self.owned) allocator.free(self.pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "conversion" {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
|
const image = try Image.init(allocator, 256, 256, 256 * 256 * 4);
|
||||||
|
defer image.deinit(allocator);
|
||||||
|
|
||||||
|
const glfw = image.toC();
|
||||||
|
_ = Image.fromC(glfw, image.width * image.height * 4);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,642 @@
|
||||||
|
//! Represents a Joystick or gamepad
|
||||||
|
//!
|
||||||
|
//! It can be manually crafted via e.g. `glfw.Joystick{.jid = .one}`, but more
|
||||||
|
//! typically you'll want to discover the joystick using `glfw.Joystick.setCallback`.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const Window = @import("Window.zig");
|
||||||
|
const Action = @import("action.zig").Action;
|
||||||
|
const GamepadAxis = @import("gamepad_axis.zig").GamepadAxis;
|
||||||
|
const GamepadButton = @import("gamepad_button.zig").GamepadButton;
|
||||||
|
const Hat = @import("hat.zig").Hat;
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
const Joystick = @This();
|
||||||
|
|
||||||
|
/// The GLFW joystick ID.
|
||||||
|
jid: Id,
|
||||||
|
|
||||||
|
/// Joystick IDs.
|
||||||
|
///
|
||||||
|
/// See glfw.Joystick.setCallback for how these are used.
|
||||||
|
pub const Id = enum(c_int) {
|
||||||
|
one = c.GLFW_JOYSTICK_1,
|
||||||
|
two = c.GLFW_JOYSTICK_2,
|
||||||
|
three = c.GLFW_JOYSTICK_3,
|
||||||
|
four = c.GLFW_JOYSTICK_4,
|
||||||
|
five = c.GLFW_JOYSTICK_5,
|
||||||
|
six = c.GLFW_JOYSTICK_6,
|
||||||
|
seven = c.GLFW_JOYSTICK_7,
|
||||||
|
eight = c.GLFW_JOYSTICK_8,
|
||||||
|
nine = c.GLFW_JOYSTICK_9,
|
||||||
|
ten = c.GLFW_JOYSTICK_10,
|
||||||
|
eleven = c.GLFW_JOYSTICK_11,
|
||||||
|
twelve = c.GLFW_JOYSTICK_12,
|
||||||
|
thirteen = c.GLFW_JOYSTICK_13,
|
||||||
|
fourteen = c.GLFW_JOYSTICK_14,
|
||||||
|
fifteen = c.GLFW_JOYSTICK_15,
|
||||||
|
sixteen = c.GLFW_JOYSTICK_16,
|
||||||
|
pub const last = @as(@This(), @enumFromInt(c.GLFW_JOYSTICK_LAST));
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Gamepad input state
|
||||||
|
///
|
||||||
|
/// This describes the input state of a gamepad.
|
||||||
|
///
|
||||||
|
/// see also: gamepad, glfwGetGamepadState
|
||||||
|
const GamepadState = extern struct {
|
||||||
|
/// The states of each gamepad button (see gamepad_buttons), `glfw.Action.press` or `glfw.Action.release`.
|
||||||
|
///
|
||||||
|
/// Use the enumeration helper e.g. `.getButton(.dpad_up)` to access these indices.
|
||||||
|
buttons: [15]u8,
|
||||||
|
|
||||||
|
/// The states of each gamepad axis (see gamepad_axes), in the range -1.0 to 1.0 inclusive.
|
||||||
|
///
|
||||||
|
/// Use the enumeration helper e.g. `.getAxis(.left_x)` to access these indices.
|
||||||
|
axes: [6]f32,
|
||||||
|
|
||||||
|
/// Returns the state of the specified gamepad button.
|
||||||
|
pub fn getButton(self: @This(), which: GamepadButton) Action {
|
||||||
|
return @as(Action, @enumFromInt(self.buttons[@as(u32, @intCast(@intFromEnum(which)))]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the status of the specified gamepad axis, in the range -1.0 to 1.0 inclusive.
|
||||||
|
pub fn getAxis(self: @This(), which: GamepadAxis) f32 {
|
||||||
|
return self.axes[@as(u32, @intCast(@intFromEnum(which)))];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns whether the specified joystick is present.
|
||||||
|
///
|
||||||
|
/// This function returns whether the specified joystick is present.
|
||||||
|
///
|
||||||
|
/// There is no need to call this function before other functions that accept a joystick ID, as
|
||||||
|
/// they all check for presence before performing any other work.
|
||||||
|
///
|
||||||
|
/// @return `true` if the joystick is present, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick
|
||||||
|
pub inline fn present(self: Joystick) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const is_present = c.glfwJoystickPresent(@intFromEnum(self.jid));
|
||||||
|
return is_present == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the values of all axes of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the values of all axes of the specified joystick. Each element in the
|
||||||
|
/// array is a value between -1.0 and 1.0.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present this function will return null but will not generate
|
||||||
|
/// an error. This can be used instead of first calling glfw.Joystick.present.
|
||||||
|
///
|
||||||
|
/// @return An array of axis values, or null if the joystick is not present.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is additionally returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned array is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected or the library is
|
||||||
|
/// terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick_axis
|
||||||
|
/// Replaces `glfwGetJoystickPos`.
|
||||||
|
pub inline fn getAxes(self: Joystick) ?[]const f32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: c_int = undefined;
|
||||||
|
const axes = c.glfwGetJoystickAxes(@intFromEnum(self.jid), &count);
|
||||||
|
if (axes == null) return null;
|
||||||
|
return axes[0..@as(u32, @intCast(count))];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the state of all buttons of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the state of all buttons of the specified joystick. Each element in the
|
||||||
|
/// array is either `glfw.Action.press` or `glfw.Action.release`.
|
||||||
|
///
|
||||||
|
/// For backward compatibility with earlier versions that did not have glfw.Joystick.getHats, the
|
||||||
|
/// button array also includes all hats, each represented as four buttons. The hats are in the same
|
||||||
|
/// order as returned by glfw.Joystick.getHats and are in the order _up_, _right_, _down_ and
|
||||||
|
/// _left_. To disable these extra buttons, set the glfw.joystick_hat_buttons init hint before
|
||||||
|
/// initialization.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present this function will return null but will not generate an
|
||||||
|
/// error. This can be used instead of first calling glfw.Joystick.present.
|
||||||
|
///
|
||||||
|
/// @return An array of button states, or null if the joystick is not present.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is additionally returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned array is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick_button
|
||||||
|
pub inline fn getButtons(self: Joystick) ?[]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: c_int = undefined;
|
||||||
|
const buttons = c.glfwGetJoystickButtons(@intFromEnum(self.jid), &count);
|
||||||
|
if (buttons == null) return null;
|
||||||
|
return buttons[0..@as(u32, @intCast(count))];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the state of all hats of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the state of all hats of the specified joystick. Each element in the array
|
||||||
|
/// is one of the following values:
|
||||||
|
///
|
||||||
|
/// | Name | Value |
|
||||||
|
/// |---------------------------|---------------------------------------------|
|
||||||
|
/// | `glfw.RawHats.centered` | 0 |
|
||||||
|
/// | `glfw.RawHats.up` | 1 |
|
||||||
|
/// | `glfw.RawHats.right` | 2 |
|
||||||
|
/// | `glfw.RawHats.down` | 4 |
|
||||||
|
/// | `glfw.RawHats.left` | 8 |
|
||||||
|
/// | `glfw.RawHats.right_up` | `glfw.RawHats.right` \| `glfw.RawHats.up` |
|
||||||
|
/// | `glfw.RawHats.right_down` | `glfw.RawHats.right` \| `glfw.RawHats.down` |
|
||||||
|
/// | `glfw.RawHats.left_up` | `glfw.RawHats.left` \| `glfw.RawHats.up` |
|
||||||
|
/// | `glfw.RawHats.left_down` | `glfw.RawHats.left` \| `glfw.RawHats.down` |
|
||||||
|
///
|
||||||
|
/// The diagonal directions are bitwise combinations of the primary (up, right, down and left)
|
||||||
|
/// directions, since the Zig GLFW wrapper returns a packed struct it is trivial to test for these:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// if (hats.up and hats.right) {
|
||||||
|
/// // up-right!
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present this function will return null but will not generate an
|
||||||
|
/// error. This can be used instead of first calling glfw.Joystick.present.
|
||||||
|
///
|
||||||
|
/// @return An array of hat states, or null if the joystick is not present.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is additionally returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned array is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected, this function is called
|
||||||
|
/// again for that joystick or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick_hat
|
||||||
|
pub inline fn getHats(self: Joystick) ?[]const Hat {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: c_int = undefined;
|
||||||
|
const hats = c.glfwGetJoystickHats(@intFromEnum(self.jid), &count);
|
||||||
|
if (hats == null) return null;
|
||||||
|
const slice = hats[0..@as(u32, @intCast(count))];
|
||||||
|
return @as(*const []const Hat, @ptrCast(&slice)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the name of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the name, encoded as UTF-8, of the specified joystick. The returned string
|
||||||
|
/// is allocated and freed by GLFW. You should not free it yourself.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present this function will return null but will not generate an
|
||||||
|
/// error. This can be used instead of first calling glfw.Joystick.present.
|
||||||
|
///
|
||||||
|
/// @return The UTF-8 encoded name of the joystick, or null if the joystick is not present or an
|
||||||
|
/// error occurred.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is additionally returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick_name
|
||||||
|
pub inline fn getName(self: Joystick) ?[:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const name_opt = c.glfwGetJoystickName(@intFromEnum(self.jid));
|
||||||
|
return if (name_opt) |name|
|
||||||
|
std.mem.span(@as([*:0]const u8, @ptrCast(name)))
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the SDL compatible GUID of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the SDL compatible GUID, as a UTF-8 encoded hexadecimal string, of the
|
||||||
|
/// specified joystick. The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself.
|
||||||
|
///
|
||||||
|
/// The GUID is what connects a joystick to a gamepad mapping. A connected joystick will always have
|
||||||
|
/// a GUID even if there is no gamepad mapping assigned to it.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present this function will return null but will not generate an
|
||||||
|
/// error. This can be used instead of first calling glfw.Joystick.present.
|
||||||
|
///
|
||||||
|
/// The GUID uses the format introduced in SDL 2.0.5. This GUID tries to uniquely identify the make
|
||||||
|
/// and model of a joystick but does not identify a specific unit, e.g. all wired Xbox 360
|
||||||
|
/// controllers will have the same GUID on that platform. The GUID for a unit may vary between
|
||||||
|
/// platforms depending on what hardware information the platform specific APIs provide.
|
||||||
|
///
|
||||||
|
/// @return The UTF-8 encoded GUID of the joystick, or null if the joystick is not present.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is additionally returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: gamepad
|
||||||
|
pub inline fn getGUID(self: Joystick) ?[:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const guid_opt = c.glfwGetJoystickGUID(@intFromEnum(self.jid));
|
||||||
|
return if (guid_opt) |guid|
|
||||||
|
std.mem.span(@as([*:0]const u8, @ptrCast(guid)))
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the user pointer of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function sets the user-defined pointer of the specified joystick. The current value is
|
||||||
|
/// retained until the joystick is disconnected. The initial value is null.
|
||||||
|
///
|
||||||
|
/// This function may be called from the joystick callback, even for a joystick that is being disconnected.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
///
|
||||||
|
/// see also: joystick_userptr, glfw.Joystick.getUserPointer
|
||||||
|
pub inline fn setUserPointer(self: Joystick, comptime T: type, pointer: *T) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwSetJoystickUserPointer(@intFromEnum(self.jid), @as(*anyopaque, @ptrCast(pointer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the user pointer of the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the current value of the user-defined pointer of the specified joystick.
|
||||||
|
/// The initial value is null.
|
||||||
|
///
|
||||||
|
/// This function may be called from the joystick callback, even for a joystick that is being
|
||||||
|
/// disconnected.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
///
|
||||||
|
/// see also: joystick_userptr, glfw.Joystick.setUserPointer
|
||||||
|
pub inline fn getUserPointer(self: Joystick, comptime PointerType: type) ?PointerType {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const ptr = c.glfwGetJoystickUserPointer(@intFromEnum(self.jid));
|
||||||
|
if (ptr) |p| return @as(PointerType, @ptrCast(@alignCast(p)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Describes an event relating to a joystick.
|
||||||
|
pub const Event = enum(c_int) {
|
||||||
|
/// The device was connected.
|
||||||
|
connected = c.GLFW_CONNECTED,
|
||||||
|
|
||||||
|
/// The device was disconnected.
|
||||||
|
disconnected = c.GLFW_DISCONNECTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sets the joystick configuration callback.
|
||||||
|
///
|
||||||
|
/// This function sets the joystick configuration callback, or removes the currently set callback.
|
||||||
|
/// This is called when a joystick is connected to or disconnected from the system.
|
||||||
|
///
|
||||||
|
/// For joystick connection and disconnection events to be delivered on all platforms, you need to
|
||||||
|
/// call one of the event processing (see events) functions. Joystick disconnection may also be
|
||||||
|
/// detected and the callback called by joystick functions. The function will then return whatever
|
||||||
|
/// it returns if the joystick is not present.
|
||||||
|
///
|
||||||
|
/// @param[in] callback The new callback, or null to remove the currently set callback.
|
||||||
|
///
|
||||||
|
/// @callback_param `jid` The joystick that was connected or disconnected.
|
||||||
|
/// @callback_param `event` One of `.connected` or `.disconnected`. Future releases may add
|
||||||
|
/// more events.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: joystick_event
|
||||||
|
pub inline fn setCallback(comptime callback: ?fn (joystick: Joystick, event: Event) void) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
|
||||||
|
if (callback) |user_callback| {
|
||||||
|
const CWrapper = struct {
|
||||||
|
pub fn joystickCallbackWrapper(jid: c_int, event: c_int) callconv(.C) void {
|
||||||
|
@call(.always_inline, user_callback, .{
|
||||||
|
Joystick{ .jid = @as(Joystick.Id, @enumFromInt(jid)) },
|
||||||
|
@as(Event, @enumFromInt(event)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c.glfwSetJoystickCallback(CWrapper.joystickCallbackWrapper) != null) return;
|
||||||
|
} else {
|
||||||
|
if (c.glfwSetJoystickCallback(null) != null) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds the specified SDL_GameControllerDB gamepad mappings.
|
||||||
|
///
|
||||||
|
/// This function parses the specified ASCII encoded string and updates the internal list with any
|
||||||
|
/// gamepad mappings it finds. This string may contain either a single gamepad mapping or many
|
||||||
|
/// mappings separated by newlines. The parser supports the full format of the `gamecontrollerdb.txt`
|
||||||
|
/// source file including empty lines and comments.
|
||||||
|
///
|
||||||
|
/// See gamepad_mapping for a description of the format.
|
||||||
|
///
|
||||||
|
/// If there is already a gamepad mapping for a given GUID in the internal list, it will be
|
||||||
|
/// replaced by the one passed to this function. If the library is terminated and re-initialized
|
||||||
|
/// the internal list will revert to the built-in default.
|
||||||
|
///
|
||||||
|
/// @param[in] string The string containing the gamepad mappings.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidValue.
|
||||||
|
/// Returns a boolean indicating success.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: gamepad, glfw.Joystick.isGamepad, glfwGetGamepadName
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// @ingroup input
|
||||||
|
pub inline fn updateGamepadMappings(gamepad_mappings: [*:0]const u8) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return c.glfwUpdateGamepadMappings(gamepad_mappings) == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the specified joystick has a gamepad mapping.
|
||||||
|
///
|
||||||
|
/// This function returns whether the specified joystick is both present and has a gamepad mapping.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is present but does not have a gamepad mapping this function will
|
||||||
|
/// return `false` but will not generate an error. Call glfw.Joystick.present to check if a
|
||||||
|
/// joystick is present regardless of whether it has a mapping.
|
||||||
|
///
|
||||||
|
/// @return `true` if a joystick is both present and has a gamepad mapping, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum.
|
||||||
|
/// Additionally returns false in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: gamepad, glfw.Joystick.getGamepadState
|
||||||
|
pub inline fn isGamepad(self: Joystick) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const is_gamepad = c.glfwJoystickIsGamepad(@intFromEnum(self.jid));
|
||||||
|
return is_gamepad == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the human-readable gamepad name for the specified joystick.
|
||||||
|
///
|
||||||
|
/// This function returns the human-readable name of the gamepad from the gamepad mapping assigned
|
||||||
|
/// to the specified joystick.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present or does not have a gamepad mapping this function will
|
||||||
|
/// return null, not an error. Call glfw.Joystick.present to check whether it is
|
||||||
|
/// present regardless of whether it has a mapping.
|
||||||
|
///
|
||||||
|
/// @return The UTF-8 encoded name of the gamepad, or null if the joystick is not present or does
|
||||||
|
/// not have a mapping.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum.
|
||||||
|
/// Additionally returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified joystick is disconnected, the gamepad mappings are
|
||||||
|
/// updated or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: gamepad, glfw.Joystick.isGamepad
|
||||||
|
pub inline fn getGamepadName(self: Joystick) ?[:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const name_opt = c.glfwGetGamepadName(@intFromEnum(self.jid));
|
||||||
|
return if (name_opt) |name|
|
||||||
|
std.mem.span(@as([*:0]const u8, @ptrCast(name)))
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the state of the joystick remapped as a gamepad.
|
||||||
|
///
|
||||||
|
/// This function retrieves the state of the joystick remapped to an Xbox-like gamepad.
|
||||||
|
///
|
||||||
|
/// If the specified joystick is not present or does not have a gamepad mapping this function will
|
||||||
|
/// return `false`. Call glfw.joystickPresent to check whether it is present regardless of whether
|
||||||
|
/// it has a mapping.
|
||||||
|
///
|
||||||
|
/// The Guide button may not be available for input as it is often hooked by the system or the
|
||||||
|
/// Steam client.
|
||||||
|
///
|
||||||
|
/// Not all devices have all the buttons or axes provided by GamepadState. Unavailable buttons
|
||||||
|
/// and axes will always report `glfw.Action.release` and 0.0 respectively.
|
||||||
|
///
|
||||||
|
/// @param[in] jid The joystick (see joysticks) to query.
|
||||||
|
/// @param[out] state The gamepad input state of the joystick.
|
||||||
|
/// @return the gamepad input state if successful, or null if no joystick is connected or it has no
|
||||||
|
/// gamepad mapping.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: gamepad, glfw.UpdateGamepadMappings, glfw.Joystick.isGamepad
|
||||||
|
pub inline fn getGamepadState(self: Joystick) ?GamepadState {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var state: GamepadState = undefined;
|
||||||
|
const success = c.glfwGetGamepadState(@intFromEnum(self.jid), @as(*c.GLFWgamepadstate, @ptrCast(&state)));
|
||||||
|
return if (success == c.GLFW_TRUE) state else null;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "present" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getAxes" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getAxes();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getButtons" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getHats" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
|
||||||
|
if (joystick.getHats()) |hats| {
|
||||||
|
for (hats) |hat| {
|
||||||
|
if (hat.down and hat.up) {
|
||||||
|
// down-up!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getName" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getGUID" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getGUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "setUserPointer_syntax" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
|
||||||
|
// Must be called from joystick callback, we cannot test it.
|
||||||
|
_ = joystick;
|
||||||
|
_ = setUserPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getUserPointer_syntax" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
|
||||||
|
// Must be called from joystick callback, we cannot test it.
|
||||||
|
_ = joystick;
|
||||||
|
_ = getUserPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "setCallback" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
glfw.Joystick.setCallback((struct {
|
||||||
|
pub fn callback(joystick: Joystick, event: Event) void {
|
||||||
|
_ = joystick;
|
||||||
|
_ = event;
|
||||||
|
}
|
||||||
|
}).callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "updateGamepadMappings_syntax" {
|
||||||
|
// We don't have a gamepad mapping to test with, just confirm the syntax is good.
|
||||||
|
_ = updateGamepadMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "isGamepad" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.isGamepad();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getGamepadName" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getGamepadName();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getGamepadState" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const joystick = glfw.Joystick{ .jid = .one };
|
||||||
|
_ = joystick.getGamepadState();
|
||||||
|
_ = (std.mem.zeroes(GamepadState)).getAxis(.left_x);
|
||||||
|
_ = (std.mem.zeroes(GamepadState)).getButton(.dpad_up);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
Copyright (c) 2021 Hexops Contributors (given via the Git commit history).
|
||||||
|
Copyright (c) 2025 Mitchell Hashimoto
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,599 @@
|
||||||
|
//! Monitor type and related functions
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
const testing = std.testing;
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const GammaRamp = @import("GammaRamp.zig");
|
||||||
|
const VideoMode = @import("VideoMode.zig");
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
const Monitor = @This();
|
||||||
|
|
||||||
|
handle: *c.GLFWmonitor,
|
||||||
|
|
||||||
|
/// A monitor position, in screen coordinates, of the upper left corner of the monitor on the
|
||||||
|
/// virtual screen.
|
||||||
|
const Pos = struct {
|
||||||
|
/// The x coordinate.
|
||||||
|
x: u32,
|
||||||
|
/// The y coordinate.
|
||||||
|
y: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the position of the monitor's viewport on the virtual screen.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_properties
|
||||||
|
pub inline fn getPos(self: Monitor) Pos {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var xpos: c_int = 0;
|
||||||
|
var ypos: c_int = 0;
|
||||||
|
c.glfwGetMonitorPos(self.handle, &xpos, &ypos);
|
||||||
|
return Pos{ .x = @as(u32, @intCast(xpos)), .y = @as(u32, @intCast(ypos)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The monitor workarea, in screen coordinates.
|
||||||
|
///
|
||||||
|
/// This is the position of the upper-left corner of the work area of the monitor, along with the
|
||||||
|
/// work area size. The work area is defined as the area of the 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.
|
||||||
|
const Workarea = struct {
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Retrieves the work area of the monitor.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
/// A zero value is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_workarea
|
||||||
|
pub inline fn getWorkarea(self: Monitor) Workarea {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var xpos: c_int = 0;
|
||||||
|
var ypos: c_int = 0;
|
||||||
|
var width: c_int = 0;
|
||||||
|
var height: c_int = 0;
|
||||||
|
c.glfwGetMonitorWorkarea(self.handle, &xpos, &ypos, &width, &height);
|
||||||
|
return Workarea{ .x = @as(u32, @intCast(xpos)), .y = @as(u32, @intCast(ypos)), .width = @as(u32, @intCast(width)), .height = @as(u32, @intCast(height)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The physical size, in millimetres, of the display area of a monitor.
|
||||||
|
const PhysicalSize = struct {
|
||||||
|
width_mm: u32,
|
||||||
|
height_mm: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the physical size of the monitor.
|
||||||
|
///
|
||||||
|
/// Some platforms do not provide accurate monitor size information, either because the monitor
|
||||||
|
/// [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
|
||||||
|
/// data is incorrect or because the driver does not report it accurately.
|
||||||
|
///
|
||||||
|
/// win32: On Windows 8 and earlier the physical size is calculated from
|
||||||
|
/// the current resolution and system DPI instead of querying the monitor EDID data
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_properties
|
||||||
|
pub inline fn getPhysicalSize(self: Monitor) PhysicalSize {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var width_mm: c_int = 0;
|
||||||
|
var height_mm: c_int = 0;
|
||||||
|
c.glfwGetMonitorPhysicalSize(self.handle, &width_mm, &height_mm);
|
||||||
|
return PhysicalSize{ .width_mm = @as(u32, @intCast(width_mm)), .height_mm = @as(u32, @intCast(height_mm)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The content scale for a monitor.
|
||||||
|
///
|
||||||
|
/// This is the ratio between the current DPI and the platform's default DPI. This is especially
|
||||||
|
/// important for text and any UI elements. If the pixel dimensions of your UI scaled by this look
|
||||||
|
/// appropriate on your machine then it should appear at a reasonable size on other machines
|
||||||
|
/// regardless of their DPI and scaling settings. This relies on the system DPI and scaling
|
||||||
|
/// settings being somewhat correct.
|
||||||
|
///
|
||||||
|
/// The content scale may depend on both the monitor resolution and pixel density and on users
|
||||||
|
/// settings. It may be very different from the raw DPI calculated from the physical size and
|
||||||
|
/// current resolution.
|
||||||
|
const ContentScale = struct {
|
||||||
|
x_scale: f32,
|
||||||
|
y_scale: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the content scale for the monitor.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
/// A zero value is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_scale, glfw.Window.getContentScale
|
||||||
|
pub inline fn getContentScale(self: Monitor) ContentScale {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var x_scale: f32 = 0;
|
||||||
|
var y_scale: f32 = 0;
|
||||||
|
c.glfwGetMonitorContentScale(self.handle, &x_scale, &y_scale);
|
||||||
|
return ContentScale{ .x_scale = @as(f32, @floatCast(x_scale)), .y_scale = @as(f32, @floatCast(y_scale)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the name of the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function returns a human-readable name, encoded as UTF-8, of the specified monitor. The
|
||||||
|
/// name typically reflects the make and model of the monitor and is not guaranteed to be unique
|
||||||
|
/// among the connected monitors.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the specified monitor is disconnected or the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_properties
|
||||||
|
pub inline fn getName(self: Monitor) [*:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetMonitorName(self.handle)) |name| return @as([*:0]const u8, @ptrCast(name));
|
||||||
|
// `glfwGetMonitorName` returns `null` only for errors, but the only error is unreachable
|
||||||
|
// (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the user pointer of the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function sets the user-defined pointer of the specified monitor. The current value is
|
||||||
|
/// retained until the monitor is disconnected.
|
||||||
|
///
|
||||||
|
/// This function may be called from the monitor callback, even for a monitor that is being
|
||||||
|
/// disconnected.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
///
|
||||||
|
/// see also: monitor_userptr, glfw.Monitor.getUserPointer
|
||||||
|
pub inline fn setUserPointer(self: Monitor, comptime T: type, ptr: *T) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwSetMonitorUserPointer(self.handle, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the user pointer of the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function returns the current value of the user-defined pointer of the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function may be called from the monitor callback, even for a monitor that is being
|
||||||
|
/// disconnected.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
///
|
||||||
|
/// see also: monitor_userptr, glfw.Monitor.setUserPointer
|
||||||
|
pub inline fn getUserPointer(self: Monitor, comptime T: type) ?*T {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const ptr = c.glfwGetMonitorUserPointer(self.handle);
|
||||||
|
if (ptr == null) return null;
|
||||||
|
return @as(*T, @ptrCast(@alignCast(ptr.?)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the available video modes for the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function returns an array of all video modes supported by the monitor. The returned slice
|
||||||
|
/// is sorted in ascending order, first by color bit depth (the sum of all channel depths) and
|
||||||
|
/// then by resolution area (the product of width and height), then resolution width and finally
|
||||||
|
/// by refresh rate.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError, glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// The returned slice memory is owned by the caller.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_modes, glfw.Monitor.getVideoMode
|
||||||
|
///
|
||||||
|
/// wayland: Gamma handling is privileged protocol, this function will thus never be implemented and
|
||||||
|
/// emits glfw.ErrorCode.FeatureUnavailable
|
||||||
|
///
|
||||||
|
/// TODO(glfw): rewrite this to not require any allocation.
|
||||||
|
pub inline fn getVideoModes(self: Monitor, allocator: mem.Allocator) mem.Allocator.Error!?[]VideoMode {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: c_int = 0;
|
||||||
|
if (c.glfwGetVideoModes(self.handle, &count)) |modes| {
|
||||||
|
const slice = try allocator.alloc(VideoMode, @as(u32, @intCast(count)));
|
||||||
|
var i: u32 = 0;
|
||||||
|
while (i < count) : (i += 1) {
|
||||||
|
slice[i] = VideoMode{ .handle = @as([*c]const c.GLFWvidmode, @ptrCast(modes))[i] };
|
||||||
|
}
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current mode of the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function returns the current video mode of the specified monitor. If you have created a
|
||||||
|
/// full screen window for that monitor, the return value will depend on whether that window is
|
||||||
|
/// iconified.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError, glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
/// Additionally returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// wayland: Gamma handling is a privileged protocol, this function will thus never be implemented
|
||||||
|
/// and will thus never be implemented and emits glfw.ErrorCode.FeatureUnavailable
|
||||||
|
///
|
||||||
|
/// see also: monitor_modes, glfw.Monitor.getVideoModes
|
||||||
|
pub inline fn getVideoMode(self: Monitor) ?VideoMode {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetVideoMode(self.handle)) |mode| return VideoMode{ .handle = mode.* };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a gamma ramp and sets it for the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function generates an appropriately sized gamma ramp from the specified exponent and then
|
||||||
|
/// calls glfw.Monitor.setGammaRamp with it. The value must be a finite number greater than zero.
|
||||||
|
///
|
||||||
|
/// The software controlled gamma ramp is applied _in addition_ to the hardware gamma correction,
|
||||||
|
/// which today is usually an approximation of sRGB gamma. This means that setting a perfectly
|
||||||
|
/// linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.
|
||||||
|
///
|
||||||
|
/// For gamma correct rendering with OpenGL or OpenGL ES, see the glfw.srgb_capable hint.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError, glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
///
|
||||||
|
/// wayland: Gamma handling is privileged protocol, this function will thus never be implemented and
|
||||||
|
/// emits glfw.ErrorCode.FeatureUnavailable
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_gamma
|
||||||
|
pub inline fn setGamma(self: Monitor, gamma: f32) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
|
||||||
|
std.debug.assert(!std.math.isNan(gamma));
|
||||||
|
std.debug.assert(gamma >= 0);
|
||||||
|
std.debug.assert(gamma <= std.math.f32_max);
|
||||||
|
|
||||||
|
c.glfwSetGamma(self.handle, gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current gamma ramp for the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function returns the current gamma ramp of the specified monitor.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
/// Additionally returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// wayland: Gamma handling is a privileged protocol, this function will thus never be implemented
|
||||||
|
/// and returns glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
///
|
||||||
|
/// The returned gamma ramp is `.owned = true` by GLFW, and is valid until the monitor is
|
||||||
|
/// disconnected, this function is called again, or `glfw.terminate()` is called.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_gamma
|
||||||
|
pub inline fn getGammaRamp(self: Monitor) ?GammaRamp {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetGammaRamp(self.handle)) |ramp| return GammaRamp.fromC(ramp.*);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current gamma ramp for the specified monitor.
|
||||||
|
///
|
||||||
|
/// This function sets the current gamma ramp for the specified monitor. The original gamma ramp
|
||||||
|
/// for that monitor is saved by GLFW the first time this function is called and is restored by
|
||||||
|
/// `glfw.terminate()`.
|
||||||
|
///
|
||||||
|
/// The software controlled gamma ramp is applied _in addition_ to the hardware gamma correction,
|
||||||
|
/// which today is usually an approximation of sRGB gamma. This means that setting a perfectly
|
||||||
|
/// linear ramp, or gamma 1.0, will produce the default (usually sRGB-like) behavior.
|
||||||
|
///
|
||||||
|
/// For gamma correct rendering with OpenGL or OpenGL ES, see the glfw.srgb_capable hint.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError, glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
///
|
||||||
|
/// The size of the specified gamma ramp should match the size of the current ramp for that
|
||||||
|
/// monitor. On win32, the gamma ramp size must be 256.
|
||||||
|
///
|
||||||
|
/// wayland: Gamma handling is a privileged protocol, this function will thus never be implemented
|
||||||
|
/// and returns glfw.ErrorCode.FeatureUnavailable.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The specified gamma ramp is copied before this function returns.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_gamma
|
||||||
|
pub inline fn setGammaRamp(self: Monitor, ramp: GammaRamp) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwSetGammaRamp(self.handle, &ramp.toC());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the currently connected monitors.
|
||||||
|
///
|
||||||
|
/// This function returns a slice of all currently connected monitors. The primary monitor is
|
||||||
|
/// always first. If no monitors were found, this function returns an empty slice.
|
||||||
|
///
|
||||||
|
/// The returned slice memory is owned by the caller. The underlying handles are owned by GLFW, and
|
||||||
|
/// are valid until the monitor configuration changes or `glfw.terminate` is called.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_monitors, monitor_event, glfw.monitor.getPrimary
|
||||||
|
pub inline fn getAll(allocator: mem.Allocator) mem.Allocator.Error![]Monitor {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: c_int = 0;
|
||||||
|
if (c.glfwGetMonitors(&count)) |monitors| {
|
||||||
|
const slice = try allocator.alloc(Monitor, @as(u32, @intCast(count)));
|
||||||
|
var i: u32 = 0;
|
||||||
|
while (i < count) : (i += 1) {
|
||||||
|
slice[i] = Monitor{ .handle = @as([*c]const ?*c.GLFWmonitor, @ptrCast(monitors))[i].? };
|
||||||
|
}
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
// `glfwGetMonitors` returning null can be either an error or no monitors, but the only error is
|
||||||
|
// unreachable (NotInitialized)
|
||||||
|
return &[_]Monitor{};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the primary monitor.
|
||||||
|
///
|
||||||
|
/// This function returns the primary monitor. This is usually the monitor where elements like
|
||||||
|
/// the task bar or global menu bar are located.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_monitors, glfw.monitors.getAll
|
||||||
|
pub inline fn getPrimary() ?Monitor {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetPrimaryMonitor()) |handle| return Monitor{ .handle = handle };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Describes an event relating to a monitor.
|
||||||
|
pub const Event = enum(c_int) {
|
||||||
|
/// The device was connected.
|
||||||
|
connected = c.GLFW_CONNECTED,
|
||||||
|
|
||||||
|
/// The device was disconnected.
|
||||||
|
disconnected = c.GLFW_DISCONNECTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sets the monitor configuration callback.
|
||||||
|
///
|
||||||
|
/// This function sets the monitor configuration callback, or removes the currently set callback.
|
||||||
|
/// This is called when a monitor is connected to or disconnected from the system. Example:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn monitorCallback(monitor: glfw.Monitor, event: glfw.Monitor.Event, data: *MyData) void {
|
||||||
|
/// // data is the pointer you passed into setCallback.
|
||||||
|
/// // event is one of .connected or .disconnected
|
||||||
|
/// }
|
||||||
|
/// ...
|
||||||
|
/// glfw.Monitor.setCallback(MyData, &myData, monitorCallback)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// `event` may be one of .connected or .disconnected. More events may be added in the future.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: monitor_event
|
||||||
|
pub inline fn setCallback(comptime callback: ?fn (monitor: Monitor, event: Event) void) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
|
||||||
|
if (callback) |user_callback| {
|
||||||
|
const CWrapper = struct {
|
||||||
|
pub fn monitorCallbackWrapper(monitor: ?*c.GLFWmonitor, event: c_int) callconv(.C) void {
|
||||||
|
@call(.always_inline, user_callback, .{
|
||||||
|
Monitor{ .handle = monitor.? },
|
||||||
|
@as(Event, @enumFromInt(event)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c.glfwSetMonitorCallback(CWrapper.monitorCallbackWrapper) != null) return;
|
||||||
|
} else {
|
||||||
|
if (c.glfwSetMonitorCallback(null) != null) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getAll" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
const monitors = try getAll(allocator);
|
||||||
|
defer allocator.free(monitors);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getPrimary" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = getPrimary();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getPos" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getPos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getWorkarea" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getWorkarea();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getPhysicalSize" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getPhysicalSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getContentScale" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getContentScale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getName" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "userPointer" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
var p = m.getUserPointer(u32);
|
||||||
|
try testing.expect(p == null);
|
||||||
|
var x: u32 = 5;
|
||||||
|
m.setUserPointer(u32, &x);
|
||||||
|
p = m.getUserPointer(u32);
|
||||||
|
try testing.expectEqual(p.?.*, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "setCallback" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
setCallback(struct {
|
||||||
|
fn callback(monitor: Monitor, event: Event) void {
|
||||||
|
_ = monitor;
|
||||||
|
_ = event;
|
||||||
|
}
|
||||||
|
}.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getVideoModes" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
const modes_maybe = try m.getVideoModes(allocator);
|
||||||
|
if (modes_maybe) |modes| {
|
||||||
|
defer allocator.free(modes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getVideoMode" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
_ = m.getVideoMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "set_getGammaRamp" {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const monitor = getPrimary();
|
||||||
|
if (monitor) |m| {
|
||||||
|
if (m.getGammaRamp()) |ramp| {
|
||||||
|
// Set it to the exact same value; if we do otherwise an our tests fail it wouldn't call
|
||||||
|
// terminate and our made-up gamma ramp would get stuck.
|
||||||
|
m.setGammaRamp(ramp);
|
||||||
|
|
||||||
|
// technically not needed here / noop because GLFW owns this gamma ramp.
|
||||||
|
defer ramp.deinit(allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
//! Monitor video modes and related functions
|
||||||
|
//!
|
||||||
|
//! see also: glfw.Monitor.getVideoMode
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const VideoMode = @This();
|
||||||
|
|
||||||
|
handle: c.GLFWvidmode,
|
||||||
|
|
||||||
|
/// Returns the width of the video mode, in screen coordinates.
|
||||||
|
pub inline fn getWidth(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the height of the video mode, in screen coordinates.
|
||||||
|
pub inline fn getHeight(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the bit depth of the red channel of the video mode.
|
||||||
|
pub inline fn getRedBits(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.redBits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the bit depth of the green channel of the video mode.
|
||||||
|
pub inline fn getGreenBits(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.greenBits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the bit depth of the blue channel of the video mode.
|
||||||
|
pub inline fn getBlueBits(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.blueBits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the refresh rate of the video mode, in Hz.
|
||||||
|
pub inline fn getRefreshRate(self: VideoMode) u32 {
|
||||||
|
return @as(u32, @intCast(self.handle.refreshRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getters" {
|
||||||
|
const x = std.mem.zeroes(VideoMode);
|
||||||
|
_ = x.getWidth();
|
||||||
|
_ = x.getHeight();
|
||||||
|
_ = x.getRedBits();
|
||||||
|
_ = x.getGreenBits();
|
||||||
|
_ = x.getBlueBits();
|
||||||
|
_ = x.getRefreshRate();
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,13 @@
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// Key and button actions
|
||||||
|
pub const Action = enum(c_int) {
|
||||||
|
/// The key or mouse button was released.
|
||||||
|
release = c.GLFW_RELEASE,
|
||||||
|
|
||||||
|
/// The key or mouse button was pressed.
|
||||||
|
press = c.GLFW_PRESS,
|
||||||
|
|
||||||
|
/// The key was held down until it repeated.
|
||||||
|
repeat = c.GLFW_REPEAT,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
// TODO: implement custom allocator support
|
||||||
|
|
||||||
|
// /*! @brief
|
||||||
|
// *
|
||||||
|
// * @sa @ref init_allocator
|
||||||
|
// * @sa @ref glfwInitAllocator
|
||||||
|
// *
|
||||||
|
// * @since Added in version 3.4.
|
||||||
|
// *
|
||||||
|
// * @ingroup init
|
||||||
|
// */
|
||||||
|
// typedef struct GLFWallocator
|
||||||
|
// {
|
||||||
|
// GLFWallocatefun allocate;
|
||||||
|
// GLFWreallocatefun reallocate;
|
||||||
|
// GLFWdeallocatefun deallocate;
|
||||||
|
// void* user;
|
||||||
|
// } GLFWallocator;
|
||||||
|
|
||||||
|
// /*! @brief 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:
|
||||||
|
// * @code
|
||||||
|
// * void* function_name(size_t size, void* user)
|
||||||
|
// * @endcode
|
||||||
|
// *
|
||||||
|
// * This function must return either a memory block at least `size` bytes long,
|
||||||
|
// * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
|
||||||
|
// * failures gracefully yet.
|
||||||
|
// *
|
||||||
|
// * This function may be called during @ref glfwInit but before the library is
|
||||||
|
// * flagged as initialized, as well as during @ref glfwTerminate after the
|
||||||
|
// * library is no longer flagged as initialized.
|
||||||
|
// *
|
||||||
|
// * Any memory allocated by this function will be deallocated during library
|
||||||
|
// * termination or earlier.
|
||||||
|
// *
|
||||||
|
// * The size will always be greater than zero. Allocations of size zero are filtered out
|
||||||
|
// * before reaching the custom allocator.
|
||||||
|
// *
|
||||||
|
// * @param[in] size The minimum size, in bytes, of the memory block.
|
||||||
|
// * @param[in] user The user-defined pointer from the allocator.
|
||||||
|
// * @return The address of the newly allocated memory block, or `NULL` if an
|
||||||
|
// * error occurred.
|
||||||
|
// *
|
||||||
|
// * @pointer_lifetime The returned memory block must be valid at least until it
|
||||||
|
// * is deallocated.
|
||||||
|
// *
|
||||||
|
// * @reentrancy This function should not call any GLFW function.
|
||||||
|
// *
|
||||||
|
// * @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||||
|
// *
|
||||||
|
// * @sa @ref init_allocator
|
||||||
|
// * @sa @ref GLFWallocator
|
||||||
|
// *
|
||||||
|
// * @since Added in version 3.4.
|
||||||
|
// *
|
||||||
|
// * @ingroup init
|
||||||
|
// */
|
||||||
|
// typedef void* (* GLFWallocatefun)(size_t size, void* user);
|
||||||
|
|
||||||
|
// /*! @brief The function pointer type for memory reallocation callbacks.
|
||||||
|
// *
|
||||||
|
// * This is the function pointer type for memory reallocation callbacks.
|
||||||
|
// * A memory reallocation callback function has the following signature:
|
||||||
|
// * @code
|
||||||
|
// * void* function_name(void* block, size_t size, void* user)
|
||||||
|
// * @endcode
|
||||||
|
// *
|
||||||
|
// * This function must return a memory block at least `size` bytes long, or
|
||||||
|
// * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
|
||||||
|
// * failures gracefully yet.
|
||||||
|
// *
|
||||||
|
// * This function may be called during @ref glfwInit but before the library is
|
||||||
|
// * flagged as initialized, as well as during @ref glfwTerminate after the
|
||||||
|
// * library is no longer flagged as initialized.
|
||||||
|
// *
|
||||||
|
// * Any memory allocated by this function will be deallocated during library
|
||||||
|
// * termination or earlier.
|
||||||
|
// *
|
||||||
|
// * The block address will never be `NULL` and the size will always be greater than zero.
|
||||||
|
// * Reallocations of a block to size zero are converted into deallocations. Reallocations
|
||||||
|
// * of `NULL` to a non-zero size are converted into regular allocations.
|
||||||
|
// *
|
||||||
|
// * @param[in] block The address of the memory block to reallocate.
|
||||||
|
// * @param[in] size The new minimum size, in bytes, of the memory block.
|
||||||
|
// * @param[in] user The user-defined pointer from the allocator.
|
||||||
|
// * @return The address of the newly allocated or resized memory block, or
|
||||||
|
// * `NULL` if an error occurred.
|
||||||
|
// *
|
||||||
|
// * @pointer_lifetime The returned memory block must be valid at least until it
|
||||||
|
// * is deallocated.
|
||||||
|
// *
|
||||||
|
// * @reentrancy This function should not call any GLFW function.
|
||||||
|
// *
|
||||||
|
// * @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||||
|
// *
|
||||||
|
// * @sa @ref init_allocator
|
||||||
|
// * @sa @ref GLFWallocator
|
||||||
|
// *
|
||||||
|
// * @since Added in version 3.4.
|
||||||
|
// *
|
||||||
|
// * @ingroup init
|
||||||
|
// */
|
||||||
|
// typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user);
|
||||||
|
|
||||||
|
// /*! @brief The function pointer type for memory deallocation callbacks.
|
||||||
|
// *
|
||||||
|
// * This is the function pointer type for memory deallocation callbacks.
|
||||||
|
// * A memory deallocation callback function has the following signature:
|
||||||
|
// * @code
|
||||||
|
// * void function_name(void* block, void* user)
|
||||||
|
// * @endcode
|
||||||
|
// *
|
||||||
|
// * This function may deallocate the specified memory block. This memory block
|
||||||
|
// * will have been allocated with the same allocator.
|
||||||
|
// *
|
||||||
|
// * This function may be called during @ref glfwInit but before the library is
|
||||||
|
// * flagged as initialized, as well as during @ref glfwTerminate after the
|
||||||
|
// * library is no longer flagged as initialized.
|
||||||
|
// *
|
||||||
|
// * The block address will never be `NULL`. Deallocations of `NULL` are filtered out
|
||||||
|
// * before reaching the custom allocator.
|
||||||
|
// *
|
||||||
|
// * @param[in] block The address of the memory block to deallocate.
|
||||||
|
// * @param[in] user The user-defined pointer from the allocator.
|
||||||
|
// *
|
||||||
|
// * @pointer_lifetime The specified memory block will not be accessed by GLFW
|
||||||
|
// * after this function is called.
|
||||||
|
// *
|
||||||
|
// * @reentrancy This function should not call any GLFW function.
|
||||||
|
// *
|
||||||
|
// * @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||||
|
// *
|
||||||
|
// * @sa @ref init_allocator
|
||||||
|
// * @sa @ref GLFWallocator
|
||||||
|
// *
|
||||||
|
// * @since Added in version 3.4.
|
||||||
|
// *
|
||||||
|
// * @ingroup init
|
||||||
|
// */
|
||||||
|
// typedef void (* GLFWdeallocatefun)(void* block, void* user);
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const apple_sdk = @import("apple_sdk");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) !void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const module = b.addModule("glfw", .{
|
||||||
|
.root_source_file = b.path("main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const lib = try buildLib(b, module, .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const test_exe: ?*std.Build.Step.Compile = if (target.query.isNative()) exe: {
|
||||||
|
const exe = b.addTest(.{
|
||||||
|
.name = "test",
|
||||||
|
.root_source_file = b.path("main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
if (target.result.os.tag.isDarwin()) {
|
||||||
|
try apple_sdk.addPaths(b, exe.root_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tests_run = b.addRunArtifact(exe);
|
||||||
|
const test_step = b.step("test", "Run tests");
|
||||||
|
test_step.dependOn(&tests_run.step);
|
||||||
|
|
||||||
|
// Uncomment this if we're debugging tests
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
break :exe exe;
|
||||||
|
} else null;
|
||||||
|
|
||||||
|
if (b.systemIntegrationOption("glfw3", .{})) {
|
||||||
|
module.linkSystemLibrary("glfw3", dynamic_link_opts);
|
||||||
|
if (test_exe) |exe| exe.linkSystemLibrary2("glfw3", dynamic_link_opts);
|
||||||
|
} else {
|
||||||
|
module.linkLibrary(lib);
|
||||||
|
b.installArtifact(lib);
|
||||||
|
if (test_exe) |exe| exe.linkLibrary(lib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buildLib(
|
||||||
|
b: *std.Build,
|
||||||
|
module: *std.Build.Module,
|
||||||
|
options: anytype,
|
||||||
|
) !*std.Build.Step.Compile {
|
||||||
|
const target = options.target;
|
||||||
|
const optimize = options.optimize;
|
||||||
|
|
||||||
|
const use_x11 = b.option(
|
||||||
|
bool,
|
||||||
|
"x11",
|
||||||
|
"Build with X11. Only useful on Linux",
|
||||||
|
) orelse true;
|
||||||
|
const use_wl = b.option(
|
||||||
|
bool,
|
||||||
|
"wayland",
|
||||||
|
"Build with Wayland. Only useful on Linux",
|
||||||
|
) orelse true;
|
||||||
|
|
||||||
|
const use_opengl = b.option(
|
||||||
|
bool,
|
||||||
|
"opengl",
|
||||||
|
"Build with OpenGL; deprecated on MacOS",
|
||||||
|
) orelse false;
|
||||||
|
const use_gles = b.option(
|
||||||
|
bool,
|
||||||
|
"gles",
|
||||||
|
"Build with GLES; not supported on MacOS",
|
||||||
|
) orelse false;
|
||||||
|
const use_metal = b.option(
|
||||||
|
bool,
|
||||||
|
"metal",
|
||||||
|
"Build with Metal; only supported on MacOS",
|
||||||
|
) orelse true;
|
||||||
|
|
||||||
|
const lib = b.addStaticLibrary(.{
|
||||||
|
.name = "glfw",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
lib.linkLibC();
|
||||||
|
|
||||||
|
const upstream = b.lazyDependency("glfw", .{}) orelse return lib;
|
||||||
|
lib.addIncludePath(upstream.path("include"));
|
||||||
|
module.addIncludePath(upstream.path("include"));
|
||||||
|
lib.installHeadersDirectory(upstream.path("include/GLFW"), "GLFW", .{});
|
||||||
|
|
||||||
|
switch (target.result.os.tag) {
|
||||||
|
.windows => {
|
||||||
|
lib.linkSystemLibrary("gdi32");
|
||||||
|
lib.linkSystemLibrary("user32");
|
||||||
|
lib.linkSystemLibrary("shell32");
|
||||||
|
|
||||||
|
if (use_opengl) {
|
||||||
|
lib.linkSystemLibrary("opengl32");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_gles) {
|
||||||
|
lib.linkSystemLibrary("GLESv3");
|
||||||
|
}
|
||||||
|
|
||||||
|
const flags = [_][]const u8{"-D_GLFW_WIN32"};
|
||||||
|
lib.addCSourceFiles(.{
|
||||||
|
.root = upstream.path(""),
|
||||||
|
.files = &base_sources,
|
||||||
|
.flags = &flags,
|
||||||
|
});
|
||||||
|
lib.addCSourceFiles(.{
|
||||||
|
.root = upstream.path(""),
|
||||||
|
.files = &windows_sources,
|
||||||
|
.flags = &flags,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
.macos => {
|
||||||
|
try apple_sdk.addPaths(b, lib.root_module);
|
||||||
|
try apple_sdk.addPaths(b, module);
|
||||||
|
|
||||||
|
// Transitive dependencies, explicit linkage of these works around
|
||||||
|
// ziglang/zig#17130
|
||||||
|
lib.linkFramework("CFNetwork");
|
||||||
|
lib.linkFramework("ApplicationServices");
|
||||||
|
lib.linkFramework("ColorSync");
|
||||||
|
lib.linkFramework("CoreText");
|
||||||
|
lib.linkFramework("ImageIO");
|
||||||
|
|
||||||
|
// Direct dependencies
|
||||||
|
lib.linkSystemLibrary("objc");
|
||||||
|
lib.linkFramework("IOKit");
|
||||||
|
lib.linkFramework("CoreFoundation");
|
||||||
|
lib.linkFramework("AppKit");
|
||||||
|
lib.linkFramework("CoreServices");
|
||||||
|
lib.linkFramework("CoreGraphics");
|
||||||
|
lib.linkFramework("Foundation");
|
||||||
|
|
||||||
|
if (use_metal) {
|
||||||
|
lib.linkFramework("Metal");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_opengl) {
|
||||||
|
lib.linkFramework("OpenGL");
|
||||||
|
}
|
||||||
|
|
||||||
|
const flags = [_][]const u8{"-D_GLFW_COCOA"};
|
||||||
|
lib.addCSourceFiles(.{
|
||||||
|
.root = upstream.path(""),
|
||||||
|
.files = &base_sources,
|
||||||
|
.flags = &flags,
|
||||||
|
});
|
||||||
|
lib.addCSourceFiles(.{
|
||||||
|
.root = upstream.path(""),
|
||||||
|
.files = &macos_sources,
|
||||||
|
.flags = &flags,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// everything that isn't windows or mac is linux :P
|
||||||
|
else => {
|
||||||
|
var sources = std.BoundedArray([]const u8, 64).init(0) catch unreachable;
|
||||||
|
var flags = std.BoundedArray([]const u8, 16).init(0) catch unreachable;
|
||||||
|
|
||||||
|
sources.appendSlice(&base_sources) catch unreachable;
|
||||||
|
sources.appendSlice(&linux_sources) catch unreachable;
|
||||||
|
|
||||||
|
if (use_x11) {
|
||||||
|
lib.linkSystemLibrary2("X11", dynamic_link_opts);
|
||||||
|
lib.linkSystemLibrary2("xkbcommon", dynamic_link_opts);
|
||||||
|
sources.appendSlice(&linux_x11_sources) catch unreachable;
|
||||||
|
flags.append("-D_GLFW_X11") catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_wl) {
|
||||||
|
lib.linkSystemLibrary2("wayland-client", dynamic_link_opts);
|
||||||
|
|
||||||
|
lib.root_module.addCMacro("WL_MARSHAL_FLAG_DESTROY", "1");
|
||||||
|
lib.addIncludePath(b.path("wayland-headers"));
|
||||||
|
|
||||||
|
sources.appendSlice(&linux_wl_sources) catch unreachable;
|
||||||
|
flags.append("-D_GLFW_WAYLAND") catch unreachable;
|
||||||
|
flags.append("-Wno-implicit-function-declaration") catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
lib.addCSourceFiles(.{
|
||||||
|
.root = upstream.path(""),
|
||||||
|
.files = sources.slice(),
|
||||||
|
.flags = flags.slice(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For dynamic linking, we prefer dynamic linking and to search by
|
||||||
|
// mode first. Mode first will search all paths for a dynamic library
|
||||||
|
// before falling back to static.
|
||||||
|
const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{
|
||||||
|
.preferred_link_mode = .dynamic,
|
||||||
|
.search_strategy = .mode_first,
|
||||||
|
};
|
||||||
|
|
||||||
|
const base_sources = [_][]const u8{
|
||||||
|
"src/context.c",
|
||||||
|
"src/egl_context.c",
|
||||||
|
"src/init.c",
|
||||||
|
"src/input.c",
|
||||||
|
"src/monitor.c",
|
||||||
|
"src/null_init.c",
|
||||||
|
"src/null_joystick.c",
|
||||||
|
"src/null_monitor.c",
|
||||||
|
"src/null_window.c",
|
||||||
|
"src/osmesa_context.c",
|
||||||
|
"src/platform.c",
|
||||||
|
"src/vulkan.c",
|
||||||
|
"src/window.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const linux_sources = [_][]const u8{
|
||||||
|
"src/linux_joystick.c",
|
||||||
|
"src/posix_module.c",
|
||||||
|
"src/posix_poll.c",
|
||||||
|
"src/posix_thread.c",
|
||||||
|
"src/posix_time.c",
|
||||||
|
"src/xkb_unicode.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const linux_wl_sources = [_][]const u8{
|
||||||
|
"src/wl_init.c",
|
||||||
|
"src/wl_monitor.c",
|
||||||
|
"src/wl_window.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const linux_x11_sources = [_][]const u8{
|
||||||
|
"src/glx_context.c",
|
||||||
|
"src/x11_init.c",
|
||||||
|
"src/x11_monitor.c",
|
||||||
|
"src/x11_window.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const windows_sources = [_][]const u8{
|
||||||
|
"src/wgl_context.c",
|
||||||
|
"src/win32_init.c",
|
||||||
|
"src/win32_joystick.c",
|
||||||
|
"src/win32_module.c",
|
||||||
|
"src/win32_monitor.c",
|
||||||
|
"src/win32_thread.c",
|
||||||
|
"src/win32_time.c",
|
||||||
|
"src/win32_window.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const macos_sources = [_][]const u8{
|
||||||
|
// C sources
|
||||||
|
"src/cocoa_time.c",
|
||||||
|
"src/posix_module.c",
|
||||||
|
"src/posix_thread.c",
|
||||||
|
|
||||||
|
// ObjC sources
|
||||||
|
"src/cocoa_init.m",
|
||||||
|
"src/cocoa_joystick.m",
|
||||||
|
"src/cocoa_monitor.m",
|
||||||
|
"src/cocoa_window.m",
|
||||||
|
"src/nsgl_context.m",
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
.{
|
||||||
|
.name = .glfw,
|
||||||
|
.version = "3.4.0",
|
||||||
|
.fingerprint = 0x3bbe0a5c667e2c62,
|
||||||
|
.paths = .{""},
|
||||||
|
.dependencies = .{
|
||||||
|
.glfw = .{
|
||||||
|
.url = "https://github.com/glfw/glfw/archive/73948e6c0f15b1053cf74b7c4e6b04fd36e97e29.zip",
|
||||||
|
.hash = "N-V-__8AADTkRwBjUvVwTLOnV96QhN0J5Nyg7YzvnISe-Eax",
|
||||||
|
.lazy = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
pub const c = @cImport({
|
||||||
|
// Must be uncommented for vulkan.zig to work
|
||||||
|
// @cDefine("GLFW_INCLUDE_VULKAN", "1");
|
||||||
|
@cDefine("GLFW_INCLUDE_NONE", "1");
|
||||||
|
@cInclude("GLFW/glfw3.h");
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// Sets the clipboard to the specified string.
|
||||||
|
///
|
||||||
|
/// This function sets the system clipboard to the specified, UTF-8 encoded string.
|
||||||
|
///
|
||||||
|
/// @param[in] string A UTF-8 encoded string.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The specified string is copied before this function returns.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: clipboard, glfwGetClipboardString
|
||||||
|
pub inline fn setClipboardString(value: [*:0]const u8) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwSetClipboardString(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the contents of the clipboard as a string.
|
||||||
|
///
|
||||||
|
/// This function returns the contents of the system clipboard, if it contains or is convertible to
|
||||||
|
/// a UTF-8 encoded string. If the clipboard is empty or if its contents cannot be converted,
|
||||||
|
/// glfw.ErrorCode.FormatUnavailable is returned.
|
||||||
|
///
|
||||||
|
/// @return The contents of the clipboard as a UTF-8 encoded string.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.FormatUnavailable and glfw.ErrorCode.PlatformError.
|
||||||
|
/// null is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// @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 glfw.getClipboardString or glfw.setClipboardString
|
||||||
|
/// or until the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: clipboard, glfwSetClipboardString
|
||||||
|
pub inline fn getClipboardString() ?[:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetClipboardString(null)) |c_str| return std.mem.span(@as([*:0]const u8, @ptrCast(c_str)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "setClipboardString" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
glfw.setClipboardString("hello mach");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getClipboardString" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.getClipboardString();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,338 @@
|
||||||
|
//! Errors
|
||||||
|
|
||||||
|
const testing = @import("std").testing;
|
||||||
|
const mem = @import("std").mem;
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// Errors that GLFW can produce.
|
||||||
|
pub const ErrorCode = error{
|
||||||
|
/// GLFW has not been initialized.
|
||||||
|
///
|
||||||
|
/// This occurs if a GLFW function was called that must not be called unless the library is
|
||||||
|
/// initialized.
|
||||||
|
NotInitialized,
|
||||||
|
|
||||||
|
/// No context is current for this thread.
|
||||||
|
///
|
||||||
|
/// This occurs if a GLFW function was called that needs and operates on the current OpenGL or
|
||||||
|
/// OpenGL ES context but no context is current on the calling thread. One such function is
|
||||||
|
/// glfw.SwapInterval.
|
||||||
|
NoCurrentContext,
|
||||||
|
|
||||||
|
/// One of the arguments to the function was an invalid enum value.
|
||||||
|
///
|
||||||
|
/// One of the arguments to the function was an invalid enum value, for example requesting
|
||||||
|
/// glfw.red_bits with glfw.getWindowAttrib.
|
||||||
|
InvalidEnum,
|
||||||
|
|
||||||
|
/// One of the arguments to the function was an invalid value.
|
||||||
|
///
|
||||||
|
/// One of the arguments to the function was an invalid value, for example requesting a
|
||||||
|
/// non-existent OpenGL or OpenGL ES version like 2.7.
|
||||||
|
///
|
||||||
|
/// Requesting a valid but unavailable OpenGL or OpenGL ES version will instead result in a
|
||||||
|
/// glfw.ErrorCode.VersionUnavailable error.
|
||||||
|
InvalidValue,
|
||||||
|
|
||||||
|
/// A memory allocation failed.
|
||||||
|
OutOfMemory,
|
||||||
|
|
||||||
|
/// GLFW could not find support for the requested API on the system.
|
||||||
|
///
|
||||||
|
/// The installed graphics driver does not support the requested 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 supports
|
||||||
|
/// OpenGL ES via EGL, while Nvidia and Intel only support it via a WGL or GLX extension. macOS
|
||||||
|
/// does not provide OpenGL ES at all. The Mesa EGL, OpenGL and OpenGL ES libraries do not
|
||||||
|
/// interface with the Nvidia binary driver. Older graphics drivers do not support Vulkan.
|
||||||
|
APIUnavailable,
|
||||||
|
|
||||||
|
/// The requested OpenGL or OpenGL ES version (including any requested context or framebuffer
|
||||||
|
/// hints) is not available on this machine.
|
||||||
|
///
|
||||||
|
/// The machine does not support your requirements. If your application is sufficiently
|
||||||
|
/// flexible, downgrade your requirements and try again. Otherwise, inform the user that their
|
||||||
|
/// machine does not match your requirements.
|
||||||
|
///
|
||||||
|
/// Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 comes out
|
||||||
|
/// before the 4.x series gets that far, also fail with this error and not glfw.ErrorCode.InvalidValue,
|
||||||
|
/// because GLFW cannot know what future versions will exist.
|
||||||
|
VersionUnavailable,
|
||||||
|
|
||||||
|
/// A platform-specific error occurred that does not match any of the more specific categories.
|
||||||
|
///
|
||||||
|
/// A bug or configuration error in GLFW, the underlying operating system or its drivers, or a
|
||||||
|
/// lack of required resources. Report the issue to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||||
|
PlatformError,
|
||||||
|
|
||||||
|
/// The requested format is not supported or available.
|
||||||
|
///
|
||||||
|
/// If emitted during window creation, the requested pixel format is not supported.
|
||||||
|
///
|
||||||
|
/// If emitted when querying the clipboard, the contents of the clipboard could not be
|
||||||
|
/// converted to the requested format.
|
||||||
|
///
|
||||||
|
/// If emitted during window creation, one or more hard constraints did not match any of the
|
||||||
|
/// available pixel formats. If your application is sufficiently flexible, downgrade your
|
||||||
|
/// requirements and try again. Otherwise, inform the user that their machine does not match
|
||||||
|
/// your requirements.
|
||||||
|
///
|
||||||
|
/// If emitted when querying the clipboard, ignore the error or report it to the user, as
|
||||||
|
/// appropriate.
|
||||||
|
FormatUnavailable,
|
||||||
|
|
||||||
|
/// The specified window does not have an OpenGL or OpenGL ES context.
|
||||||
|
///
|
||||||
|
/// A window that does not have an OpenGL or OpenGL ES context was passed to a function that
|
||||||
|
/// requires it to have one.
|
||||||
|
NoWindowContext,
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
CursorUnavailable,
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
FeatureUnavailable,
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
FeatureUnimplemented,
|
||||||
|
|
||||||
|
/// Platform unavailable or no matching platform was found.
|
||||||
|
///
|
||||||
|
/// If emitted during initialization, no matching platform was found. If glfw.InitHint.platform
|
||||||
|
/// is set to `.any_platform`, GLFW could not detect any of the platforms supported by this
|
||||||
|
/// library binary, except for the Null platform. If 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 glfw.platformSupported to
|
||||||
|
/// check whether a specific platform is supported by a library binary.
|
||||||
|
///
|
||||||
|
PlatformUnavailable,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An error produced by GLFW and the description associated with it.
|
||||||
|
pub const Error = struct {
|
||||||
|
error_code: ErrorCode,
|
||||||
|
description: [:0]const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn convertError(e: c_int) ErrorCode!void {
|
||||||
|
return switch (e) {
|
||||||
|
c.GLFW_NO_ERROR => {},
|
||||||
|
c.GLFW_NOT_INITIALIZED => ErrorCode.NotInitialized,
|
||||||
|
c.GLFW_NO_CURRENT_CONTEXT => ErrorCode.NoCurrentContext,
|
||||||
|
c.GLFW_INVALID_ENUM => ErrorCode.InvalidEnum,
|
||||||
|
c.GLFW_INVALID_VALUE => ErrorCode.InvalidValue,
|
||||||
|
c.GLFW_OUT_OF_MEMORY => ErrorCode.OutOfMemory,
|
||||||
|
c.GLFW_API_UNAVAILABLE => ErrorCode.APIUnavailable,
|
||||||
|
c.GLFW_VERSION_UNAVAILABLE => ErrorCode.VersionUnavailable,
|
||||||
|
c.GLFW_PLATFORM_ERROR => ErrorCode.PlatformError,
|
||||||
|
c.GLFW_FORMAT_UNAVAILABLE => ErrorCode.FormatUnavailable,
|
||||||
|
c.GLFW_NO_WINDOW_CONTEXT => ErrorCode.NoWindowContext,
|
||||||
|
c.GLFW_CURSOR_UNAVAILABLE => ErrorCode.CursorUnavailable,
|
||||||
|
c.GLFW_FEATURE_UNAVAILABLE => ErrorCode.FeatureUnavailable,
|
||||||
|
c.GLFW_FEATURE_UNIMPLEMENTED => ErrorCode.FeatureUnimplemented,
|
||||||
|
c.GLFW_PLATFORM_UNAVAILABLE => ErrorCode.PlatformUnavailable,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the last error and the error description pointer for the calling thread. Does nothing if
|
||||||
|
/// no error has occurred since the last call.
|
||||||
|
///
|
||||||
|
/// @remark This function may be called before @ref glfwInit.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn clearError() void {
|
||||||
|
_ = c.glfwGetError(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns and clears the last error for the calling thread.
|
||||||
|
///
|
||||||
|
/// This function returns and clears the error code of the last error that occurred on the calling
|
||||||
|
/// thread, along with a UTF-8 encoded human-readable description of it. If no error has occurred
|
||||||
|
/// since the last call, it returns GLFW_NO_ERROR (zero) and the description pointer is set to
|
||||||
|
/// `NULL`.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is guaranteed to be valid only until the next error occurs or the library is
|
||||||
|
/// terminated.
|
||||||
|
///
|
||||||
|
/// @remark This function may be called before @ref glfwInit.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn getError() ?Error {
|
||||||
|
var desc: [*c]const u8 = null;
|
||||||
|
convertError(c.glfwGetError(&desc)) catch |error_code| {
|
||||||
|
return .{
|
||||||
|
.error_code = error_code,
|
||||||
|
.description = mem.sliceTo(desc, 0),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn mustGetError() Error {
|
||||||
|
return getError() orelse {
|
||||||
|
@panic("glfw: mustGetError called but no error is present");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns and clears the last error for the calling thread.
|
||||||
|
///
|
||||||
|
/// This function returns and clears the error code of the last error that occurred on the calling
|
||||||
|
/// thread. If no error has occurred since the last call, it returns GLFW_NO_ERROR (zero).
|
||||||
|
///
|
||||||
|
/// @return The last error code for the calling thread, or @ref GLFW_NO_ERROR (zero).
|
||||||
|
///
|
||||||
|
/// @remark This function may be called before @ref glfwInit.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn getErrorCode() ErrorCode!void {
|
||||||
|
return convertError(c.glfwGetError(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns and clears the last error code for the calling thread. If no error is present, this
|
||||||
|
/// function panics.
|
||||||
|
pub inline fn mustGetErrorCode() ErrorCode {
|
||||||
|
try getErrorCode();
|
||||||
|
@panic("glfw: mustGetErrorCode called but no error is present");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns and clears the last error description for the calling thread.
|
||||||
|
///
|
||||||
|
/// This function returns a UTF-8 encoded human-readable description of the last error that occured
|
||||||
|
/// on the calling thread. If no error has occurred since the last call, it returns null.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is guaranteed to be valid only until the next error occurs or the library is
|
||||||
|
/// terminated.
|
||||||
|
///
|
||||||
|
/// @remark This function may be called before @ref glfwInit.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn getErrorString() ?[:0]const u8 {
|
||||||
|
var desc: [*c]const u8 = null;
|
||||||
|
const error_code = c.glfwGetError(&desc);
|
||||||
|
if (error_code != c.GLFW_NO_ERROR) {
|
||||||
|
return mem.sliceTo(desc, 0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns and clears the last error description for the calling thread. If no error is present,
|
||||||
|
/// this function panics.
|
||||||
|
pub inline fn mustGetErrorString() [:0]const u8 {
|
||||||
|
return getErrorString() orelse {
|
||||||
|
@panic("glfw: mustGetErrorString called but no error is present");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the error callback.
|
||||||
|
///
|
||||||
|
/// This function sets the error callback, which is called with an error code
|
||||||
|
/// and a human-readable description each time a GLFW error occurs.
|
||||||
|
///
|
||||||
|
/// The error code is set before the callback is called. Calling @ref
|
||||||
|
/// glfwGetError from the error callback will return the same value as the error
|
||||||
|
/// code argument.
|
||||||
|
///
|
||||||
|
/// The error callback is called on the thread where the error occurred. If you
|
||||||
|
/// are using GLFW from multiple threads, your error callback needs to be
|
||||||
|
/// written accordingly.
|
||||||
|
///
|
||||||
|
/// Because the description string may have been generated specifically for that
|
||||||
|
/// error, it is not guaranteed to be valid after the callback has returned. If
|
||||||
|
/// you wish to use it after the callback returns, you need to make a copy.
|
||||||
|
///
|
||||||
|
/// Once set, the error callback remains set even after the library has been
|
||||||
|
/// terminated.
|
||||||
|
///
|
||||||
|
/// @param[in] callback The new callback, or `NULL` to remove the currently set
|
||||||
|
/// callback.
|
||||||
|
///
|
||||||
|
/// @callback_param `error_code` An error code. Future releases may add more error codes.
|
||||||
|
/// @callback_param `description` A UTF-8 encoded string describing the error.
|
||||||
|
///
|
||||||
|
/// @errors None.
|
||||||
|
///
|
||||||
|
/// @remark This function may be called before @ref glfwInit.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
pub fn setErrorCallback(comptime callback: ?fn (error_code: ErrorCode, description: [:0]const u8) void) void {
|
||||||
|
if (callback) |user_callback| {
|
||||||
|
const CWrapper = struct {
|
||||||
|
pub fn errorCallbackWrapper(err_int: c_int, c_description: [*c]const u8) callconv(.C) void {
|
||||||
|
convertError(err_int) catch |error_code| {
|
||||||
|
user_callback(error_code, mem.sliceTo(c_description, 0));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = c.glfwSetErrorCallback(CWrapper.errorCallbackWrapper);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = c.glfwSetErrorCallback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "set error callback" {
|
||||||
|
const TestStruct = struct {
|
||||||
|
pub fn callback(_: ErrorCode, _: [:0]const u8) void {}
|
||||||
|
};
|
||||||
|
setErrorCallback(TestStruct.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "error string" {
|
||||||
|
try testing.expect(getErrorString() == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "error code" {
|
||||||
|
try getErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "error code and string" {
|
||||||
|
try testing.expect(getError() == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "clear error" {
|
||||||
|
clearError();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// Gamepad axes.
|
||||||
|
///
|
||||||
|
/// See glfw.getGamepadState for how these are used.
|
||||||
|
pub const GamepadAxis = enum(c_int) {
|
||||||
|
left_x = c.GLFW_GAMEPAD_AXIS_LEFT_X,
|
||||||
|
left_y = c.GLFW_GAMEPAD_AXIS_LEFT_Y,
|
||||||
|
right_x = c.GLFW_GAMEPAD_AXIS_RIGHT_X,
|
||||||
|
right_y = c.GLFW_GAMEPAD_AXIS_RIGHT_Y,
|
||||||
|
left_trigger = c.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER,
|
||||||
|
right_trigger = c.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const last = GamepadAxis.right_trigger;
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// Gamepad buttons.
|
||||||
|
///
|
||||||
|
/// See glfw.getGamepadState for how these are used.
|
||||||
|
pub const GamepadButton = enum(c_int) {
|
||||||
|
a = c.GLFW_GAMEPAD_BUTTON_A,
|
||||||
|
b = c.GLFW_GAMEPAD_BUTTON_B,
|
||||||
|
x = c.GLFW_GAMEPAD_BUTTON_X,
|
||||||
|
y = c.GLFW_GAMEPAD_BUTTON_Y,
|
||||||
|
left_bumper = c.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER,
|
||||||
|
right_bumper = c.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER,
|
||||||
|
back = c.GLFW_GAMEPAD_BUTTON_BACK,
|
||||||
|
start = c.GLFW_GAMEPAD_BUTTON_START,
|
||||||
|
guide = c.GLFW_GAMEPAD_BUTTON_GUIDE,
|
||||||
|
left_thumb = c.GLFW_GAMEPAD_BUTTON_LEFT_THUMB,
|
||||||
|
right_thumb = c.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB,
|
||||||
|
dpad_up = c.GLFW_GAMEPAD_BUTTON_DPAD_UP,
|
||||||
|
dpad_right = c.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT,
|
||||||
|
dpad_down = c.GLFW_GAMEPAD_BUTTON_DPAD_DOWN,
|
||||||
|
dpad_left = c.GLFW_GAMEPAD_BUTTON_DPAD_LEFT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const last = GamepadButton.dpad_left;
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const cross = GamepadButton.a;
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const circle = GamepadButton.b;
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const square = GamepadButton.x;
|
||||||
|
|
||||||
|
/// Not in the GamepadAxis enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const triangle = GamepadButton.y;
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
// must be in sync with GLFW C constants in hat state group, search for "@defgroup hat_state Joystick hat states"
|
||||||
|
/// A bitmask of all Joystick hat states
|
||||||
|
///
|
||||||
|
/// See glfw.Joystick.getHats for how these are used.
|
||||||
|
pub const Hat = packed struct(u8) {
|
||||||
|
up: bool = false,
|
||||||
|
right: bool = false,
|
||||||
|
down: bool = false,
|
||||||
|
left: bool = false,
|
||||||
|
_padding: u4 = 0,
|
||||||
|
|
||||||
|
pub inline fn centered(self: Hat) bool {
|
||||||
|
return self.up == false and self.right == false and self.down == false and self.left == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn verifyIntType(comptime IntType: type) void {
|
||||||
|
comptime {
|
||||||
|
switch (@import("shims.zig").typeInfo(IntType)) {
|
||||||
|
.int => {},
|
||||||
|
else => @compileError("Int was not of int type"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn toInt(self: Hat, comptime IntType: type) IntType {
|
||||||
|
verifyIntType(IntType);
|
||||||
|
return @as(IntType, @intCast(@as(u8, @bitCast(self))));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn fromInt(flags: anytype) Hat {
|
||||||
|
verifyIntType(@TypeOf(flags));
|
||||||
|
return @as(Hat, @bitCast(@as(u8, @intCast(flags))));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Holds all GLFW hat values in their raw form.
|
||||||
|
pub const RawHat = struct {
|
||||||
|
pub const centered = c.GLFW_HAT_CENTERED;
|
||||||
|
pub const up = c.GLFW_HAT_UP;
|
||||||
|
pub const right = c.GLFW_HAT_RIGHT;
|
||||||
|
pub const down = c.GLFW_HAT_DOWN;
|
||||||
|
pub const left = c.GLFW_HAT_LEFT;
|
||||||
|
|
||||||
|
pub const right_up = right | up;
|
||||||
|
pub const right_down = right | down;
|
||||||
|
pub const left_up = left | up;
|
||||||
|
pub const left_down = left | down;
|
||||||
|
};
|
||||||
|
|
||||||
|
test "from int, single" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
try std.testing.expectEqual(Hat{
|
||||||
|
.up = true,
|
||||||
|
.right = false,
|
||||||
|
.down = false,
|
||||||
|
.left = false,
|
||||||
|
._padding = 0,
|
||||||
|
}, Hat.fromInt(RawHat.up));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "from int, multi" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
try std.testing.expectEqual(Hat{
|
||||||
|
.up = true,
|
||||||
|
.right = false,
|
||||||
|
.down = true,
|
||||||
|
.left = true,
|
||||||
|
._padding = 0,
|
||||||
|
}, Hat.fromInt(RawHat.up | RawHat.down | RawHat.left));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "to int, single" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
var v = Hat{
|
||||||
|
.up = true,
|
||||||
|
.right = false,
|
||||||
|
.down = false,
|
||||||
|
.left = false,
|
||||||
|
._padding = 0,
|
||||||
|
};
|
||||||
|
try std.testing.expectEqual(v.toInt(c_int), RawHat.up);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "to int, multi" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
var v = Hat{
|
||||||
|
.up = true,
|
||||||
|
.right = false,
|
||||||
|
.down = true,
|
||||||
|
.left = true,
|
||||||
|
._padding = 0,
|
||||||
|
};
|
||||||
|
try std.testing.expectEqual(v.toInt(c_int), RawHat.up | RawHat.down | RawHat.left);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const is_debug = builtin.mode == .Debug;
|
||||||
|
var glfw_initialized = if (is_debug) false else @as(void, {});
|
||||||
|
pub inline fn toggleInitialized() void {
|
||||||
|
if (is_debug) glfw_initialized = !glfw_initialized;
|
||||||
|
}
|
||||||
|
pub inline fn assertInitialized() void {
|
||||||
|
if (is_debug) std.debug.assert(glfw_initialized);
|
||||||
|
}
|
||||||
|
pub inline fn assumeInitialized() void {
|
||||||
|
if (is_debug) glfw_initialized = true;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
//! Keyboard key IDs.
|
||||||
|
//!
|
||||||
|
//! See glfw.setKeyCallback for how these are used.
|
||||||
|
//!
|
||||||
|
//! These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), but re-arranged to
|
||||||
|
//! map to 7-bit ASCII for printable keys (function keys are put in the 256+ range).
|
||||||
|
//!
|
||||||
|
//! The naming of the key codes follow these rules:
|
||||||
|
//!
|
||||||
|
//! - The US keyboard layout is used
|
||||||
|
//! - Names of printable alphanumeric characters are used (e.g. "a", "r", "three", etc.)
|
||||||
|
//! - For non-alphanumeric characters, Unicode:ish names are used (e.g. "comma", "left_bracket",
|
||||||
|
//! etc.). Note that some names do not correspond to the Unicode standard (usually for brevity)
|
||||||
|
//! - Keys that lack a clear US mapping are named "world_x"
|
||||||
|
//! - For non-printable keys, custom names are used (e.g. "F4", "backspace", etc.)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const cc = @import("c.zig").c;
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// enum containing all glfw keys
|
||||||
|
pub const Key = enum(c_int) {
|
||||||
|
/// The unknown key
|
||||||
|
unknown = cc.GLFW_KEY_UNKNOWN,
|
||||||
|
|
||||||
|
/// Printable keys
|
||||||
|
space = cc.GLFW_KEY_SPACE,
|
||||||
|
apostrophe = cc.GLFW_KEY_APOSTROPHE,
|
||||||
|
comma = cc.GLFW_KEY_COMMA,
|
||||||
|
minus = cc.GLFW_KEY_MINUS,
|
||||||
|
period = cc.GLFW_KEY_PERIOD,
|
||||||
|
slash = cc.GLFW_KEY_SLASH,
|
||||||
|
zero = cc.GLFW_KEY_0,
|
||||||
|
one = cc.GLFW_KEY_1,
|
||||||
|
two = cc.GLFW_KEY_2,
|
||||||
|
three = cc.GLFW_KEY_3,
|
||||||
|
four = cc.GLFW_KEY_4,
|
||||||
|
five = cc.GLFW_KEY_5,
|
||||||
|
six = cc.GLFW_KEY_6,
|
||||||
|
seven = cc.GLFW_KEY_7,
|
||||||
|
eight = cc.GLFW_KEY_8,
|
||||||
|
nine = cc.GLFW_KEY_9,
|
||||||
|
semicolon = cc.GLFW_KEY_SEMICOLON,
|
||||||
|
equal = cc.GLFW_KEY_EQUAL,
|
||||||
|
a = cc.GLFW_KEY_A,
|
||||||
|
b = cc.GLFW_KEY_B,
|
||||||
|
c = cc.GLFW_KEY_C,
|
||||||
|
d = cc.GLFW_KEY_D,
|
||||||
|
e = cc.GLFW_KEY_E,
|
||||||
|
f = cc.GLFW_KEY_F,
|
||||||
|
g = cc.GLFW_KEY_G,
|
||||||
|
h = cc.GLFW_KEY_H,
|
||||||
|
i = cc.GLFW_KEY_I,
|
||||||
|
j = cc.GLFW_KEY_J,
|
||||||
|
k = cc.GLFW_KEY_K,
|
||||||
|
l = cc.GLFW_KEY_L,
|
||||||
|
m = cc.GLFW_KEY_M,
|
||||||
|
n = cc.GLFW_KEY_N,
|
||||||
|
o = cc.GLFW_KEY_O,
|
||||||
|
p = cc.GLFW_KEY_P,
|
||||||
|
q = cc.GLFW_KEY_Q,
|
||||||
|
r = cc.GLFW_KEY_R,
|
||||||
|
s = cc.GLFW_KEY_S,
|
||||||
|
t = cc.GLFW_KEY_T,
|
||||||
|
u = cc.GLFW_KEY_U,
|
||||||
|
v = cc.GLFW_KEY_V,
|
||||||
|
w = cc.GLFW_KEY_W,
|
||||||
|
x = cc.GLFW_KEY_X,
|
||||||
|
y = cc.GLFW_KEY_Y,
|
||||||
|
z = cc.GLFW_KEY_Z,
|
||||||
|
left_bracket = cc.GLFW_KEY_LEFT_BRACKET,
|
||||||
|
backslash = cc.GLFW_KEY_BACKSLASH,
|
||||||
|
right_bracket = cc.GLFW_KEY_RIGHT_BRACKET,
|
||||||
|
grave_accent = cc.GLFW_KEY_GRAVE_ACCENT,
|
||||||
|
world_1 = cc.GLFW_KEY_WORLD_1, // non-US #1
|
||||||
|
world_2 = cc.GLFW_KEY_WORLD_2, // non-US #2
|
||||||
|
|
||||||
|
// Function keys
|
||||||
|
escape = cc.GLFW_KEY_ESCAPE,
|
||||||
|
enter = cc.GLFW_KEY_ENTER,
|
||||||
|
tab = cc.GLFW_KEY_TAB,
|
||||||
|
backspace = cc.GLFW_KEY_BACKSPACE,
|
||||||
|
insert = cc.GLFW_KEY_INSERT,
|
||||||
|
delete = cc.GLFW_KEY_DELETE,
|
||||||
|
right = cc.GLFW_KEY_RIGHT,
|
||||||
|
left = cc.GLFW_KEY_LEFT,
|
||||||
|
down = cc.GLFW_KEY_DOWN,
|
||||||
|
up = cc.GLFW_KEY_UP,
|
||||||
|
page_up = cc.GLFW_KEY_PAGE_UP,
|
||||||
|
page_down = cc.GLFW_KEY_PAGE_DOWN,
|
||||||
|
home = cc.GLFW_KEY_HOME,
|
||||||
|
end = cc.GLFW_KEY_END,
|
||||||
|
caps_lock = cc.GLFW_KEY_CAPS_LOCK,
|
||||||
|
scroll_lock = cc.GLFW_KEY_SCROLL_LOCK,
|
||||||
|
num_lock = cc.GLFW_KEY_NUM_LOCK,
|
||||||
|
print_screen = cc.GLFW_KEY_PRINT_SCREEN,
|
||||||
|
pause = cc.GLFW_KEY_PAUSE,
|
||||||
|
F1 = cc.GLFW_KEY_F1,
|
||||||
|
F2 = cc.GLFW_KEY_F2,
|
||||||
|
F3 = cc.GLFW_KEY_F3,
|
||||||
|
F4 = cc.GLFW_KEY_F4,
|
||||||
|
F5 = cc.GLFW_KEY_F5,
|
||||||
|
F6 = cc.GLFW_KEY_F6,
|
||||||
|
F7 = cc.GLFW_KEY_F7,
|
||||||
|
F8 = cc.GLFW_KEY_F8,
|
||||||
|
F9 = cc.GLFW_KEY_F9,
|
||||||
|
F10 = cc.GLFW_KEY_F10,
|
||||||
|
F11 = cc.GLFW_KEY_F11,
|
||||||
|
F12 = cc.GLFW_KEY_F12,
|
||||||
|
F13 = cc.GLFW_KEY_F13,
|
||||||
|
F14 = cc.GLFW_KEY_F14,
|
||||||
|
F15 = cc.GLFW_KEY_F15,
|
||||||
|
F16 = cc.GLFW_KEY_F16,
|
||||||
|
F17 = cc.GLFW_KEY_F17,
|
||||||
|
F18 = cc.GLFW_KEY_F18,
|
||||||
|
F19 = cc.GLFW_KEY_F19,
|
||||||
|
F20 = cc.GLFW_KEY_F20,
|
||||||
|
F21 = cc.GLFW_KEY_F21,
|
||||||
|
F22 = cc.GLFW_KEY_F22,
|
||||||
|
F23 = cc.GLFW_KEY_F23,
|
||||||
|
F24 = cc.GLFW_KEY_F24,
|
||||||
|
F25 = cc.GLFW_KEY_F25,
|
||||||
|
kp_0 = cc.GLFW_KEY_KP_0,
|
||||||
|
kp_1 = cc.GLFW_KEY_KP_1,
|
||||||
|
kp_2 = cc.GLFW_KEY_KP_2,
|
||||||
|
kp_3 = cc.GLFW_KEY_KP_3,
|
||||||
|
kp_4 = cc.GLFW_KEY_KP_4,
|
||||||
|
kp_5 = cc.GLFW_KEY_KP_5,
|
||||||
|
kp_6 = cc.GLFW_KEY_KP_6,
|
||||||
|
kp_7 = cc.GLFW_KEY_KP_7,
|
||||||
|
kp_8 = cc.GLFW_KEY_KP_8,
|
||||||
|
kp_9 = cc.GLFW_KEY_KP_9,
|
||||||
|
kp_decimal = cc.GLFW_KEY_KP_DECIMAL,
|
||||||
|
kp_divide = cc.GLFW_KEY_KP_DIVIDE,
|
||||||
|
kp_multiply = cc.GLFW_KEY_KP_MULTIPLY,
|
||||||
|
kp_subtract = cc.GLFW_KEY_KP_SUBTRACT,
|
||||||
|
kp_add = cc.GLFW_KEY_KP_ADD,
|
||||||
|
kp_enter = cc.GLFW_KEY_KP_ENTER,
|
||||||
|
kp_equal = cc.GLFW_KEY_KP_EQUAL,
|
||||||
|
left_shift = cc.GLFW_KEY_LEFT_SHIFT,
|
||||||
|
left_control = cc.GLFW_KEY_LEFT_CONTROL,
|
||||||
|
left_alt = cc.GLFW_KEY_LEFT_ALT,
|
||||||
|
left_super = cc.GLFW_KEY_LEFT_SUPER,
|
||||||
|
right_shift = cc.GLFW_KEY_RIGHT_SHIFT,
|
||||||
|
right_control = cc.GLFW_KEY_RIGHT_CONTROL,
|
||||||
|
right_alt = cc.GLFW_KEY_RIGHT_ALT,
|
||||||
|
right_super = cc.GLFW_KEY_RIGHT_SUPER,
|
||||||
|
menu = cc.GLFW_KEY_MENU,
|
||||||
|
|
||||||
|
pub inline fn last() Key {
|
||||||
|
return @as(Key, @enumFromInt(cc.GLFW_KEY_LAST));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the layout-specific name of the specified printable key.
|
||||||
|
///
|
||||||
|
/// This function returns the name of the specified printable key, encoded as UTF-8. This is
|
||||||
|
/// typically the character that key would produce without any modifier keys, intended for
|
||||||
|
/// displaying key bindings to the user. For dead keys, it is typically the diacritic it would add
|
||||||
|
/// to a character.
|
||||||
|
///
|
||||||
|
/// __Do not use this function__ for text input (see input_char). You will break text input for many
|
||||||
|
/// languages even if it happens to work for yours.
|
||||||
|
///
|
||||||
|
/// If the key is `glfw.key.unknown`, the scancode is used to identify the key, otherwise the
|
||||||
|
/// scancode is ignored. If you specify a non-printable key, or `glfw.key.unknown` and a scancode
|
||||||
|
/// that maps to a non-printable key, this function returns null but does not emit an error.
|
||||||
|
///
|
||||||
|
/// This behavior allows you to always pass in the arguments in the key callback (see input_key)
|
||||||
|
/// without modification.
|
||||||
|
///
|
||||||
|
/// The printable keys are:
|
||||||
|
///
|
||||||
|
/// - `glfw.Key.apostrophe`
|
||||||
|
/// - `glfw.Key.comma`
|
||||||
|
/// - `glfw.Key.minus`
|
||||||
|
/// - `glfw.Key.period`
|
||||||
|
/// - `glfw.Key.slash`
|
||||||
|
/// - `glfw.Key.semicolon`
|
||||||
|
/// - `glfw.Key.equal`
|
||||||
|
/// - `glfw.Key.left_bracket`
|
||||||
|
/// - `glfw.Key.right_bracket`
|
||||||
|
/// - `glfw.Key.backslash`
|
||||||
|
/// - `glfw.Key.world_1`
|
||||||
|
/// - `glfw.Key.world_2`
|
||||||
|
/// - `glfw.Key.0` to `glfw.key.9`
|
||||||
|
/// - `glfw.Key.a` to `glfw.key.z`
|
||||||
|
/// - `glfw.Key.kp_0` to `glfw.key.kp_9`
|
||||||
|
/// - `glfw.Key.kp_decimal`
|
||||||
|
/// - `glfw.Key.kp_divide`
|
||||||
|
/// - `glfw.Key.kp_multiply`
|
||||||
|
/// - `glfw.Key.kp_subtract`
|
||||||
|
/// - `glfw.Key.kp_add`
|
||||||
|
/// - `glfw.Key.kp_equal`
|
||||||
|
///
|
||||||
|
/// Names for printable keys depend on keyboard layout, while names for non-printable keys are the
|
||||||
|
/// same across layouts but depend on the application language and should be localized along with
|
||||||
|
/// other user interface text.
|
||||||
|
///
|
||||||
|
/// @param[in] key The key to query, or `glfw.key.unknown`.
|
||||||
|
/// @param[in] scancode The scancode of the key to query.
|
||||||
|
/// @return The UTF-8 encoded, layout-specific name of the key, or null.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
/// Also returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// The contents of the returned string may change when a keyboard layout change event is received.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: input_key_name
|
||||||
|
pub inline fn getName(self: Key, scancode: i32) ?[:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const name_opt = cc.glfwGetKeyName(@intFromEnum(self), @as(c_int, @intCast(scancode)));
|
||||||
|
return if (name_opt) |name|
|
||||||
|
std.mem.span(@as([*:0]const u8, @ptrCast(name)))
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the platform-specific scancode of the specified key.
|
||||||
|
///
|
||||||
|
/// This function returns the platform-specific scancode of the specified key.
|
||||||
|
///
|
||||||
|
/// If the key is `glfw.key.UNKNOWN` or does not exist on the keyboard this method will return `-1`.
|
||||||
|
///
|
||||||
|
/// @param[in] key Any named key (see keys).
|
||||||
|
/// @return The platform-specific scancode for the key.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.PlatformError.
|
||||||
|
/// Additionally returns -1 in the event of an error.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn getScancode(self: Key) i32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return cc.glfwGetKeyScancode(@intFromEnum(self));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "getName" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.Key.a.getName(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getScancode" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.Key.a.getScancode();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,586 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const key = @import("key.zig");
|
||||||
|
const errors = @import("errors.zig");
|
||||||
|
|
||||||
|
/// Possible value for various window hints, etc.
|
||||||
|
pub const dont_care = c.GLFW_DONT_CARE;
|
||||||
|
|
||||||
|
pub const getError = errors.getError;
|
||||||
|
pub const mustGetError = errors.mustGetError;
|
||||||
|
pub const getErrorCode = errors.getErrorCode;
|
||||||
|
pub const mustGetErrorCode = errors.mustGetErrorCode;
|
||||||
|
pub const getErrorString = errors.getErrorString;
|
||||||
|
pub const mustGetErrorString = errors.mustGetErrorString;
|
||||||
|
pub const setErrorCallback = errors.setErrorCallback;
|
||||||
|
pub const clearError = errors.clearError;
|
||||||
|
pub const ErrorCode = errors.ErrorCode;
|
||||||
|
pub const Error = errors.Error;
|
||||||
|
|
||||||
|
pub const Action = @import("action.zig").Action;
|
||||||
|
pub const GamepadAxis = @import("gamepad_axis.zig").GamepadAxis;
|
||||||
|
pub const GamepadButton = @import("gamepad_button.zig").GamepadButton;
|
||||||
|
pub const gamepad_axis = @import("gamepad_axis.zig");
|
||||||
|
pub const gamepad_button = @import("gamepad_button.zig");
|
||||||
|
pub const GammaRamp = @import("GammaRamp.zig");
|
||||||
|
pub const Image = @import("Image.zig");
|
||||||
|
pub const Joystick = @import("Joystick.zig");
|
||||||
|
pub const Monitor = @import("Monitor.zig");
|
||||||
|
pub const mouse_button = @import("mouse_button.zig");
|
||||||
|
pub const MouseButton = mouse_button.MouseButton;
|
||||||
|
pub const version = @import("version.zig");
|
||||||
|
pub const VideoMode = @import("VideoMode.zig");
|
||||||
|
pub const Window = @import("Window.zig");
|
||||||
|
pub const Cursor = @import("Cursor.zig");
|
||||||
|
pub const Native = @import("native.zig").Native;
|
||||||
|
pub const BackendOptions = @import("native.zig").BackendOptions;
|
||||||
|
pub const Key = key.Key;
|
||||||
|
pub const setClipboardString = @import("clipboard.zig").setClipboardString;
|
||||||
|
pub const getClipboardString = @import("clipboard.zig").getClipboardString;
|
||||||
|
pub const makeContextCurrent = @import("opengl.zig").makeContextCurrent;
|
||||||
|
pub const getCurrentContext = @import("opengl.zig").getCurrentContext;
|
||||||
|
pub const swapInterval = @import("opengl.zig").swapInterval;
|
||||||
|
pub const extensionSupported = @import("opengl.zig").extensionSupported;
|
||||||
|
pub const GLProc = @import("opengl.zig").GLProc;
|
||||||
|
pub const getProcAddress = @import("opengl.zig").getProcAddress;
|
||||||
|
pub const getTime = @import("time.zig").getTime;
|
||||||
|
pub const setTime = @import("time.zig").setTime;
|
||||||
|
pub const getTimerValue = @import("time.zig").getTimerValue;
|
||||||
|
pub const getTimerFrequency = @import("time.zig").getTimerFrequency;
|
||||||
|
pub const Hat = @import("hat.zig").Hat;
|
||||||
|
pub const RawHat = @import("hat.zig").RawHat;
|
||||||
|
pub const Mods = @import("mod.zig").Mods;
|
||||||
|
pub const RawMods = @import("mod.zig").RawMods;
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// If GLFW was already initialized in your program, e.g. you are embedding Zig code into an existing
|
||||||
|
/// program that has already called glfwInit via the C API for you - then you need to tell mach/glfw
|
||||||
|
/// that it has in fact been initialized already, otherwise when you call other methods mach/glfw
|
||||||
|
/// would panic thinking glfw.init has not been called yet.
|
||||||
|
pub fn assumeInitialized() void {
|
||||||
|
internal_debug.assumeInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initializes the GLFW library.
|
||||||
|
///
|
||||||
|
/// This function initializes the GLFW library. Before most GLFW functions can be used, GLFW must
|
||||||
|
/// be initialized, and before an application terminates GLFW should be terminated in order to free
|
||||||
|
/// any resources allocated during or after initialization.
|
||||||
|
///
|
||||||
|
/// If this function fails, it calls glfw.Terminate before returning. If it succeeds, you should
|
||||||
|
/// call glfw.Terminate before the application exits.
|
||||||
|
///
|
||||||
|
/// Additional calls to this function after successful initialization but before termination will
|
||||||
|
/// return immediately with no error.
|
||||||
|
///
|
||||||
|
/// The glfw.InitHint.platform init hint controls which platforms are considered during
|
||||||
|
/// initialization. This also depends on which platforms the library was compiled to support.
|
||||||
|
///
|
||||||
|
/// macos: This function will change the current directory of the application to the
|
||||||
|
/// `Contents/Resources` subdirectory of the application's bundle, if present. This can be disabled
|
||||||
|
/// with `glfw.InitHint.cocoa_chdir_resources`.
|
||||||
|
///
|
||||||
|
/// macos: This function will create the main menu and dock icon for the application. If GLFW finds
|
||||||
|
/// a `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 `glfw.InitHint.cocoa_menubar`.
|
||||||
|
///
|
||||||
|
/// x11: This function will set the `LC_CTYPE` category of the application locale according to the
|
||||||
|
/// current environment if that category is still "C". This is because the "C" locale breaks
|
||||||
|
/// Unicode text input.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformUnavailable, glfw.ErrorCode.PlatformError.
|
||||||
|
/// Returns a bool indicating success.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
pub inline fn init(hints: InitHints) bool {
|
||||||
|
internal_debug.toggleInitialized();
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
errdefer {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
internal_debug.toggleInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline for (comptime std.meta.fieldNames(InitHints)) |field_name| {
|
||||||
|
const init_hint = @field(InitHint, field_name);
|
||||||
|
const init_value = @field(hints, field_name);
|
||||||
|
if (@TypeOf(init_value) == PlatformType) {
|
||||||
|
initHint(init_hint, @intFromEnum(init_value));
|
||||||
|
} else {
|
||||||
|
initHint(init_hint, init_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.glfwInit() == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement custom allocator support
|
||||||
|
//
|
||||||
|
// /*! @brief Sets the init allocator to the desired value.
|
||||||
|
// *
|
||||||
|
// * To use the default allocator, call this function with a `NULL` argument.
|
||||||
|
// *
|
||||||
|
// * If you specify an allocator struct, every member must be a valid function
|
||||||
|
// * pointer. If any member is `NULL`, this function emits @ref
|
||||||
|
// * GLFW_INVALID_VALUE and the init allocator is unchanged.
|
||||||
|
// *
|
||||||
|
// * @param[in] allocator The allocator to use at the next initialization, or
|
||||||
|
// * `NULL` to use the default one.
|
||||||
|
// *
|
||||||
|
// * @errors Possible errors include @ref GLFW_INVALID_VALUE.
|
||||||
|
// *
|
||||||
|
// * @pointer_lifetime The specified allocator is copied before this function
|
||||||
|
// * returns.
|
||||||
|
// *
|
||||||
|
// * @thread_safety This function must only be called from the main thread.
|
||||||
|
// *
|
||||||
|
// * @sa @ref init_allocator
|
||||||
|
// * @sa @ref glfwInit
|
||||||
|
// *
|
||||||
|
// * @since Added in version 3.4.
|
||||||
|
// *
|
||||||
|
// * @ingroup init
|
||||||
|
// */
|
||||||
|
// GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
|
||||||
|
|
||||||
|
/// Terminates the GLFW library.
|
||||||
|
///
|
||||||
|
/// This function destroys all remaining windows and cursors, restores any modified gamma ramps
|
||||||
|
/// and frees any other allocated resources. Once this function is called, you must again call
|
||||||
|
/// glfw.init successfully before you will be able to use most GLFW functions.
|
||||||
|
///
|
||||||
|
/// If GLFW has been successfully initialized, this function should be called before the
|
||||||
|
/// application exits. If initialization fails, there is no need to call this function, as it is
|
||||||
|
/// called by glfw.init before it returns failure.
|
||||||
|
///
|
||||||
|
/// This function has no effect if GLFW is not initialized.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// warning: The contexts of any remaining windows must not be current on any other thread when
|
||||||
|
/// this function is called.
|
||||||
|
///
|
||||||
|
/// reentrancy: This function must not be called from a callback.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function must only be called from the main thread.
|
||||||
|
pub inline fn terminate() void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
internal_debug.toggleInitialized();
|
||||||
|
c.glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialization hints for passing into glfw.init
|
||||||
|
pub const InitHints = struct {
|
||||||
|
/// Specifies whether to also expose joystick hats as buttons, for compatibility with earlier
|
||||||
|
/// versions of GLFW that did not have glfwGetJoystickHats.
|
||||||
|
joystick_hat_buttons: bool = true,
|
||||||
|
|
||||||
|
/// macOS specific init hint. Ignored on other platforms.
|
||||||
|
///
|
||||||
|
/// Specifies whether to set the current directory to the application to the Contents/Resources
|
||||||
|
/// subdirectory of the application's bundle, if present.
|
||||||
|
cocoa_chdir_resources: bool = true,
|
||||||
|
|
||||||
|
/// macOS specific init hint. Ignored on other platforms.
|
||||||
|
///
|
||||||
|
/// specifies whether to create a basic menu bar, either from a nib or manually, when the first
|
||||||
|
/// window is created, which is when AppKit is initialized.
|
||||||
|
cocoa_menubar: bool = true,
|
||||||
|
|
||||||
|
/// Platform selection init hint.
|
||||||
|
///
|
||||||
|
/// Possible values are `PlatformType` enums.
|
||||||
|
platform: PlatformType = .any,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Initialization hints for passing into glfw.initHint
|
||||||
|
const InitHint = enum(c_int) {
|
||||||
|
/// Specifies whether to also expose joystick hats as buttons, for compatibility with earlier
|
||||||
|
/// versions of GLFW that did not have glfwGetJoystickHats.
|
||||||
|
///
|
||||||
|
/// Possible values are `true` and `false`.
|
||||||
|
joystick_hat_buttons = c.GLFW_JOYSTICK_HAT_BUTTONS,
|
||||||
|
|
||||||
|
/// ANGLE rendering backend init hint.
|
||||||
|
///
|
||||||
|
/// Possible values are `AnglePlatformType` enums.
|
||||||
|
angle_platform_type = c.GLFW_ANGLE_PLATFORM_TYPE,
|
||||||
|
|
||||||
|
/// Platform selection init hint.
|
||||||
|
///
|
||||||
|
/// Possible values are `PlatformType` enums.
|
||||||
|
platform = c.GLFW_PLATFORM,
|
||||||
|
|
||||||
|
/// macOS specific init hint. Ignored on other platforms.
|
||||||
|
///
|
||||||
|
/// Specifies whether to set the current directory to the application to the Contents/Resources
|
||||||
|
/// subdirectory of the application's bundle, if present.
|
||||||
|
///
|
||||||
|
/// Possible values are `true` and `false`.
|
||||||
|
cocoa_chdir_resources = c.GLFW_COCOA_CHDIR_RESOURCES,
|
||||||
|
|
||||||
|
/// macOS specific init hint. Ignored on other platforms.
|
||||||
|
///
|
||||||
|
/// specifies whether to create a basic menu bar, either from a nib or manually, when the first
|
||||||
|
/// window is created, which is when AppKit is initialized.
|
||||||
|
///
|
||||||
|
/// Possible values are `true` and `false`.
|
||||||
|
cocoa_menubar = c.GLFW_COCOA_MENUBAR,
|
||||||
|
|
||||||
|
/// X11 specific init hint.
|
||||||
|
x11_xcb_vulkan_surface = c.GLFW_X11_XCB_VULKAN_SURFACE,
|
||||||
|
|
||||||
|
/// Wayland specific init hint.
|
||||||
|
///
|
||||||
|
/// Possible values are `WaylandLibdecorInitHint` enums.
|
||||||
|
wayland_libdecor = c.GLFW_WAYLAND_LIBDECOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Angle platform type hints for glfw.InitHint.angle_platform_type
|
||||||
|
pub const AnglePlatformType = enum(c_int) {
|
||||||
|
none = c.GLFW_ANGLE_PLATFORM_TYPE_NONE,
|
||||||
|
opengl = c.GLFW_ANGLE_PLATFORM_TYPE_OPENGL,
|
||||||
|
opengles = c.GLFW_ANGLE_PLATFORM_TYPE_OPENGLES,
|
||||||
|
d3d9 = c.GLFW_ANGLE_PLATFORM_TYPE_D3D9,
|
||||||
|
d3d11 = c.GLFW_ANGLE_PLATFORM_TYPE_D3D11,
|
||||||
|
vulkan = c.GLFW_ANGLE_PLATFORM_TYPE_VULKAN,
|
||||||
|
metal = c.GLFW_ANGLE_PLATFORM_TYPE_METAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Wayland libdecor hints for glfw.InitHint.wayland_libdecor
|
||||||
|
///
|
||||||
|
/// libdecor is important for GNOME, since GNOME does not implement server side decorations on
|
||||||
|
/// wayland. libdecor is loaded dynamically at runtime, so in general enabling it is always
|
||||||
|
/// safe to do. It is enabled by default.
|
||||||
|
pub const WaylandLibdecorInitHint = enum(c_int) {
|
||||||
|
wayland_prefer_libdecor = c.GLFW_WAYLAND_PREFER_LIBDECOR,
|
||||||
|
wayland_disable_libdecor = c.GLFW_WAYLAND_DISABLE_LIBDECOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Platform type hints for glfw.InitHint.platform
|
||||||
|
pub const PlatformType = enum(c_int) {
|
||||||
|
/// Enables automatic platform detection.
|
||||||
|
/// Will default to X11 on wayland.
|
||||||
|
any = c.GLFW_ANY_PLATFORM,
|
||||||
|
win32 = c.GLFW_PLATFORM_WIN32,
|
||||||
|
cocoa = c.GLFW_PLATFORM_COCOA,
|
||||||
|
wayland = c.GLFW_PLATFORM_WAYLAND,
|
||||||
|
x11 = c.GLFW_PLATFORM_X11,
|
||||||
|
null = c.GLFW_PLATFORM_NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sets the specified init hint to the desired value.
|
||||||
|
///
|
||||||
|
/// This function sets hints for the next initialization of GLFW.
|
||||||
|
///
|
||||||
|
/// The values you set hints to are never reset by GLFW, but they only take effect during
|
||||||
|
/// initialization. Once GLFW has been initialized, any values you set will be ignored until the
|
||||||
|
/// library is terminated and initialized again.
|
||||||
|
///
|
||||||
|
/// Some hints are platform specific. These may be set on any platform but they will only affect
|
||||||
|
/// their specific platform. Other platforms will ignore them. Setting these hints requires no
|
||||||
|
/// platform specific headers or functions.
|
||||||
|
///
|
||||||
|
/// @param hint: The init hint to set.
|
||||||
|
/// @param value: The new value of the init hint.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidEnum and glfw.ErrorCode.InvalidValue.
|
||||||
|
///
|
||||||
|
/// @remarks This function may be called before glfw.init.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
fn initHint(hint: InitHint, value: anytype) void {
|
||||||
|
switch (@import("shims.zig").typeInfo(@TypeOf(value))) {
|
||||||
|
.int, .comptime_int => {
|
||||||
|
c.glfwInitHint(@intFromEnum(hint), @as(c_int, @intCast(value)));
|
||||||
|
},
|
||||||
|
.bool => c.glfwInitHint(@intFromEnum(hint), @as(c_int, @intCast(@intFromBool(value)))),
|
||||||
|
else => @compileError("expected a int or bool, got " ++ @typeName(@TypeOf(value))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a string describing the compile-time configuration.
|
||||||
|
///
|
||||||
|
/// This function returns the compile-time generated version string of the GLFW library binary. It
|
||||||
|
/// describes the version, platform, 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 `glGetString`.
|
||||||
|
///
|
||||||
|
/// __Do not use the version string__ to parse the GLFW library version. Use the glfw.version
|
||||||
|
/// constants instead.
|
||||||
|
///
|
||||||
|
/// __Do not use the version string__ to parse what platforms are supported. The
|
||||||
|
/// `glfw.platformSupported` function lets you query platform support.
|
||||||
|
///
|
||||||
|
/// returns: The ASCII encoded GLFW version string.
|
||||||
|
///
|
||||||
|
/// remark: This function may be called before @ref glfw.Init.
|
||||||
|
///
|
||||||
|
/// pointer_lifetime: The returned string is static and compile-time generated.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread.
|
||||||
|
pub inline fn getVersionString() [:0]const u8 {
|
||||||
|
return std.mem.span(@as([*:0]const u8, @ptrCast(c.glfwGetVersionString())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the currently selected platform.
|
||||||
|
///
|
||||||
|
/// This function returns the platform that was selected during initialization. The returned value
|
||||||
|
/// will be one of `glfw.PlatformType.win32`, `glfw.PlatformType.cocoa`,
|
||||||
|
/// `glfw.PlatformType.wayland`, `glfw.PlatformType.x11` or `glfw.PlatformType.null`.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread.
|
||||||
|
pub fn getPlatform() PlatformType {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return @as(PlatformType, @enumFromInt(c.glfwGetPlatform()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 `glfw.PlatformType.win32`, `glfw.PlatformType.cocoa`,
|
||||||
|
/// `glfw.PlatformType.wayland`, `glfw.PlatformType.x11` or `glfw.PlatformType.null`.
|
||||||
|
///
|
||||||
|
/// remark: This function may be called before glfw.Init.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread.
|
||||||
|
pub fn platformSupported(platform: PlatformType) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return c.glfwPlatformSupported(@intFromEnum(platform)) == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Processes all pending events.
|
||||||
|
///
|
||||||
|
/// This function processes only those events that are already in the event queue and then returns
|
||||||
|
/// immediately. Processing events will cause the window and input callbacks associated with those
|
||||||
|
/// events to be called.
|
||||||
|
///
|
||||||
|
/// On some platforms, a window move, resize or menu operation will cause event processing to
|
||||||
|
/// block. This is due to how event processing is designed on those platforms. You can use the
|
||||||
|
/// window refresh callback (see window_refresh) to redraw the contents of your window when
|
||||||
|
/// necessary during such operations.
|
||||||
|
///
|
||||||
|
/// Do not assume that callbacks you set will _only_ be called in response to event processing
|
||||||
|
/// functions like this one. While it is necessary to poll for events, window systems that require
|
||||||
|
/// GLFW to register callbacks of its own can pass events to GLFW in response to many window system
|
||||||
|
/// function calls. GLFW will pass those events on to the application callbacks before returning.
|
||||||
|
///
|
||||||
|
/// Event processing is not required for joystick input to work.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @reentrancy This function must not be called from a callback.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: events, glfw.waitEvents, glfw.waitEventsTimeout
|
||||||
|
pub inline fn pollEvents() void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Waits until events are queued and processes them.
|
||||||
|
///
|
||||||
|
/// This function puts the calling thread to sleep until at least one event is available in the
|
||||||
|
/// event queue. Once one or more events are available, it behaves exactly like glfw.pollEvents,
|
||||||
|
/// i.e. the events in the queue are processed and the function then returns immediately.
|
||||||
|
/// Processing events will cause the window and input callbacks associated with those events to be
|
||||||
|
/// called.
|
||||||
|
///
|
||||||
|
/// Since not all events are associated with callbacks, this function may return without a callback
|
||||||
|
/// having been called even if you are monitoring all callbacks.
|
||||||
|
///
|
||||||
|
/// On some platforms, a window move, resize or menu operation will cause event processing to
|
||||||
|
/// block. This is due to how event processing is designed on those platforms. You can use the
|
||||||
|
/// window refresh callback (see window_refresh) to redraw the contents of your window when
|
||||||
|
/// necessary during such operations.
|
||||||
|
///
|
||||||
|
/// Do not assume that callbacks you set will _only_ be called in response to event processing
|
||||||
|
/// functions like this one. While it is necessary to poll for events, window systems that require
|
||||||
|
/// GLFW to register callbacks of its own can pass events to GLFW in response to many window system
|
||||||
|
/// function calls. GLFW will pass those events on to the application callbacks before returning.
|
||||||
|
///
|
||||||
|
/// Event processing is not required for joystick input to work.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @reentrancy This function must not be called from a callback.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: events, glfw.pollEvents, glfw.waitEventsTimeout
|
||||||
|
pub inline fn waitEvents() void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Waits with timeout until events are queued and processes them.
|
||||||
|
///
|
||||||
|
/// This function puts the calling thread to sleep until at least one event is available in the
|
||||||
|
/// event queue, or until the specified timeout is reached. If one or more events are available, it
|
||||||
|
/// behaves exactly like glfw.pollEvents, i.e. the events in the queue are processed and the
|
||||||
|
/// function then returns immediately. Processing events will cause the window and input callbacks
|
||||||
|
/// associated with those events to be called.
|
||||||
|
///
|
||||||
|
/// The timeout value must be a positive finite number.
|
||||||
|
///
|
||||||
|
/// Since not all events are associated with callbacks, this function may return without a callback
|
||||||
|
/// having been called even if you are monitoring all callbacks.
|
||||||
|
///
|
||||||
|
/// On some platforms, a window move, resize or menu operation will cause event processing to
|
||||||
|
/// block. This is due to how event processing is designed on those platforms. You can use the
|
||||||
|
/// window refresh callback (see window_refresh) to redraw the contents of your window when
|
||||||
|
/// necessary during such operations.
|
||||||
|
///
|
||||||
|
/// Do not assume that callbacks you set will _only_ be called in response to event processing
|
||||||
|
/// functions like this one. While it is necessary to poll for events, window systems that require
|
||||||
|
/// GLFW to register callbacks of its own can pass events to GLFW in response to many window system
|
||||||
|
/// function calls. GLFW will pass those events on to the application callbacks before returning.
|
||||||
|
///
|
||||||
|
/// Event processing is not required for joystick input to work.
|
||||||
|
///
|
||||||
|
/// @param[in] timeout The maximum amount of time, in seconds, to wait.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidValue and glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @reentrancy This function must not be called from a callback.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: events, glfw.pollEvents, glfw.waitEvents
|
||||||
|
pub inline fn waitEventsTimeout(timeout: f64) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
std.debug.assert(!std.math.isNan(timeout));
|
||||||
|
std.debug.assert(timeout >= 0);
|
||||||
|
std.debug.assert(timeout <= std.math.floatMax(f64));
|
||||||
|
c.glfwWaitEventsTimeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Posts an empty event to the event queue.
|
||||||
|
///
|
||||||
|
/// This function posts an empty event from the current thread to the event queue, causing
|
||||||
|
/// glfw.waitEvents or glfw.waitEventsTimeout to return.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: events, glfw.waitEvents, glfw.waitEventsTimeout
|
||||||
|
pub inline fn postEmptyEvent() void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwPostEmptyEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether raw mouse motion is supported.
|
||||||
|
///
|
||||||
|
/// This function returns whether raw mouse motion is supported on the current system. This status
|
||||||
|
/// does not change after GLFW has been initialized so you only need to check this once. If you
|
||||||
|
/// attempt to enable raw motion on a system that does not support it, glfw.ErrorCode.PlatformError
|
||||||
|
/// will be emitted.
|
||||||
|
///
|
||||||
|
/// Raw mouse motion is closer to the actual motion of the mouse across a surface. It is not
|
||||||
|
/// affected by the scaling and acceleration applied to the motion of the desktop cursor. That
|
||||||
|
/// processing is suitable for a cursor while raw motion is better for controlling for example a 3D
|
||||||
|
/// camera. Because of this, raw mouse motion is only provided when the cursor is disabled.
|
||||||
|
///
|
||||||
|
/// @return `true` if raw mouse motion is supported on the current machine, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function must only be called from the main thread.
|
||||||
|
///
|
||||||
|
/// see also: raw_mouse_motion, glfw.setInputMode
|
||||||
|
pub inline fn rawMouseMotionSupported() bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return c.glfwRawMouseMotionSupported() == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn basicTest() !void {
|
||||||
|
defer clearError(); // clear any error we generate
|
||||||
|
if (!init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
|
||||||
|
const window = Window.create(640, 480, "GLFW example", null, null, .{}) orelse {
|
||||||
|
std.log.warn("failed to create window: {?s}", .{getErrorString()});
|
||||||
|
return error.SkipZigTest; // note: we don't exit(1) here because our CI can't open windows
|
||||||
|
};
|
||||||
|
defer window.destroy();
|
||||||
|
|
||||||
|
const start = std.time.milliTimestamp();
|
||||||
|
while (std.time.milliTimestamp() < start + 1000 and !window.shouldClose()) {
|
||||||
|
c.glfwPollEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
std.testing.refAllDeclsRecursive(@This());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getVersionString" {
|
||||||
|
std.debug.print("\nGLFW version v{}.{}.{}\n", .{ version.major, version.minor, version.revision });
|
||||||
|
std.debug.print("\nstring: {s}\n", .{getVersionString()});
|
||||||
|
}
|
||||||
|
|
||||||
|
test "init" {
|
||||||
|
_ = init(.{ .cocoa_chdir_resources = true });
|
||||||
|
if (getErrorString()) |err| {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{err});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "pollEvents" {
|
||||||
|
defer clearError(); // clear any error we generate
|
||||||
|
if (!init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
|
||||||
|
pollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "waitEventsTimeout" {
|
||||||
|
defer clearError(); // clear any error we generate
|
||||||
|
if (!init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
|
||||||
|
waitEventsTimeout(0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "postEmptyEvent_and_waitEvents" {
|
||||||
|
defer clearError(); // clear any error we generate
|
||||||
|
if (!init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
|
||||||
|
postEmptyEvent();
|
||||||
|
waitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "rawMouseMotionSupported" {
|
||||||
|
defer clearError(); // clear any error we generate
|
||||||
|
if (!init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer terminate();
|
||||||
|
|
||||||
|
_ = rawMouseMotionSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "basic" {
|
||||||
|
try basicTest();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
//! Modifier key flags
|
||||||
|
//!
|
||||||
|
//! See glfw.setKeyCallback for how these are used.
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
// must be in sync with GLFW C constants in modifier group, search for "@defgroup mods Modifier key flags"
|
||||||
|
/// A bitmask of all key modifiers
|
||||||
|
pub const Mods = packed struct(u8) {
|
||||||
|
shift: bool = false,
|
||||||
|
control: bool = false,
|
||||||
|
alt: bool = false,
|
||||||
|
super: bool = false,
|
||||||
|
caps_lock: bool = false,
|
||||||
|
num_lock: bool = false,
|
||||||
|
_padding: u2 = 0,
|
||||||
|
|
||||||
|
inline fn verifyIntType(comptime IntType: type) void {
|
||||||
|
comptime {
|
||||||
|
switch (@import("shims.zig").typeInfo(IntType)) {
|
||||||
|
.int => {},
|
||||||
|
else => @compileError("Int was not of int type"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn toInt(self: Mods, comptime IntType: type) IntType {
|
||||||
|
verifyIntType(IntType);
|
||||||
|
return @as(IntType, @intCast(@as(u8, @bitCast(self))));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn fromInt(flags: anytype) Mods {
|
||||||
|
verifyIntType(@TypeOf(flags));
|
||||||
|
return @as(Mods, @bitCast(@as(u8, @intCast(flags))));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Holds all GLFW mod values in their raw form.
|
||||||
|
pub const RawMods = struct {
|
||||||
|
/// If this bit is set one or more Shift keys were held down.
|
||||||
|
pub const shift = c.GLFW_MOD_SHIFT;
|
||||||
|
|
||||||
|
/// If this bit is set one or more Control keys were held down.
|
||||||
|
pub const control = c.GLFW_MOD_CONTROL;
|
||||||
|
|
||||||
|
/// If this bit is set one or more Alt keys were held down.
|
||||||
|
pub const alt = c.GLFW_MOD_ALT;
|
||||||
|
|
||||||
|
/// If this bit is set one or more Super keys were held down.
|
||||||
|
pub const super = c.GLFW_MOD_SUPER;
|
||||||
|
|
||||||
|
/// If this bit is set the Caps Lock key is enabled and the glfw.lock_key_mods input mode is set.
|
||||||
|
pub const caps_lock = c.GLFW_MOD_CAPS_LOCK;
|
||||||
|
|
||||||
|
/// If this bit is set the Num Lock key is enabled and the glfw.lock_key_mods input mode is set.
|
||||||
|
pub const num_lock = c.GLFW_MOD_NUM_LOCK;
|
||||||
|
};
|
||||||
|
|
||||||
|
test "shift int to bitmask" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const int_mod = RawMods.shift;
|
||||||
|
const mod = Mods.fromInt(int_mod);
|
||||||
|
|
||||||
|
try std.testing.expect(mod.shift == true);
|
||||||
|
try std.testing.expect(mod.control == false);
|
||||||
|
try std.testing.expect(mod.alt == false);
|
||||||
|
try std.testing.expect(mod.super == false);
|
||||||
|
try std.testing.expect(mod.caps_lock == false);
|
||||||
|
try std.testing.expect(mod.num_lock == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "shift int and alt to bitmask" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const int_mod = RawMods.shift | RawMods.alt;
|
||||||
|
const mod = Mods.fromInt(int_mod);
|
||||||
|
|
||||||
|
try std.testing.expect(mod.shift == true);
|
||||||
|
try std.testing.expect(mod.control == false);
|
||||||
|
try std.testing.expect(mod.alt == true);
|
||||||
|
try std.testing.expect(mod.super == false);
|
||||||
|
try std.testing.expect(mod.caps_lock == false);
|
||||||
|
try std.testing.expect(mod.num_lock == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "super int to bitmask" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const int_mod = RawMods.super;
|
||||||
|
const mod = Mods.fromInt(int_mod);
|
||||||
|
|
||||||
|
try std.testing.expect(mod.shift == false);
|
||||||
|
try std.testing.expect(mod.control == false);
|
||||||
|
try std.testing.expect(mod.alt == false);
|
||||||
|
try std.testing.expect(mod.super == true);
|
||||||
|
try std.testing.expect(mod.caps_lock == false);
|
||||||
|
try std.testing.expect(mod.num_lock == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "num lock int to bitmask" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const int_mod = RawMods.num_lock;
|
||||||
|
const mod = Mods.fromInt(int_mod);
|
||||||
|
|
||||||
|
try std.testing.expect(mod.shift == false);
|
||||||
|
try std.testing.expect(mod.control == false);
|
||||||
|
try std.testing.expect(mod.alt == false);
|
||||||
|
try std.testing.expect(mod.super == false);
|
||||||
|
try std.testing.expect(mod.caps_lock == false);
|
||||||
|
try std.testing.expect(mod.num_lock == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "all int to bitmask" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const int_mod = RawMods.shift | RawMods.control |
|
||||||
|
RawMods.alt | RawMods.super |
|
||||||
|
RawMods.caps_lock | RawMods.num_lock;
|
||||||
|
const mod = Mods.fromInt(int_mod);
|
||||||
|
|
||||||
|
try std.testing.expect(mod.shift == true);
|
||||||
|
try std.testing.expect(mod.control == true);
|
||||||
|
try std.testing.expect(mod.alt == true);
|
||||||
|
try std.testing.expect(mod.super == true);
|
||||||
|
try std.testing.expect(mod.caps_lock == true);
|
||||||
|
try std.testing.expect(mod.num_lock == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "shift bitmask to int" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const mod = Mods{ .shift = true };
|
||||||
|
const int_mod = mod.toInt(c_int);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(int_mod, RawMods.shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "shift and alt bitmask to int" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const mod = Mods{ .shift = true, .alt = true };
|
||||||
|
const int_mod = mod.toInt(c_int);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(int_mod, RawMods.shift | RawMods.alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "all bitmask to int" {
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const mod = Mods{
|
||||||
|
.shift = true,
|
||||||
|
.control = true,
|
||||||
|
.alt = true,
|
||||||
|
.super = true,
|
||||||
|
.caps_lock = true,
|
||||||
|
.num_lock = true,
|
||||||
|
};
|
||||||
|
const int_mod = mod.toInt(c_int);
|
||||||
|
|
||||||
|
const expected = RawMods.shift | RawMods.control |
|
||||||
|
RawMods.alt | RawMods.super |
|
||||||
|
RawMods.caps_lock | RawMods.num_lock;
|
||||||
|
|
||||||
|
try std.testing.expectEqual(int_mod, expected);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// Mouse button IDs.
|
||||||
|
///
|
||||||
|
/// See glfw.setMouseButtonCallback for how these are used.
|
||||||
|
pub const MouseButton = enum(c_int) {
|
||||||
|
// We use left/right/middle aliases here because those are more common and we cannot have
|
||||||
|
// duplicate values in a Zig enum.
|
||||||
|
left = c.GLFW_MOUSE_BUTTON_1,
|
||||||
|
right = c.GLFW_MOUSE_BUTTON_2,
|
||||||
|
middle = c.GLFW_MOUSE_BUTTON_3,
|
||||||
|
four = c.GLFW_MOUSE_BUTTON_4,
|
||||||
|
five = c.GLFW_MOUSE_BUTTON_5,
|
||||||
|
six = c.GLFW_MOUSE_BUTTON_6,
|
||||||
|
seven = c.GLFW_MOUSE_BUTTON_7,
|
||||||
|
eight = c.GLFW_MOUSE_BUTTON_8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Not in the MouseButton enumeration as it is a duplicate value which is forbidden.
|
||||||
|
pub const last = MouseButton.eight;
|
||||||
|
pub const one = MouseButton.left;
|
||||||
|
pub const two = MouseButton.right;
|
||||||
|
pub const three = MouseButton.middle;
|
||||||
|
|
@ -0,0 +1,393 @@
|
||||||
|
//! Native access functions
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Window = @import("Window.zig");
|
||||||
|
const Monitor = @import("Monitor.zig");
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
pub const BackendOptions = struct {
|
||||||
|
win32: bool = false,
|
||||||
|
wgl: bool = false,
|
||||||
|
cocoa: bool = false,
|
||||||
|
nsgl: bool = false,
|
||||||
|
x11: bool = false,
|
||||||
|
glx: bool = false,
|
||||||
|
wayland: bool = false,
|
||||||
|
egl: bool = false,
|
||||||
|
osmesa: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This function returns a type which allows provides an interface to access
|
||||||
|
/// the native handles based on backends selected.
|
||||||
|
///
|
||||||
|
/// The available window API options are:
|
||||||
|
/// * win32
|
||||||
|
/// * cocoa
|
||||||
|
/// * x11
|
||||||
|
/// * wayland
|
||||||
|
///
|
||||||
|
/// The available context API options are:
|
||||||
|
///
|
||||||
|
/// * wgl
|
||||||
|
/// * nsgl
|
||||||
|
/// * glx
|
||||||
|
/// * egl
|
||||||
|
/// * osmesa
|
||||||
|
///
|
||||||
|
/// The chosen backends must match those the library was compiled for. Failure to do so
|
||||||
|
/// will cause a link-time error.
|
||||||
|
pub fn Native(comptime options: BackendOptions) type {
|
||||||
|
const native = @cImport({
|
||||||
|
// @cDefine("GLFW_INCLUDE_VULKAN", "1");
|
||||||
|
@cDefine("GLFW_INCLUDE_NONE", "1");
|
||||||
|
if (options.win32) @cDefine("GLFW_EXPOSE_NATIVE_WIN32", "1");
|
||||||
|
if (options.wgl) @cDefine("GLFW_EXPOSE_NATIVE_WGL", "1");
|
||||||
|
if (options.cocoa) @cDefine("GLFW_EXPOSE_NATIVE_COCOA", "1");
|
||||||
|
if (options.nsgl) @cDefine("GLFW_EXPOSE_NATIVE_NGSL", "1");
|
||||||
|
if (options.x11) @cDefine("GLFW_EXPOSE_NATIVE_X11", "1");
|
||||||
|
if (options.glx) @cDefine("GLFW_EXPOSE_NATIVE_GLX", "1");
|
||||||
|
if (options.wayland) @cDefine("GLFW_EXPOSE_NATIVE_WAYLAND", "1");
|
||||||
|
if (options.egl) @cDefine("GLFW_EXPOSE_NATIVE_EGL", "1");
|
||||||
|
if (options.osmesa) @cDefine("GLFW_EXPOSE_NATIVE_OSMESA", "1");
|
||||||
|
@cDefine("__kernel_ptr_semantics", "");
|
||||||
|
@cInclude("GLFW/glfw3.h");
|
||||||
|
@cInclude("GLFW/glfw3native.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
return struct {
|
||||||
|
/// Returns the adapter device name of the specified monitor.
|
||||||
|
///
|
||||||
|
/// return: The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) of the
|
||||||
|
/// specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWin32Adapter(monitor: Monitor) [*:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWin32Adapter(@as(*native.GLFWmonitor, @ptrCast(monitor.handle)))) |adapter| return adapter;
|
||||||
|
// `glfwGetWin32Adapter` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the display device name of the specified monitor.
|
||||||
|
///
|
||||||
|
/// return: The UTF-8 encoded display device name (for example `\\.\DISPLAY1\Monitor0`)
|
||||||
|
/// of the specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWin32Monitor(monitor: Monitor) [*:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWin32Monitor(@as(*native.GLFWmonitor, @ptrCast(monitor.handle)))) |mon| return mon;
|
||||||
|
// `glfwGetWin32Monitor` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `HWND` of the specified window.
|
||||||
|
///
|
||||||
|
/// The `HDC` associated with the window can be queried with the
|
||||||
|
/// [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
|
||||||
|
/// function.
|
||||||
|
/// ```
|
||||||
|
/// const dc = std.os.windows.user32.GetDC(native.getWin32Window(window));
|
||||||
|
/// ```
|
||||||
|
/// This DC is private and does not need to be released.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWin32Window(window: Window) std.os.windows.HWND {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWin32Window(@as(*native.GLFWwindow, @ptrCast(window.handle)))) |win|
|
||||||
|
return @as(std.os.windows.HWND, @ptrCast(win));
|
||||||
|
// `glfwGetWin32Window` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `HGLRC` of the specified window.
|
||||||
|
///
|
||||||
|
/// The `HDC` associated with the window can be queried with the
|
||||||
|
/// [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
|
||||||
|
/// function.
|
||||||
|
/// ```
|
||||||
|
/// const dc = std.os.windows.user32.GetDC(native.getWin32Window(window));
|
||||||
|
/// ```
|
||||||
|
/// This DC is private and does not need to be released.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext
|
||||||
|
/// null is returned in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWGLContext(window: Window) ?std.os.windows.HGLRC {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWGLContext(@as(*native.GLFWwindow, @ptrCast(window.handle)))) |context| return context;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `CGDirectDisplayID` of the specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getCocoaMonitor(monitor: Monitor) u32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const mon = native.glfwGetCocoaMonitor(@as(*native.GLFWmonitor, @ptrCast(monitor.handle)));
|
||||||
|
if (mon != native.kCGNullDirectDisplay) return mon;
|
||||||
|
// `glfwGetCocoaMonitor` returns `kCGNullDirectDisplay` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `NSWindow` of the specified window.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getCocoaWindow(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return native.glfwGetCocoaWindow(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `NSWindow` of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getNSGLContext(window: Window) u32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return native.glfwGetNSGLContext(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `Display` used by GLFW.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getX11Display() *anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetX11Display()) |display| return @as(*anyopaque, @ptrCast(display));
|
||||||
|
// `glfwGetX11Display` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `RRCrtc` of the specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getX11Adapter(monitor: Monitor) u32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const adapter = native.glfwGetX11Adapter(@as(*native.GLFWMonitor, @ptrCast(monitor.handle)));
|
||||||
|
if (adapter != 0) return adapter;
|
||||||
|
// `glfwGetX11Adapter` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `RROutput` of the specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getX11Monitor(monitor: Monitor) u32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const mon = native.glfwGetX11Monitor(@as(*native.GLFWmonitor, @ptrCast(monitor.handle)));
|
||||||
|
if (mon != 0) return mon;
|
||||||
|
// `glfwGetX11Monitor` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `Window` of the specified window.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getX11Window(window: Window) u32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const win = native.glfwGetX11Window(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
if (win != 0) return @as(u32, @intCast(win));
|
||||||
|
// `glfwGetX11Window` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current primary selection to the specified string.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// The specified string is copied before this function returns.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function must only be called from the main thread.
|
||||||
|
pub fn setX11SelectionString(string: [*:0]const u8) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
native.glfwSetX11SelectionString(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the contents of the current primary selection as a string.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.PlatformError.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// The returned string is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is valid until the next call to getX11SelectionString or
|
||||||
|
/// setX11SelectionString, or until the library is terminated.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function must only be called from the main thread.
|
||||||
|
pub fn getX11SelectionString() ?[*:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetX11SelectionString()) |str| return str;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `GLXContext` of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getGLXContext(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetGLXContext(@as(*native.GLFWwindow, @ptrCast(window.handle)))) |context| return @as(*anyopaque, @ptrCast(context));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `GLXWindow` of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getGLXWindow(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const win = native.glfwGetGLXWindow(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
if (win != 0) return @as(*anyopaque, @ptrCast(win));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `*wl_display` used by GLFW.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWaylandDisplay() *anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWaylandDisplay()) |display| return @as(*anyopaque, @ptrCast(display));
|
||||||
|
// `glfwGetWaylandDisplay` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `*wl_output` of the specified monitor.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWaylandMonitor(monitor: Monitor) *anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWaylandMonitor(@as(*native.GLFWmonitor, @ptrCast(monitor.handle)))) |mon| return @as(*anyopaque, @ptrCast(mon));
|
||||||
|
// `glfwGetWaylandMonitor` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `*wl_surface` of the specified window.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getWaylandWindow(window: Window) *anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetWaylandWindow(@as(*native.GLFWwindow, @ptrCast(window.handle)))) |win| return @as(*anyopaque, @ptrCast(win));
|
||||||
|
// `glfwGetWaylandWindow` returns `null` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `EGLDisplay` used by GLFW.
|
||||||
|
///
|
||||||
|
/// remark: Because EGL is initialized on demand, this function will return `EGL_NO_DISPLAY`
|
||||||
|
/// until the first context has been created via EGL.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getEGLDisplay() *anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const display = native.glfwGetEGLDisplay();
|
||||||
|
if (display != native.EGL_NO_DISPLAY) return @as(*anyopaque, @ptrCast(display));
|
||||||
|
// `glfwGetEGLDisplay` returns `EGL_NO_DISPLAY` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `EGLContext` of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getEGLContext(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const context = native.glfwGetEGLContext(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
if (context != native.EGL_NO_CONTEXT) return @as(*anyopaque, @ptrCast(context));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the `EGLSurface` of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NotInitalized and glfw.ErrorCode.NoWindowContext.
|
||||||
|
///
|
||||||
|
/// thread_safety This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getEGLSurface(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const surface = native.glfwGetEGLSurface(@as(*native.GLFWwindow, @ptrCast(window.handle)));
|
||||||
|
if (surface != native.EGL_NO_SURFACE) return @as(*anyopaque, @ptrCast(surface));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const OSMesaColorBuffer = struct {
|
||||||
|
width: c_int,
|
||||||
|
height: c_int,
|
||||||
|
format: c_int,
|
||||||
|
buffer: *anyopaque,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Retrieves the color buffer associated with the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext and glfw.ErrorCode.PlatformError.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getOSMesaColorBuffer(window: Window) ?OSMesaColorBuffer {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var buf: OSMesaColorBuffer = undefined;
|
||||||
|
if (native.glfwGetOSMesaColorBuffer(
|
||||||
|
@as(*native.GLFWwindow, @ptrCast(window.handle)),
|
||||||
|
&buf.width,
|
||||||
|
&buf.height,
|
||||||
|
&buf.format,
|
||||||
|
&buf.buffer,
|
||||||
|
) == native.GLFW_TRUE) return buf;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const OSMesaDepthBuffer = struct {
|
||||||
|
width: c_int,
|
||||||
|
height: c_int,
|
||||||
|
bytes_per_value: c_int,
|
||||||
|
buffer: *anyopaque,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Retrieves the depth buffer associated with the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext and glfw.ErrorCode.PlatformError.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getOSMesaDepthBuffer(window: Window) ?OSMesaDepthBuffer {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var buf: OSMesaDepthBuffer = undefined;
|
||||||
|
if (native.glfwGetOSMesaDepthBuffer(
|
||||||
|
@as(*native.GLFWwindow, @ptrCast(window.handle)),
|
||||||
|
&buf.width,
|
||||||
|
&buf.height,
|
||||||
|
&buf.bytes_per_value,
|
||||||
|
&buf.buffer,
|
||||||
|
) == native.GLFW_TRUE) return buf;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the 'OSMesaContext' of the specified window.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function may be called from any thread. Access is not synchronized.
|
||||||
|
pub fn getOSMesaContext(window: Window) ?*anyopaque {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (native.glfwGetOSMesaContext(@as(*native.GLFWwindow, @ptrCast(window.handle)))) |context| return @as(*anyopaque, @ptrCast(context));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const Window = @import("Window.zig");
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// Makes the context of the specified window current for the calling thread.
|
||||||
|
///
|
||||||
|
/// This function makes the OpenGL or OpenGL ES context of the specified window current on the
|
||||||
|
/// calling thread. A context must only be made current on a single thread at a time and each
|
||||||
|
/// thread can have only a single current context at a time.
|
||||||
|
///
|
||||||
|
/// When moving a context between threads, you must make it non-current on the old thread before
|
||||||
|
/// making it current on the new one.
|
||||||
|
///
|
||||||
|
/// By default, making a context non-current implicitly forces a pipeline flush. On machines that
|
||||||
|
/// support `GL_KHR_context_flush_control`, you can control whether a context performs this flush
|
||||||
|
/// by setting the glfw.context_release_behavior hint.
|
||||||
|
///
|
||||||
|
/// The specified window must have an OpenGL or OpenGL ES context. Specifying a window without a
|
||||||
|
/// context will generate glfw.ErrorCode.NoWindowContext.
|
||||||
|
///
|
||||||
|
/// @param[in] window The window whose context to make current, or null to
|
||||||
|
/// detach the current context.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoWindowContext and glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: context_current, glfwGetCurrentContext
|
||||||
|
pub inline fn makeContextCurrent(window: ?Window) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (window) |w| c.glfwMakeContextCurrent(w.handle) else c.glfwMakeContextCurrent(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the window whose context is current on the calling thread.
|
||||||
|
///
|
||||||
|
/// This function returns the window whose OpenGL or OpenGL ES context is current on the calling
|
||||||
|
/// thread.
|
||||||
|
///
|
||||||
|
/// Returns he window whose context is current, or null if no window's context is current.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: context_current, glfwMakeContextCurrent
|
||||||
|
pub inline fn getCurrentContext() ?Window {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetCurrentContext()) |handle| return Window.from(handle);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the swap interval for the current context.
|
||||||
|
///
|
||||||
|
/// This function sets the swap interval for the current OpenGL or OpenGL ES context, i.e. the
|
||||||
|
/// number of screen updates to wait from the time glfw.SwapBuffers was called before swapping the
|
||||||
|
/// buffers and returning. This is sometimes called _vertical synchronization_, _vertical retrace
|
||||||
|
/// synchronization_ or just _vsync_.
|
||||||
|
///
|
||||||
|
/// A context that supports either of the `WGL_EXT_swap_control_tear` and `GLX_EXT_swap_control_tear`
|
||||||
|
/// extensions also accepts _negative_ swap intervals, which allows the driver to swap immediately
|
||||||
|
/// even if a frame arrives a little bit late. You can check for these extensions with glfw.extensionSupported.
|
||||||
|
///
|
||||||
|
/// A context must be current on the calling thread. Calling this function without a current context
|
||||||
|
/// will cause glfw.ErrorCode.NoCurrentContext.
|
||||||
|
///
|
||||||
|
/// This function does not apply to Vulkan. If you are rendering with Vulkan, see the present mode
|
||||||
|
/// of your swapchain instead.
|
||||||
|
///
|
||||||
|
/// @param[in] interval The minimum number of screen updates to wait for until the buffers are
|
||||||
|
/// swapped by glfw.swapBuffers.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoCurrentContext and glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// This function is not called during context creation, leaving the 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.
|
||||||
|
///
|
||||||
|
/// Some GPU drivers do not honor the requested swap interval, either because of a user setting
|
||||||
|
/// that overrides the application's request or due to bugs in the driver.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: buffer_swap, glfwSwapBuffers
|
||||||
|
pub inline fn swapInterval(interval: i32) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
c.glfwSwapInterval(@as(c_int, @intCast(interval)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the specified extension is available.
|
||||||
|
///
|
||||||
|
/// This function returns whether the specified API extension (see context_glext) is supported by
|
||||||
|
/// the current OpenGL or OpenGL ES context. It searches both for client API extension and context
|
||||||
|
/// creation API extensions.
|
||||||
|
///
|
||||||
|
/// A context must be current on the calling thread. Calling this function without a current
|
||||||
|
/// context will cause glfw.ErrorCode.NoCurrentContext.
|
||||||
|
///
|
||||||
|
/// As this functions retrieves and searches one or more extension strings each call, it is
|
||||||
|
/// recommended that you cache its results if it is going to be used frequently. The extension
|
||||||
|
/// strings will not change during the lifetime of a context, so there is no danger in doing this.
|
||||||
|
///
|
||||||
|
/// This function does not apply to Vulkan. If you are using Vulkan, see glfw.getRequiredInstanceExtensions,
|
||||||
|
/// `vkEnumerateInstanceExtensionProperties` and `vkEnumerateDeviceExtensionProperties` instead.
|
||||||
|
///
|
||||||
|
/// @param[in] extension The ASCII encoded name of the extension.
|
||||||
|
/// @return `true` if the extension is available, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.NoCurrentContext, glfw.ErrorCode.InvalidValue
|
||||||
|
/// and glfw.ErrorCode.PlatformError.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: context_glext, glfw.getProcAddress
|
||||||
|
pub inline fn extensionSupported(extension: [:0]const u8) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
|
||||||
|
std.debug.assert(extension.len != 0);
|
||||||
|
std.debug.assert(extension[0] != 0);
|
||||||
|
|
||||||
|
return c.glfwExtensionSupported(extension.ptr) == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Client API function pointer type.
|
||||||
|
///
|
||||||
|
/// Generic function pointer used for returning client API function pointers.
|
||||||
|
///
|
||||||
|
/// see also: context_glext, glfwGetProcAddress
|
||||||
|
pub const GLProc = *const fn () callconv(if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) .Stdcall else .C) void;
|
||||||
|
|
||||||
|
/// Returns the address of the specified function for the current context.
|
||||||
|
///
|
||||||
|
/// This function returns the address of the specified OpenGL or OpenGL ES core or extension
|
||||||
|
/// function (see context_glext), if it is supported by the current context.
|
||||||
|
///
|
||||||
|
/// A context must be current on the calling thread. Calling this function without a current
|
||||||
|
/// context will cause glfw.ErrorCode.NoCurrentContext.
|
||||||
|
///
|
||||||
|
/// This function does not apply to Vulkan. If you are rendering with Vulkan, see glfw.getInstanceProcAddress,
|
||||||
|
/// `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` instead.
|
||||||
|
///
|
||||||
|
/// @param[in] procname The ASCII encoded name of the function.
|
||||||
|
/// @return The address of the function, or null if an error occurred.
|
||||||
|
///
|
||||||
|
/// To maintain ABI compatability with the C glfwGetProcAddress, as it is commonly passed into
|
||||||
|
/// libraries expecting that exact ABI, this function does not return an error. Instead, if
|
||||||
|
/// glfw.ErrorCode.NotInitialized, glfw.ErrorCode.NoCurrentContext, or glfw.ErrorCode.PlatformError
|
||||||
|
/// would occur this function will panic. You should ensure a valid OpenGL context exists and the
|
||||||
|
/// GLFW is initialized before calling this function.
|
||||||
|
///
|
||||||
|
/// The address of a given function is not guaranteed to be the same between contexts.
|
||||||
|
///
|
||||||
|
/// This function may return a non-null address despite the associated version or extension
|
||||||
|
/// not being available. Always check the context version or extension string first.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned function pointer is valid until the context is destroyed or the
|
||||||
|
/// library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: context_glext, glfwExtensionSupported
|
||||||
|
pub fn getProcAddress(proc_name: [*:0]const u8) callconv(.C) ?GLProc {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetProcAddress(proc_name)) |proc_address| return @ptrCast(proc_address);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "makeContextCurrent" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const window = Window.create(640, 480, "Hello, Zig!", null, null, .{}) orelse {
|
||||||
|
std.log.warn("failed to create window: {?s}", .{glfw.getErrorString()});
|
||||||
|
return error.SkipZigTest; // note: we don't exit(1) here because our CI can't open windows
|
||||||
|
};
|
||||||
|
defer window.destroy();
|
||||||
|
|
||||||
|
glfw.makeContextCurrent(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getCurrentContext" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const current_context = glfw.getCurrentContext();
|
||||||
|
std.debug.assert(current_context == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "swapInterval" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const window = Window.create(640, 480, "Hello, Zig!", null, null, .{}) orelse {
|
||||||
|
std.log.warn("failed to create window: {?s}", .{glfw.getErrorString()});
|
||||||
|
return error.SkipZigTest; // note: we don't exit(1) here because our CI can't open windows
|
||||||
|
};
|
||||||
|
defer window.destroy();
|
||||||
|
|
||||||
|
glfw.makeContextCurrent(window);
|
||||||
|
glfw.swapInterval(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getProcAddress" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const window = Window.create(640, 480, "Hello, Zig!", null, null, .{}) orelse {
|
||||||
|
std.log.warn("failed to create window: {?s}", .{glfw.getErrorString()});
|
||||||
|
return error.SkipZigTest; // note: we don't exit(1) here because our CI can't open windows
|
||||||
|
};
|
||||||
|
defer window.destroy();
|
||||||
|
|
||||||
|
glfw.makeContextCurrent(window);
|
||||||
|
_ = glfw.getProcAddress("foobar");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "extensionSupported" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
const window = Window.create(640, 480, "Hello, Zig!", null, null, .{}) orelse {
|
||||||
|
std.log.warn("failed to create window: {?s}", .{glfw.getErrorString()});
|
||||||
|
return error.SkipZigTest; // note: we don't exit(1) here because our CI can't open windows
|
||||||
|
};
|
||||||
|
defer window.destroy();
|
||||||
|
|
||||||
|
glfw.makeContextCurrent(window);
|
||||||
|
_ = glfw.extensionSupported("foobar");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Zig 0.14.0-dev changed the names of all 'std.builtin.Type' fields.
|
||||||
|
const old_std_builtin_type_field_names = @hasField(@import("std").builtin.Type, "Type");
|
||||||
|
|
||||||
|
pub const std = struct {
|
||||||
|
pub const builtin = struct {
|
||||||
|
pub const Type = if (old_std_builtin_type_field_names) union(enum) {
|
||||||
|
type: void,
|
||||||
|
void: void,
|
||||||
|
bool: void,
|
||||||
|
noreturn: void,
|
||||||
|
int: Int,
|
||||||
|
float: Float,
|
||||||
|
pointer: Pointer,
|
||||||
|
array: Array,
|
||||||
|
@"struct": Struct,
|
||||||
|
comptime_float: void,
|
||||||
|
comptime_int: void,
|
||||||
|
undefined: void,
|
||||||
|
null: void,
|
||||||
|
optional: Optional,
|
||||||
|
error_union: ErrorUnion,
|
||||||
|
error_set: ErrorSet,
|
||||||
|
@"enum": Enum,
|
||||||
|
@"union": Union,
|
||||||
|
@"fn": Fn,
|
||||||
|
@"opaque": Opaque,
|
||||||
|
frame: Frame,
|
||||||
|
@"anyframe": AnyFrame,
|
||||||
|
vector: Vector,
|
||||||
|
enum_literal: void,
|
||||||
|
|
||||||
|
pub const Int = @import("std").builtin.Type.Int;
|
||||||
|
pub const Float = @import("std").builtin.Type.Float;
|
||||||
|
pub const Pointer = @import("std").builtin.Type.Pointer;
|
||||||
|
pub const Array = @import("std").builtin.Type.Array;
|
||||||
|
pub const ContainerLayout = @import("std").builtin.Type.ContainerLayout;
|
||||||
|
pub const StructField = @import("std").builtin.Type.StructField;
|
||||||
|
pub const Struct = @import("std").builtin.Type.Struct;
|
||||||
|
pub const Optional = @import("std").builtin.Type.Optional;
|
||||||
|
pub const ErrorUnion = @import("std").builtin.Type.ErrorUnion;
|
||||||
|
pub const Error = @import("std").builtin.Type.Error;
|
||||||
|
pub const ErrorSet = @import("std").builtin.Type.ErrorSet;
|
||||||
|
pub const EnumField = @import("std").builtin.Type.EnumField;
|
||||||
|
pub const Enum = @import("std").builtin.Type.Enum;
|
||||||
|
pub const UnionField = @import("std").builtin.Type.UnionField;
|
||||||
|
pub const Union = @import("std").builtin.Type.Union;
|
||||||
|
pub const Fn = @import("std").builtin.Type.Fn;
|
||||||
|
pub const Opaque = @import("std").builtin.Type.Opaque;
|
||||||
|
pub const Frame = @import("std").builtin.Type.Frame;
|
||||||
|
pub const AnyFrame = @import("std").builtin.Type.AnyFrame;
|
||||||
|
pub const Vector = @import("std").builtin.Type.Vector;
|
||||||
|
pub const Declaration = @import("std").builtin.Type.Declaration;
|
||||||
|
} else @import("std").builtin.Type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn typeInfo(comptime T: type) std.builtin.Type {
|
||||||
|
return if (old_std_builtin_type_field_names) switch (@typeInfo(T)) {
|
||||||
|
.Type => .type,
|
||||||
|
.Void => .void,
|
||||||
|
.Bool => .bool,
|
||||||
|
.NoReturn => .noreturn,
|
||||||
|
.Int => |x| .{ .int = x },
|
||||||
|
.Float => |x| .{ .float = x },
|
||||||
|
.Pointer => |x| .{ .pointer = x },
|
||||||
|
.Array => |x| .{ .array = x },
|
||||||
|
.Struct => |x| .{ .@"struct" = x },
|
||||||
|
.ComptimeFloat => .comptime_float,
|
||||||
|
.ComptimeInt => .comptime_int,
|
||||||
|
.Undefined => .undefined,
|
||||||
|
.Null => .null,
|
||||||
|
.Optional => |x| .{ .optional = x },
|
||||||
|
.ErrorUnion => |x| .{ .error_union = x },
|
||||||
|
.ErrorSet => |x| .{ .error_set = x },
|
||||||
|
.Enum => |x| .{ .@"enum" = x },
|
||||||
|
.Union => |x| .{ .@"union" = x },
|
||||||
|
.Fn => |x| .{ .@"fn" = x },
|
||||||
|
.Opaque => |x| .{ .@"opaque" = x },
|
||||||
|
.Frame => |x| .{ .frame = x },
|
||||||
|
.AnyFrame => .@"anyframe",
|
||||||
|
.Vector => |x| .{ .vector = x },
|
||||||
|
.EnumLiteral => .enum_literal,
|
||||||
|
} else @typeInfo(T);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// Returns the GLFW time.
|
||||||
|
///
|
||||||
|
/// This function returns the current GLFW time, in seconds. Unless the time
|
||||||
|
/// has been set using @ref glfwSetTime it measures time elapsed since GLFW was
|
||||||
|
/// initialized.
|
||||||
|
///
|
||||||
|
/// This function and @ref glfwSetTime are helper functions on top of glfw.getTimerFrequency
|
||||||
|
/// and glfw.getTimerValue.
|
||||||
|
///
|
||||||
|
/// 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 operating system.
|
||||||
|
///
|
||||||
|
/// @return The current time, in seconds, or zero if an
|
||||||
|
/// error occurred.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Reading and
|
||||||
|
/// writing of the internal base time is not atomic, so it needs to be
|
||||||
|
/// externally synchronized with calls to @ref glfwSetTime.
|
||||||
|
///
|
||||||
|
/// see also: time
|
||||||
|
pub inline fn getTime() f64 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const time = c.glfwGetTime();
|
||||||
|
if (time != 0) return time;
|
||||||
|
// `glfwGetTime` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the GLFW time.
|
||||||
|
///
|
||||||
|
/// This function sets the current GLFW time, in seconds. The value must be a positive finite
|
||||||
|
/// number less than or equal to 18446744073.0, which is approximately 584.5 years.
|
||||||
|
///
|
||||||
|
/// This function and @ref glfwGetTime are helper functions on top of glfw.getTimerFrequency and
|
||||||
|
/// glfw.getTimerValue.
|
||||||
|
///
|
||||||
|
/// @param[in] time The new value, in seconds.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.InvalidValue.
|
||||||
|
///
|
||||||
|
/// The upper limit of GLFW time is calculated as `floor((2^64 - 1) / 10^9)` and is due to
|
||||||
|
/// implementations storing nanoseconds in 64 bits. The limit may be increased in the future.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. Reading and writing of the internal
|
||||||
|
/// base time is not atomic, so it needs to be externally synchronized with calls to glfw.getTime.
|
||||||
|
///
|
||||||
|
/// see also: time
|
||||||
|
pub inline fn setTime(time: f64) void {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
|
||||||
|
std.debug.assert(!std.math.isNan(time));
|
||||||
|
std.debug.assert(time >= 0);
|
||||||
|
// assert time is lteq to largest number of seconds representable by u64 with nanosecond precision
|
||||||
|
std.debug.assert(time <= max_time: {
|
||||||
|
const @"2^64" = std.math.maxInt(u64);
|
||||||
|
break :max_time @divTrunc(@"2^64", std.time.ns_per_s);
|
||||||
|
});
|
||||||
|
|
||||||
|
c.glfwSetTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current value of the raw timer.
|
||||||
|
///
|
||||||
|
/// This function returns the current value of the raw timer, measured in `1/frequency` seconds. To
|
||||||
|
/// get the frequency, call glfw.getTimerFrequency.
|
||||||
|
///
|
||||||
|
/// @return The value of the timer, or zero if an error occurred.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: time, glfw.getTimerFrequency
|
||||||
|
pub inline fn getTimerValue() u64 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const value = c.glfwGetTimerValue();
|
||||||
|
if (value != 0) return value;
|
||||||
|
// `glfwGetTimerValue` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the frequency, in Hz, of the raw timer.
|
||||||
|
///
|
||||||
|
/// This function returns the frequency, in Hz, of the raw timer.
|
||||||
|
///
|
||||||
|
/// @return The frequency of the timer, in Hz, or zero if an error occurred.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: time, glfw.getTimerValue
|
||||||
|
pub inline fn getTimerFrequency() u64 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const frequency = c.glfwGetTimerFrequency();
|
||||||
|
if (frequency != 0) return frequency;
|
||||||
|
// `glfwGetTimerFrequency` returns `0` only for errors
|
||||||
|
// but the only potential error is unreachable (NotInitialized)
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getTime" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "setTime" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.setTime(1234);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getTimerValue" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.getTimerValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getTimerFrequency" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.getTimerFrequency();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
//! GLFW version info
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
/// The major version number of the GLFW library.
|
||||||
|
///
|
||||||
|
/// This is incremented when the API is changed in non-compatible ways.
|
||||||
|
pub const major = c.GLFW_VERSION_MAJOR;
|
||||||
|
|
||||||
|
/// The minor version number of the GLFW library.
|
||||||
|
///
|
||||||
|
/// This is incremented when features are added to the API but it remains backward-compatible.
|
||||||
|
pub const minor = c.GLFW_VERSION_MINOR;
|
||||||
|
|
||||||
|
/// The revision number of the GLFW library.
|
||||||
|
///
|
||||||
|
/// This is incremented when a bug fix release is made that does not contain any API changes.
|
||||||
|
pub const revision = c.GLFW_VERSION_REVISION;
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const Window = @import("Window.zig");
|
||||||
|
|
||||||
|
const internal_debug = @import("internal_debug.zig");
|
||||||
|
|
||||||
|
/// Sets the desired Vulkan `vkGetInstanceProcAddr` function.
|
||||||
|
///
|
||||||
|
/// This function sets the `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 `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 `vulkan-1.dll` on Windows, `libvulkan.so.1` on
|
||||||
|
/// Linux and other Unix-like systems and `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.
|
||||||
|
///
|
||||||
|
/// remark: This function may be called before glfw.Init.
|
||||||
|
///
|
||||||
|
/// thread_safety: This function must only be called from the main thread.
|
||||||
|
pub fn initVulkanLoader(loader_function: ?VKGetInstanceProcAddr) void {
|
||||||
|
c.glfwInitVulkanLoader(loader_function orelse null);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const VKGetInstanceProcAddr = *const fn (vk_instance: c.VkInstance, name: [*c]const u8) callconv(.C) ?VKProc;
|
||||||
|
|
||||||
|
/// Returns whether the Vulkan loader and an ICD have been found.
|
||||||
|
///
|
||||||
|
/// This function returns whether the Vulkan loader and any minimally functional ICD have been
|
||||||
|
/// found.
|
||||||
|
///
|
||||||
|
/// The availability of a Vulkan loader and even an ICD does not by itself guarantee that surface
|
||||||
|
/// creation or even instance creation is possible. Call glfw.getRequiredInstanceExtensions
|
||||||
|
/// to check whether the extensions necessary for Vulkan surface creation are available and
|
||||||
|
/// glfw.getPhysicalDevicePresentationSupport to check whether a queue family of a physical device
|
||||||
|
/// supports image presentation.
|
||||||
|
///
|
||||||
|
/// @return `true` if Vulkan is minimally available, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub inline fn vulkanSupported() bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
const supported = c.glfwVulkanSupported();
|
||||||
|
return supported == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the Vulkan instance extensions required by GLFW.
|
||||||
|
///
|
||||||
|
/// This function returns an array of names of Vulkan instance extensions required by GLFW for
|
||||||
|
/// creating Vulkan surfaces for GLFW windows. If successful, the list will always contain
|
||||||
|
/// `VK_KHR_surface`, so if you don't require any additional extensions you can pass this list
|
||||||
|
/// directly to the `VkInstanceCreateInfo` struct.
|
||||||
|
///
|
||||||
|
/// If Vulkan is not available on the machine, this function returns null and generates a
|
||||||
|
/// glfw.ErrorCode.APIUnavailable error. Call glfw.vulkanSupported to check whether Vulkan is at
|
||||||
|
/// least minimally available.
|
||||||
|
///
|
||||||
|
/// If Vulkan is available but no set of extensions allowing window surface creation was found,
|
||||||
|
/// this function returns null. You may still use Vulkan for off-screen rendering and compute work.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.APIUnavailable.
|
||||||
|
/// Returns null in the event of an error.
|
||||||
|
///
|
||||||
|
/// Additional extensions may be required by future versions of GLFW. You should check if any
|
||||||
|
/// extensions you wish to enable are already in the returned array, as it is an error to specify
|
||||||
|
/// an extension more than once in the `VkInstanceCreateInfo` struct.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned array is allocated and freed by GLFW. You should not free it
|
||||||
|
/// yourself. It is guaranteed to be valid only until the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
///
|
||||||
|
/// see also: vulkan_ext, glfwCreateWindowSurface
|
||||||
|
pub inline fn getRequiredInstanceExtensions() ?[][*:0]const u8 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
var count: u32 = 0;
|
||||||
|
if (c.glfwGetRequiredInstanceExtensions(&count)) |extensions| return @as([*][*:0]const u8, @ptrCast(extensions))[0..count];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Vulkan API function pointer type.
|
||||||
|
///
|
||||||
|
/// Generic function pointer used for returning Vulkan API function pointers.
|
||||||
|
///
|
||||||
|
/// see also: vulkan_proc, glfw.getInstanceProcAddress
|
||||||
|
pub const VKProc = *const fn () callconv(if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) .Stdcall else .C) void;
|
||||||
|
|
||||||
|
/// Returns the address of the specified Vulkan instance function.
|
||||||
|
///
|
||||||
|
/// This function returns the address of the specified Vulkan core or extension function for the
|
||||||
|
/// specified instance. If instance is set to null it can return any function exported from the
|
||||||
|
/// Vulkan loader, including at least the following functions:
|
||||||
|
///
|
||||||
|
/// - `vkEnumerateInstanceExtensionProperties`
|
||||||
|
/// - `vkEnumerateInstanceLayerProperties`
|
||||||
|
/// - `vkCreateInstance`
|
||||||
|
/// - `vkGetInstanceProcAddr`
|
||||||
|
///
|
||||||
|
/// If Vulkan is not available on the machine, this function returns null and generates a
|
||||||
|
/// glfw.ErrorCode.APIUnavailable error. Call glfw.vulkanSupported to check whether Vulkan is at
|
||||||
|
/// least minimally available.
|
||||||
|
///
|
||||||
|
/// This function is equivalent to calling `vkGetInstanceProcAddr` with a platform-specific query
|
||||||
|
/// of the Vulkan loader as a fallback.
|
||||||
|
///
|
||||||
|
/// @param[in] instance The Vulkan instance to query, or null to retrieve functions related to
|
||||||
|
/// instance creation.
|
||||||
|
/// @param[in] procname The ASCII encoded name of the function.
|
||||||
|
/// @return The address of the function, or null if an error occurred.
|
||||||
|
///
|
||||||
|
/// To maintain ABI compatability with the C glfwGetInstanceProcAddress, as it is commonly passed
|
||||||
|
/// into libraries expecting that exact ABI, this function does not return an error. Instead, if
|
||||||
|
/// glfw.ErrorCode.NotInitialized or glfw.ErrorCode.APIUnavailable would occur this function will panic.
|
||||||
|
/// You may check glfw.vulkanSupported prior to invoking this function.
|
||||||
|
///
|
||||||
|
/// @pointer_lifetime The returned function pointer is valid until the library is terminated.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread.
|
||||||
|
pub fn getInstanceProcAddress(vk_instance: ?*anyopaque, proc_name: [*:0]const u8) callconv(.C) ?VKProc {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
if (c.glfwGetInstanceProcAddress(if (vk_instance) |v| @as(c.VkInstance, @ptrCast(v)) else null, proc_name)) |proc_address| return proc_address;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the specified queue family can present images.
|
||||||
|
///
|
||||||
|
/// This function returns whether the specified queue family of the specified physical device
|
||||||
|
/// supports presentation to the platform GLFW was built for.
|
||||||
|
///
|
||||||
|
/// If Vulkan or the required window surface creation instance extensions are not available on the
|
||||||
|
/// machine, or if the specified instance was not created with the required extensions, this
|
||||||
|
/// function returns `GLFW_FALSE` and generates a glfw.ErrorCode.APIUnavailable error. Call
|
||||||
|
/// glfw.vulkanSupported to check whether Vulkan is at least minimally available and
|
||||||
|
/// glfw.getRequiredInstanceExtensions to check what instance extensions are required.
|
||||||
|
///
|
||||||
|
/// @param[in] instance The instance that the physical device belongs to.
|
||||||
|
/// @param[in] device The physical device that the queue family belongs to.
|
||||||
|
/// @param[in] queuefamily The index of the queue family to query.
|
||||||
|
/// @return `true` if the queue family supports presentation, or `false` otherwise.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.APIUnavailable and glfw.ErrorCode.PlatformError.
|
||||||
|
/// Returns false in the event of an error.
|
||||||
|
///
|
||||||
|
/// macos: This function currently always returns `true`, as the `VK_MVK_macos_surface` and
|
||||||
|
/// 'VK_EXT_metal_surface' extension does not provide a `vkGetPhysicalDevice*PresentationSupport` type function.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. For synchronization details of
|
||||||
|
/// Vulkan objects, see the Vulkan specification.
|
||||||
|
///
|
||||||
|
/// see also: vulkan_present
|
||||||
|
pub inline fn getPhysicalDevicePresentationSupport(
|
||||||
|
vk_instance: *anyopaque,
|
||||||
|
vk_physical_device: *anyopaque,
|
||||||
|
queue_family: u32,
|
||||||
|
) bool {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
return c.glfwGetPhysicalDevicePresentationSupport(
|
||||||
|
@as(c.VkInstance, @ptrCast(vk_instance)),
|
||||||
|
@as(c.VkPhysicalDevice, @ptrCast(vk_physical_device)),
|
||||||
|
queue_family,
|
||||||
|
) == c.GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a Vulkan surface for the specified window.
|
||||||
|
///
|
||||||
|
/// This function creates a Vulkan surface for the specified window.
|
||||||
|
///
|
||||||
|
/// If the Vulkan loader or at least one minimally functional ICD were not found, this function
|
||||||
|
/// returns `VK_ERROR_INITIALIZATION_FAILED` and generates a glfw.ErrorCode.APIUnavailable error. Call
|
||||||
|
/// glfw.vulkanSupported to check whether Vulkan is at least minimally available.
|
||||||
|
///
|
||||||
|
/// If the required window surface creation instance extensions are not available or if the
|
||||||
|
/// specified instance was not created with these extensions enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT`
|
||||||
|
/// and generates a glfw.ErrorCode.APIUnavailable error. Call glfw.getRequiredInstanceExtensions to
|
||||||
|
/// check what instance extensions are required.
|
||||||
|
///
|
||||||
|
/// The window surface cannot be shared with another API so the window must have been created with
|
||||||
|
/// the client api hint set to `GLFW_NO_API` otherwise it generates a glfw.ErrorCode.InvalidValue error
|
||||||
|
/// and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`.
|
||||||
|
///
|
||||||
|
/// The window surface must be destroyed before the specified Vulkan instance. It is the
|
||||||
|
/// responsibility of the caller to destroy the window surface. GLFW does not destroy it for you.
|
||||||
|
/// Call `vkDestroySurfaceKHR` to destroy the surface.
|
||||||
|
///
|
||||||
|
/// @param[in] vk_instance The Vulkan instance to create the surface in.
|
||||||
|
/// @param[in] window The window to create the surface for.
|
||||||
|
/// @param[in] vk_allocation_callbacks The allocator to use, or null to use the default
|
||||||
|
/// allocator.
|
||||||
|
/// @param[out] surface Where to store the handle of the surface. This is set
|
||||||
|
/// to `VK_NULL_HANDLE` if an error occurred.
|
||||||
|
/// @return `VkResult` type, `VK_SUCCESS` if successful, or a Vulkan error code if an
|
||||||
|
/// error occurred.
|
||||||
|
///
|
||||||
|
/// Possible errors include glfw.ErrorCode.APIUnavailable, glfw.ErrorCode.PlatformError and glfw.ErrorCode.InvalidValue
|
||||||
|
/// Returns a bool indicating success.
|
||||||
|
///
|
||||||
|
/// If an error occurs before the creation call is made, GLFW returns the Vulkan error code most
|
||||||
|
/// appropriate for the error. Appropriate use of glfw.vulkanSupported and glfw.getRequiredInstanceExtensions
|
||||||
|
/// should eliminate almost all occurrences of these errors.
|
||||||
|
///
|
||||||
|
/// macos: GLFW prefers the `VK_EXT_metal_surface` extension, with the `VK_MVK_macos_surface`
|
||||||
|
/// extension as a fallback. The name of the selected extension, if any, is included in the array
|
||||||
|
/// returned by glfw.getRequiredInstanceExtensions.
|
||||||
|
///
|
||||||
|
/// macos: This function currently only supports the `VK_MVK_macos_surface` extension from MoltenVK.
|
||||||
|
///
|
||||||
|
/// macos: This function creates and sets a `CAMetalLayer` instance for the window content view,
|
||||||
|
/// which is required for MoltenVK to function.
|
||||||
|
///
|
||||||
|
/// x11: By default GLFW prefers the `VK_KHR_xcb_surface` extension, with the `VK_KHR_xlib_surface`
|
||||||
|
/// extension as a fallback. You can make `VK_KHR_xlib_surface` the preferred extension by setting
|
||||||
|
/// glfw.InitHints.x11_xcb_vulkan_surface. The name of the selected extension, if any, is included
|
||||||
|
/// in the array returned by glfw.getRequiredInstanceExtensions.
|
||||||
|
///
|
||||||
|
/// @thread_safety This function may be called from any thread. For synchronization details of
|
||||||
|
/// Vulkan objects, see the Vulkan specification.
|
||||||
|
///
|
||||||
|
/// see also: vulkan_surface, glfw.getRequiredInstanceExtensions
|
||||||
|
pub inline fn createWindowSurface(vk_instance: anytype, window: Window, vk_allocation_callbacks: anytype, vk_surface_khr: anytype) i32 {
|
||||||
|
internal_debug.assertInitialized();
|
||||||
|
// zig-vulkan uses enums to represent opaque pointers:
|
||||||
|
// pub const Instance = enum(usize) { null_handle = 0, _ };
|
||||||
|
const instance: c.VkInstance = switch (@import("shims.zig").typeInfo(@TypeOf(vk_instance))) {
|
||||||
|
.@"enum" => @as(c.VkInstance, @ptrFromInt(@intFromEnum(vk_instance))),
|
||||||
|
else => @as(c.VkInstance, @ptrCast(vk_instance)),
|
||||||
|
};
|
||||||
|
|
||||||
|
return c.glfwCreateWindowSurface(
|
||||||
|
instance,
|
||||||
|
window.handle,
|
||||||
|
if (vk_allocation_callbacks == null) null else @as(*const c.VkAllocationCallbacks, @ptrCast(@alignCast(vk_allocation_callbacks))),
|
||||||
|
@as(*c.VkSurfaceKHR, @ptrCast(@alignCast(vk_surface_khr))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "vulkanSupported" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.vulkanSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getRequiredInstanceExtensions" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
_ = glfw.getRequiredInstanceExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getInstanceProcAddress" {
|
||||||
|
const glfw = @import("main.zig");
|
||||||
|
defer glfw.clearError(); // clear any error we generate
|
||||||
|
if (!glfw.init(.{})) {
|
||||||
|
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
defer glfw.terminate();
|
||||||
|
|
||||||
|
// syntax check only, we don't have a real vulkan instance and so this function would panic.
|
||||||
|
_ = glfw.getInstanceProcAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "syntax" {
|
||||||
|
// Best we can do for these two functions in terms of testing in lieu of an actual Vulkan
|
||||||
|
// context.
|
||||||
|
_ = getPhysicalDevicePresentationSupport;
|
||||||
|
_ = createWindowSurface;
|
||||||
|
_ = initVulkanLoader;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,524 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2011 Kristian Høgsberg
|
||||||
|
* Copyright © 2010-2011 Intel Corporation
|
||||||
|
* Copyright © 2012-2013 Collabora, Ltd.
|
||||||
|
*
|
||||||
|
* 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 (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial
|
||||||
|
* portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_buffer_interface;
|
||||||
|
extern const struct wl_interface wl_callback_interface;
|
||||||
|
extern const struct wl_interface wl_data_device_interface;
|
||||||
|
extern const struct wl_interface wl_data_offer_interface;
|
||||||
|
extern const struct wl_interface wl_data_source_interface;
|
||||||
|
extern const struct wl_interface wl_keyboard_interface;
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_pointer_interface;
|
||||||
|
extern const struct wl_interface wl_region_interface;
|
||||||
|
extern const struct wl_interface wl_registry_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_shell_surface_interface;
|
||||||
|
extern const struct wl_interface wl_shm_pool_interface;
|
||||||
|
extern const struct wl_interface wl_subsurface_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface wl_touch_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *wayland_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_callback_interface,
|
||||||
|
&wl_registry_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_buffer_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_shm_pool_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
&wl_data_source_interface,
|
||||||
|
&wl_data_device_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
&wl_shell_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_buffer_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_callback_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_keyboard_interface,
|
||||||
|
&wl_touch_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_subsurface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_display_requests[] = {
|
||||||
|
{ "sync", "n", wayland_types + 8 },
|
||||||
|
{ "get_registry", "n", wayland_types + 9 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_display_events[] = {
|
||||||
|
{ "error", "ous", wayland_types + 0 },
|
||||||
|
{ "delete_id", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_display_interface = {
|
||||||
|
"wl_display", 1,
|
||||||
|
2, wl_display_requests,
|
||||||
|
2, wl_display_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_registry_requests[] = {
|
||||||
|
{ "bind", "usun", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_registry_events[] = {
|
||||||
|
{ "global", "usu", wayland_types + 0 },
|
||||||
|
{ "global_remove", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_registry_interface = {
|
||||||
|
"wl_registry", 1,
|
||||||
|
1, wl_registry_requests,
|
||||||
|
2, wl_registry_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_callback_events[] = {
|
||||||
|
{ "done", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_callback_interface = {
|
||||||
|
"wl_callback", 1,
|
||||||
|
0, NULL,
|
||||||
|
1, wl_callback_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_compositor_requests[] = {
|
||||||
|
{ "create_surface", "n", wayland_types + 10 },
|
||||||
|
{ "create_region", "n", wayland_types + 11 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_compositor_interface = {
|
||||||
|
"wl_compositor", 6,
|
||||||
|
2, wl_compositor_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_pool_requests[] = {
|
||||||
|
{ "create_buffer", "niiiiu", wayland_types + 12 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "resize", "i", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shm_pool_interface = {
|
||||||
|
"wl_shm_pool", 1,
|
||||||
|
3, wl_shm_pool_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_requests[] = {
|
||||||
|
{ "create_pool", "nhi", wayland_types + 18 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shm_events[] = {
|
||||||
|
{ "format", "u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shm_interface = {
|
||||||
|
"wl_shm", 1,
|
||||||
|
1, wl_shm_requests,
|
||||||
|
1, wl_shm_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_buffer_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_buffer_events[] = {
|
||||||
|
{ "release", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_buffer_interface = {
|
||||||
|
"wl_buffer", 1,
|
||||||
|
1, wl_buffer_requests,
|
||||||
|
1, wl_buffer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_offer_requests[] = {
|
||||||
|
{ "accept", "u?s", wayland_types + 0 },
|
||||||
|
{ "receive", "sh", wayland_types + 0 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "finish", "3", wayland_types + 0 },
|
||||||
|
{ "set_actions", "3uu", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_offer_events[] = {
|
||||||
|
{ "offer", "s", wayland_types + 0 },
|
||||||
|
{ "source_actions", "3u", wayland_types + 0 },
|
||||||
|
{ "action", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_offer_interface = {
|
||||||
|
"wl_data_offer", 3,
|
||||||
|
5, wl_data_offer_requests,
|
||||||
|
3, wl_data_offer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_source_requests[] = {
|
||||||
|
{ "offer", "s", wayland_types + 0 },
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "set_actions", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_source_events[] = {
|
||||||
|
{ "target", "?s", wayland_types + 0 },
|
||||||
|
{ "send", "sh", wayland_types + 0 },
|
||||||
|
{ "cancelled", "", wayland_types + 0 },
|
||||||
|
{ "dnd_drop_performed", "3", wayland_types + 0 },
|
||||||
|
{ "dnd_finished", "3", wayland_types + 0 },
|
||||||
|
{ "action", "3u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_source_interface = {
|
||||||
|
"wl_data_source", 3,
|
||||||
|
3, wl_data_source_requests,
|
||||||
|
6, wl_data_source_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_requests[] = {
|
||||||
|
{ "start_drag", "?oo?ou", wayland_types + 21 },
|
||||||
|
{ "set_selection", "?ou", wayland_types + 25 },
|
||||||
|
{ "release", "2", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_events[] = {
|
||||||
|
{ "data_offer", "n", wayland_types + 27 },
|
||||||
|
{ "enter", "uoff?o", wayland_types + 28 },
|
||||||
|
{ "leave", "", wayland_types + 0 },
|
||||||
|
{ "motion", "uff", wayland_types + 0 },
|
||||||
|
{ "drop", "", wayland_types + 0 },
|
||||||
|
{ "selection", "?o", wayland_types + 33 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_device_interface = {
|
||||||
|
"wl_data_device", 3,
|
||||||
|
3, wl_data_device_requests,
|
||||||
|
6, wl_data_device_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_data_device_manager_requests[] = {
|
||||||
|
{ "create_data_source", "n", wayland_types + 34 },
|
||||||
|
{ "get_data_device", "no", wayland_types + 35 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = {
|
||||||
|
"wl_data_device_manager", 3,
|
||||||
|
2, wl_data_device_manager_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_requests[] = {
|
||||||
|
{ "get_shell_surface", "no", wayland_types + 37 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shell_interface = {
|
||||||
|
"wl_shell", 1,
|
||||||
|
1, wl_shell_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_surface_requests[] = {
|
||||||
|
{ "pong", "u", wayland_types + 0 },
|
||||||
|
{ "move", "ou", wayland_types + 39 },
|
||||||
|
{ "resize", "ouu", wayland_types + 41 },
|
||||||
|
{ "set_toplevel", "", wayland_types + 0 },
|
||||||
|
{ "set_transient", "oiiu", wayland_types + 44 },
|
||||||
|
{ "set_fullscreen", "uu?o", wayland_types + 48 },
|
||||||
|
{ "set_popup", "ouoiiu", wayland_types + 51 },
|
||||||
|
{ "set_maximized", "?o", wayland_types + 57 },
|
||||||
|
{ "set_title", "s", wayland_types + 0 },
|
||||||
|
{ "set_class", "s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_shell_surface_events[] = {
|
||||||
|
{ "ping", "u", wayland_types + 0 },
|
||||||
|
{ "configure", "uii", wayland_types + 0 },
|
||||||
|
{ "popup_done", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_shell_surface_interface = {
|
||||||
|
"wl_shell_surface", 1,
|
||||||
|
10, wl_shell_surface_requests,
|
||||||
|
3, wl_shell_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_surface_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "attach", "?oii", wayland_types + 58 },
|
||||||
|
{ "damage", "iiii", wayland_types + 0 },
|
||||||
|
{ "frame", "n", wayland_types + 61 },
|
||||||
|
{ "set_opaque_region", "?o", wayland_types + 62 },
|
||||||
|
{ "set_input_region", "?o", wayland_types + 63 },
|
||||||
|
{ "commit", "", wayland_types + 0 },
|
||||||
|
{ "set_buffer_transform", "2i", wayland_types + 0 },
|
||||||
|
{ "set_buffer_scale", "3i", wayland_types + 0 },
|
||||||
|
{ "damage_buffer", "4iiii", wayland_types + 0 },
|
||||||
|
{ "offset", "5ii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_surface_events[] = {
|
||||||
|
{ "enter", "o", wayland_types + 64 },
|
||||||
|
{ "leave", "o", wayland_types + 65 },
|
||||||
|
{ "preferred_buffer_scale", "6i", wayland_types + 0 },
|
||||||
|
{ "preferred_buffer_transform", "6u", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_surface_interface = {
|
||||||
|
"wl_surface", 6,
|
||||||
|
11, wl_surface_requests,
|
||||||
|
4, wl_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_seat_requests[] = {
|
||||||
|
{ "get_pointer", "n", wayland_types + 66 },
|
||||||
|
{ "get_keyboard", "n", wayland_types + 67 },
|
||||||
|
{ "get_touch", "n", wayland_types + 68 },
|
||||||
|
{ "release", "5", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_seat_events[] = {
|
||||||
|
{ "capabilities", "u", wayland_types + 0 },
|
||||||
|
{ "name", "2s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_seat_interface = {
|
||||||
|
"wl_seat", 9,
|
||||||
|
4, wl_seat_requests,
|
||||||
|
2, wl_seat_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_pointer_requests[] = {
|
||||||
|
{ "set_cursor", "u?oii", wayland_types + 69 },
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_pointer_events[] = {
|
||||||
|
{ "enter", "uoff", wayland_types + 73 },
|
||||||
|
{ "leave", "uo", wayland_types + 77 },
|
||||||
|
{ "motion", "uff", wayland_types + 0 },
|
||||||
|
{ "button", "uuuu", wayland_types + 0 },
|
||||||
|
{ "axis", "uuf", wayland_types + 0 },
|
||||||
|
{ "frame", "5", wayland_types + 0 },
|
||||||
|
{ "axis_source", "5u", wayland_types + 0 },
|
||||||
|
{ "axis_stop", "5uu", wayland_types + 0 },
|
||||||
|
{ "axis_discrete", "5ui", wayland_types + 0 },
|
||||||
|
{ "axis_value120", "8ui", wayland_types + 0 },
|
||||||
|
{ "axis_relative_direction", "9uu", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_pointer_interface = {
|
||||||
|
"wl_pointer", 9,
|
||||||
|
2, wl_pointer_requests,
|
||||||
|
11, wl_pointer_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_keyboard_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_keyboard_events[] = {
|
||||||
|
{ "keymap", "uhu", wayland_types + 0 },
|
||||||
|
{ "enter", "uoa", wayland_types + 79 },
|
||||||
|
{ "leave", "uo", wayland_types + 82 },
|
||||||
|
{ "key", "uuuu", wayland_types + 0 },
|
||||||
|
{ "modifiers", "uuuuu", wayland_types + 0 },
|
||||||
|
{ "repeat_info", "4ii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_keyboard_interface = {
|
||||||
|
"wl_keyboard", 9,
|
||||||
|
1, wl_keyboard_requests,
|
||||||
|
6, wl_keyboard_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_touch_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_touch_events[] = {
|
||||||
|
{ "down", "uuoiff", wayland_types + 84 },
|
||||||
|
{ "up", "uui", wayland_types + 0 },
|
||||||
|
{ "motion", "uiff", wayland_types + 0 },
|
||||||
|
{ "frame", "", wayland_types + 0 },
|
||||||
|
{ "cancel", "", wayland_types + 0 },
|
||||||
|
{ "shape", "6iff", wayland_types + 0 },
|
||||||
|
{ "orientation", "6if", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_touch_interface = {
|
||||||
|
"wl_touch", 9,
|
||||||
|
1, wl_touch_requests,
|
||||||
|
7, wl_touch_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_output_requests[] = {
|
||||||
|
{ "release", "3", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_output_events[] = {
|
||||||
|
{ "geometry", "iiiiissi", wayland_types + 0 },
|
||||||
|
{ "mode", "uiii", wayland_types + 0 },
|
||||||
|
{ "done", "2", wayland_types + 0 },
|
||||||
|
{ "scale", "2i", wayland_types + 0 },
|
||||||
|
{ "name", "4s", wayland_types + 0 },
|
||||||
|
{ "description", "4s", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_output_interface = {
|
||||||
|
"wl_output", 4,
|
||||||
|
1, wl_output_requests,
|
||||||
|
6, wl_output_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_region_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "add", "iiii", wayland_types + 0 },
|
||||||
|
{ "subtract", "iiii", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_region_interface = {
|
||||||
|
"wl_region", 1,
|
||||||
|
3, wl_region_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_subcompositor_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "get_subsurface", "noo", wayland_types + 90 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_subcompositor_interface = {
|
||||||
|
"wl_subcompositor", 1,
|
||||||
|
2, wl_subcompositor_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wl_subsurface_requests[] = {
|
||||||
|
{ "destroy", "", wayland_types + 0 },
|
||||||
|
{ "set_position", "ii", wayland_types + 0 },
|
||||||
|
{ "place_above", "o", wayland_types + 93 },
|
||||||
|
{ "place_below", "o", wayland_types + 94 },
|
||||||
|
{ "set_sync", "", wayland_types + 0 },
|
||||||
|
{ "set_desync", "", wayland_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wl_subsurface_interface = {
|
||||||
|
"wl_subsurface", 1,
|
||||||
|
6, wl_subsurface_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
68
pkg/glfw/wayland-headers/wayland-idle-inhibit-unstable-v1-client-protocol-code.h
vendored
Executable file
68
pkg/glfw/wayland-headers/wayland-idle-inhibit-unstable-v1-client-protocol-code.h
vendored
Executable file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2015 Samsung Electronics Co., Ltd
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface zwp_idle_inhibitor_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *idle_inhibit_unstable_v1_types[] = {
|
||||||
|
&zwp_idle_inhibitor_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_idle_inhibit_manager_v1_requests[] = {
|
||||||
|
{ "destroy", "", idle_inhibit_unstable_v1_types + 0 },
|
||||||
|
{ "create_inhibitor", "no", idle_inhibit_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_idle_inhibit_manager_v1_interface = {
|
||||||
|
"zwp_idle_inhibit_manager_v1", 1,
|
||||||
|
2, zwp_idle_inhibit_manager_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_idle_inhibitor_v1_requests[] = {
|
||||||
|
{ "destroy", "", idle_inhibit_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_idle_inhibitor_v1_interface = {
|
||||||
|
"zwp_idle_inhibitor_v1", 1,
|
||||||
|
1, zwp_idle_inhibitor_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
232
pkg/glfw/wayland-headers/wayland-idle-inhibit-unstable-v1-client-protocol.h
vendored
Executable file
232
pkg/glfw/wayland-headers/wayland-idle-inhibit-unstable-v1-client-protocol.h
vendored
Executable file
|
|
@ -0,0 +1,232 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
#ifndef IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define IDLE_INHIBIT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_idle_inhibit_unstable_v1 The idle_inhibit_unstable_v1 protocol
|
||||||
|
* @section page_ifaces_idle_inhibit_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zwp_idle_inhibit_manager_v1 - control behavior when display idles
|
||||||
|
* - @subpage page_iface_zwp_idle_inhibitor_v1 - context object for inhibiting idle behavior
|
||||||
|
* @section page_copyright_idle_inhibit_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2015 Samsung Electronics Co., Ltd
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_surface;
|
||||||
|
struct zwp_idle_inhibit_manager_v1;
|
||||||
|
struct zwp_idle_inhibitor_v1;
|
||||||
|
|
||||||
|
#ifndef ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE
|
||||||
|
#define ZWP_IDLE_INHIBIT_MANAGER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_idle_inhibit_manager_v1 zwp_idle_inhibit_manager_v1
|
||||||
|
* @section page_iface_zwp_idle_inhibit_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* This interface permits inhibiting the idle behavior such as screen
|
||||||
|
* blanking, locking, and screensaving. The client binds the idle manager
|
||||||
|
* globally, then creates idle-inhibitor objects for each surface.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
* @section page_iface_zwp_idle_inhibit_manager_v1_api API
|
||||||
|
* See @ref iface_zwp_idle_inhibit_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_idle_inhibit_manager_v1 The zwp_idle_inhibit_manager_v1 interface
|
||||||
|
*
|
||||||
|
* This interface permits inhibiting the idle behavior such as screen
|
||||||
|
* blanking, locking, and screensaving. The client binds the idle manager
|
||||||
|
* globally, then creates idle-inhibitor objects for each surface.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_idle_inhibit_manager_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_IDLE_INHIBITOR_V1_INTERFACE
|
||||||
|
#define ZWP_IDLE_INHIBITOR_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_idle_inhibitor_v1 zwp_idle_inhibitor_v1
|
||||||
|
* @section page_iface_zwp_idle_inhibitor_v1_desc Description
|
||||||
|
*
|
||||||
|
* An idle inhibitor prevents the output that the associated surface is
|
||||||
|
* visible on from being set to a state where it is not visually usable due
|
||||||
|
* to lack of user interaction (e.g. blanked, dimmed, locked, set to power
|
||||||
|
* save, etc.) Any screensaver processes are also blocked from displaying.
|
||||||
|
*
|
||||||
|
* If the surface is destroyed, unmapped, becomes occluded, loses
|
||||||
|
* visibility, or otherwise becomes not visually relevant for the user, the
|
||||||
|
* idle inhibitor will not be honored by the compositor; if the surface
|
||||||
|
* subsequently regains visibility the inhibitor takes effect once again.
|
||||||
|
* Likewise, the inhibitor isn't honored if the system was already idled at
|
||||||
|
* the time the inhibitor was established, although if the system later
|
||||||
|
* de-idles and re-idles the inhibitor will take effect.
|
||||||
|
* @section page_iface_zwp_idle_inhibitor_v1_api API
|
||||||
|
* See @ref iface_zwp_idle_inhibitor_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_idle_inhibitor_v1 The zwp_idle_inhibitor_v1 interface
|
||||||
|
*
|
||||||
|
* An idle inhibitor prevents the output that the associated surface is
|
||||||
|
* visible on from being set to a state where it is not visually usable due
|
||||||
|
* to lack of user interaction (e.g. blanked, dimmed, locked, set to power
|
||||||
|
* save, etc.) Any screensaver processes are also blocked from displaying.
|
||||||
|
*
|
||||||
|
* If the surface is destroyed, unmapped, becomes occluded, loses
|
||||||
|
* visibility, or otherwise becomes not visually relevant for the user, the
|
||||||
|
* idle inhibitor will not be honored by the compositor; if the surface
|
||||||
|
* subsequently regains visibility the inhibitor takes effect once again.
|
||||||
|
* Likewise, the inhibitor isn't honored if the system was already idled at
|
||||||
|
* the time the inhibitor was established, although if the system later
|
||||||
|
* de-idles and re-idles the inhibitor will take effect.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_idle_inhibitor_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY 0
|
||||||
|
#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibit_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibit_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_idle_inhibit_manager_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_idle_inhibit_manager_v1_set_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_idle_inhibit_manager_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_idle_inhibit_manager_v1_get_user_data(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibit_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_idle_inhibit_manager_v1_get_version(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibit_manager_v1
|
||||||
|
*
|
||||||
|
* Destroy the inhibit manager.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_idle_inhibit_manager_v1_destroy(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1,
|
||||||
|
ZWP_IDLE_INHIBIT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibit_manager_v1
|
||||||
|
*
|
||||||
|
* Create a new inhibitor object associated with the given surface.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_idle_inhibitor_v1 *
|
||||||
|
zwp_idle_inhibit_manager_v1_create_inhibitor(struct zwp_idle_inhibit_manager_v1 *zwp_idle_inhibit_manager_v1, struct wl_surface *surface)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibit_manager_v1,
|
||||||
|
ZWP_IDLE_INHIBIT_MANAGER_V1_CREATE_INHIBITOR, &zwp_idle_inhibitor_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibit_manager_v1), 0, NULL, surface);
|
||||||
|
|
||||||
|
return (struct zwp_idle_inhibitor_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_IDLE_INHIBITOR_V1_DESTROY 0
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibitor_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_IDLE_INHIBITOR_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_idle_inhibitor_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_idle_inhibitor_v1_set_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_idle_inhibitor_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_idle_inhibitor_v1_get_user_data(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_idle_inhibitor_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_idle_inhibitor_v1_get_version(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_idle_inhibitor_v1
|
||||||
|
*
|
||||||
|
* Remove the inhibitor effect from the associated wl_surface.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_idle_inhibitor_v1_destroy(struct zwp_idle_inhibitor_v1 *zwp_idle_inhibitor_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_idle_inhibitor_v1,
|
||||||
|
ZWP_IDLE_INHIBITOR_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_idle_inhibitor_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
108
pkg/glfw/wayland-headers/wayland-pointer-constraints-unstable-v1-client-protocol-code.h
vendored
Executable file
108
pkg/glfw/wayland-headers/wayland-pointer-constraints-unstable-v1-client-protocol-code.h
vendored
Executable file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_pointer_interface;
|
||||||
|
extern const struct wl_interface wl_region_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface zwp_confined_pointer_v1_interface;
|
||||||
|
extern const struct wl_interface zwp_locked_pointer_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *pointer_constraints_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zwp_locked_pointer_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
NULL,
|
||||||
|
&zwp_confined_pointer_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_pointer_constraints_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 2 },
|
||||||
|
{ "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 7 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_pointer_constraints_v1_interface = {
|
||||||
|
"zwp_pointer_constraints_v1", 1,
|
||||||
|
3, zwp_pointer_constraints_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_locked_pointer_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_region", "?o", pointer_constraints_unstable_v1_types + 12 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_locked_pointer_v1_events[] = {
|
||||||
|
{ "locked", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "unlocked", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_locked_pointer_v1_interface = {
|
||||||
|
"zwp_locked_pointer_v1", 1,
|
||||||
|
3, zwp_locked_pointer_v1_requests,
|
||||||
|
2, zwp_locked_pointer_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_confined_pointer_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_region", "?o", pointer_constraints_unstable_v1_types + 13 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_confined_pointer_v1_events[] = {
|
||||||
|
{ "confined", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "unconfined", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_confined_pointer_v1_interface = {
|
||||||
|
"zwp_confined_pointer_v1", 1,
|
||||||
|
2, zwp_confined_pointer_v1_requests,
|
||||||
|
2, zwp_confined_pointer_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
667
pkg/glfw/wayland-headers/wayland-pointer-constraints-unstable-v1-client-protocol.h
vendored
Executable file
667
pkg/glfw/wayland-headers/wayland-pointer-constraints-unstable-v1-client-protocol.h
vendored
Executable file
|
|
@ -0,0 +1,667 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
#ifndef POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_pointer_constraints_unstable_v1 The pointer_constraints_unstable_v1 protocol
|
||||||
|
* protocol for constraining pointer motions
|
||||||
|
*
|
||||||
|
* @section page_desc_pointer_constraints_unstable_v1 Description
|
||||||
|
*
|
||||||
|
* This protocol specifies a set of interfaces used for adding constraints to
|
||||||
|
* the motion of a pointer. Possible constraints include confining pointer
|
||||||
|
* motions to a given region, or locking it to its current position.
|
||||||
|
*
|
||||||
|
* In order to constrain the pointer, a client must first bind the global
|
||||||
|
* interface "wp_pointer_constraints" which, if a compositor supports pointer
|
||||||
|
* constraints, is exposed by the registry. Using the bound global object, the
|
||||||
|
* client uses the request that corresponds to the type of constraint it wants
|
||||||
|
* to make. See wp_pointer_constraints for more details.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and backward
|
||||||
|
* incompatible changes may be made. Backward compatible changes may be added
|
||||||
|
* together with the corresponding interface version bump. Backward
|
||||||
|
* incompatible changes are done by bumping the version number in the protocol
|
||||||
|
* and interface names and resetting the interface version. Once the protocol
|
||||||
|
* is to be declared stable, the 'z' prefix and the version number in the
|
||||||
|
* protocol and interface names are removed and the interface version number is
|
||||||
|
* reset.
|
||||||
|
*
|
||||||
|
* @section page_ifaces_pointer_constraints_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zwp_pointer_constraints_v1 - constrain the movement of a pointer
|
||||||
|
* - @subpage page_iface_zwp_locked_pointer_v1 - receive relative pointer motion events
|
||||||
|
* - @subpage page_iface_zwp_confined_pointer_v1 - confined pointer object
|
||||||
|
* @section page_copyright_pointer_constraints_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_pointer;
|
||||||
|
struct wl_region;
|
||||||
|
struct wl_surface;
|
||||||
|
struct zwp_confined_pointer_v1;
|
||||||
|
struct zwp_locked_pointer_v1;
|
||||||
|
struct zwp_pointer_constraints_v1;
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_INTERFACE
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_pointer_constraints_v1 zwp_pointer_constraints_v1
|
||||||
|
* @section page_iface_zwp_pointer_constraints_v1_desc Description
|
||||||
|
*
|
||||||
|
* The global interface exposing pointer constraining functionality. It
|
||||||
|
* exposes two requests: lock_pointer for locking the pointer to its
|
||||||
|
* position, and confine_pointer for locking the pointer to a region.
|
||||||
|
*
|
||||||
|
* The lock_pointer and confine_pointer requests create the objects
|
||||||
|
* wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||||
|
* use these objects to interact with the lock.
|
||||||
|
*
|
||||||
|
* For any surface, only one lock or confinement may be active across all
|
||||||
|
* wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||||
|
* when another lock or confinement is active or requested on the same surface
|
||||||
|
* and with any of the wl_pointer objects of the same seat, an
|
||||||
|
* 'already_constrained' error will be raised.
|
||||||
|
* @section page_iface_zwp_pointer_constraints_v1_api API
|
||||||
|
* See @ref iface_zwp_pointer_constraints_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_pointer_constraints_v1 The zwp_pointer_constraints_v1 interface
|
||||||
|
*
|
||||||
|
* The global interface exposing pointer constraining functionality. It
|
||||||
|
* exposes two requests: lock_pointer for locking the pointer to its
|
||||||
|
* position, and confine_pointer for locking the pointer to a region.
|
||||||
|
*
|
||||||
|
* The lock_pointer and confine_pointer requests create the objects
|
||||||
|
* wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||||
|
* use these objects to interact with the lock.
|
||||||
|
*
|
||||||
|
* For any surface, only one lock or confinement may be active across all
|
||||||
|
* wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||||
|
* when another lock or confinement is active or requested on the same surface
|
||||||
|
* and with any of the wl_pointer objects of the same seat, an
|
||||||
|
* 'already_constrained' error will be raised.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_pointer_constraints_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_LOCKED_POINTER_V1_INTERFACE
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_locked_pointer_v1 zwp_locked_pointer_v1
|
||||||
|
* @section page_iface_zwp_locked_pointer_v1_desc Description
|
||||||
|
*
|
||||||
|
* The wp_locked_pointer interface represents a locked pointer state.
|
||||||
|
*
|
||||||
|
* While the lock of this object is active, the wl_pointer objects of the
|
||||||
|
* associated seat will not emit any wl_pointer.motion events.
|
||||||
|
*
|
||||||
|
* This object will send the event 'locked' when the lock is activated.
|
||||||
|
* Whenever the lock is activated, it is guaranteed that the locked surface
|
||||||
|
* will already have received pointer focus and that the pointer will be
|
||||||
|
* within the region passed to the request creating this object.
|
||||||
|
*
|
||||||
|
* To unlock the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_locked_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unlock the pointer the unlocked event is
|
||||||
|
* sent. See wp_locked_pointer.unlock for details.
|
||||||
|
*
|
||||||
|
* When unlocking, the compositor may warp the cursor position to the set
|
||||||
|
* cursor position hint. If it does, it will not result in any relative
|
||||||
|
* motion events emitted via wp_relative_pointer.
|
||||||
|
*
|
||||||
|
* If the surface the lock was requested on is destroyed and the lock is not
|
||||||
|
* yet activated, the wp_locked_pointer object is now defunct and must be
|
||||||
|
* destroyed.
|
||||||
|
* @section page_iface_zwp_locked_pointer_v1_api API
|
||||||
|
* See @ref iface_zwp_locked_pointer_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_locked_pointer_v1 The zwp_locked_pointer_v1 interface
|
||||||
|
*
|
||||||
|
* The wp_locked_pointer interface represents a locked pointer state.
|
||||||
|
*
|
||||||
|
* While the lock of this object is active, the wl_pointer objects of the
|
||||||
|
* associated seat will not emit any wl_pointer.motion events.
|
||||||
|
*
|
||||||
|
* This object will send the event 'locked' when the lock is activated.
|
||||||
|
* Whenever the lock is activated, it is guaranteed that the locked surface
|
||||||
|
* will already have received pointer focus and that the pointer will be
|
||||||
|
* within the region passed to the request creating this object.
|
||||||
|
*
|
||||||
|
* To unlock the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_locked_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unlock the pointer the unlocked event is
|
||||||
|
* sent. See wp_locked_pointer.unlock for details.
|
||||||
|
*
|
||||||
|
* When unlocking, the compositor may warp the cursor position to the set
|
||||||
|
* cursor position hint. If it does, it will not result in any relative
|
||||||
|
* motion events emitted via wp_relative_pointer.
|
||||||
|
*
|
||||||
|
* If the surface the lock was requested on is destroyed and the lock is not
|
||||||
|
* yet activated, the wp_locked_pointer object is now defunct and must be
|
||||||
|
* destroyed.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_locked_pointer_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_CONFINED_POINTER_V1_INTERFACE
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_confined_pointer_v1 zwp_confined_pointer_v1
|
||||||
|
* @section page_iface_zwp_confined_pointer_v1_desc Description
|
||||||
|
*
|
||||||
|
* The wp_confined_pointer interface represents a confined pointer state.
|
||||||
|
*
|
||||||
|
* This object will send the event 'confined' when the confinement is
|
||||||
|
* activated. Whenever the confinement is activated, it is guaranteed that
|
||||||
|
* the surface the pointer is confined to will already have received pointer
|
||||||
|
* focus and that the pointer will be within the region passed to the request
|
||||||
|
* creating this object. It is up to the compositor to decide whether this
|
||||||
|
* requires some user interaction and if the pointer will warp to within the
|
||||||
|
* passed region if outside.
|
||||||
|
*
|
||||||
|
* To unconfine the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_confined_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unconfine the pointer the unconfined event is
|
||||||
|
* sent. The wp_confined_pointer object is at this point defunct and should
|
||||||
|
* be destroyed.
|
||||||
|
* @section page_iface_zwp_confined_pointer_v1_api API
|
||||||
|
* See @ref iface_zwp_confined_pointer_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_confined_pointer_v1 The zwp_confined_pointer_v1 interface
|
||||||
|
*
|
||||||
|
* The wp_confined_pointer interface represents a confined pointer state.
|
||||||
|
*
|
||||||
|
* This object will send the event 'confined' when the confinement is
|
||||||
|
* activated. Whenever the confinement is activated, it is guaranteed that
|
||||||
|
* the surface the pointer is confined to will already have received pointer
|
||||||
|
* focus and that the pointer will be within the region passed to the request
|
||||||
|
* creating this object. It is up to the compositor to decide whether this
|
||||||
|
* requires some user interaction and if the pointer will warp to within the
|
||||||
|
* passed region if outside.
|
||||||
|
*
|
||||||
|
* To unconfine the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_confined_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unconfine the pointer the unconfined event is
|
||||||
|
* sent. The wp_confined_pointer object is at this point defunct and should
|
||||||
|
* be destroyed.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_confined_pointer_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
* wp_pointer_constraints error values
|
||||||
|
*
|
||||||
|
* These errors can be emitted in response to wp_pointer_constraints
|
||||||
|
* requests.
|
||||||
|
*/
|
||||||
|
enum zwp_pointer_constraints_v1_error {
|
||||||
|
/**
|
||||||
|
* pointer constraint already requested on that surface
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED = 1,
|
||||||
|
};
|
||||||
|
#endif /* ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
* constraint lifetime
|
||||||
|
*
|
||||||
|
* These values represent different lifetime semantics. They are passed
|
||||||
|
* as arguments to the factory requests to specify how the constraint
|
||||||
|
* lifetimes should be managed.
|
||||||
|
*/
|
||||||
|
enum zwp_pointer_constraints_v1_lifetime {
|
||||||
|
/**
|
||||||
|
* the pointer constraint is defunct once deactivated
|
||||||
|
*
|
||||||
|
* A oneshot pointer constraint will never reactivate once it has
|
||||||
|
* been deactivated. See the corresponding deactivation event
|
||||||
|
* (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined)
|
||||||
|
* for details.
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT = 1,
|
||||||
|
/**
|
||||||
|
* the pointer constraint may reactivate
|
||||||
|
*
|
||||||
|
* A persistent pointer constraint may again reactivate once it
|
||||||
|
* has been deactivated. See the corresponding deactivation event
|
||||||
|
* (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined)
|
||||||
|
* for details.
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM */
|
||||||
|
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY 0
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER 1
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER 2
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_pointer_constraints_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_pointer_constraints_v1_set_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_pointer_constraints_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_pointer_constraints_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_pointer_constraints_v1_get_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_pointer_constraints_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_pointer_constraints_v1_get_version(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* Used by the client to notify the server that it will no longer use this
|
||||||
|
* pointer constraints object.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* The lock_pointer request lets the client request to disable movements of
|
||||||
|
* the virtual pointer (i.e. the cursor), effectively locking the pointer
|
||||||
|
* to a position. This request may not take effect immediately; in the
|
||||||
|
* future, when the compositor deems implementation-specific constraints
|
||||||
|
* are satisfied, the pointer lock will be activated and the compositor
|
||||||
|
* sends a locked event.
|
||||||
|
*
|
||||||
|
* The protocol provides no guarantee that the constraints are ever
|
||||||
|
* satisfied, and does not require the compositor to send an error if the
|
||||||
|
* constraints cannot ever be satisfied. It is thus possible to request a
|
||||||
|
* lock that will never activate.
|
||||||
|
*
|
||||||
|
* There may not be another pointer constraint of any kind requested or
|
||||||
|
* active on the surface for any of the wl_pointer objects of the seat of
|
||||||
|
* the passed pointer when requesting a lock. If there is, an error will be
|
||||||
|
* raised. See general pointer lock documentation for more details.
|
||||||
|
*
|
||||||
|
* The intersection of the region passed with this request and the input
|
||||||
|
* region of the surface is used to determine where the pointer must be
|
||||||
|
* in order for the lock to activate. It is up to the compositor whether to
|
||||||
|
* warp the pointer or require some kind of user interaction for the lock
|
||||||
|
* to activate. If the region is null the surface input region is used.
|
||||||
|
*
|
||||||
|
* A surface may receive pointer focus without the lock being activated.
|
||||||
|
*
|
||||||
|
* The request creates a new object wp_locked_pointer which is used to
|
||||||
|
* interact with the lock as well as receive updates about its state. See
|
||||||
|
* the the description of wp_locked_pointer for further information.
|
||||||
|
*
|
||||||
|
* Note that while a pointer is locked, the wl_pointer objects of the
|
||||||
|
* corresponding seat will not emit any wl_pointer.motion events, but
|
||||||
|
* relative motion events will still be emitted via wp_relative_pointer
|
||||||
|
* objects of the same seat. wl_pointer.axis and wl_pointer.button events
|
||||||
|
* are unaffected.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_locked_pointer_v1 *
|
||||||
|
zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER, &zwp_locked_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime);
|
||||||
|
|
||||||
|
return (struct zwp_locked_pointer_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* The confine_pointer request lets the client request to confine the
|
||||||
|
* pointer cursor to a given region. This request may not take effect
|
||||||
|
* immediately; in the future, when the compositor deems implementation-
|
||||||
|
* specific constraints are satisfied, the pointer confinement will be
|
||||||
|
* activated and the compositor sends a confined event.
|
||||||
|
*
|
||||||
|
* The intersection of the region passed with this request and the input
|
||||||
|
* region of the surface is used to determine where the pointer must be
|
||||||
|
* in order for the confinement to activate. It is up to the compositor
|
||||||
|
* whether to warp the pointer or require some kind of user interaction for
|
||||||
|
* the confinement to activate. If the region is null the surface input
|
||||||
|
* region is used.
|
||||||
|
*
|
||||||
|
* The request will create a new object wp_confined_pointer which is used
|
||||||
|
* to interact with the confinement as well as receive updates about its
|
||||||
|
* state. See the the description of wp_confined_pointer for further
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_confined_pointer_v1 *
|
||||||
|
zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER, &zwp_confined_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime);
|
||||||
|
|
||||||
|
return (struct zwp_confined_pointer_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
* @struct zwp_locked_pointer_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwp_locked_pointer_v1_listener {
|
||||||
|
/**
|
||||||
|
* lock activation event
|
||||||
|
*
|
||||||
|
* Notification that the pointer lock of the seat's pointer is
|
||||||
|
* activated.
|
||||||
|
*/
|
||||||
|
void (*locked)(void *data,
|
||||||
|
struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
|
||||||
|
/**
|
||||||
|
* lock deactivation event
|
||||||
|
*
|
||||||
|
* Notification that the pointer lock of the seat's pointer is no
|
||||||
|
* longer active. If this is a oneshot pointer lock (see
|
||||||
|
* wp_pointer_constraints.lifetime) this object is now defunct and
|
||||||
|
* should be destroyed. If this is a persistent pointer lock (see
|
||||||
|
* wp_pointer_constraints.lifetime) this pointer lock may again
|
||||||
|
* reactivate in the future.
|
||||||
|
*/
|
||||||
|
void (*unlocked)(void *data,
|
||||||
|
struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1,
|
||||||
|
const struct zwp_locked_pointer_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_DESTROY 0
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT 1
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_REGION 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_LOCKED_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_UNLOCKED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_REGION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_locked_pointer_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_locked_pointer_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_locked_pointer_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_locked_pointer_v1_get_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_locked_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_locked_pointer_v1_get_version(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Destroy the locked pointer object. If applicable, the compositor will
|
||||||
|
* unlock the pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Set the cursor position hint relative to the top left corner of the
|
||||||
|
* surface.
|
||||||
|
*
|
||||||
|
* If the client is drawing its own cursor, it should update the position
|
||||||
|
* hint to the position of its own cursor. A compositor may use this
|
||||||
|
* information to warp the pointer upon unlock in order to avoid pointer
|
||||||
|
* jumps.
|
||||||
|
*
|
||||||
|
* The cursor position hint is double buffered. The new hint will only take
|
||||||
|
* effect when the associated surface gets it pending state applied. See
|
||||||
|
* wl_surface.commit for details.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_cursor_position_hint(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, surface_x, surface_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Set a new region used to lock the pointer.
|
||||||
|
*
|
||||||
|
* The new lock region is double-buffered. The new lock region will
|
||||||
|
* only take effect when the associated surface gets its pending state
|
||||||
|
* applied. See wl_surface.commit for details.
|
||||||
|
*
|
||||||
|
* For details about the lock region, see wp_locked_pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_region(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, struct wl_region *region)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
* @struct zwp_confined_pointer_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwp_confined_pointer_v1_listener {
|
||||||
|
/**
|
||||||
|
* pointer confined
|
||||||
|
*
|
||||||
|
* Notification that the pointer confinement of the seat's
|
||||||
|
* pointer is activated.
|
||||||
|
*/
|
||||||
|
void (*confined)(void *data,
|
||||||
|
struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
|
||||||
|
/**
|
||||||
|
* pointer unconfined
|
||||||
|
*
|
||||||
|
* Notification that the pointer confinement of the seat's
|
||||||
|
* pointer is no longer active. If this is a oneshot pointer
|
||||||
|
* confinement (see wp_pointer_constraints.lifetime) this object is
|
||||||
|
* now defunct and should be destroyed. If this is a persistent
|
||||||
|
* pointer confinement (see wp_pointer_constraints.lifetime) this
|
||||||
|
* pointer confinement may again reactivate in the future.
|
||||||
|
*/
|
||||||
|
void (*unconfined)(void *data,
|
||||||
|
struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1,
|
||||||
|
const struct zwp_confined_pointer_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_DESTROY 0
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_SET_REGION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_CONFINED_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_UNCONFINED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_SET_REGION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_confined_pointer_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_set_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_confined_pointer_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_confined_pointer_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_confined_pointer_v1_get_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_confined_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_confined_pointer_v1_get_version(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*
|
||||||
|
* Destroy the confined pointer object. If applicable, the compositor will
|
||||||
|
* unconfine the pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
ZWP_CONFINED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*
|
||||||
|
* Set a new region used to confine the pointer.
|
||||||
|
*
|
||||||
|
* The new confine region is double-buffered. The new confine region will
|
||||||
|
* only take effect when the associated surface gets its pending state
|
||||||
|
* applied. See wl_surface.commit for details.
|
||||||
|
*
|
||||||
|
* If the confinement is active when the new confinement region is applied
|
||||||
|
* and the pointer ends up outside of newly applied region, the pointer may
|
||||||
|
* warped to a position within the new confinement region. If warped, a
|
||||||
|
* wl_pointer.motion event will be emitted, but no
|
||||||
|
* wp_relative_pointer.relative_motion event.
|
||||||
|
*
|
||||||
|
* The compositor may also, instead of using the new region, unconfine the
|
||||||
|
* pointer.
|
||||||
|
*
|
||||||
|
* For details about the confine region, see wp_confined_pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_set_region(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, struct wl_region *region)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
ZWP_CONFINED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), 0, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
79
pkg/glfw/wayland-headers/wayland-relative-pointer-unstable-v1-client-protocol-code.h
vendored
Executable file
79
pkg/glfw/wayland-headers/wayland-relative-pointer-unstable-v1-client-protocol-code.h
vendored
Executable file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_pointer_interface;
|
||||||
|
extern const struct wl_interface zwp_relative_pointer_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *relative_pointer_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zwp_relative_pointer_v1_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_relative_pointer_manager_v1_requests[] = {
|
||||||
|
{ "destroy", "", relative_pointer_unstable_v1_types + 0 },
|
||||||
|
{ "get_relative_pointer", "no", relative_pointer_unstable_v1_types + 6 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_relative_pointer_manager_v1_interface = {
|
||||||
|
"zwp_relative_pointer_manager_v1", 1,
|
||||||
|
2, zwp_relative_pointer_manager_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_relative_pointer_v1_requests[] = {
|
||||||
|
{ "destroy", "", relative_pointer_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_relative_pointer_v1_events[] = {
|
||||||
|
{ "relative_motion", "uuffff", relative_pointer_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwp_relative_pointer_v1_interface = {
|
||||||
|
"zwp_relative_pointer_v1", 1,
|
||||||
|
1, zwp_relative_pointer_v1_requests,
|
||||||
|
1, zwp_relative_pointer_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
297
pkg/glfw/wayland-headers/wayland-relative-pointer-unstable-v1-client-protocol.h
vendored
Executable file
297
pkg/glfw/wayland-headers/wayland-relative-pointer-unstable-v1-client-protocol.h
vendored
Executable file
|
|
@ -0,0 +1,297 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
#ifndef RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define RELATIVE_POINTER_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_relative_pointer_unstable_v1 The relative_pointer_unstable_v1 protocol
|
||||||
|
* protocol for relative pointer motion events
|
||||||
|
*
|
||||||
|
* @section page_desc_relative_pointer_unstable_v1 Description
|
||||||
|
*
|
||||||
|
* This protocol specifies a set of interfaces used for making clients able to
|
||||||
|
* receive relative pointer events not obstructed by barriers (such as the
|
||||||
|
* monitor edge or other pointer barriers).
|
||||||
|
*
|
||||||
|
* To start receiving relative pointer events, a client must first bind the
|
||||||
|
* global interface "wp_relative_pointer_manager" which, if a compositor
|
||||||
|
* supports relative pointer motion events, is exposed by the registry. After
|
||||||
|
* having created the relative pointer manager proxy object, the client uses
|
||||||
|
* it to create the actual relative pointer object using the
|
||||||
|
* "get_relative_pointer" request given a wl_pointer. The relative pointer
|
||||||
|
* motion events will then, when applicable, be transmitted via the proxy of
|
||||||
|
* the newly created relative pointer object. See the documentation of the
|
||||||
|
* relative pointer interface for more details.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and backward
|
||||||
|
* incompatible changes may be made. Backward compatible changes may be added
|
||||||
|
* together with the corresponding interface version bump. Backward
|
||||||
|
* incompatible changes are done by bumping the version number in the protocol
|
||||||
|
* and interface names and resetting the interface version. Once the protocol
|
||||||
|
* is to be declared stable, the 'z' prefix and the version number in the
|
||||||
|
* protocol and interface names are removed and the interface version number is
|
||||||
|
* reset.
|
||||||
|
*
|
||||||
|
* @section page_ifaces_relative_pointer_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zwp_relative_pointer_manager_v1 - get relative pointer objects
|
||||||
|
* - @subpage page_iface_zwp_relative_pointer_v1 - relative pointer object
|
||||||
|
* @section page_copyright_relative_pointer_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_pointer;
|
||||||
|
struct zwp_relative_pointer_manager_v1;
|
||||||
|
struct zwp_relative_pointer_v1;
|
||||||
|
|
||||||
|
#ifndef ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE
|
||||||
|
#define ZWP_RELATIVE_POINTER_MANAGER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_relative_pointer_manager_v1 zwp_relative_pointer_manager_v1
|
||||||
|
* @section page_iface_zwp_relative_pointer_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* A global interface used for getting the relative pointer object for a
|
||||||
|
* given pointer.
|
||||||
|
* @section page_iface_zwp_relative_pointer_manager_v1_api API
|
||||||
|
* See @ref iface_zwp_relative_pointer_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_relative_pointer_manager_v1 The zwp_relative_pointer_manager_v1 interface
|
||||||
|
*
|
||||||
|
* A global interface used for getting the relative pointer object for a
|
||||||
|
* given pointer.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_relative_pointer_manager_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_RELATIVE_POINTER_V1_INTERFACE
|
||||||
|
#define ZWP_RELATIVE_POINTER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_relative_pointer_v1 zwp_relative_pointer_v1
|
||||||
|
* @section page_iface_zwp_relative_pointer_v1_desc Description
|
||||||
|
*
|
||||||
|
* A wp_relative_pointer object is an extension to the wl_pointer interface
|
||||||
|
* used for emitting relative pointer events. It shares the same focus as
|
||||||
|
* wl_pointer objects of the same seat and will only emit events when it has
|
||||||
|
* focus.
|
||||||
|
* @section page_iface_zwp_relative_pointer_v1_api API
|
||||||
|
* See @ref iface_zwp_relative_pointer_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_relative_pointer_v1 The zwp_relative_pointer_v1 interface
|
||||||
|
*
|
||||||
|
* A wp_relative_pointer object is an extension to the wl_pointer interface
|
||||||
|
* used for emitting relative pointer events. It shares the same focus as
|
||||||
|
* wl_pointer objects of the same seat and will only emit events when it has
|
||||||
|
* focus.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_relative_pointer_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY 0
|
||||||
|
#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_relative_pointer_manager_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_relative_pointer_manager_v1_set_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_relative_pointer_manager_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_relative_pointer_manager_v1_get_user_data(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_relative_pointer_manager_v1_get_version(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_manager_v1
|
||||||
|
*
|
||||||
|
* Used by the client to notify the server that it will no longer use this
|
||||||
|
* relative pointer manager object.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1,
|
||||||
|
ZWP_RELATIVE_POINTER_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_manager_v1
|
||||||
|
*
|
||||||
|
* Create a relative pointer interface given a wl_pointer object. See the
|
||||||
|
* wp_relative_pointer interface for more details.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_relative_pointer_v1 *
|
||||||
|
zwp_relative_pointer_manager_v1_get_relative_pointer(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, struct wl_pointer *pointer)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_manager_v1,
|
||||||
|
ZWP_RELATIVE_POINTER_MANAGER_V1_GET_RELATIVE_POINTER, &zwp_relative_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_manager_v1), 0, NULL, pointer);
|
||||||
|
|
||||||
|
return (struct zwp_relative_pointer_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_v1
|
||||||
|
* @struct zwp_relative_pointer_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwp_relative_pointer_v1_listener {
|
||||||
|
/**
|
||||||
|
* relative pointer motion
|
||||||
|
*
|
||||||
|
* Relative x/y pointer motion from the pointer of the seat
|
||||||
|
* associated with this object.
|
||||||
|
*
|
||||||
|
* A relative motion is in the same dimension as regular wl_pointer
|
||||||
|
* motion events, except they do not represent an absolute
|
||||||
|
* position. For example, moving a pointer from (x, y) to (x', y')
|
||||||
|
* would have the equivalent relative motion (x' - x, y' - y). If a
|
||||||
|
* pointer motion caused the absolute pointer position to be
|
||||||
|
* clipped by for example the edge of the monitor, the relative
|
||||||
|
* motion is unaffected by the clipping and will represent the
|
||||||
|
* unclipped motion.
|
||||||
|
*
|
||||||
|
* This event also contains non-accelerated motion deltas. The
|
||||||
|
* non-accelerated delta is, when applicable, the regular pointer
|
||||||
|
* motion delta as it was before having applied motion acceleration
|
||||||
|
* and other transformations such as normalization.
|
||||||
|
*
|
||||||
|
* Note that the non-accelerated delta does not represent 'raw'
|
||||||
|
* events as they were read from some device. Pointer motion
|
||||||
|
* acceleration is device- and configuration-specific and
|
||||||
|
* non-accelerated deltas and accelerated deltas may have the same
|
||||||
|
* value on some devices.
|
||||||
|
*
|
||||||
|
* Relative motions are not coupled to wl_pointer.motion events,
|
||||||
|
* and can be sent in combination with such events, but also
|
||||||
|
* independently. There may also be scenarios where
|
||||||
|
* wl_pointer.motion is sent, but there is no relative motion. The
|
||||||
|
* order of an absolute and relative motion event originating from
|
||||||
|
* the same physical motion is not guaranteed.
|
||||||
|
*
|
||||||
|
* If the client needs button events or focus state, it can receive
|
||||||
|
* them from a wl_pointer object of the same seat that the
|
||||||
|
* wp_relative_pointer object is associated with.
|
||||||
|
* @param utime_hi high 32 bits of a 64 bit timestamp with microsecond granularity
|
||||||
|
* @param utime_lo low 32 bits of a 64 bit timestamp with microsecond granularity
|
||||||
|
* @param dx the x component of the motion vector
|
||||||
|
* @param dy the y component of the motion vector
|
||||||
|
* @param dx_unaccel the x component of the unaccelerated motion vector
|
||||||
|
* @param dy_unaccel the y component of the unaccelerated motion vector
|
||||||
|
*/
|
||||||
|
void (*relative_motion)(void *data,
|
||||||
|
struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
|
||||||
|
uint32_t utime_hi,
|
||||||
|
uint32_t utime_lo,
|
||||||
|
wl_fixed_t dx,
|
||||||
|
wl_fixed_t dy,
|
||||||
|
wl_fixed_t dx_unaccel,
|
||||||
|
wl_fixed_t dy_unaccel);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwp_relative_pointer_v1_add_listener(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
|
||||||
|
const struct zwp_relative_pointer_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_relative_pointer_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_RELATIVE_POINTER_V1_DESTROY 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_RELATIVE_POINTER_V1_RELATIVE_MOTION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_RELATIVE_POINTER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_relative_pointer_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_relative_pointer_v1_set_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_relative_pointer_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_relative_pointer_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_relative_pointer_v1_get_user_data(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_relative_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_relative_pointer_v1_get_version(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_relative_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_relative_pointer_v1,
|
||||||
|
ZWP_RELATIVE_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_relative_pointer_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2013-2016 Collabora, Ltd.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface wp_viewport_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *viewporter_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wp_viewport_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wp_viewporter_requests[] = {
|
||||||
|
{ "destroy", "", viewporter_types + 0 },
|
||||||
|
{ "get_viewport", "no", viewporter_types + 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wp_viewporter_interface = {
|
||||||
|
"wp_viewporter", 1,
|
||||||
|
2, wp_viewporter_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message wp_viewport_requests[] = {
|
||||||
|
{ "destroy", "", viewporter_types + 0 },
|
||||||
|
{ "set_source", "ffff", viewporter_types + 0 },
|
||||||
|
{ "set_destination", "ii", viewporter_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface wp_viewport_interface = {
|
||||||
|
"wp_viewport", 1,
|
||||||
|
3, wp_viewport_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,398 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
#ifndef VIEWPORTER_CLIENT_PROTOCOL_H
|
||||||
|
#define VIEWPORTER_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_viewporter The viewporter protocol
|
||||||
|
* @section page_ifaces_viewporter Interfaces
|
||||||
|
* - @subpage page_iface_wp_viewporter - surface cropping and scaling
|
||||||
|
* - @subpage page_iface_wp_viewport - crop and scale interface to a wl_surface
|
||||||
|
* @section page_copyright_viewporter Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2013-2016 Collabora, Ltd.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_surface;
|
||||||
|
struct wp_viewport;
|
||||||
|
struct wp_viewporter;
|
||||||
|
|
||||||
|
#ifndef WP_VIEWPORTER_INTERFACE
|
||||||
|
#define WP_VIEWPORTER_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_wp_viewporter wp_viewporter
|
||||||
|
* @section page_iface_wp_viewporter_desc Description
|
||||||
|
*
|
||||||
|
* The global interface exposing surface cropping and scaling
|
||||||
|
* capabilities is used to instantiate an interface extension for a
|
||||||
|
* wl_surface object. This extended interface will then allow
|
||||||
|
* cropping and scaling the surface contents, effectively
|
||||||
|
* disconnecting the direct relationship between the buffer and the
|
||||||
|
* surface size.
|
||||||
|
* @section page_iface_wp_viewporter_api API
|
||||||
|
* See @ref iface_wp_viewporter.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_wp_viewporter The wp_viewporter interface
|
||||||
|
*
|
||||||
|
* The global interface exposing surface cropping and scaling
|
||||||
|
* capabilities is used to instantiate an interface extension for a
|
||||||
|
* wl_surface object. This extended interface will then allow
|
||||||
|
* cropping and scaling the surface contents, effectively
|
||||||
|
* disconnecting the direct relationship between the buffer and the
|
||||||
|
* surface size.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface wp_viewporter_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef WP_VIEWPORT_INTERFACE
|
||||||
|
#define WP_VIEWPORT_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_wp_viewport wp_viewport
|
||||||
|
* @section page_iface_wp_viewport_desc Description
|
||||||
|
*
|
||||||
|
* An additional interface to a wl_surface object, which allows the
|
||||||
|
* client to specify the cropping and scaling of the surface
|
||||||
|
* contents.
|
||||||
|
*
|
||||||
|
* This interface works with two concepts: the source rectangle (src_x,
|
||||||
|
* src_y, src_width, src_height), and the destination size (dst_width,
|
||||||
|
* dst_height). The contents of the source rectangle are scaled to the
|
||||||
|
* destination size, and content outside the source rectangle is ignored.
|
||||||
|
* This state is double-buffered, and is applied on the next
|
||||||
|
* wl_surface.commit.
|
||||||
|
*
|
||||||
|
* The two parts of crop and scale state are independent: the source
|
||||||
|
* rectangle, and the destination size. Initially both are unset, that
|
||||||
|
* is, no scaling is applied. The whole of the current wl_buffer is
|
||||||
|
* used as the source, and the surface size is as defined in
|
||||||
|
* wl_surface.attach.
|
||||||
|
*
|
||||||
|
* If the destination size is set, it causes the surface size to become
|
||||||
|
* dst_width, dst_height. The source (rectangle) is scaled to exactly
|
||||||
|
* this size. This overrides whatever the attached wl_buffer size is,
|
||||||
|
* unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
|
||||||
|
* has no content and therefore no size. Otherwise, the size is always
|
||||||
|
* at least 1x1 in surface local coordinates.
|
||||||
|
*
|
||||||
|
* If the source rectangle is set, it defines what area of the wl_buffer is
|
||||||
|
* taken as the source. If the source rectangle is set and the destination
|
||||||
|
* size is not set, then src_width and src_height must be integers, and the
|
||||||
|
* surface size becomes the source rectangle size. This results in cropping
|
||||||
|
* without scaling. If src_width or src_height are not integers and
|
||||||
|
* destination size is not set, the bad_size protocol error is raised when
|
||||||
|
* the surface state is applied.
|
||||||
|
*
|
||||||
|
* The coordinate transformations from buffer pixel coordinates up to
|
||||||
|
* the surface-local coordinates happen in the following order:
|
||||||
|
* 1. buffer_transform (wl_surface.set_buffer_transform)
|
||||||
|
* 2. buffer_scale (wl_surface.set_buffer_scale)
|
||||||
|
* 3. crop and scale (wp_viewport.set*)
|
||||||
|
* This means, that the source rectangle coordinates of crop and scale
|
||||||
|
* are given in the coordinates after the buffer transform and scale,
|
||||||
|
* i.e. in the coordinates that would be the surface-local coordinates
|
||||||
|
* if the crop and scale was not applied.
|
||||||
|
*
|
||||||
|
* If src_x or src_y are negative, the bad_value protocol error is raised.
|
||||||
|
* Otherwise, if the source rectangle is partially or completely outside of
|
||||||
|
* the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
|
||||||
|
* when the surface state is applied. A NULL wl_buffer does not raise the
|
||||||
|
* out_of_buffer error.
|
||||||
|
*
|
||||||
|
* If the wl_surface associated with the wp_viewport is destroyed,
|
||||||
|
* all wp_viewport requests except 'destroy' raise the protocol error
|
||||||
|
* no_surface.
|
||||||
|
*
|
||||||
|
* If the wp_viewport object is destroyed, the crop and scale
|
||||||
|
* state is removed from the wl_surface. The change will be applied
|
||||||
|
* on the next wl_surface.commit.
|
||||||
|
* @section page_iface_wp_viewport_api API
|
||||||
|
* See @ref iface_wp_viewport.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_wp_viewport The wp_viewport interface
|
||||||
|
*
|
||||||
|
* An additional interface to a wl_surface object, which allows the
|
||||||
|
* client to specify the cropping and scaling of the surface
|
||||||
|
* contents.
|
||||||
|
*
|
||||||
|
* This interface works with two concepts: the source rectangle (src_x,
|
||||||
|
* src_y, src_width, src_height), and the destination size (dst_width,
|
||||||
|
* dst_height). The contents of the source rectangle are scaled to the
|
||||||
|
* destination size, and content outside the source rectangle is ignored.
|
||||||
|
* This state is double-buffered, and is applied on the next
|
||||||
|
* wl_surface.commit.
|
||||||
|
*
|
||||||
|
* The two parts of crop and scale state are independent: the source
|
||||||
|
* rectangle, and the destination size. Initially both are unset, that
|
||||||
|
* is, no scaling is applied. The whole of the current wl_buffer is
|
||||||
|
* used as the source, and the surface size is as defined in
|
||||||
|
* wl_surface.attach.
|
||||||
|
*
|
||||||
|
* If the destination size is set, it causes the surface size to become
|
||||||
|
* dst_width, dst_height. The source (rectangle) is scaled to exactly
|
||||||
|
* this size. This overrides whatever the attached wl_buffer size is,
|
||||||
|
* unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
|
||||||
|
* has no content and therefore no size. Otherwise, the size is always
|
||||||
|
* at least 1x1 in surface local coordinates.
|
||||||
|
*
|
||||||
|
* If the source rectangle is set, it defines what area of the wl_buffer is
|
||||||
|
* taken as the source. If the source rectangle is set and the destination
|
||||||
|
* size is not set, then src_width and src_height must be integers, and the
|
||||||
|
* surface size becomes the source rectangle size. This results in cropping
|
||||||
|
* without scaling. If src_width or src_height are not integers and
|
||||||
|
* destination size is not set, the bad_size protocol error is raised when
|
||||||
|
* the surface state is applied.
|
||||||
|
*
|
||||||
|
* The coordinate transformations from buffer pixel coordinates up to
|
||||||
|
* the surface-local coordinates happen in the following order:
|
||||||
|
* 1. buffer_transform (wl_surface.set_buffer_transform)
|
||||||
|
* 2. buffer_scale (wl_surface.set_buffer_scale)
|
||||||
|
* 3. crop and scale (wp_viewport.set*)
|
||||||
|
* This means, that the source rectangle coordinates of crop and scale
|
||||||
|
* are given in the coordinates after the buffer transform and scale,
|
||||||
|
* i.e. in the coordinates that would be the surface-local coordinates
|
||||||
|
* if the crop and scale was not applied.
|
||||||
|
*
|
||||||
|
* If src_x or src_y are negative, the bad_value protocol error is raised.
|
||||||
|
* Otherwise, if the source rectangle is partially or completely outside of
|
||||||
|
* the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
|
||||||
|
* when the surface state is applied. A NULL wl_buffer does not raise the
|
||||||
|
* out_of_buffer error.
|
||||||
|
*
|
||||||
|
* If the wl_surface associated with the wp_viewport is destroyed,
|
||||||
|
* all wp_viewport requests except 'destroy' raise the protocol error
|
||||||
|
* no_surface.
|
||||||
|
*
|
||||||
|
* If the wp_viewport object is destroyed, the crop and scale
|
||||||
|
* state is removed from the wl_surface. The change will be applied
|
||||||
|
* on the next wl_surface.commit.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface wp_viewport_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WP_VIEWPORTER_ERROR_ENUM
|
||||||
|
#define WP_VIEWPORTER_ERROR_ENUM
|
||||||
|
enum wp_viewporter_error {
|
||||||
|
/**
|
||||||
|
* the surface already has a viewport object associated
|
||||||
|
*/
|
||||||
|
WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS = 0,
|
||||||
|
};
|
||||||
|
#endif /* WP_VIEWPORTER_ERROR_ENUM */
|
||||||
|
|
||||||
|
#define WP_VIEWPORTER_DESTROY 0
|
||||||
|
#define WP_VIEWPORTER_GET_VIEWPORT 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewporter
|
||||||
|
*/
|
||||||
|
#define WP_VIEWPORTER_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewporter
|
||||||
|
*/
|
||||||
|
#define WP_VIEWPORTER_GET_VIEWPORT_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_wp_viewporter */
|
||||||
|
static inline void
|
||||||
|
wp_viewporter_set_user_data(struct wp_viewporter *wp_viewporter, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) wp_viewporter, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_wp_viewporter */
|
||||||
|
static inline void *
|
||||||
|
wp_viewporter_get_user_data(struct wp_viewporter *wp_viewporter)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) wp_viewporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
wp_viewporter_get_version(struct wp_viewporter *wp_viewporter)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) wp_viewporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewporter
|
||||||
|
*
|
||||||
|
* Informs the server that the client will not be using this
|
||||||
|
* protocol object anymore. This does not affect any other objects,
|
||||||
|
* wp_viewport objects included.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
wp_viewporter_destroy(struct wp_viewporter *wp_viewporter)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter,
|
||||||
|
WP_VIEWPORTER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewporter
|
||||||
|
*
|
||||||
|
* Instantiate an interface extension for the given wl_surface to
|
||||||
|
* crop and scale its content. If the given wl_surface already has
|
||||||
|
* a wp_viewport object associated, the viewport_exists
|
||||||
|
* protocol error is raised.
|
||||||
|
*/
|
||||||
|
static inline struct wp_viewport *
|
||||||
|
wp_viewporter_get_viewport(struct wp_viewporter *wp_viewporter, struct wl_surface *surface)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) wp_viewporter,
|
||||||
|
WP_VIEWPORTER_GET_VIEWPORT, &wp_viewport_interface, wl_proxy_get_version((struct wl_proxy *) wp_viewporter), 0, NULL, surface);
|
||||||
|
|
||||||
|
return (struct wp_viewport *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WP_VIEWPORT_ERROR_ENUM
|
||||||
|
#define WP_VIEWPORT_ERROR_ENUM
|
||||||
|
enum wp_viewport_error {
|
||||||
|
/**
|
||||||
|
* negative or zero values in width or height
|
||||||
|
*/
|
||||||
|
WP_VIEWPORT_ERROR_BAD_VALUE = 0,
|
||||||
|
/**
|
||||||
|
* destination size is not integer
|
||||||
|
*/
|
||||||
|
WP_VIEWPORT_ERROR_BAD_SIZE = 1,
|
||||||
|
/**
|
||||||
|
* source rectangle extends outside of the content area
|
||||||
|
*/
|
||||||
|
WP_VIEWPORT_ERROR_OUT_OF_BUFFER = 2,
|
||||||
|
/**
|
||||||
|
* the wl_surface was destroyed
|
||||||
|
*/
|
||||||
|
WP_VIEWPORT_ERROR_NO_SURFACE = 3,
|
||||||
|
};
|
||||||
|
#endif /* WP_VIEWPORT_ERROR_ENUM */
|
||||||
|
|
||||||
|
#define WP_VIEWPORT_DESTROY 0
|
||||||
|
#define WP_VIEWPORT_SET_SOURCE 1
|
||||||
|
#define WP_VIEWPORT_SET_DESTINATION 2
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*/
|
||||||
|
#define WP_VIEWPORT_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*/
|
||||||
|
#define WP_VIEWPORT_SET_SOURCE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*/
|
||||||
|
#define WP_VIEWPORT_SET_DESTINATION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_wp_viewport */
|
||||||
|
static inline void
|
||||||
|
wp_viewport_set_user_data(struct wp_viewport *wp_viewport, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) wp_viewport, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_wp_viewport */
|
||||||
|
static inline void *
|
||||||
|
wp_viewport_get_user_data(struct wp_viewport *wp_viewport)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) wp_viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
wp_viewport_get_version(struct wp_viewport *wp_viewport)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) wp_viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*
|
||||||
|
* The associated wl_surface's crop and scale state is removed.
|
||||||
|
* The change is applied on the next wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
wp_viewport_destroy(struct wp_viewport *wp_viewport)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport,
|
||||||
|
WP_VIEWPORT_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*
|
||||||
|
* Set the source rectangle of the associated wl_surface. See
|
||||||
|
* wp_viewport for the description, and relation to the wl_buffer
|
||||||
|
* size.
|
||||||
|
*
|
||||||
|
* If all of x, y, width and height are -1.0, the source rectangle is
|
||||||
|
* unset instead. Any other set of values where width or height are zero
|
||||||
|
* or negative, or x or y are negative, raise the bad_value protocol
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* The crop and scale state is double-buffered state, and will be
|
||||||
|
* applied on the next wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
wp_viewport_set_source(struct wp_viewport *wp_viewport, wl_fixed_t x, wl_fixed_t y, wl_fixed_t width, wl_fixed_t height)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport,
|
||||||
|
WP_VIEWPORT_SET_SOURCE, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_viewport
|
||||||
|
*
|
||||||
|
* Set the destination size of the associated wl_surface. See
|
||||||
|
* wp_viewport for the description, and relation to the wl_buffer
|
||||||
|
* size.
|
||||||
|
*
|
||||||
|
* If width is -1 and height is -1, the destination size is unset
|
||||||
|
* instead. Any other pair of values for width and height that
|
||||||
|
* contains zero or negative values raises the bad_value protocol
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* The crop and scale state is double-buffered state, and will be
|
||||||
|
* applied on the next wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
wp_viewport_set_destination(struct wp_viewport *wp_viewport, int32_t width, int32_t height)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) wp_viewport,
|
||||||
|
WP_VIEWPORT_SET_DESTINATION, NULL, wl_proxy_get_version((struct wl_proxy *) wp_viewport), 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2018 Simon Ser
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_decoration_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
&zxdg_toplevel_decoration_v1_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = {
|
||||||
|
"zxdg_decoration_manager_v1", 1,
|
||||||
|
2, zxdg_decoration_manager_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "set_mode", "u", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "unset_mode", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
|
||||||
|
{ "configure", "u", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
|
||||||
|
"zxdg_toplevel_decoration_v1", 1,
|
||||||
|
3, zxdg_toplevel_decoration_v1_requests,
|
||||||
|
1, zxdg_toplevel_decoration_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,378 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol
|
||||||
|
* @section page_ifaces_xdg_decoration_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager
|
||||||
|
* - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface
|
||||||
|
* @section page_copyright_xdg_decoration_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2018 Simon Ser
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct xdg_toplevel;
|
||||||
|
struct zxdg_decoration_manager_v1;
|
||||||
|
struct zxdg_toplevel_decoration_v1;
|
||||||
|
|
||||||
|
#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1
|
||||||
|
* @section page_iface_zxdg_decoration_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* This interface allows a compositor to announce support for server-side
|
||||||
|
* decorations.
|
||||||
|
*
|
||||||
|
* A window decoration is a set of window controls as deemed appropriate by
|
||||||
|
* the party managing them, such as user interface components used to move,
|
||||||
|
* resize and change a window's state.
|
||||||
|
*
|
||||||
|
* A client can use this protocol to request being decorated by a supporting
|
||||||
|
* compositor.
|
||||||
|
*
|
||||||
|
* If compositor and client do not negotiate the use of a server-side
|
||||||
|
* decoration using this protocol, clients continue to self-decorate as they
|
||||||
|
* see fit.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
* @section page_iface_zxdg_decoration_manager_v1_api API
|
||||||
|
* See @ref iface_zxdg_decoration_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface
|
||||||
|
*
|
||||||
|
* This interface allows a compositor to announce support for server-side
|
||||||
|
* decorations.
|
||||||
|
*
|
||||||
|
* A window decoration is a set of window controls as deemed appropriate by
|
||||||
|
* the party managing them, such as user interface components used to move,
|
||||||
|
* resize and change a window's state.
|
||||||
|
*
|
||||||
|
* A client can use this protocol to request being decorated by a supporting
|
||||||
|
* compositor.
|
||||||
|
*
|
||||||
|
* If compositor and client do not negotiate the use of a server-side
|
||||||
|
* decoration using this protocol, clients continue to self-decorate as they
|
||||||
|
* see fit.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_decoration_manager_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1
|
||||||
|
* @section page_iface_zxdg_toplevel_decoration_v1_desc Description
|
||||||
|
*
|
||||||
|
* The decoration object allows the compositor to toggle server-side window
|
||||||
|
* decorations for a toplevel surface. The client can request to switch to
|
||||||
|
* another mode.
|
||||||
|
*
|
||||||
|
* The xdg_toplevel_decoration object must be destroyed before its
|
||||||
|
* xdg_toplevel.
|
||||||
|
* @section page_iface_zxdg_toplevel_decoration_v1_api API
|
||||||
|
* See @ref iface_zxdg_toplevel_decoration_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface
|
||||||
|
*
|
||||||
|
* The decoration object allows the compositor to toggle server-side window
|
||||||
|
* decorations for a toplevel surface. The client can request to switch to
|
||||||
|
* another mode.
|
||||||
|
*
|
||||||
|
* The xdg_toplevel_decoration object must be destroyed before its
|
||||||
|
* xdg_toplevel.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*
|
||||||
|
* Destroy the decoration manager. This doesn't destroy objects created
|
||||||
|
* with the manager.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||||
|
ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*
|
||||||
|
* Create a new decoration object associated with the given toplevel.
|
||||||
|
*
|
||||||
|
* Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
|
||||||
|
* buffer attached or committed is a client error, and any attempts by a
|
||||||
|
* client to attach or manipulate a buffer prior to the first
|
||||||
|
* xdg_toplevel_decoration.configure event must also be treated as
|
||||||
|
* errors.
|
||||||
|
*/
|
||||||
|
static inline struct zxdg_toplevel_decoration_v1 *
|
||||||
|
zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||||
|
ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel);
|
||||||
|
|
||||||
|
return (struct zxdg_toplevel_decoration_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||||
|
enum zxdg_toplevel_decoration_v1_error {
|
||||||
|
/**
|
||||||
|
* xdg_toplevel has a buffer attached before configure
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0,
|
||||||
|
/**
|
||||||
|
* xdg_toplevel already has a decoration object
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1,
|
||||||
|
/**
|
||||||
|
* xdg_toplevel destroyed before the decoration object
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
* window decoration modes
|
||||||
|
*
|
||||||
|
* These values describe window decoration modes.
|
||||||
|
*/
|
||||||
|
enum zxdg_toplevel_decoration_v1_mode {
|
||||||
|
/**
|
||||||
|
* no server-side window decoration
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
|
||||||
|
/**
|
||||||
|
* server-side window decoration
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
* @struct zxdg_toplevel_decoration_v1_listener
|
||||||
|
*/
|
||||||
|
struct zxdg_toplevel_decoration_v1_listener {
|
||||||
|
/**
|
||||||
|
* suggest a surface change
|
||||||
|
*
|
||||||
|
* The configure event asks the client to change its decoration
|
||||||
|
* mode. The configured state should not be applied immediately.
|
||||||
|
* Clients must send an ack_configure in response to this event.
|
||||||
|
* See xdg_surface.configure and xdg_surface.ack_configure for
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* A configure event can be sent at any time. The specified mode
|
||||||
|
* must be obeyed by the client.
|
||||||
|
* @param mode the decoration mode
|
||||||
|
*/
|
||||||
|
void (*configure)(void *data,
|
||||||
|
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||||
|
uint32_t mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||||
|
const struct zxdg_toplevel_decoration_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Switch back to a mode without any server-side decorations at the next
|
||||||
|
* commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Set the toplevel surface decoration mode. This informs the compositor
|
||||||
|
* that the client prefers the provided decoration mode.
|
||||||
|
*
|
||||||
|
* After requesting a decoration mode, the compositor will respond by
|
||||||
|
* emitting an xdg_surface.configure event. The client should then update
|
||||||
|
* its content, drawing it without decorations if the received mode is
|
||||||
|
* server-side decorations. The client must also acknowledge the configure
|
||||||
|
* when committing the new content (see xdg_surface.ack_configure).
|
||||||
|
*
|
||||||
|
* The compositor can decide not to use the client's mode and enforce a
|
||||||
|
* different mode instead.
|
||||||
|
*
|
||||||
|
* Clients whose decoration mode depend on the xdg_toplevel state may send
|
||||||
|
* a set_mode request in response to an xdg_surface.configure event and wait
|
||||||
|
* for the next xdg_surface.configure event to prevent unwanted state.
|
||||||
|
* Such clients are responsible for preventing configure loops and must
|
||||||
|
* make sure not to send multiple successive set_mode requests with the
|
||||||
|
* same decoration mode.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Unset the toplevel surface decoration mode. This informs the compositor
|
||||||
|
* that the client doesn't prefer a particular decoration mode.
|
||||||
|
*
|
||||||
|
* This request has the same semantics as set_mode.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
/* Generated by wayland-scanner 1.20.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2013 Kristian Høgsberg
|
||||||
|
* Copyright © 2013 Rafael Antognolli
|
||||||
|
* Copyright © 2013 Jasper St. Pierre
|
||||||
|
* Copyright © 2010-2013 Intel Corporation
|
||||||
|
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||||
|
* Copyright © 2015-2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface xdg_positioner_interface;
|
||||||
|
extern const struct wl_interface xdg_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_shell_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||||
|
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||||
|
{ "pong", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_events[] = {
|
||||||
|
{ "ping", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||||
|
"xdg_wm_base", 6,
|
||||||
|
4, xdg_wm_base_requests,
|
||||||
|
1, xdg_wm_base_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_positioner_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||||
|
"xdg_positioner", 6,
|
||||||
|
10, xdg_positioner_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||||
|
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||||
|
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_events[] = {
|
||||||
|
{ "configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||||
|
"xdg_surface", 6,
|
||||||
|
5, xdg_surface_requests,
|
||||||
|
1, xdg_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||||
|
{ "set_title", "s", xdg_shell_types + 0 },
|
||||||
|
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||||
|
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||||
|
{ "move", "ou", xdg_shell_types + 16 },
|
||||||
|
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||||
|
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||||
|
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_events[] = {
|
||||||
|
{ "configure", "iia", xdg_shell_types + 0 },
|
||||||
|
{ "close", "", xdg_shell_types + 0 },
|
||||||
|
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||||
|
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||||
|
"xdg_toplevel", 6,
|
||||||
|
14, xdg_toplevel_requests,
|
||||||
|
4, xdg_toplevel_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "grab", "ou", xdg_shell_types + 22 },
|
||||||
|
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_events[] = {
|
||||||
|
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "popup_done", "", xdg_shell_types + 0 },
|
||||||
|
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||||
|
"xdg_popup", 6,
|
||||||
|
3, xdg_popup_requests,
|
||||||
|
3, xdg_popup_events,
|
||||||
|
};
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -337,8 +337,8 @@ pub fn init(b: *std.Build) !Config {
|
||||||
target.result.os.tag == .macos and
|
target.result.os.tag == .macos and
|
||||||
config.app_runtime == .none and
|
config.app_runtime == .none and
|
||||||
(!config.emit_bench and
|
(!config.emit_bench and
|
||||||
!config.emit_test_exe and
|
!config.emit_test_exe and
|
||||||
!config.emit_helpgen);
|
!config.emit_helpgen);
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// System Packages
|
// System Packages
|
||||||
|
|
@ -379,6 +379,11 @@ pub fn init(b: *std.Build) !Config {
|
||||||
"glslang",
|
"glslang",
|
||||||
"spirv-cross",
|
"spirv-cross",
|
||||||
"simdutf",
|
"simdutf",
|
||||||
|
|
||||||
|
// This is default false because it is used for testing
|
||||||
|
// primarily and not official packaging. The packaging
|
||||||
|
// guide advises against building the GLFW backend.
|
||||||
|
"glfw3",
|
||||||
}) |dep| {
|
}) |dep| {
|
||||||
_ = b.systemIntegrationOption(dep, .{ .default = false });
|
_ = b.systemIntegrationOption(dep, .{ .default = false });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -438,12 +438,15 @@ pub fn add(
|
||||||
switch (self.config.app_runtime) {
|
switch (self.config.app_runtime) {
|
||||||
.none => {},
|
.none => {},
|
||||||
|
|
||||||
.glfw => glfw: {
|
.glfw => {
|
||||||
const mach_glfw_dep = b.lazyDependency("mach_glfw", .{
|
const glfw_dep = b.dependency("glfw", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
}) orelse break :glfw;
|
});
|
||||||
step.root_module.addImport("glfw", mach_glfw_dep.module("mach-glfw"));
|
step.root_module.addImport(
|
||||||
|
"glfw",
|
||||||
|
glfw_dep.module("glfw"),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
.gtk => {
|
.gtk => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue