Nuke GLFW, make `zig build run` on macOS build the Xcode project (#7815)
This PR does two things. 1. Build system improvements to make developing on macOS more enjoyable 2. Delete the GLFW apprt ## Build System Improvements (macOS) On macOS, there are a few major improvements: * `zig build` now produces a full macOS app bundle and copies it into `zig-out` * `zig build run` now builds the macOS app and runs it, streaming logs directly into the terminal * `-Demit-macos-app` can control whether app bundle is created * `-Dxcframework-target` can be set to one of `native` or `universal` to control whether the xcframework uses only your target machines arch or creates a universal one with macOS and iOS. This defaults to `native` for the `run` command and `universal` for all others. * The general flow of the `build.zig` file was improved to be more declarative ## Nuke GLFW > This deletes the GLFW apprt from the Ghostty codebase. > > The GLFW apprt was the original apprt used by Ghostty (well, before > Ghostty even had the concept of an "apprt" -- it was all just a single > application then). It let me iterate on the core terminal features, > rendering, etc. without bothering about the UI. It was a good way to get > started. But it has long since outlived its usefulness. > > We've had a stable GTK apprt for Linux (and Windows via WSL) and a > native macOS app via libghostty for awhile now. The GLFW apprt only > remained within the tree for a few reasons: > > 1. Primarily, it provided a faster feedback loop on macOS because > building the macOS app historically required us to hop out of the > zig build system and into Xcode, which is slow and cumbersome. > > 2. It was a convenient way to narrow whether a bug was in the > core Ghostty codebase or in the apprt itself. If a bug was in both > the glfw and macOS app then it was likely in the core. > > 3. It provided us a way on macOS to test OpenGL. > > All of these reasons are no longer valid. Respectively: > > 1. Our Zig build scripts now execute the `xcodebuild` CLI directly and > can open the resulting app, stream logs, etc. This is the same > experience we have on Linux. (Xcode has always been a dependency of > building on macOS in general, so this is not cumbersome.) > > 2. We have a healthy group of maintainers, many of which have access > to both macOS and Linux, so we can quickly narrow down bugs > regardless of the apprt. > > 3. Our OpenGL renderer hasn't been compatible with macOS for some time > now, so this is no longer a useful feature. > > At this point, the GLFW apprt is just a burden. It adds complexity > across the board, and some people try to run Ghostty with it in the real > world and get confused when it doesn't work (it's always been lacking in > features and buggy compared to the other apprts). > > So, it's time to say goodbye. Its bittersweet because it is a big part > of Ghostty's history, but we've grown up now and it's time to move on. > Thank you, goodbye. > > (NOTE: If you are a user of the GLFW apprt, then please fork the project > prior to this commit or start a new project based on it. We've warned > against using it for a very, very long time now.)pull/7821/head
commit
390812828a
|
|
@ -21,7 +21,6 @@ jobs:
|
||||||
- build-macos-tahoe
|
- build-macos-tahoe
|
||||||
- build-macos-matrix
|
- build-macos-matrix
|
||||||
- build-windows
|
- build-windows
|
||||||
- build-windows-cross
|
|
||||||
- flatpak-check-zig-cache
|
- flatpak-check-zig-cache
|
||||||
- flatpak
|
- flatpak
|
||||||
- test
|
- test
|
||||||
|
|
@ -84,7 +83,7 @@ jobs:
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
- name: Build Benchmarks
|
- name: Build Benchmarks
|
||||||
run: nix develop -c zig build -Dapp-runtime=glfw -Demit-bench
|
run: nix develop -c zig build -Demit-bench
|
||||||
|
|
||||||
build-flatpak:
|
build-flatpak:
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -151,7 +150,7 @@ jobs:
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
- name: Test Build
|
- name: Test Build
|
||||||
run: nix develop -c zig build -Dapp-runtime=glfw
|
run: nix develop -c zig build
|
||||||
|
|
||||||
build-linux-libghostty:
|
build-linux-libghostty:
|
||||||
runs-on: namespace-profile-ghostty-md
|
runs-on: namespace-profile-ghostty-md
|
||||||
|
|
@ -295,7 +294,7 @@ jobs:
|
||||||
# GhosttyKit is the framework that is built from Zig for our native
|
# GhosttyKit is the framework that is built from Zig for our native
|
||||||
# Mac app to access.
|
# Mac app to access.
|
||||||
- name: Build GhosttyKit
|
- name: Build GhosttyKit
|
||||||
run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }}
|
run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false
|
||||||
|
|
||||||
# The native app is built with native Xcode tooling. This also does
|
# The native app is built with native Xcode tooling. This also does
|
||||||
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
|
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
|
||||||
|
|
@ -335,7 +334,7 @@ jobs:
|
||||||
# GhosttyKit is the framework that is built from Zig for our native
|
# GhosttyKit is the framework that is built from Zig for our native
|
||||||
# Mac app to access.
|
# Mac app to access.
|
||||||
- name: Build GhosttyKit
|
- name: Build GhosttyKit
|
||||||
run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }}
|
run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false
|
||||||
|
|
||||||
# The native app is built with native Xcode tooling. This also does
|
# The native app is built with native Xcode tooling. This also does
|
||||||
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
|
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
|
||||||
|
|
@ -374,33 +373,19 @@ jobs:
|
||||||
|
|
||||||
- name: Test All
|
- name: Test All
|
||||||
run: |
|
run: |
|
||||||
# OpenGL
|
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=freetype
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=freetype
|
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=coretext
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext
|
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=coretext_freetype
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_freetype
|
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=coretext_harfbuzz
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_harfbuzz
|
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=coretext_noshape
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_noshape
|
|
||||||
|
|
||||||
# Metal
|
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=freetype
|
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext
|
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_freetype
|
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_harfbuzz
|
|
||||||
nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_noshape
|
|
||||||
|
|
||||||
- name: Build All
|
- name: Build All
|
||||||
run: |
|
run: |
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=freetype
|
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=freetype
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext
|
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=coretext
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_freetype
|
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=coretext_freetype
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_harfbuzz
|
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=coretext_harfbuzz
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=opengl -Dfont-backend=coretext_noshape
|
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=coretext_noshape
|
||||||
|
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=freetype
|
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext
|
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_freetype
|
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_harfbuzz
|
|
||||||
nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_noshape
|
|
||||||
|
|
||||||
build-snap:
|
build-snap:
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -507,52 +492,6 @@ 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.8
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
/nix
|
|
||||||
/zig
|
|
||||||
|
|
||||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
|
||||||
- uses: cachix/install-nix-action@v31
|
|
||||||
with:
|
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
|
||||||
- uses: cachix/cachix-action@v16
|
|
||||||
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
|
||||||
|
|
@ -585,9 +524,6 @@ jobs:
|
||||||
- name: Test GTK Build
|
- name: Test GTK Build
|
||||||
run: nix develop -c zig build -Dapp-runtime=gtk -Demit-docs
|
run: nix develop -c zig build -Dapp-runtime=gtk -Demit-docs
|
||||||
|
|
||||||
- name: Test GLFW Build
|
|
||||||
run: nix develop -c zig build -Dapp-runtime=glfw
|
|
||||||
|
|
||||||
# This relies on the cache being populated by the commands above.
|
# This relies on the cache being populated by the commands above.
|
||||||
- name: Test System Build
|
- name: Test System Build
|
||||||
run: nix develop -c zig build --system ${ZIG_GLOBAL_CACHE_DIR}/p
|
run: nix develop -c zig build --system ${ZIG_GLOBAL_CACHE_DIR}/p
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,3 @@ relevant to package maintainers:
|
||||||
often necessary for system packages to specify a specific minimum Linux
|
often necessary for system packages to specify a specific minimum Linux
|
||||||
version, glibc, etc. Run `zig targets` to a get a full list of available
|
version, glibc, etc. Run `zig targets` to a get a full list of available
|
||||||
targets.
|
targets.
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
>
|
|
||||||
> **The GLFW runtime is not meant for distribution.** The GLFW runtime
|
|
||||||
> (`-Dapp-runtime=glfw`) is meant for development and testing only. It is
|
|
||||||
> missing many features, has known memory leak scenarios, known crashes,
|
|
||||||
> and more. Please do not package the GLFW-based Ghostty runtime for
|
|
||||||
> distribution.
|
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,6 @@ omit the `-Doptimize` flag to build a debug build, and you may require
|
||||||
additional dependencies since the source tarball includes some processed
|
additional dependencies since the source tarball includes some processed
|
||||||
files that are not in the Git repository.
|
files that are not in the Git repository.
|
||||||
|
|
||||||
On Linux or macOS, you can use `zig build -Dapp-runtime=glfw run` for a quick
|
|
||||||
GLFW-based app for a faster development cycle while developing core
|
|
||||||
terminal features. Note that this app is missing many features and is also
|
|
||||||
known to crash in certain scenarios, so it is only meant for development
|
|
||||||
tasks.
|
|
||||||
|
|
||||||
Other useful commands:
|
Other useful commands:
|
||||||
|
|
||||||
- `zig build test` for running unit tests.
|
- `zig build test` for running unit tests.
|
||||||
|
|
|
||||||
153
build.zig
153
build.zig
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const buildpkg = @import("src/build/main.zig");
|
const buildpkg = @import("src/build/main.zig");
|
||||||
|
|
||||||
|
|
@ -22,7 +23,14 @@ pub fn build(b: *std.Build) !void {
|
||||||
|
|
||||||
// Ghostty docs
|
// Ghostty docs
|
||||||
const docs = try buildpkg.GhosttyDocs.init(b, &deps);
|
const docs = try buildpkg.GhosttyDocs.init(b, &deps);
|
||||||
if (config.emit_docs) docs.install();
|
if (config.emit_docs) {
|
||||||
|
docs.install();
|
||||||
|
} else if (config.target.result.os.tag.isDarwin()) {
|
||||||
|
// If we aren't emitting docs we need to emit a placeholder so
|
||||||
|
// our macOS xcodeproject builds since it expects the `share/man`
|
||||||
|
// directory to exist to copy into the app bundle.
|
||||||
|
docs.installDummy(b.getInstallStep());
|
||||||
|
}
|
||||||
|
|
||||||
// Ghostty webdata
|
// Ghostty webdata
|
||||||
const webdata = try buildpkg.GhosttyWebdata.init(b, &deps);
|
const webdata = try buildpkg.GhosttyWebdata.init(b, &deps);
|
||||||
|
|
@ -42,65 +50,116 @@ pub fn build(b: *std.Build) !void {
|
||||||
check_step.dependOn(dist.install_step);
|
check_step.dependOn(dist.install_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not building libghostty, then install the exe and resources.
|
// libghostty
|
||||||
|
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
||||||
|
b,
|
||||||
|
&deps,
|
||||||
|
);
|
||||||
|
const libghostty_static = try buildpkg.GhosttyLib.initStatic(
|
||||||
|
b,
|
||||||
|
&deps,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Runtime "none" is libghostty, anything else is an executable.
|
||||||
if (config.app_runtime != .none) {
|
if (config.app_runtime != .none) {
|
||||||
exe.install();
|
exe.install();
|
||||||
resources.install();
|
resources.install();
|
||||||
i18n.install();
|
i18n.install();
|
||||||
}
|
} else {
|
||||||
|
// Libghostty
|
||||||
|
//
|
||||||
|
// Note: libghostty is not stable for general purpose use. It is used
|
||||||
|
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
|
||||||
|
// As such, these build steps are lacking. For example, the Darwin
|
||||||
|
// build only produces an xcframework.
|
||||||
|
|
||||||
// Libghostty
|
// We shouldn't have this guard but we don't currently
|
||||||
//
|
// build on macOS this way ironically so we need to fix that.
|
||||||
// Note: libghostty is not stable for general purpose use. It is used
|
if (!config.target.result.os.tag.isDarwin()) {
|
||||||
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
|
|
||||||
// As such, these build steps are lacking. For example, the Darwin
|
|
||||||
// build only produces an xcframework.
|
|
||||||
if (config.app_runtime == .none) {
|
|
||||||
if (config.target.result.os.tag.isDarwin()) darwin: {
|
|
||||||
if (!config.emit_xcframework) break :darwin;
|
|
||||||
|
|
||||||
// Build the xcframework
|
|
||||||
const xcframework = try buildpkg.GhosttyXCFramework.init(b, &deps);
|
|
||||||
xcframework.install();
|
|
||||||
|
|
||||||
// The xcframework build always installs resources because our
|
|
||||||
// macOS xcode project contains references to them.
|
|
||||||
resources.install();
|
|
||||||
i18n.install();
|
|
||||||
|
|
||||||
// If we aren't emitting docs we need to emit a placeholder so
|
|
||||||
// our macOS xcodeproject builds.
|
|
||||||
if (!config.emit_docs) {
|
|
||||||
var wf = b.addWriteFiles();
|
|
||||||
const path = "share/man/.placeholder";
|
|
||||||
const placeholder = wf.add(path, "emit-docs not true so no man pages");
|
|
||||||
b.getInstallStep().dependOn(&b.addInstallFile(placeholder, path).step);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const libghostty_shared = try buildpkg.GhosttyLib.initShared(b, &deps);
|
|
||||||
const libghostty_static = try buildpkg.GhosttyLib.initStatic(b, &deps);
|
|
||||||
libghostty_shared.installHeader(); // Only need one header
|
libghostty_shared.installHeader(); // Only need one header
|
||||||
libghostty_shared.install("libghostty.so");
|
libghostty_shared.install("libghostty.so");
|
||||||
libghostty_static.install("libghostty.a");
|
libghostty_static.install("libghostty.a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run runs the Ghostty exe
|
// macOS only artifacts. These will error if they're initialized for
|
||||||
{
|
// other targets.
|
||||||
const run_cmd = b.addRunArtifact(exe.exe);
|
if (config.target.result.os.tag.isDarwin()) {
|
||||||
if (b.args) |args| run_cmd.addArgs(args);
|
// Ghostty xcframework
|
||||||
|
const xcframework = try buildpkg.GhosttyXCFramework.init(
|
||||||
// Set the proper resources dir so things like shell integration
|
b,
|
||||||
// work correctly. If we're running `zig build run` in Ghostty,
|
&deps,
|
||||||
// this also ensures it overwrites the release one with our debug
|
config.xcframework_target,
|
||||||
// build.
|
|
||||||
run_cmd.setEnvironmentVariable(
|
|
||||||
"GHOSTTY_RESOURCES_DIR",
|
|
||||||
b.getInstallPath(.prefix, "share/ghostty"),
|
|
||||||
);
|
);
|
||||||
|
if (config.emit_xcframework) {
|
||||||
|
xcframework.install();
|
||||||
|
|
||||||
const run_step = b.step("run", "Run the app");
|
// The xcframework build always installs resources because our
|
||||||
run_step.dependOn(&run_cmd.step);
|
// macOS xcode project contains references to them.
|
||||||
|
resources.install();
|
||||||
|
i18n.install();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ghostty macOS app
|
||||||
|
const macos_app = try buildpkg.GhosttyXcodebuild.init(
|
||||||
|
b,
|
||||||
|
&config,
|
||||||
|
.{
|
||||||
|
.xcframework = &xcframework,
|
||||||
|
.docs = &docs,
|
||||||
|
.i18n = &i18n,
|
||||||
|
.resources = &resources,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (config.emit_macos_app) {
|
||||||
|
macos_app.install();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run step
|
||||||
|
run: {
|
||||||
|
if (config.app_runtime != .none) {
|
||||||
|
const run_cmd = b.addRunArtifact(exe.exe);
|
||||||
|
if (b.args) |args| run_cmd.addArgs(args);
|
||||||
|
|
||||||
|
// Set the proper resources dir so things like shell integration
|
||||||
|
// work correctly. If we're running `zig build run` in Ghostty,
|
||||||
|
// this also ensures it overwrites the release one with our debug
|
||||||
|
// build.
|
||||||
|
run_cmd.setEnvironmentVariable(
|
||||||
|
"GHOSTTY_RESOURCES_DIR",
|
||||||
|
b.getInstallPath(.prefix, "share/ghostty"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
break :run;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(config.app_runtime == .none);
|
||||||
|
|
||||||
|
// On macOS we can run the macOS app. For "run" we always force
|
||||||
|
// a native-only build so that we can run as quickly as possible.
|
||||||
|
if (config.target.result.os.tag.isDarwin()) {
|
||||||
|
const xcframework_native = try buildpkg.GhosttyXCFramework.init(
|
||||||
|
b,
|
||||||
|
&deps,
|
||||||
|
.native,
|
||||||
|
);
|
||||||
|
const macos_app_native_only = try buildpkg.GhosttyXcodebuild.init(
|
||||||
|
b,
|
||||||
|
&config,
|
||||||
|
.{
|
||||||
|
.xcframework = &xcframework_native,
|
||||||
|
.docs = &docs,
|
||||||
|
.i18n = &i18n,
|
||||||
|
.resources = &resources,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&macos_app_native_only.open.step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@
|
||||||
.cimgui = .{ .path = "./pkg/cimgui", .lazy = true },
|
.cimgui = .{ .path = "./pkg/cimgui", .lazy = true },
|
||||||
.fontconfig = .{ .path = "./pkg/fontconfig", .lazy = true },
|
.fontconfig = .{ .path = "./pkg/fontconfig", .lazy = true },
|
||||||
.freetype = .{ .path = "./pkg/freetype", .lazy = true },
|
.freetype = .{ .path = "./pkg/freetype", .lazy = true },
|
||||||
.glfw = .{ .path = "./pkg/glfw", .lazy = true },
|
|
||||||
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell", .lazy = true },
|
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell", .lazy = true },
|
||||||
.harfbuzz = .{ .path = "./pkg/harfbuzz", .lazy = true },
|
.harfbuzz = .{ .path = "./pkg/harfbuzz", .lazy = true },
|
||||||
.highway = .{ .path = "./pkg/highway", .lazy = true },
|
.highway = .{ .path = "./pkg/highway", .lazy = true },
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@
|
||||||
"url": "https://deps.files.ghostty.org/gettext-0.24.tar.gz",
|
"url": "https://deps.files.ghostty.org/gettext-0.24.tar.gz",
|
||||||
"hash": "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc="
|
"hash": "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc="
|
||||||
},
|
},
|
||||||
"N-V-__8AAMrJSwAUGb9-vTzkNR-5LXS81MR__ZRVfF3tWgG6": {
|
|
||||||
"name": "glfw",
|
|
||||||
"url": "https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz",
|
|
||||||
"hash": "sha256-M3N1XUAlMebBo5X1Py+9YxjKXgZ6eacqWRCbUmwLKQo="
|
|
||||||
},
|
|
||||||
"N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy": {
|
"N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy": {
|
||||||
"name": "glslang",
|
"name": "glslang",
|
||||||
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||||
|
|
|
||||||
|
|
@ -113,14 +113,6 @@ in
|
||||||
hash = "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc=";
|
hash = "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc=";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "N-V-__8AAMrJSwAUGb9-vTzkNR-5LXS81MR__ZRVfF3tWgG6";
|
|
||||||
path = fetchZigArtifact {
|
|
||||||
name = "glfw";
|
|
||||||
url = "https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz";
|
|
||||||
hash = "sha256-M3N1XUAlMebBo5X1Py+9YxjKXgZ6eacqWRCbUmwLKQo=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy";
|
name = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy";
|
||||||
path = fetchZigArtifact {
|
path = fetchZigArtifact {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ 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/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz
|
|
||||||
https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-18-21-1/ghostty-gobject-0.14.0-2025-03-18-21-1.tar.zst
|
https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-18-21-1/ghostty-gobject-0.14.0-2025-03-18-21-1.tar.zst
|
||||||
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/6fa671fdc1daf1fcfa025cb960ffa3e7373a2ed8.tar.gz
|
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/6fa671fdc1daf1fcfa025cb960ffa3e7373a2ed8.tar.gz
|
||||||
https://github.com/mitchellh/libxev/archive/75a10d0fb374e8eb84948dcfc68d865e755e59c2.tar.gz
|
https://github.com/mitchellh/libxev/archive/75a10d0fb374e8eb84948dcfc68d865e755e59c2.tar.gz
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,6 @@
|
||||||
"dest": "vendor/p/N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-",
|
"dest": "vendor/p/N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-",
|
||||||
"sha256": "c918503d593d70daf4844d175a13d816afacb667c06fba1ec9dcd5002c1518b7"
|
"sha256": "c918503d593d70daf4844d175a13d816afacb667c06fba1ec9dcd5002c1518b7"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "archive",
|
|
||||||
"url": "https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz",
|
|
||||||
"dest": "vendor/p/N-V-__8AAMrJSwAUGb9-vTzkNR-5LXS81MR__ZRVfF3tWgG6",
|
|
||||||
"sha256": "3373755d402531e6c1a395f53f2fbd6318ca5e067a79a72a59109b526c0b290a"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,22 @@ class AppDelegate: NSObject,
|
||||||
|
|
||||||
// Setup signal handlers
|
// Setup signal handlers
|
||||||
setupSignals()
|
setupSignals()
|
||||||
|
|
||||||
|
// This is a hack used by our build scripts, specifically `zig build run`,
|
||||||
|
// to force our app to the foreground.
|
||||||
|
if ProcessInfo.processInfo.environment["GHOSTTY_MAC_ACTIVATE"] == "1" {
|
||||||
|
// This never gets called until we click the dock icon. This forces it
|
||||||
|
// activate immediately.
|
||||||
|
applicationDidBecomeActive(.init(name: NSApplication.didBecomeActiveNotification))
|
||||||
|
|
||||||
|
// We run in the background, this forces us to the front.
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
NSApp.setActivationPolicy(.regular)
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
NSApp.unhide(nil)
|
||||||
|
NSApp.arrangeInFront(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationDidBecomeActive(_ notification: Notification) {
|
func applicationDidBecomeActive(_ notification: Notification) {
|
||||||
|
|
|
||||||
|
|
@ -1,209 +0,0 @@
|
||||||
//! 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();
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,642 +0,0 @@
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
Copyright (c) 2021 Hexops Contributors (given via the Git commit history).
|
|
||||||
Copyright (c) 2025 Mitchell Hashimoto, Ghostty contributors
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
@ -1,599 +0,0 @@
|
||||||
//! 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 .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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
//! 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();
|
|
||||||
}
|
|
||||||
3551
pkg/glfw/Window.zig
3551
pkg/glfw/Window.zig
File diff suppressed because it is too large
Load Diff
|
|
@ -1,13 +0,0 @@
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
// 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);
|
|
||||||
|
|
@ -1,271 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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",
|
|
||||||
};
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
.{
|
|
||||||
.name = .glfw,
|
|
||||||
.version = "3.4.0",
|
|
||||||
.fingerprint = 0x3bbe0a5c667e2c62,
|
|
||||||
.paths = .{""},
|
|
||||||
.dependencies = .{
|
|
||||||
.glfw = .{
|
|
||||||
.url = "https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz",
|
|
||||||
.hash = "N-V-__8AAMrJSwAUGb9-vTzkNR-5LXS81MR__ZRVfF3tWgG6",
|
|
||||||
.lazy = true,
|
|
||||||
},
|
|
||||||
|
|
||||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
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");
|
|
||||||
});
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
@ -1,338 +0,0 @@
|
||||||
//! 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();
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
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;
|
|
||||||
100
pkg/glfw/hat.zig
100
pkg/glfw/hat.zig
|
|
@ -1,100 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
266
pkg/glfw/key.zig
266
pkg/glfw/key.zig
|
|
@ -1,266 +0,0 @@
|
||||||
//! 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();
|
|
||||||
}
|
|
||||||
|
|
@ -1,586 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
167
pkg/glfw/mod.zig
167
pkg/glfw/mod.zig
|
|
@ -1,167 +0,0 @@
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
@ -1,393 +0,0 @@
|
||||||
//! 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
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 .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");
|
|
||||||
}
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
//! 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;
|
|
||||||
|
|
@ -1,290 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2022 Kenny Levinsen
|
|
||||||
*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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_fractional_scale_v1_interface;
|
|
||||||
|
|
||||||
static const struct wl_interface *fractional_scale_v1_types[] = {
|
|
||||||
NULL,
|
|
||||||
&wp_fractional_scale_v1_interface,
|
|
||||||
&wl_surface_interface,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message wp_fractional_scale_manager_v1_requests[] = {
|
|
||||||
{ "destroy", "", fractional_scale_v1_types + 0 },
|
|
||||||
{ "get_fractional_scale", "no", fractional_scale_v1_types + 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
WL_PRIVATE const struct wl_interface wp_fractional_scale_manager_v1_interface = {
|
|
||||||
"wp_fractional_scale_manager_v1", 1,
|
|
||||||
2, wp_fractional_scale_manager_v1_requests,
|
|
||||||
0, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message wp_fractional_scale_v1_requests[] = {
|
|
||||||
{ "destroy", "", fractional_scale_v1_types + 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message wp_fractional_scale_v1_events[] = {
|
|
||||||
{ "preferred_scale", "u", fractional_scale_v1_types + 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
WL_PRIVATE const struct wl_interface wp_fractional_scale_v1_interface = {
|
|
||||||
"wp_fractional_scale_v1", 1,
|
|
||||||
1, wp_fractional_scale_v1_requests,
|
|
||||||
1, wp_fractional_scale_v1_events,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,264 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#ifndef FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H
|
|
||||||
#define FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "wayland-client.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @page page_fractional_scale_v1 The fractional_scale_v1 protocol
|
|
||||||
* Protocol for requesting fractional surface scales
|
|
||||||
*
|
|
||||||
* @section page_desc_fractional_scale_v1 Description
|
|
||||||
*
|
|
||||||
* This protocol allows a compositor to suggest for surfaces to render at
|
|
||||||
* fractional scales.
|
|
||||||
*
|
|
||||||
* A client can submit scaled content by utilizing wp_viewport. This is done by
|
|
||||||
* creating a wp_viewport object for the surface and setting the destination
|
|
||||||
* rectangle to the surface size before the scale factor is applied.
|
|
||||||
*
|
|
||||||
* The buffer size is calculated by multiplying the surface size by the
|
|
||||||
* intended scale.
|
|
||||||
*
|
|
||||||
* The wl_surface buffer scale should remain set to 1.
|
|
||||||
*
|
|
||||||
* If a surface has a surface-local size of 100 px by 50 px and wishes to
|
|
||||||
* submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should
|
|
||||||
* be used and the wp_viewport destination rectangle should be 100 px by 50 px.
|
|
||||||
*
|
|
||||||
* For toplevel surfaces, the size is rounded halfway away from zero. The
|
|
||||||
* rounding algorithm for subsurface position and size is not defined.
|
|
||||||
*
|
|
||||||
* @section page_ifaces_fractional_scale_v1 Interfaces
|
|
||||||
* - @subpage page_iface_wp_fractional_scale_manager_v1 - fractional surface scale information
|
|
||||||
* - @subpage page_iface_wp_fractional_scale_v1 - fractional scale interface to a wl_surface
|
|
||||||
* @section page_copyright_fractional_scale_v1 Copyright
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* Copyright © 2022 Kenny Levinsen
|
|
||||||
*
|
|
||||||
* 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_fractional_scale_manager_v1;
|
|
||||||
struct wp_fractional_scale_v1;
|
|
||||||
|
|
||||||
#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE
|
|
||||||
/**
|
|
||||||
* @page page_iface_wp_fractional_scale_manager_v1 wp_fractional_scale_manager_v1
|
|
||||||
* @section page_iface_wp_fractional_scale_manager_v1_desc Description
|
|
||||||
*
|
|
||||||
* A global interface for requesting surfaces to use fractional scales.
|
|
||||||
* @section page_iface_wp_fractional_scale_manager_v1_api API
|
|
||||||
* See @ref iface_wp_fractional_scale_manager_v1.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup iface_wp_fractional_scale_manager_v1 The wp_fractional_scale_manager_v1 interface
|
|
||||||
*
|
|
||||||
* A global interface for requesting surfaces to use fractional scales.
|
|
||||||
*/
|
|
||||||
extern const struct wl_interface wp_fractional_scale_manager_v1_interface;
|
|
||||||
#endif
|
|
||||||
#ifndef WP_FRACTIONAL_SCALE_V1_INTERFACE
|
|
||||||
#define WP_FRACTIONAL_SCALE_V1_INTERFACE
|
|
||||||
/**
|
|
||||||
* @page page_iface_wp_fractional_scale_v1 wp_fractional_scale_v1
|
|
||||||
* @section page_iface_wp_fractional_scale_v1_desc Description
|
|
||||||
*
|
|
||||||
* An additional interface to a wl_surface object which allows the compositor
|
|
||||||
* to inform the client of the preferred scale.
|
|
||||||
* @section page_iface_wp_fractional_scale_v1_api API
|
|
||||||
* See @ref iface_wp_fractional_scale_v1.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup iface_wp_fractional_scale_v1 The wp_fractional_scale_v1 interface
|
|
||||||
*
|
|
||||||
* An additional interface to a wl_surface object which allows the compositor
|
|
||||||
* to inform the client of the preferred scale.
|
|
||||||
*/
|
|
||||||
extern const struct wl_interface wp_fractional_scale_v1_interface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM
|
|
||||||
enum wp_fractional_scale_manager_v1_error {
|
|
||||||
/**
|
|
||||||
* the surface already has a fractional_scale object associated
|
|
||||||
*/
|
|
||||||
WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS = 0,
|
|
||||||
};
|
|
||||||
#endif /* WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM */
|
|
||||||
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY 0
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE 1
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_manager_v1
|
|
||||||
*/
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_manager_v1
|
|
||||||
*/
|
|
||||||
#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/** @ingroup iface_wp_fractional_scale_manager_v1 */
|
|
||||||
static inline void
|
|
||||||
wp_fractional_scale_manager_v1_set_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, void *user_data)
|
|
||||||
{
|
|
||||||
wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @ingroup iface_wp_fractional_scale_manager_v1 */
|
|
||||||
static inline void *
|
|
||||||
wp_fractional_scale_manager_v1_get_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
wp_fractional_scale_manager_v1_get_version(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_manager_v1
|
|
||||||
*
|
|
||||||
* Informs the server that the client will not be using this protocol
|
|
||||||
* object anymore. This does not affect any other objects,
|
|
||||||
* wp_fractional_scale_v1 objects included.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
wp_fractional_scale_manager_v1_destroy(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1,
|
|
||||||
WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_manager_v1
|
|
||||||
*
|
|
||||||
* Create an add-on object for the the wl_surface to let the compositor
|
|
||||||
* request fractional scales. If the given wl_surface already has a
|
|
||||||
* wp_fractional_scale_v1 object associated, the fractional_scale_exists
|
|
||||||
* protocol error is raised.
|
|
||||||
*/
|
|
||||||
static inline struct wp_fractional_scale_v1 *
|
|
||||||
wp_fractional_scale_manager_v1_get_fractional_scale(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, struct wl_surface *surface)
|
|
||||||
{
|
|
||||||
struct wl_proxy *id;
|
|
||||||
|
|
||||||
id = wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1,
|
|
||||||
WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE, &wp_fractional_scale_v1_interface, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), 0, NULL, surface);
|
|
||||||
|
|
||||||
return (struct wp_fractional_scale_v1 *) id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_v1
|
|
||||||
* @struct wp_fractional_scale_v1_listener
|
|
||||||
*/
|
|
||||||
struct wp_fractional_scale_v1_listener {
|
|
||||||
/**
|
|
||||||
* notify of new preferred scale
|
|
||||||
*
|
|
||||||
* Notification of a new preferred scale for this surface that
|
|
||||||
* the compositor suggests that the client should use.
|
|
||||||
*
|
|
||||||
* The sent scale is the numerator of a fraction with a denominator
|
|
||||||
* of 120.
|
|
||||||
* @param scale the new preferred scale
|
|
||||||
*/
|
|
||||||
void (*preferred_scale)(void *data,
|
|
||||||
struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
|
||||||
uint32_t scale);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_v1
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
wp_fractional_scale_v1_add_listener(struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
|
||||||
const struct wp_fractional_scale_v1_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
return wl_proxy_add_listener((struct wl_proxy *) wp_fractional_scale_v1,
|
|
||||||
(void (**)(void)) listener, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WP_FRACTIONAL_SCALE_V1_DESTROY 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_v1
|
|
||||||
*/
|
|
||||||
#define WP_FRACTIONAL_SCALE_V1_PREFERRED_SCALE_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_v1
|
|
||||||
*/
|
|
||||||
#define WP_FRACTIONAL_SCALE_V1_DESTROY_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/** @ingroup iface_wp_fractional_scale_v1 */
|
|
||||||
static inline void
|
|
||||||
wp_fractional_scale_v1_set_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, void *user_data)
|
|
||||||
{
|
|
||||||
wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_v1, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @ingroup iface_wp_fractional_scale_v1 */
|
|
||||||
static inline void *
|
|
||||||
wp_fractional_scale_v1_get_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
wp_fractional_scale_v1_get_version(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_wp_fractional_scale_v1
|
|
||||||
*
|
|
||||||
* Destroy the fractional scale object. When this object is destroyed,
|
|
||||||
* preferred_scale events will no longer be sent.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
wp_fractional_scale_v1_destroy(struct wp_fractional_scale_v1 *wp_fractional_scale_v1)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_v1,
|
|
||||||
WP_FRACTIONAL_SCALE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1), WL_MARSHAL_FLAG_DESTROY);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,232 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,667 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,297 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,398 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
@ -1,525 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,85 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
|
||||||
* Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
|
|
||||||
*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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_seat_interface;
|
|
||||||
extern const struct wl_interface wl_surface_interface;
|
|
||||||
extern const struct wl_interface xdg_activation_token_v1_interface;
|
|
||||||
|
|
||||||
static const struct wl_interface *xdg_activation_v1_types[] = {
|
|
||||||
NULL,
|
|
||||||
&xdg_activation_token_v1_interface,
|
|
||||||
NULL,
|
|
||||||
&wl_surface_interface,
|
|
||||||
NULL,
|
|
||||||
&wl_seat_interface,
|
|
||||||
&wl_surface_interface,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message xdg_activation_v1_requests[] = {
|
|
||||||
{ "destroy", "", xdg_activation_v1_types + 0 },
|
|
||||||
{ "get_activation_token", "n", xdg_activation_v1_types + 1 },
|
|
||||||
{ "activate", "so", xdg_activation_v1_types + 2 },
|
|
||||||
};
|
|
||||||
|
|
||||||
WL_PRIVATE const struct wl_interface xdg_activation_v1_interface = {
|
|
||||||
"xdg_activation_v1", 1,
|
|
||||||
3, xdg_activation_v1_requests,
|
|
||||||
0, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message xdg_activation_token_v1_requests[] = {
|
|
||||||
{ "set_serial", "uo", xdg_activation_v1_types + 4 },
|
|
||||||
{ "set_app_id", "s", xdg_activation_v1_types + 0 },
|
|
||||||
{ "set_surface", "o", xdg_activation_v1_types + 6 },
|
|
||||||
{ "commit", "", xdg_activation_v1_types + 0 },
|
|
||||||
{ "destroy", "", xdg_activation_v1_types + 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct wl_message xdg_activation_token_v1_events[] = {
|
|
||||||
{ "done", "s", xdg_activation_v1_types + 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
WL_PRIVATE const struct wl_interface xdg_activation_token_v1_interface = {
|
|
||||||
"xdg_activation_token_v1", 1,
|
|
||||||
5, xdg_activation_token_v1_requests,
|
|
||||||
1, xdg_activation_token_v1_events,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,415 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#ifndef XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H
|
|
||||||
#define XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "wayland-client.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @page page_xdg_activation_v1 The xdg_activation_v1 protocol
|
|
||||||
* Protocol for requesting activation of surfaces
|
|
||||||
*
|
|
||||||
* @section page_desc_xdg_activation_v1 Description
|
|
||||||
*
|
|
||||||
* The way for a client to pass focus to another toplevel is as follows.
|
|
||||||
*
|
|
||||||
* The client that intends to activate another toplevel uses the
|
|
||||||
* xdg_activation_v1.get_activation_token request to get an activation token.
|
|
||||||
* This token is then forwarded to the client, which is supposed to activate
|
|
||||||
* one of its surfaces, through a separate band of communication.
|
|
||||||
*
|
|
||||||
* One established way of doing this is through the XDG_ACTIVATION_TOKEN
|
|
||||||
* environment variable of a newly launched child process. The child process
|
|
||||||
* should unset the environment variable again right after reading it out in
|
|
||||||
* order to avoid propagating it to other child processes.
|
|
||||||
*
|
|
||||||
* Another established way exists for Applications implementing the D-Bus
|
|
||||||
* interface org.freedesktop.Application, which should get their token under
|
|
||||||
* activation-token on their platform_data.
|
|
||||||
*
|
|
||||||
* In general activation tokens may be transferred across clients through
|
|
||||||
* means not described in this protocol.
|
|
||||||
*
|
|
||||||
* The client to be activated will then pass the token
|
|
||||||
* it received to the xdg_activation_v1.activate request. The compositor can
|
|
||||||
* then use this token to decide how to react to the activation request.
|
|
||||||
*
|
|
||||||
* The token the activating client gets may be ineffective either already at
|
|
||||||
* the time it receives it, for example if it was not focused, for focus
|
|
||||||
* stealing prevention. The activating client will have no way to discover
|
|
||||||
* the validity of the token, and may still forward it to the to be activated
|
|
||||||
* client.
|
|
||||||
*
|
|
||||||
* The created activation token may optionally get information attached to it
|
|
||||||
* that can be used by the compositor to identify the application that we
|
|
||||||
* intend to activate. This can for example be used to display a visual hint
|
|
||||||
* about what application is being started.
|
|
||||||
*
|
|
||||||
* Warning! The protocol described in this file is currently in the testing
|
|
||||||
* phase. Backward compatible changes may be added together with the
|
|
||||||
* corresponding interface version bump. Backward incompatible changes can
|
|
||||||
* only be done by creating a new major version of the extension.
|
|
||||||
*
|
|
||||||
* @section page_ifaces_xdg_activation_v1 Interfaces
|
|
||||||
* - @subpage page_iface_xdg_activation_v1 - interface for activating surfaces
|
|
||||||
* - @subpage page_iface_xdg_activation_token_v1 - an exported activation handle
|
|
||||||
* @section page_copyright_xdg_activation_v1 Copyright
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
|
||||||
* Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
|
|
||||||
*
|
|
||||||
* 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_seat;
|
|
||||||
struct wl_surface;
|
|
||||||
struct xdg_activation_token_v1;
|
|
||||||
struct xdg_activation_v1;
|
|
||||||
|
|
||||||
#ifndef XDG_ACTIVATION_V1_INTERFACE
|
|
||||||
#define XDG_ACTIVATION_V1_INTERFACE
|
|
||||||
/**
|
|
||||||
* @page page_iface_xdg_activation_v1 xdg_activation_v1
|
|
||||||
* @section page_iface_xdg_activation_v1_desc Description
|
|
||||||
*
|
|
||||||
* A global interface used for informing the compositor about applications
|
|
||||||
* being activated or started, or for applications to request to be
|
|
||||||
* activated.
|
|
||||||
* @section page_iface_xdg_activation_v1_api API
|
|
||||||
* See @ref iface_xdg_activation_v1.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup iface_xdg_activation_v1 The xdg_activation_v1 interface
|
|
||||||
*
|
|
||||||
* A global interface used for informing the compositor about applications
|
|
||||||
* being activated or started, or for applications to request to be
|
|
||||||
* activated.
|
|
||||||
*/
|
|
||||||
extern const struct wl_interface xdg_activation_v1_interface;
|
|
||||||
#endif
|
|
||||||
#ifndef XDG_ACTIVATION_TOKEN_V1_INTERFACE
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_INTERFACE
|
|
||||||
/**
|
|
||||||
* @page page_iface_xdg_activation_token_v1 xdg_activation_token_v1
|
|
||||||
* @section page_iface_xdg_activation_token_v1_desc Description
|
|
||||||
*
|
|
||||||
* An object for setting up a token and receiving a token handle that can
|
|
||||||
* be passed as an activation token to another client.
|
|
||||||
*
|
|
||||||
* The object is created using the xdg_activation_v1.get_activation_token
|
|
||||||
* request. This object should then be populated with the app_id, surface
|
|
||||||
* and serial information and committed. The compositor shall then issue a
|
|
||||||
* done event with the token. In case the request's parameters are invalid,
|
|
||||||
* the compositor will provide an invalid token.
|
|
||||||
* @section page_iface_xdg_activation_token_v1_api API
|
|
||||||
* See @ref iface_xdg_activation_token_v1.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup iface_xdg_activation_token_v1 The xdg_activation_token_v1 interface
|
|
||||||
*
|
|
||||||
* An object for setting up a token and receiving a token handle that can
|
|
||||||
* be passed as an activation token to another client.
|
|
||||||
*
|
|
||||||
* The object is created using the xdg_activation_v1.get_activation_token
|
|
||||||
* request. This object should then be populated with the app_id, surface
|
|
||||||
* and serial information and committed. The compositor shall then issue a
|
|
||||||
* done event with the token. In case the request's parameters are invalid,
|
|
||||||
* the compositor will provide an invalid token.
|
|
||||||
*/
|
|
||||||
extern const struct wl_interface xdg_activation_token_v1_interface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define XDG_ACTIVATION_V1_DESTROY 0
|
|
||||||
#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN 1
|
|
||||||
#define XDG_ACTIVATION_V1_ACTIVATE 2
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_V1_DESTROY_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_V1_ACTIVATE_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/** @ingroup iface_xdg_activation_v1 */
|
|
||||||
static inline void
|
|
||||||
xdg_activation_v1_set_user_data(struct xdg_activation_v1 *xdg_activation_v1, void *user_data)
|
|
||||||
{
|
|
||||||
wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_v1, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @ingroup iface_xdg_activation_v1 */
|
|
||||||
static inline void *
|
|
||||||
xdg_activation_v1_get_user_data(struct xdg_activation_v1 *xdg_activation_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
xdg_activation_v1_get_version(struct xdg_activation_v1 *xdg_activation_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*
|
|
||||||
* Notify the compositor that the xdg_activation object will no longer be
|
|
||||||
* used.
|
|
||||||
*
|
|
||||||
* The child objects created via this interface are unaffected and should
|
|
||||||
* be destroyed separately.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_v1_destroy(struct xdg_activation_v1 *xdg_activation_v1)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1,
|
|
||||||
XDG_ACTIVATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), WL_MARSHAL_FLAG_DESTROY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*
|
|
||||||
* Creates an xdg_activation_token_v1 object that will provide
|
|
||||||
* the initiating client with a unique token for this activation. This
|
|
||||||
* token should be offered to the clients to be activated.
|
|
||||||
*/
|
|
||||||
static inline struct xdg_activation_token_v1 *
|
|
||||||
xdg_activation_v1_get_activation_token(struct xdg_activation_v1 *xdg_activation_v1)
|
|
||||||
{
|
|
||||||
struct wl_proxy *id;
|
|
||||||
|
|
||||||
id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1,
|
|
||||||
XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN, &xdg_activation_token_v1_interface, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), 0, NULL);
|
|
||||||
|
|
||||||
return (struct xdg_activation_token_v1 *) id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_v1
|
|
||||||
*
|
|
||||||
* Requests surface activation. It's up to the compositor to display
|
|
||||||
* this information as desired, for example by placing the surface above
|
|
||||||
* the rest.
|
|
||||||
*
|
|
||||||
* The compositor may know who requested this by checking the activation
|
|
||||||
* token and might decide not to follow through with the activation if it's
|
|
||||||
* considered unwanted.
|
|
||||||
*
|
|
||||||
* Compositors can ignore unknown activation tokens when an invalid
|
|
||||||
* token is passed.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_v1_activate(struct xdg_activation_v1 *xdg_activation_v1, const char *token, struct wl_surface *surface)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_v1,
|
|
||||||
XDG_ACTIVATION_V1_ACTIVATE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1), 0, token, surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM
|
|
||||||
enum xdg_activation_token_v1_error {
|
|
||||||
/**
|
|
||||||
* The token has already been used previously
|
|
||||||
*/
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_ERROR_ALREADY_USED = 0,
|
|
||||||
};
|
|
||||||
#endif /* XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
* @struct xdg_activation_token_v1_listener
|
|
||||||
*/
|
|
||||||
struct xdg_activation_token_v1_listener {
|
|
||||||
/**
|
|
||||||
* the exported activation token
|
|
||||||
*
|
|
||||||
* The 'done' event contains the unique token of this activation
|
|
||||||
* request and notifies that the provider is done.
|
|
||||||
* @param token the exported activation token
|
|
||||||
*/
|
|
||||||
void (*done)(void *data,
|
|
||||||
struct xdg_activation_token_v1 *xdg_activation_token_v1,
|
|
||||||
const char *token);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
xdg_activation_token_v1_add_listener(struct xdg_activation_token_v1 *xdg_activation_token_v1,
|
|
||||||
const struct xdg_activation_token_v1_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
return wl_proxy_add_listener((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
(void (**)(void)) listener, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL 0
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID 1
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE 2
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_COMMIT 3
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_DESTROY 4
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_DONE_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_COMMIT_SINCE_VERSION 1
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*/
|
|
||||||
#define XDG_ACTIVATION_TOKEN_V1_DESTROY_SINCE_VERSION 1
|
|
||||||
|
|
||||||
/** @ingroup iface_xdg_activation_token_v1 */
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_set_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1, void *user_data)
|
|
||||||
{
|
|
||||||
wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_token_v1, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @ingroup iface_xdg_activation_token_v1 */
|
|
||||||
static inline void *
|
|
||||||
xdg_activation_token_v1_get_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_token_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
xdg_activation_token_v1_get_version(struct xdg_activation_token_v1 *xdg_activation_token_v1)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*
|
|
||||||
* Provides information about the seat and serial event that requested the
|
|
||||||
* token.
|
|
||||||
*
|
|
||||||
* The serial can come from an input or focus event. For instance, if a
|
|
||||||
* click triggers the launch of a third-party client, the launcher client
|
|
||||||
* should send a set_serial request with the serial and seat from the
|
|
||||||
* wl_pointer.button event.
|
|
||||||
*
|
|
||||||
* Some compositors might refuse to activate toplevels when the token
|
|
||||||
* doesn't have a valid and recent enough event serial.
|
|
||||||
*
|
|
||||||
* Must be sent before commit. This information is optional.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_set_serial(struct xdg_activation_token_v1 *xdg_activation_token_v1, uint32_t serial, struct wl_seat *seat)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_SET_SERIAL, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, serial, seat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*
|
|
||||||
* The requesting client can specify an app_id to associate the token
|
|
||||||
* being created with it.
|
|
||||||
*
|
|
||||||
* Must be sent before commit. This information is optional.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_set_app_id(struct xdg_activation_token_v1 *xdg_activation_token_v1, const char *app_id)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, app_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*
|
|
||||||
* This request sets the surface requesting the activation. Note, this is
|
|
||||||
* different from the surface that will be activated.
|
|
||||||
*
|
|
||||||
* Some compositors might refuse to activate toplevels when the token
|
|
||||||
* doesn't have a requesting surface.
|
|
||||||
*
|
|
||||||
* Must be sent before commit. This information is optional.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_set_surface(struct xdg_activation_token_v1 *xdg_activation_token_v1, struct wl_surface *surface)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_SET_SURFACE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0, surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*
|
|
||||||
* Requests an activation token based on the different parameters that
|
|
||||||
* have been offered through set_serial, set_surface and set_app_id.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_commit(struct xdg_activation_token_v1 *xdg_activation_token_v1)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup iface_xdg_activation_token_v1
|
|
||||||
*
|
|
||||||
* Notify the compositor that the xdg_activation_token_v1 object will no
|
|
||||||
* longer be used. The received token stays valid.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
xdg_activation_token_v1_destroy(struct xdg_activation_token_v1 *xdg_activation_token_v1)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal_flags((struct wl_proxy *) xdg_activation_token_v1,
|
|
||||||
XDG_ACTIVATION_TOKEN_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1), WL_MARSHAL_FLAG_DESTROY);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,378 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
||||||
/* Generated by wayland-scanner 1.23.1 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#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
|
|
@ -3,7 +3,7 @@
|
||||||
//! getting user input (mouse/keyboard), etc.
|
//! getting user input (mouse/keyboard), etc.
|
||||||
//!
|
//!
|
||||||
//! This enables compile-time interfaces to be built to swap out the underlying
|
//! This enables compile-time interfaces to be built to swap out the underlying
|
||||||
//! application runtime. For example: glfw, pure macOS Cocoa, GTK+, browser, etc.
|
//! application runtime. For example: pure macOS Cocoa, GTK+, browser, etc.
|
||||||
//!
|
//!
|
||||||
//! The goal is to have different implementations share as much of the core
|
//! The goal is to have different implementations share as much of the core
|
||||||
//! logic as possible, and to only reach out to platform-specific implementation
|
//! logic as possible, and to only reach out to platform-specific implementation
|
||||||
|
|
@ -15,7 +15,6 @@ const build_config = @import("build_config.zig");
|
||||||
const structs = @import("apprt/structs.zig");
|
const structs = @import("apprt/structs.zig");
|
||||||
|
|
||||||
pub const action = @import("apprt/action.zig");
|
pub const action = @import("apprt/action.zig");
|
||||||
pub const glfw = @import("apprt/glfw.zig");
|
|
||||||
pub const gtk = @import("apprt/gtk.zig");
|
pub const gtk = @import("apprt/gtk.zig");
|
||||||
pub const none = @import("apprt/none.zig");
|
pub const none = @import("apprt/none.zig");
|
||||||
pub const browser = @import("apprt/browser.zig");
|
pub const browser = @import("apprt/browser.zig");
|
||||||
|
|
@ -42,7 +41,6 @@ pub const SurfaceSize = structs.SurfaceSize;
|
||||||
pub const runtime = switch (build_config.artifact) {
|
pub const runtime = switch (build_config.artifact) {
|
||||||
.exe => switch (build_config.app_runtime) {
|
.exe => switch (build_config.app_runtime) {
|
||||||
.none => none,
|
.none => none,
|
||||||
.glfw => glfw,
|
|
||||||
.gtk => gtk,
|
.gtk => gtk,
|
||||||
},
|
},
|
||||||
.lib => embedded,
|
.lib => embedded,
|
||||||
|
|
@ -53,18 +51,12 @@ pub const App = runtime.App;
|
||||||
pub const Surface = runtime.Surface;
|
pub const Surface = runtime.Surface;
|
||||||
|
|
||||||
/// Runtime is the runtime to use for Ghostty. All runtimes do not provide
|
/// Runtime is the runtime to use for Ghostty. All runtimes do not provide
|
||||||
/// equivalent feature sets. For example, GTK offers tabbing and more features
|
/// equivalent feature sets.
|
||||||
/// that glfw does not provide. However, glfw may require many less
|
|
||||||
/// dependencies.
|
|
||||||
pub const Runtime = enum {
|
pub const Runtime = enum {
|
||||||
/// Will not produce an executable at all when `zig build` is called.
|
/// Will not produce an executable at all when `zig build` is called.
|
||||||
/// This is only useful if you're only interested in the lib only (macOS).
|
/// This is only useful if you're only interested in the lib only (macOS).
|
||||||
none,
|
none,
|
||||||
|
|
||||||
/// Glfw-backed. Very simple. Glfw is statically linked. Tabbing and
|
|
||||||
/// other rich windowing features are not supported.
|
|
||||||
glfw,
|
|
||||||
|
|
||||||
/// GTK-backed. Rich windowed application. GTK is dynamically linked.
|
/// GTK-backed. Rich windowed application. GTK is dynamically linked.
|
||||||
gtk,
|
gtk,
|
||||||
|
|
||||||
|
|
@ -72,12 +64,8 @@ pub const Runtime = enum {
|
||||||
// The Linux default is GTK because it is full featured.
|
// The Linux default is GTK because it is full featured.
|
||||||
if (target.os.tag == .linux) return .gtk;
|
if (target.os.tag == .linux) return .gtk;
|
||||||
|
|
||||||
// Windows we currently only support glfw
|
// Otherwise, we do NONE so we don't create an exe and we
|
||||||
if (target.os.tag == .windows) return .glfw;
|
// create libghostty.
|
||||||
|
|
||||||
// Otherwise, we do NONE so we don't create an exe. The GLFW
|
|
||||||
// build is opt-in because it is missing so many features compared
|
|
||||||
// to the other builds that are impossible due to the GLFW interface.
|
|
||||||
return .none;
|
return .none;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ pub const App = struct {
|
||||||
var surface = try self.core_app.alloc.create(Surface);
|
var surface = try self.core_app.alloc.create(Surface);
|
||||||
errdefer self.core_app.alloc.destroy(surface);
|
errdefer self.core_app.alloc.destroy(surface);
|
||||||
|
|
||||||
// Create the surface -- because windows are surfaces for glfw.
|
// Create the surface
|
||||||
try surface.init(self, opts);
|
try surface.init(self, opts);
|
||||||
errdefer surface.deinit();
|
errdefer surface.deinit();
|
||||||
|
|
||||||
|
|
|
||||||
1266
src/apprt/glfw.zig
1266
src/apprt/glfw.zig
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@ const apprt = @import("../apprt.zig");
|
||||||
const font = @import("../font/main.zig");
|
const font = @import("../font/main.zig");
|
||||||
const rendererpkg = @import("../renderer.zig");
|
const rendererpkg = @import("../renderer.zig");
|
||||||
const Command = @import("../Command.zig");
|
const Command = @import("../Command.zig");
|
||||||
|
const XCFramework = @import("GhosttyXCFramework.zig");
|
||||||
const WasmTarget = @import("../os/wasm/target.zig").Target;
|
const WasmTarget = @import("../os/wasm/target.zig").Target;
|
||||||
|
|
||||||
const gtk = @import("gtk.zig");
|
const gtk = @import("gtk.zig");
|
||||||
|
|
@ -24,6 +25,7 @@ const app_version: std.SemanticVersion = .{ .major = 1, .minor = 1, .patch = 4 }
|
||||||
/// Standard build configuration options.
|
/// Standard build configuration options.
|
||||||
optimize: std.builtin.OptimizeMode,
|
optimize: std.builtin.OptimizeMode,
|
||||||
target: std.Build.ResolvedTarget,
|
target: std.Build.ResolvedTarget,
|
||||||
|
xcframework_target: XCFramework.Target = .universal,
|
||||||
wasm_target: WasmTarget,
|
wasm_target: WasmTarget,
|
||||||
|
|
||||||
/// Comptime interfaces
|
/// Comptime interfaces
|
||||||
|
|
@ -48,14 +50,15 @@ patch_rpath: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Artifacts
|
/// Artifacts
|
||||||
flatpak: bool = false,
|
flatpak: bool = false,
|
||||||
emit_test_exe: bool = false,
|
|
||||||
emit_bench: bool = false,
|
emit_bench: bool = false,
|
||||||
emit_helpgen: bool = false,
|
|
||||||
emit_docs: bool = false,
|
emit_docs: bool = false,
|
||||||
emit_webdata: bool = false,
|
emit_helpgen: bool = false,
|
||||||
emit_xcframework: bool = false,
|
emit_macos_app: bool = false,
|
||||||
emit_terminfo: bool = false,
|
emit_terminfo: bool = false,
|
||||||
emit_termcap: bool = false,
|
emit_termcap: bool = false,
|
||||||
|
emit_test_exe: bool = false,
|
||||||
|
emit_xcframework: bool = false,
|
||||||
|
emit_webdata: bool = false,
|
||||||
|
|
||||||
/// Environmental properties
|
/// Environmental properties
|
||||||
env: std.process.EnvMap,
|
env: std.process.EnvMap,
|
||||||
|
|
@ -109,6 +112,14 @@ pub fn init(b: *std.Build) !Config {
|
||||||
.env = env,
|
.env = env,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
// Target-specific properties
|
||||||
|
config.xcframework_target = b.option(
|
||||||
|
XCFramework.Target,
|
||||||
|
"xcframework-target",
|
||||||
|
"The target for the xcframework.",
|
||||||
|
) orelse .universal;
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Comptime Interfaces
|
// Comptime Interfaces
|
||||||
config.font_backend = b.option(
|
config.font_backend = b.option(
|
||||||
|
|
@ -340,6 +351,12 @@ pub fn init(b: *std.Build) !Config {
|
||||||
!config.emit_test_exe and
|
!config.emit_test_exe and
|
||||||
!config.emit_helpgen);
|
!config.emit_helpgen);
|
||||||
|
|
||||||
|
config.emit_macos_app = b.option(
|
||||||
|
bool,
|
||||||
|
"emit-macos-app",
|
||||||
|
"Build and install the macOS app bundle.",
|
||||||
|
) orelse config.emit_xcframework;
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// System Packages
|
// System Packages
|
||||||
|
|
||||||
|
|
@ -378,11 +395,6 @@ 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 });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,5 +93,32 @@ pub fn init(
|
||||||
|
|
||||||
pub fn install(self: *const GhosttyDocs) void {
|
pub fn install(self: *const GhosttyDocs) void {
|
||||||
const b = self.steps[0].owner;
|
const b = self.steps[0].owner;
|
||||||
for (self.steps) |step| b.getInstallStep().dependOn(step);
|
self.addStepDependencies(b.getInstallStep());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addStepDependencies(
|
||||||
|
self: *const GhosttyDocs,
|
||||||
|
other_step: *std.Build.Step,
|
||||||
|
) void {
|
||||||
|
for (self.steps) |step| other_step.dependOn(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Installs some dummy files to satisfy the folder structure of docs
|
||||||
|
/// without actually generating any documentation. This is useful
|
||||||
|
/// when the `emit-docs` option is not set to true, but we still
|
||||||
|
/// need the rough directory structure to exist, such as for the macOS
|
||||||
|
/// app.
|
||||||
|
pub fn installDummy(self: *const GhosttyDocs, step: *std.Build.Step) void {
|
||||||
|
_ = self;
|
||||||
|
|
||||||
|
const b = step.owner;
|
||||||
|
var wf = b.addWriteFiles();
|
||||||
|
const path = "share/man/.placeholder";
|
||||||
|
step.dependOn(&b.addInstallFile(
|
||||||
|
wf.add(
|
||||||
|
path,
|
||||||
|
"emit-docs not true so no man pages",
|
||||||
|
),
|
||||||
|
path,
|
||||||
|
).step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,14 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install(self: *const GhosttyI18n) void {
|
pub fn install(self: *const GhosttyI18n) void {
|
||||||
for (self.steps) |step| self.owner.getInstallStep().dependOn(step);
|
self.addStepDependencies(self.owner.getInstallStep());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addStepDependencies(
|
||||||
|
self: *const GhosttyI18n,
|
||||||
|
other_step: *std.Build.Step,
|
||||||
|
) void {
|
||||||
|
for (self.steps) |step| other_step.dependOn(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createUpdateStep(b: *std.Build) !*std.Build.Step {
|
fn createUpdateStep(b: *std.Build) !*std.Build.Step {
|
||||||
|
|
|
||||||
|
|
@ -397,5 +397,12 @@ fn addLinuxAppResources(
|
||||||
|
|
||||||
pub fn install(self: *const GhosttyResources) void {
|
pub fn install(self: *const GhosttyResources) void {
|
||||||
const b = self.steps[0].owner;
|
const b = self.steps[0].owner;
|
||||||
for (self.steps) |step| b.getInstallStep().dependOn(step);
|
self.addStepDependencies(b.getInstallStep());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addStepDependencies(
|
||||||
|
self: *const GhosttyResources,
|
||||||
|
other_step: *std.Build.Step,
|
||||||
|
) void {
|
||||||
|
for (self.steps) |step| other_step.dependOn(step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,23 @@ const GhosttyLib = @import("GhosttyLib.zig");
|
||||||
const XCFrameworkStep = @import("XCFrameworkStep.zig");
|
const XCFrameworkStep = @import("XCFrameworkStep.zig");
|
||||||
|
|
||||||
xcframework: *XCFrameworkStep,
|
xcframework: *XCFrameworkStep,
|
||||||
macos: GhosttyLib,
|
target: Target,
|
||||||
|
|
||||||
pub fn init(b: *std.Build, deps: *const SharedDeps) !GhosttyXCFramework {
|
pub const Target = enum { native, universal };
|
||||||
// Create our universal macOS static library.
|
|
||||||
const macos = try GhosttyLib.initMacOSUniversal(b, deps);
|
pub fn init(
|
||||||
|
b: *std.Build,
|
||||||
|
deps: *const SharedDeps,
|
||||||
|
target: Target,
|
||||||
|
) !GhosttyXCFramework {
|
||||||
|
// Universal macOS build
|
||||||
|
const macos_universal = try GhosttyLib.initMacOSUniversal(b, deps);
|
||||||
|
|
||||||
|
// Native macOS build
|
||||||
|
const macos_native = try GhosttyLib.initStatic(b, &try deps.retarget(
|
||||||
|
b,
|
||||||
|
Config.genericMacOSTarget(b, null),
|
||||||
|
));
|
||||||
|
|
||||||
// iOS
|
// iOS
|
||||||
const ios = try GhosttyLib.initStatic(b, &try deps.retarget(
|
const ios = try GhosttyLib.initStatic(b, &try deps.retarget(
|
||||||
|
|
@ -47,29 +59,43 @@ pub fn init(b: *std.Build, deps: *const SharedDeps) !GhosttyXCFramework {
|
||||||
const xcframework = XCFrameworkStep.create(b, .{
|
const xcframework = XCFrameworkStep.create(b, .{
|
||||||
.name = "GhosttyKit",
|
.name = "GhosttyKit",
|
||||||
.out_path = "macos/GhosttyKit.xcframework",
|
.out_path = "macos/GhosttyKit.xcframework",
|
||||||
.libraries = &.{
|
.libraries = switch (target) {
|
||||||
.{
|
.universal => &.{
|
||||||
.library = macos.output,
|
.{
|
||||||
.headers = b.path("include"),
|
.library = macos_universal.output,
|
||||||
|
.headers = b.path("include"),
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.library = ios.output,
|
||||||
|
.headers = b.path("include"),
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.library = ios_sim.output,
|
||||||
|
.headers = b.path("include"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.{
|
|
||||||
.library = ios.output,
|
.native => &.{.{
|
||||||
|
.library = macos_native.output,
|
||||||
.headers = b.path("include"),
|
.headers = b.path("include"),
|
||||||
},
|
}},
|
||||||
.{
|
|
||||||
.library = ios_sim.output,
|
|
||||||
.headers = b.path("include"),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.xcframework = xcframework,
|
.xcframework = xcframework,
|
||||||
.macos = macos,
|
.target = target,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install(self: *const GhosttyXCFramework) void {
|
pub fn install(self: *const GhosttyXCFramework) void {
|
||||||
const b = self.xcframework.step.owner;
|
const b = self.xcframework.step.owner;
|
||||||
b.getInstallStep().dependOn(self.xcframework.step);
|
self.addStepDependencies(b.getInstallStep());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addStepDependencies(
|
||||||
|
self: *const GhosttyXCFramework,
|
||||||
|
other_step: *std.Build.Step,
|
||||||
|
) void {
|
||||||
|
other_step.dependOn(self.xcframework.step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
const Ghostty = @This();
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const RunStep = std.Build.Step.Run;
|
||||||
|
const Config = @import("Config.zig");
|
||||||
|
const Docs = @import("GhosttyDocs.zig");
|
||||||
|
const I18n = @import("GhosttyI18n.zig");
|
||||||
|
const Resources = @import("GhosttyResources.zig");
|
||||||
|
const XCFramework = @import("GhosttyXCFramework.zig");
|
||||||
|
|
||||||
|
build: *std.Build.Step.Run,
|
||||||
|
open: *std.Build.Step.Run,
|
||||||
|
copy: *std.Build.Step.Run,
|
||||||
|
|
||||||
|
pub const Deps = struct {
|
||||||
|
xcframework: *const XCFramework,
|
||||||
|
docs: *const Docs,
|
||||||
|
i18n: *const I18n,
|
||||||
|
resources: *const Resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(
|
||||||
|
b: *std.Build,
|
||||||
|
config: *const Config,
|
||||||
|
deps: Deps,
|
||||||
|
) !Ghostty {
|
||||||
|
const xc_config = switch (config.optimize) {
|
||||||
|
.Debug => "Debug",
|
||||||
|
.ReleaseSafe,
|
||||||
|
.ReleaseSmall,
|
||||||
|
.ReleaseFast,
|
||||||
|
=> "Release",
|
||||||
|
};
|
||||||
|
|
||||||
|
const app_path = b.fmt("macos/build/{s}/Ghostty.app", .{xc_config});
|
||||||
|
|
||||||
|
// Our step to build the Ghostty macOS app.
|
||||||
|
const build = build: {
|
||||||
|
// External environment variables can mess up xcodebuild, so
|
||||||
|
// we create a new empty environment.
|
||||||
|
const env_map = try b.allocator.create(std.process.EnvMap);
|
||||||
|
env_map.* = .init(b.allocator);
|
||||||
|
|
||||||
|
const build = RunStep.create(b, "xcodebuild");
|
||||||
|
build.has_side_effects = true;
|
||||||
|
build.cwd = b.path("macos");
|
||||||
|
build.env_map = env_map;
|
||||||
|
build.addArgs(&.{
|
||||||
|
"xcodebuild",
|
||||||
|
"-target",
|
||||||
|
"Ghostty",
|
||||||
|
"-configuration",
|
||||||
|
xc_config,
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (deps.xcframework.target) {
|
||||||
|
// Universal is our default target, so we don't have to
|
||||||
|
// add anything.
|
||||||
|
.universal => {},
|
||||||
|
|
||||||
|
// Native we need to override the architecture in the Xcode
|
||||||
|
// project with the -arch flag.
|
||||||
|
.native => build.addArgs(&.{
|
||||||
|
"-arch",
|
||||||
|
switch (builtin.cpu.arch) {
|
||||||
|
.aarch64 => "arm64",
|
||||||
|
.x86_64 => "x86_64",
|
||||||
|
else => @panic("unsupported macOS arch"),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need the xcframework
|
||||||
|
deps.xcframework.addStepDependencies(&build.step);
|
||||||
|
|
||||||
|
// We also need all these resources because the xcode project
|
||||||
|
// references them via symlinks.
|
||||||
|
deps.resources.addStepDependencies(&build.step);
|
||||||
|
deps.i18n.addStepDependencies(&build.step);
|
||||||
|
deps.docs.installDummy(&build.step);
|
||||||
|
|
||||||
|
// Expect success
|
||||||
|
build.expectExitCode(0);
|
||||||
|
|
||||||
|
break :build build;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Our step to open the resulting Ghostty app.
|
||||||
|
const open = open: {
|
||||||
|
const open = RunStep.create(b, "run Ghostty app");
|
||||||
|
open.has_side_effects = true;
|
||||||
|
open.cwd = b.path("");
|
||||||
|
open.addArgs(&.{b.fmt(
|
||||||
|
"{s}/Contents/MacOS/ghostty",
|
||||||
|
.{app_path},
|
||||||
|
)});
|
||||||
|
|
||||||
|
// Open depends on the app
|
||||||
|
open.step.dependOn(&build.step);
|
||||||
|
|
||||||
|
// This overrides our default behavior and forces logs to show
|
||||||
|
// up on stderr (in addition to the centralized macOS log).
|
||||||
|
open.setEnvironmentVariable("GHOSTTY_LOG", "1");
|
||||||
|
|
||||||
|
// This is hack so that we can activate the app and bring it to
|
||||||
|
// the front forcibly even though we're executing directly
|
||||||
|
// via the binary and not launch services.
|
||||||
|
open.setEnvironmentVariable("GHOSTTY_MAC_ACTIVATE", "1");
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
open.addArgs(args);
|
||||||
|
} else {
|
||||||
|
// This tricks the app into thinking it's running from the
|
||||||
|
// app bundle so we don't execute our CLI mode.
|
||||||
|
open.setEnvironmentVariable("GHOSTTY_MAC_APP", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
break :open open;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Our step to copy the app bundle to the install path.
|
||||||
|
// We have to use `cp -R` because there are symlinks in the
|
||||||
|
// bundle.
|
||||||
|
const copy = copy: {
|
||||||
|
const step = RunStep.create(b, "copy app bundle");
|
||||||
|
step.addArgs(&.{ "cp", "-R" });
|
||||||
|
step.addFileArg(b.path(app_path));
|
||||||
|
step.addArg(b.fmt("{s}", .{b.install_path}));
|
||||||
|
step.step.dependOn(&build.step);
|
||||||
|
break :copy step;
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.build = build,
|
||||||
|
.open = open,
|
||||||
|
.copy = copy,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(self: *const Ghostty) void {
|
||||||
|
const b = self.copy.step.owner;
|
||||||
|
b.getInstallStep().dependOn(&self.copy.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn installXcframework(self: *const Ghostty) void {
|
||||||
|
const b = self.build.step.owner;
|
||||||
|
b.getInstallStep().dependOn(&self.build.step);
|
||||||
|
}
|
||||||
|
|
@ -515,17 +515,6 @@ pub fn add(
|
||||||
|
|
||||||
switch (self.config.app_runtime) {
|
switch (self.config.app_runtime) {
|
||||||
.none => {},
|
.none => {},
|
||||||
|
|
||||||
.glfw => if (b.lazyDependency("glfw", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
})) |glfw_dep| {
|
|
||||||
step.root_module.addImport(
|
|
||||||
"glfw",
|
|
||||||
glfw_dep.module("glfw"),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
.gtk => try self.addGTK(step),
|
.gtk => try self.addGTK(step),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,9 @@ pub fn create(b: *std.Build, opts: Options) *XCFrameworkStep {
|
||||||
}
|
}
|
||||||
run.addArg("-output");
|
run.addArg("-output");
|
||||||
run.addArg(opts.out_path);
|
run.addArg(opts.out_path);
|
||||||
|
run.expectExitCode(0);
|
||||||
|
_ = run.captureStdOut();
|
||||||
|
_ = run.captureStdErr();
|
||||||
break :run run;
|
break :run run;
|
||||||
};
|
};
|
||||||
run_create.step.dependOn(&run_delete.step);
|
run_create.step.dependOn(&run_delete.step);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ pub const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
||||||
pub const GhosttyLib = @import("GhosttyLib.zig");
|
pub const GhosttyLib = @import("GhosttyLib.zig");
|
||||||
pub const GhosttyResources = @import("GhosttyResources.zig");
|
pub const GhosttyResources = @import("GhosttyResources.zig");
|
||||||
pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
||||||
|
pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig");
|
||||||
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
||||||
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
||||||
pub const HelpStrings = @import("HelpStrings.zig");
|
pub const HelpStrings = @import("HelpStrings.zig");
|
||||||
|
|
|
||||||
|
|
@ -1582,9 +1582,9 @@ keybind: Keybinds = .{},
|
||||||
/// the visible screen area. This means that if the menu bar is visible, the
|
/// the visible screen area. This means that if the menu bar is visible, the
|
||||||
/// window will be placed below the menu bar.
|
/// window will be placed below the menu bar.
|
||||||
///
|
///
|
||||||
/// Note: this is only supported on macOS and Linux GLFW builds. The GTK
|
/// Note: this is only supported on macOS. The GTK runtime does not support
|
||||||
/// runtime does not support setting the window position, as windows are
|
/// setting the window position, as windows are only allowed position
|
||||||
/// only allowed position themselves in X11 and not Wayland.
|
/// themselves in X11 and not Wayland.
|
||||||
@"window-position-x": ?i16 = null,
|
@"window-position-x": ?i16 = null,
|
||||||
@"window-position-y": ?i16 = null,
|
@"window-position-y": ?i16 = null,
|
||||||
|
|
||||||
|
|
@ -2504,8 +2504,6 @@ keybind: Keybinds = .{},
|
||||||
///
|
///
|
||||||
/// The values `left` or `right` enable this for the left or right *Option*
|
/// The values `left` or `right` enable this for the left or right *Option*
|
||||||
/// key, respectively.
|
/// key, respectively.
|
||||||
///
|
|
||||||
/// This does not work with GLFW builds.
|
|
||||||
@"macos-option-as-alt": ?OptionAsAlt = null,
|
@"macos-option-as-alt": ?OptionAsAlt = null,
|
||||||
|
|
||||||
/// Whether to enable the macOS window shadow. The default value is true.
|
/// Whether to enable the macOS window shadow. The default value is true.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ const Allocator = std.mem.Allocator;
|
||||||
const posix = std.posix;
|
const posix = std.posix;
|
||||||
const build_config = @import("build_config.zig");
|
const build_config = @import("build_config.zig");
|
||||||
const options = @import("build_options");
|
const options = @import("build_options");
|
||||||
const glfw = @import("glfw");
|
|
||||||
const glslang = @import("glslang");
|
const glslang = @import("glslang");
|
||||||
const macos = @import("macos");
|
const macos = @import("macos");
|
||||||
const oni = @import("oniguruma");
|
const oni = @import("oniguruma");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const glfw = @import("glfw");
|
|
||||||
const objc = @import("objc");
|
const objc = @import("objc");
|
||||||
const macos = @import("macos");
|
const macos = @import("macos");
|
||||||
const graphics = macos.graphics;
|
const graphics = macos.graphics;
|
||||||
|
|
@ -38,11 +37,6 @@ pub const swap_chain_count = 3;
|
||||||
|
|
||||||
const log = std.log.scoped(.metal);
|
const log = std.log.scoped(.metal);
|
||||||
|
|
||||||
// Get native API access on certain platforms so we can do more customization.
|
|
||||||
const glfwNative = glfw.Native(.{
|
|
||||||
.cocoa = builtin.os.tag == .macos,
|
|
||||||
});
|
|
||||||
|
|
||||||
layer: IOSurfaceLayer,
|
layer: IOSurfaceLayer,
|
||||||
|
|
||||||
/// MTLDevice
|
/// MTLDevice
|
||||||
|
|
@ -87,27 +81,6 @@ pub fn init(alloc: Allocator, opts: rendererpkg.Options) !Metal {
|
||||||
|
|
||||||
// Get the metadata about our underlying view that we'll be rendering to.
|
// Get the metadata about our underlying view that we'll be rendering to.
|
||||||
const info: ViewInfo = switch (apprt.runtime) {
|
const info: ViewInfo = switch (apprt.runtime) {
|
||||||
apprt.glfw => info: {
|
|
||||||
// Everything in glfw is window-oriented so we grab the backing
|
|
||||||
// window, then derive everything from that.
|
|
||||||
const nswindow = objc.Object.fromId(glfwNative.getCocoaWindow(
|
|
||||||
opts.rt_surface.window,
|
|
||||||
).?);
|
|
||||||
|
|
||||||
const contentView = objc.Object.fromId(
|
|
||||||
nswindow.getProperty(?*anyopaque, "contentView").?,
|
|
||||||
);
|
|
||||||
const scaleFactor = nswindow.getProperty(
|
|
||||||
graphics.c.CGFloat,
|
|
||||||
"backingScaleFactor",
|
|
||||||
);
|
|
||||||
|
|
||||||
break :info .{
|
|
||||||
.view = contentView,
|
|
||||||
.scaleFactor = scaleFactor,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
apprt.embedded => .{
|
apprt.embedded => .{
|
||||||
.scaleFactor = @floatCast(opts.rt_surface.content_scale.x),
|
.scaleFactor = @floatCast(opts.rt_surface.content_scale.x),
|
||||||
.view = switch (opts.rt_surface.platform) {
|
.view = switch (opts.rt_surface.platform) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const glfw = @import("glfw");
|
|
||||||
const gl = @import("opengl");
|
const gl = @import("opengl");
|
||||||
const shadertoy = @import("shadertoy.zig");
|
const shadertoy = @import("shadertoy.zig");
|
||||||
const apprt = @import("../apprt.zig");
|
const apprt = @import("../apprt.zig");
|
||||||
|
|
@ -60,18 +59,6 @@ pub fn deinit(self: *OpenGL) void {
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the hints that we want for this
|
|
||||||
pub fn glfwWindowHints(config: *const configpkg.Config) glfw.Window.Hints {
|
|
||||||
_ = config;
|
|
||||||
return .{
|
|
||||||
.context_version_major = MIN_VERSION_MAJOR,
|
|
||||||
.context_version_minor = MIN_VERSION_MINOR,
|
|
||||||
.opengl_profile = .opengl_core_profile,
|
|
||||||
.opengl_forward_compat = true,
|
|
||||||
.transparent_framebuffer = true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 32-bit windows cross-compilation breaks with `.c` for some reason, so...
|
/// 32-bit windows cross-compilation breaks with `.c` for some reason, so...
|
||||||
const gl_debug_proc_callconv =
|
const gl_debug_proc_callconv =
|
||||||
@typeInfo(
|
@typeInfo(
|
||||||
|
|
@ -172,8 +159,7 @@ fn prepareContext(getProcAddress: anytype) !void {
|
||||||
|
|
||||||
/// This is called early right after surface creation.
|
/// This is called early right after surface creation.
|
||||||
pub fn surfaceInit(surface: *apprt.Surface) !void {
|
pub fn surfaceInit(surface: *apprt.Surface) !void {
|
||||||
// Treat this like a thread entry
|
_ = surface;
|
||||||
const self: OpenGL = undefined;
|
|
||||||
|
|
||||||
switch (apprt.runtime) {
|
switch (apprt.runtime) {
|
||||||
else => @compileError("unsupported app runtime for OpenGL"),
|
else => @compileError("unsupported app runtime for OpenGL"),
|
||||||
|
|
@ -181,8 +167,6 @@ pub fn surfaceInit(surface: *apprt.Surface) !void {
|
||||||
// GTK uses global OpenGL context so we load from null.
|
// GTK uses global OpenGL context so we load from null.
|
||||||
apprt.gtk => try prepareContext(null),
|
apprt.gtk => try prepareContext(null),
|
||||||
|
|
||||||
apprt.glfw => try self.threadEnter(surface),
|
|
||||||
|
|
||||||
apprt.embedded => {
|
apprt.embedded => {
|
||||||
// TODO(mitchellh): this does nothing today to allow libghostty
|
// TODO(mitchellh): this does nothing today to allow libghostty
|
||||||
// to compile for OpenGL targets but libghostty is strictly
|
// to compile for OpenGL targets but libghostty is strictly
|
||||||
|
|
@ -205,17 +189,12 @@ pub fn surfaceInit(surface: *apprt.Surface) !void {
|
||||||
pub fn finalizeSurfaceInit(self: *const OpenGL, surface: *apprt.Surface) !void {
|
pub fn finalizeSurfaceInit(self: *const OpenGL, surface: *apprt.Surface) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
_ = surface;
|
_ = surface;
|
||||||
|
|
||||||
// For GLFW, we grabbed the OpenGL context in surfaceInit and
|
|
||||||
// we need to release it before we start the renderer thread.
|
|
||||||
if (apprt.runtime == apprt.glfw) {
|
|
||||||
glfw.makeContextCurrent(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback called by renderer.Thread when it begins.
|
/// Callback called by renderer.Thread when it begins.
|
||||||
pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
|
pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
_ = surface;
|
||||||
|
|
||||||
switch (apprt.runtime) {
|
switch (apprt.runtime) {
|
||||||
else => @compileError("unsupported app runtime for OpenGL"),
|
else => @compileError("unsupported app runtime for OpenGL"),
|
||||||
|
|
@ -227,21 +206,6 @@ pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
|
||||||
// on the main thread. As such, we don't do anything here.
|
// on the main thread. As such, we don't do anything here.
|
||||||
},
|
},
|
||||||
|
|
||||||
apprt.glfw => {
|
|
||||||
// We need to make the OpenGL context current. OpenGL requires
|
|
||||||
// that a single thread own the a single OpenGL context (if any).
|
|
||||||
// This ensures that the context switches over to our thread.
|
|
||||||
// Important: the prior thread MUST have detached the context
|
|
||||||
// prior to calling this entrypoint.
|
|
||||||
glfw.makeContextCurrent(surface.window);
|
|
||||||
errdefer glfw.makeContextCurrent(null);
|
|
||||||
glfw.swapInterval(1);
|
|
||||||
|
|
||||||
// Load OpenGL bindings. This API is context-aware so this sets
|
|
||||||
// a threadlocal context for these pointers.
|
|
||||||
try prepareContext(&glfw.getProcAddress);
|
|
||||||
},
|
|
||||||
|
|
||||||
apprt.embedded => {
|
apprt.embedded => {
|
||||||
// TODO(mitchellh): this does nothing today to allow libghostty
|
// TODO(mitchellh): this does nothing today to allow libghostty
|
||||||
// to compile for OpenGL targets but libghostty is strictly
|
// to compile for OpenGL targets but libghostty is strictly
|
||||||
|
|
@ -262,11 +226,6 @@ pub fn threadExit(self: *const OpenGL) void {
|
||||||
// be sharing the global bindings with other windows.
|
// be sharing the global bindings with other windows.
|
||||||
},
|
},
|
||||||
|
|
||||||
apprt.glfw => {
|
|
||||||
gl.glad.unload();
|
|
||||||
glfw.makeContextCurrent(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
apprt.embedded => {
|
apprt.embedded => {
|
||||||
// TODO: see threadEnter
|
// TODO: see threadEnter
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const glfw = @import("glfw");
|
|
||||||
const xev = @import("xev");
|
const xev = @import("xev");
|
||||||
const wuffs = @import("wuffs");
|
const wuffs = @import("wuffs");
|
||||||
const apprt = @import("../apprt.zig");
|
const apprt = @import("../apprt.zig");
|
||||||
|
|
@ -606,20 +605,6 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the hints that we want for this window.
|
|
||||||
pub fn glfwWindowHints(config: *const configpkg.Config) glfw.Window.Hints {
|
|
||||||
// If our graphics API provides hints, use them,
|
|
||||||
// otherwise fall back to generic hints.
|
|
||||||
if (@hasDecl(GraphicsAPI, "glfwWindowHints")) {
|
|
||||||
return GraphicsAPI.glfwWindowHints(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
return .{
|
|
||||||
.client_api = .no_api,
|
|
||||||
.transparent_framebuffer = config.@"background-opacity" < 1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(alloc: Allocator, options: renderer.Options) !Self {
|
pub fn init(alloc: Allocator, options: renderer.Options) !Self {
|
||||||
// Initialize our graphics API wrapper, this will prepare the
|
// Initialize our graphics API wrapper, this will prepare the
|
||||||
// surface provided by the apprt and set up any API-specific
|
// surface provided by the apprt and set up any API-specific
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,6 @@ const posix = std.posix;
|
||||||
|
|
||||||
const log = std.log.scoped(.io_handler);
|
const log = std.log.scoped(.io_handler);
|
||||||
|
|
||||||
/// True if we should disable the kitty keyboard protocol. We have to
|
|
||||||
/// disable this on GLFW because GLFW input events don't support the
|
|
||||||
/// correct granularity of events.
|
|
||||||
const disable_kitty_keyboard_protocol = apprt.runtime == apprt.glfw;
|
|
||||||
|
|
||||||
/// This is used as the handler for the terminal.Stream type. This is
|
/// This is used as the handler for the terminal.Stream type. This is
|
||||||
/// stateful and is expected to live for the entire lifetime of the terminal.
|
/// stateful and is expected to live for the entire lifetime of the terminal.
|
||||||
/// It is NOT VALID to stop a stream handler, create a new one, and use that
|
/// It is NOT VALID to stop a stream handler, create a new one, and use that
|
||||||
|
|
@ -913,8 +908,6 @@ pub const StreamHandler = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn queryKittyKeyboard(self: *StreamHandler) !void {
|
pub fn queryKittyKeyboard(self: *StreamHandler) !void {
|
||||||
if (comptime disable_kitty_keyboard_protocol) return;
|
|
||||||
|
|
||||||
log.debug("querying kitty keyboard mode", .{});
|
log.debug("querying kitty keyboard mode", .{});
|
||||||
var data: termio.Message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
const resp = try std.fmt.bufPrint(&data, "\x1b[?{}u", .{
|
const resp = try std.fmt.bufPrint(&data, "\x1b[?{}u", .{
|
||||||
|
|
@ -933,15 +926,11 @@ pub const StreamHandler = struct {
|
||||||
self: *StreamHandler,
|
self: *StreamHandler,
|
||||||
flags: terminal.kitty.KeyFlags,
|
flags: terminal.kitty.KeyFlags,
|
||||||
) !void {
|
) !void {
|
||||||
if (comptime disable_kitty_keyboard_protocol) return;
|
|
||||||
|
|
||||||
log.debug("pushing kitty keyboard mode: {}", .{flags});
|
log.debug("pushing kitty keyboard mode: {}", .{flags});
|
||||||
self.terminal.screen.kitty_keyboard.push(flags);
|
self.terminal.screen.kitty_keyboard.push(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn popKittyKeyboard(self: *StreamHandler, n: u16) !void {
|
pub fn popKittyKeyboard(self: *StreamHandler, n: u16) !void {
|
||||||
if (comptime disable_kitty_keyboard_protocol) return;
|
|
||||||
|
|
||||||
log.debug("popping kitty keyboard mode n={}", .{n});
|
log.debug("popping kitty keyboard mode n={}", .{n});
|
||||||
self.terminal.screen.kitty_keyboard.pop(@intCast(n));
|
self.terminal.screen.kitty_keyboard.pop(@intCast(n));
|
||||||
}
|
}
|
||||||
|
|
@ -951,8 +940,6 @@ pub const StreamHandler = struct {
|
||||||
mode: terminal.kitty.KeySetMode,
|
mode: terminal.kitty.KeySetMode,
|
||||||
flags: terminal.kitty.KeyFlags,
|
flags: terminal.kitty.KeyFlags,
|
||||||
) !void {
|
) !void {
|
||||||
if (comptime disable_kitty_keyboard_protocol) return;
|
|
||||||
|
|
||||||
log.debug("setting kitty keyboard mode: {} {}", .{ mode, flags });
|
log.debug("setting kitty keyboard mode: {} {}", .{ mode, flags });
|
||||||
self.terminal.screen.kitty_keyboard.set(mode, flags);
|
self.terminal.screen.kitty_keyboard.set(mode, flags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue